blob: 73026c86a534287689435184a9f8db402a88ad47 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifdef _WIN32
# include <windows.h>
#endif
#include <sql.h>
#include <sqlext.h>
#include <vector>
#include <string>
#include <algorithm>
#include <boost/test/unit_test.hpp>
#include "ignite/ignition.h"
#include "ignite/common/fixed_size_array.h"
#include "ignite/impl/binary/binary_utils.h"
#include "test_type.h"
#include "complex_type.h"
#include "test_utils.h"
#include "odbc_test_suite.h"
using namespace ignite;
using namespace ignite::cache;
using namespace ignite::cache::query;
using namespace ignite::common;
using namespace ignite_test;
using namespace ignite::binary;
using namespace ignite::impl::binary;
using namespace ignite::impl::interop;
using namespace boost::unit_test;
/**
* Test setup fixture.
*/
struct MetaQueriesTestSuiteFixture : public odbc::OdbcTestSuite
{
/**
* Start additional node with the specified name.
*
* @param name Node name.
*/
static Ignite StartAdditionalNode(const char* name)
{
return StartPlatformNode("queries-test.xml", name);
}
/**
* Checks single row result set for correct work with SQLGetData.
*
* @param stmt Statement.
*/
void CheckSingleRowResultSetWithGetData(SQLHSTMT stmt)
{
SQLRETURN ret = SQLFetch(stmt);
if (!SQL_SUCCEEDED(ret))
BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
char buf[1024];
SQLLEN bufLen = sizeof(buf);
ret = SQLGetData(stmt, 1, SQL_C_CHAR, buf, sizeof(buf), &bufLen);
if (!SQL_SUCCEEDED(ret))
BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
ret = SQLFetch(stmt);
BOOST_REQUIRE_EQUAL(ret, SQL_NO_DATA);
ret = SQLGetData(stmt, 1, SQL_C_CHAR, buf, sizeof(buf), &bufLen);
BOOST_REQUIRE_EQUAL(ret, SQL_ERROR);
BOOST_CHECK_EQUAL(GetOdbcErrorState(SQL_HANDLE_STMT, stmt), "24000");
}
/**
* Check string column.
*
* @param stmt Statement.
* @param colId Column ID to check.
* @param value Expected value.
*/
void CheckStringColumn(SQLHSTMT stmt, int colId, const std::string& value)
{
char buf[1024];
SQLLEN bufLen = sizeof(buf);
SQLRETURN ret = SQLGetData(stmt, colId, SQL_C_CHAR, buf, sizeof(buf), &bufLen);
if (!SQL_SUCCEEDED(ret))
BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
if (bufLen <= 0)
BOOST_CHECK(value.empty());
else
BOOST_CHECK_EQUAL(std::string(buf, static_cast<size_t>(bufLen)), value);
}
/**
* Constructor.
*/
MetaQueriesTestSuiteFixture() :
grid(0),
cache1(0),
cache2(0)
{
grid = StartPlatformNode("queries-test.xml", "NodeMain");
cache1 = grid.GetCache<int64_t, TestType>("cache");
cache2 = grid.GetCache<int64_t, ComplexType>("cache2");
}
/**
* Check result set column metadata using SQLDescribeCol.
*
* @param stmt Statement.
* @param idx Index.
* @param expName Expected name.
* @param expDataType Expected data type.
* @param expSize Expected column size.
* @param expScale Expected column scale.
* @param expNullability expected nullability.
*/
void CheckColumnMetaWithSQLDescribeCol(SQLHSTMT stmt, SQLUSMALLINT idx, const std::string& expName,
SQLSMALLINT expDataType, SQLULEN expSize, SQLSMALLINT expScale, SQLSMALLINT expNullability)
{
std::vector<SQLCHAR> name(ODBC_BUFFER_SIZE);
SQLSMALLINT nameLen = 0;
SQLSMALLINT dataType = 0;
SQLULEN size;
SQLSMALLINT scale;
SQLSMALLINT nullability;
SQLRETURN ret = SQLDescribeCol(stmt, idx, &name[0], (SQLSMALLINT)name.size(), &nameLen, &dataType, &size, &scale, &nullability);
ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);
BOOST_CHECK_GE(nameLen, 0);
BOOST_CHECK_LE(nameLen, static_cast<SQLSMALLINT>(ODBC_BUFFER_SIZE));
std::string nameStr(name.begin(), name.begin() + nameLen);
BOOST_CHECK_EQUAL(nameStr, expName);
BOOST_CHECK_EQUAL(dataType, expDataType);
BOOST_CHECK_EQUAL(size, expSize);
BOOST_CHECK_EQUAL(scale, expScale);
BOOST_CHECK_EQUAL(nullability, expNullability);
}
/**
* @param func Function to call before tests. May be PrepareQuery or ExecQuery.
*
* 1. Start node.
* 2. Connect to node using ODBC.
* 3. Create table with decimal and char columns with specified size and scale.
* 4. Execute or prepare statement.
* 5. Check presicion and scale of every column using SQLDescribeCol.
*/
template<typename F>
void CheckSQLDescribeColPrecisionAndScale(F func)
{
Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=PUBLIC");
SQLRETURN ret = ExecQuery(
"create table TestScalePrecision("
" id int primary key,"
" dec1 decimal(3,0),"
" dec2 decimal(42,12),"
" dec3 decimal,"
" char1 char(3),"
" char2 char(42),"
" char3 char not null,"
" vchar varchar"
")");
ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);
ret = SQLFreeStmt(stmt, SQL_CLOSE);
ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);
ret = ExecQuery(
"insert into "
"TestScalePrecision(id, dec1, dec2, dec3, char1, char2, char3, vchar) "
"values (1, 12, 160.23, -1234.56789, 'TST', 'Lorem Ipsum', 'Some test value', 'Some test varchar')");
ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);
ret = SQLFreeStmt(stmt, SQL_CLOSE);
ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);
ret = (this->*func)("select id, dec1, dec2, dec3, char1, char2, char3, vchar from PUBLIC.TestScalePrecision");
ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);
SQLSMALLINT columnCount = 0;
ret = SQLNumResultCols(stmt, &columnCount);
ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);
BOOST_CHECK_EQUAL(columnCount, 8);
CheckColumnMetaWithSQLDescribeCol(stmt, 1, "ID", SQL_INTEGER, 10, 0, SQL_NULLABLE);
CheckColumnMetaWithSQLDescribeCol(stmt, 2, "DEC1", SQL_DECIMAL, 3, 0, SQL_NULLABLE);
CheckColumnMetaWithSQLDescribeCol(stmt, 3, "DEC2", SQL_DECIMAL, 42, 12, SQL_NULLABLE);
CheckColumnMetaWithSQLDescribeCol(stmt, 4, "DEC3", SQL_DECIMAL, 65535, 32767, SQL_NULLABLE);
CheckColumnMetaWithSQLDescribeCol(stmt, 5, "CHAR1", SQL_VARCHAR, 3, 0, SQL_NULLABLE);
CheckColumnMetaWithSQLDescribeCol(stmt, 6, "CHAR2", SQL_VARCHAR, 42, 0, SQL_NULLABLE);
CheckColumnMetaWithSQLDescribeCol(stmt, 7, "CHAR3", SQL_VARCHAR, 2147483647, 0, SQL_NO_NULLS);
CheckColumnMetaWithSQLDescribeCol(stmt, 8, "VCHAR", SQL_VARCHAR, 2147483647, 0, SQL_NULLABLE);
}
/**
* Check result set column metadata using SQLColAttribute.
*
* @param stmt Statement.
* @param idx Index.
* @param expName Expected name.
* @param expDataType Expected data type.
* @param expSize Expected column size.
* @param expScale Expected column scale.
* @param expNullability expected nullability.
*/
void CheckColumnMetaWithSQLColAttribute(SQLHSTMT stmt, SQLUSMALLINT idx, const std::string& expName,
SQLLEN expDataType, SQLULEN expSize, SQLLEN expScale, SQLLEN expNullability)
{
std::vector<SQLCHAR> name(ODBC_BUFFER_SIZE);
SQLSMALLINT nameLen = 0;
SQLLEN dataType = 0;
SQLLEN size;
SQLLEN scale;
SQLLEN nullability;
SQLRETURN ret = SQLColAttribute(stmt, idx, SQL_DESC_NAME, &name[0], (SQLSMALLINT)name.size(), &nameLen, 0);
ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);
ret = SQLColAttribute(stmt, idx, SQL_DESC_TYPE, 0, 0, 0, &dataType);
ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);
ret = SQLColAttribute(stmt, idx, SQL_DESC_PRECISION, 0, 0, 0, &size);
ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);
ret = SQLColAttribute(stmt, idx, SQL_DESC_SCALE, 0, 0, 0, &scale);
ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);
ret = SQLColAttribute(stmt, idx, SQL_DESC_NULLABLE, 0, 0, 0, &nullability);
ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);
BOOST_CHECK_GE(nameLen, 0);
BOOST_CHECK_LE(nameLen, static_cast<SQLSMALLINT>(ODBC_BUFFER_SIZE));
std::string nameStr(name.begin(), name.begin() + nameLen);
BOOST_CHECK_EQUAL(nameStr, expName);
BOOST_CHECK_EQUAL(dataType, expDataType);
BOOST_CHECK_EQUAL(size, expSize);
BOOST_CHECK_EQUAL(scale, expScale);
BOOST_CHECK_EQUAL(nullability, expNullability);
}
/**
* @param func Function to call before tests. May be PrepareQuery or ExecQuery.
*
* 1. Start node.
* 2. Connect to node using ODBC.
* 3. Create table with decimal and char columns with specified size and scale.
* 4. Execute or prepare statement.
* 5. Check presicion and scale of every column using SQLColAttribute.
*/
template<typename F>
void CheckSQLColAttributePrecisionAndScale(F func)
{
Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=PUBLIC");
SQLRETURN ret = ExecQuery(
"create table TestScalePrecision("
" id int primary key,"
" dec1 decimal(3,0),"
" dec2 decimal(42,12),"
" dec3 decimal,"
" char1 char(3),"
" char2 char(42),"
" char3 char not null,"
" vchar varchar"
")");
ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);
ret = SQLFreeStmt(stmt, SQL_CLOSE);
ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);
ret = ExecQuery(
"insert into "
"TestScalePrecision(id, dec1, dec2, dec3, char1, char2, char3, vchar) "
"values (1, 12, 160.23, -1234.56789, 'TST', 'Lorem Ipsum', 'Some test value', 'Some test varchar')");
ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);
ret = SQLFreeStmt(stmt, SQL_CLOSE);
ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);
ret = (this->*func)("select id, dec1, dec2, dec3, char1, char2, char3, vchar from PUBLIC.TestScalePrecision");
ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);
SQLSMALLINT columnCount = 0;
ret = SQLNumResultCols(stmt, &columnCount);
ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);
BOOST_CHECK_EQUAL(columnCount, 8);
CheckColumnMetaWithSQLColAttribute(stmt, 1, "ID", SQL_INTEGER, 10, 0, SQL_NULLABLE);
CheckColumnMetaWithSQLColAttribute(stmt, 2, "DEC1", SQL_DECIMAL, 3, 0, SQL_NULLABLE);
CheckColumnMetaWithSQLColAttribute(stmt, 3, "DEC2", SQL_DECIMAL, 42, 12, SQL_NULLABLE);
CheckColumnMetaWithSQLColAttribute(stmt, 4, "DEC3", SQL_DECIMAL, 65535, 32767, SQL_NULLABLE);
CheckColumnMetaWithSQLColAttribute(stmt, 5, "CHAR1", SQL_VARCHAR, 3, 0, SQL_NULLABLE);
CheckColumnMetaWithSQLColAttribute(stmt, 6, "CHAR2", SQL_VARCHAR, 42, 0, SQL_NULLABLE);
CheckColumnMetaWithSQLColAttribute(stmt, 7, "CHAR3", SQL_VARCHAR, 2147483647, 0, SQL_NO_NULLS);
CheckColumnMetaWithSQLColAttribute(stmt, 8, "VCHAR", SQL_VARCHAR, 2147483647, 0, SQL_NULLABLE);
}
/**
* Destructor.
*/
~MetaQueriesTestSuiteFixture()
{
// No-op.
}
/** Node started during the test. */
Ignite grid;
/** Frist cache instance. */
Cache<int64_t, TestType> cache1;
/** Second cache instance. */
Cache<int64_t, ComplexType> cache2;
};
BOOST_FIXTURE_TEST_SUITE(MetaQueriesTestSuite, MetaQueriesTestSuiteFixture)
BOOST_AUTO_TEST_CASE(TestGetTypeInfoAllTypes)
{
Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=cache");
SQLRETURN ret = SQLGetTypeInfo(stmt, SQL_ALL_TYPES);
if (!SQL_SUCCEEDED(ret))
BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
}
BOOST_AUTO_TEST_CASE(TestDateTypeColumnAttributeCurdate)
{
Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=cache");
SQLCHAR req[] = "select CURDATE()";
SQLExecDirect(stmt, req, SQL_NTS);
SQLLEN intVal = 0;
SQLRETURN ret = SQLColAttribute(stmt, 1, SQL_DESC_TYPE, 0, 0, 0, &intVal);
if (!SQL_SUCCEEDED(ret))
BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
BOOST_CHECK_EQUAL(intVal, SQL_TYPE_DATE);
}
BOOST_AUTO_TEST_CASE(TestDateTypeColumnAttributeLiteral)
{
Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=cache");
SQLCHAR req[] = "select DATE '2020-10-25'";
SQLExecDirect(stmt, req, SQL_NTS);
SQLLEN intVal = 0;
SQLRETURN ret = SQLColAttribute(stmt, 1, SQL_DESC_TYPE, 0, 0, 0, &intVal);
if (!SQL_SUCCEEDED(ret))
BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
BOOST_CHECK_EQUAL(intVal, SQL_TYPE_DATE);
}
BOOST_AUTO_TEST_CASE(TestDateTypeColumnAttributeField)
{
Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=cache");
SQLCHAR req[] = "select CAST (dateField as DATE) from TestType";
SQLExecDirect(stmt, req, SQL_NTS);
SQLLEN intVal = 0;
SQLRETURN ret = SQLColAttribute(stmt, 1, SQL_DESC_TYPE, 0, 0, 0, &intVal);
if (!SQL_SUCCEEDED(ret))
BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
BOOST_CHECK_EQUAL(intVal, SQL_TYPE_DATE);
}
BOOST_AUTO_TEST_CASE(TestTimeTypeColumnAttributeLiteral)
{
Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=cache");
SQLCHAR req[] = "select TIME '12:42:13'";
SQLExecDirect(stmt, req, SQL_NTS);
SQLLEN intVal = 0;
SQLRETURN ret = SQLColAttribute(stmt, 1, SQL_DESC_TYPE, 0, 0, 0, &intVal);
if (!SQL_SUCCEEDED(ret))
BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
BOOST_CHECK_EQUAL(intVal, SQL_TYPE_TIME);
}
BOOST_AUTO_TEST_CASE(TestTimeTypeColumnAttributeField)
{
Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=cache");
SQLCHAR req[] = "select timeField from TestType";
SQLExecDirect(stmt, req, SQL_NTS);
SQLLEN intVal = 0;
SQLRETURN ret = SQLColAttribute(stmt, 1, SQL_DESC_TYPE, 0, 0, 0, &intVal);
if (!SQL_SUCCEEDED(ret))
BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
BOOST_CHECK_EQUAL(intVal, SQL_TYPE_TIME);
}
BOOST_AUTO_TEST_CASE(TestColAttributesColumnLength)
{
Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=cache");
SQLCHAR req[] = "select strField from TestType";
SQLExecDirect(stmt, req, SQL_NTS);
SQLLEN intVal;
SQLCHAR strBuf[1024];
SQLSMALLINT strLen;
SQLRETURN ret = SQLColAttribute(stmt, 1, SQL_COLUMN_LENGTH, strBuf, sizeof(strBuf), &strLen, &intVal);
if (!SQL_SUCCEEDED(ret))
BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
BOOST_CHECK_EQUAL(intVal, 60);
}
BOOST_AUTO_TEST_CASE(TestColAttributesColumnPresicion)
{
Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=cache");
SQLCHAR req[] = "select strField from TestType";
SQLExecDirect(stmt, req, SQL_NTS);
SQLLEN intVal;
SQLCHAR strBuf[1024];
SQLSMALLINT strLen;
SQLRETURN ret = SQLColAttribute(stmt, 1, SQL_COLUMN_PRECISION, strBuf, sizeof(strBuf), &strLen, &intVal);
if (!SQL_SUCCEEDED(ret))
BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
BOOST_CHECK_EQUAL(intVal, 60);
}
BOOST_AUTO_TEST_CASE(TestColAttributesColumnScale)
{
Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=cache");
SQLCHAR req[] = "select strField from TestType";
SQLExecDirect(stmt, req, SQL_NTS);
SQLLEN intVal;
SQLCHAR strBuf[1024];
SQLSMALLINT strLen;
SQLRETURN ret = SQLColAttribute(stmt, 1, SQL_COLUMN_SCALE, strBuf, sizeof(strBuf), &strLen, &intVal);
if (!SQL_SUCCEEDED(ret))
BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
}
BOOST_AUTO_TEST_CASE(TestColAttributesColumnLengthPrepare)
{
StartAdditionalNode("Node2");
Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=cache");
InsertTestStrings(1);
SQLCHAR req[] = "select strField from TestType";
SQLPrepare(stmt, req, SQL_NTS);
SQLLEN intVal;
SQLCHAR strBuf[1024];
SQLSMALLINT strLen;
SQLRETURN ret = SQLColAttribute(stmt, 1, SQL_COLUMN_LENGTH, strBuf, sizeof(strBuf), &strLen, &intVal);
if (!SQL_SUCCEEDED(ret))
BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
BOOST_CHECK_EQUAL(intVal, 60);
ret = SQLExecute(stmt);
ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);
ret = SQLColAttribute(stmt, 1, SQL_COLUMN_LENGTH, strBuf, sizeof(strBuf), &strLen, &intVal);
if (!SQL_SUCCEEDED(ret))
BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
BOOST_CHECK_EQUAL(intVal, 60);
}
BOOST_AUTO_TEST_CASE(TestColAttributesColumnPresicionPrepare)
{
StartAdditionalNode("Node2");
Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=cache");
InsertTestStrings(1);
SQLCHAR req[] = "select strField from TestType";
SQLPrepare(stmt, req, SQL_NTS);
SQLLEN intVal;
SQLCHAR strBuf[1024];
SQLSMALLINT strLen;
SQLRETURN ret = SQLColAttribute(stmt, 1, SQL_COLUMN_PRECISION, strBuf, sizeof(strBuf), &strLen, &intVal);
if (!SQL_SUCCEEDED(ret))
BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
BOOST_CHECK_EQUAL(intVal, 60);
ret = SQLExecute(stmt);
ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);
ret = SQLColAttribute(stmt, 1, SQL_COLUMN_PRECISION, strBuf, sizeof(strBuf), &strLen, &intVal);
if (!SQL_SUCCEEDED(ret))
BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
BOOST_CHECK_EQUAL(intVal, 60);
}
BOOST_AUTO_TEST_CASE(TestColAttributesColumnScalePrepare)
{
StartAdditionalNode("Node2");
Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=cache");
InsertTestStrings(1);
SQLCHAR req[] = "select strField from TestType";
SQLPrepare(stmt, req, SQL_NTS);
SQLLEN intVal;
SQLCHAR strBuf[1024];
SQLSMALLINT strLen;
SQLRETURN ret = SQLColAttribute(stmt, 1, SQL_COLUMN_SCALE, strBuf, sizeof(strBuf), &strLen, &intVal);
if (!SQL_SUCCEEDED(ret))
BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
ret = SQLExecute(stmt);
ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);
ret = SQLColAttribute(stmt, 1, SQL_COLUMN_SCALE, strBuf, sizeof(strBuf), &strLen, &intVal);
if (!SQL_SUCCEEDED(ret))
BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
}
BOOST_AUTO_TEST_CASE(TestGetDataWithGetTypeInfo)
{
Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=cache");
SQLRETURN ret = SQLGetTypeInfo(stmt, SQL_VARCHAR);
if (!SQL_SUCCEEDED(ret))
BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
CheckSingleRowResultSetWithGetData(stmt);
}
BOOST_AUTO_TEST_CASE(TestGetDataWithTables)
{
Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=cache");
SQLCHAR empty[] = "";
SQLCHAR table[] = "TestType";
SQLRETURN ret = SQLTables(stmt, empty, SQL_NTS, empty, SQL_NTS, table, SQL_NTS, empty, SQL_NTS);
if (!SQL_SUCCEEDED(ret))
BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
CheckSingleRowResultSetWithGetData(stmt);
}
BOOST_AUTO_TEST_CASE(TestGetDataWithColumns)
{
Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=cache");
SQLCHAR empty[] = "";
SQLCHAR table[] = "TestType";
SQLCHAR column[] = "strField";
SQLRETURN ret = SQLColumns(stmt, empty, SQL_NTS, empty, SQL_NTS, table, SQL_NTS, column, SQL_NTS);
if (!SQL_SUCCEEDED(ret))
BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
CheckSingleRowResultSetWithGetData(stmt);
}
BOOST_AUTO_TEST_CASE(TestGetDataWithSelectQuery)
{
Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=cache");
SQLCHAR insertReq[] = "insert into TestType(_key, strField) VALUES(1, 'Lorem ipsum')";
SQLRETURN ret = SQLExecDirect(stmt, insertReq, SQL_NTS);
if (!SQL_SUCCEEDED(ret))
BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
SQLCHAR selectReq[] = "select strField from TestType";
ret = SQLExecDirect(stmt, selectReq, SQL_NTS);
if (!SQL_SUCCEEDED(ret))
BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
CheckSingleRowResultSetWithGetData(stmt);
}
BOOST_AUTO_TEST_CASE(TestInsertTooLongValueFail)
{
Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=cache");
SQLCHAR insertReq[] =
"insert into TestType(_key, strField) VALUES(42, '0123456789012345678901234567890123456789012345678901234567891')";
SQLRETURN ret = SQLExecDirect(stmt, insertReq, SQL_NTS);
if (SQL_SUCCEEDED(ret))
BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
}
BOOST_AUTO_TEST_CASE(TestGetInfoScrollOptions)
{
Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=cache");
SQLUINTEGER val = 0;
SQLRETURN ret = SQLGetInfo(dbc, SQL_SCROLL_OPTIONS, &val, 0, 0);
if (!SQL_SUCCEEDED(ret))
BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_DBC, dbc));
BOOST_CHECK_NE(val, 0);
}
BOOST_AUTO_TEST_CASE(TestDdlTablesMeta)
{
Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=PUBLIC");
SQLCHAR createTable[] = "create table TestTable(id int primary key, testColumn varchar)";
SQLRETURN ret = SQLExecDirect(stmt, createTable, SQL_NTS);
if (!SQL_SUCCEEDED(ret))
BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
SQLCHAR empty[] = "";
SQLCHAR table[] = "TestTable";
ret = SQLTables(stmt, empty, SQL_NTS, empty, SQL_NTS, table, SQL_NTS, empty, SQL_NTS);
if (!SQL_SUCCEEDED(ret))
BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
ret = SQLFetch(stmt);
if (!SQL_SUCCEEDED(ret))
BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
CheckStringColumn(stmt, 1, "");
CheckStringColumn(stmt, 2, "\"PUBLIC\"");
CheckStringColumn(stmt, 3, "TESTTABLE");
CheckStringColumn(stmt, 4, "TABLE");
ret = SQLFetch(stmt);
BOOST_REQUIRE_EQUAL(ret, SQL_NO_DATA);
}
BOOST_AUTO_TEST_CASE(TestDdlTablesMetaTableTypeList)
{
Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=PUBLIC");
SQLCHAR createTable[] = "create table TestTable(id int primary key, testColumn varchar)";
SQLRETURN ret = SQLExecDirect(stmt, createTable, SQL_NTS);
if (!SQL_SUCCEEDED(ret))
BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
SQLCHAR* typeLists[] = {(SQLCHAR*)"'TABLE'", (SQLCHAR*)"TABLE,VIEW"};
for (size_t i = 0; i < sizeof(typeLists) / sizeof(*typeLists); ++i) {
SQLCHAR empty[] = "";
SQLCHAR table[] = "TestTable";
ret = SQLTables(stmt, empty, SQL_NTS, empty, SQL_NTS, table, SQL_NTS, typeLists[i], SQL_NTS);
if (!SQL_SUCCEEDED(ret))
BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
ret = SQLFetch(stmt);
if (!SQL_SUCCEEDED(ret))
BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
CheckStringColumn(stmt, 1, "");
CheckStringColumn(stmt, 2, "\"PUBLIC\"");
CheckStringColumn(stmt, 3, "TESTTABLE");
CheckStringColumn(stmt, 4, "TABLE");
ret = SQLFetch(stmt);
BOOST_REQUIRE_EQUAL(ret, SQL_NO_DATA);
}
}
BOOST_AUTO_TEST_CASE(TestDdlColumnsMeta)
{
Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=PUBLIC");
SQLCHAR createTable[] = "create table TestTable(id int primary key, testColumn varchar)";
SQLRETURN ret = SQLExecDirect(stmt, createTable, SQL_NTS);
if (!SQL_SUCCEEDED(ret))
BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
SQLCHAR empty[] = "";
SQLCHAR table[] = "TestTable";
ret = SQLColumns(stmt, empty, SQL_NTS, empty, SQL_NTS, table, SQL_NTS, empty, SQL_NTS);
if (!SQL_SUCCEEDED(ret))
BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
ret = SQLFetch(stmt);
if (!SQL_SUCCEEDED(ret))
BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
CheckStringColumn(stmt, 1, "");
CheckStringColumn(stmt, 2, "\"PUBLIC\"");
CheckStringColumn(stmt, 3, "TESTTABLE");
CheckStringColumn(stmt, 4, "ID");
ret = SQLFetch(stmt);
if (!SQL_SUCCEEDED(ret))
BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
CheckStringColumn(stmt, 1, "");
CheckStringColumn(stmt, 2, "\"PUBLIC\"");
CheckStringColumn(stmt, 3, "TESTTABLE");
CheckStringColumn(stmt, 4, "TESTCOLUMN");
ret = SQLFetch(stmt);
BOOST_REQUIRE_EQUAL(ret, SQL_NO_DATA);
}
BOOST_AUTO_TEST_CASE(TestDdlColumnsMetaEscaped)
{
Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=PUBLIC");
SQLCHAR createTable[] = "create table ESG_FOCUS(id int primary key, TEST_COLUMN varchar)";
SQLRETURN ret = SQLExecDirect(stmt, createTable, SQL_NTS);
if (!SQL_SUCCEEDED(ret))
BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
SQLCHAR empty[] = "";
SQLCHAR table[] = "ESG\\_FOCUS";
ret = SQLColumns(stmt, empty, SQL_NTS, empty, SQL_NTS, table, SQL_NTS, empty, SQL_NTS);
if (!SQL_SUCCEEDED(ret))
BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
ret = SQLFetch(stmt);
if (!SQL_SUCCEEDED(ret))
BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
CheckStringColumn(stmt, 1, "");
CheckStringColumn(stmt, 2, "\"PUBLIC\"");
CheckStringColumn(stmt, 3, "ESG_FOCUS");
CheckStringColumn(stmt, 4, "ID");
ret = SQLFetch(stmt);
if (!SQL_SUCCEEDED(ret))
BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
CheckStringColumn(stmt, 1, "");
CheckStringColumn(stmt, 2, "\"PUBLIC\"");
CheckStringColumn(stmt, 3, "ESG_FOCUS");
CheckStringColumn(stmt, 4, "TEST_COLUMN");
ret = SQLFetch(stmt);
BOOST_REQUIRE_EQUAL(ret, SQL_NO_DATA);
}
BOOST_AUTO_TEST_CASE(TestSQLNumResultColsAfterSQLPrepare)
{
StartAdditionalNode("Node2");
Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=PUBLIC");
SQLRETURN ret = ExecQuery("create table TestSqlPrepare(id int primary key, test1 varchar, test2 long, test3 varchar)");
ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);
ret = SQLFreeStmt(stmt, SQL_CLOSE);
ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);
ret = PrepareQuery("select * from PUBLIC.TestSqlPrepare");
ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);
SQLSMALLINT columnCount = 0;
ret = SQLNumResultCols(stmt, &columnCount);
ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);
BOOST_CHECK_EQUAL(columnCount, 4);
ret = SQLExecute(stmt);
ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);
columnCount = 0;
ret = SQLNumResultCols(stmt, &columnCount);
ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);
BOOST_CHECK_EQUAL(columnCount, 4);
}
/**
* Check that SQLDescribeCol return valid scale and precision for columns of different type after Prepare.
*
* 1. Start node.
* 2. Connect to node using ODBC.
* 3. Create table with decimal and char columns with specified size and scale.
* 4. Prepare statement.
* 5. Check precision and scale of every column using SQLDescribeCol.
*/
BOOST_AUTO_TEST_CASE(TestSQLDescribeColPrecisionAndScaleAfterPrepare)
{
CheckSQLDescribeColPrecisionAndScale(&OdbcTestSuite::PrepareQuery);
}
/**
* Check that SQLDescribeCol return valid scale and precision for columns of different type after Execute.
*
* 1. Start node.
* 2. Connect to node using ODBC.
* 3. Create table with decimal and char columns with specified size and scale.
* 4. Execute statement.
* 5. Check precision and scale of every column using SQLDescribeCol. */
BOOST_AUTO_TEST_CASE(TestSQLDescribeColPrecisionAndScaleAfterExec)
{
CheckSQLDescribeColPrecisionAndScale(&OdbcTestSuite::ExecQuery);
}
/**
* Check that SQLColAttribute return valid scale and precision for columns of different type after Prepare.
*
* 1. Start node.
* 2. Connect to node using ODBC.
* 3. Create table with decimal and char columns with specified size and scale.
* 4. Prepare statement.
* 5. Check precision and scale of every column using SQLColAttribute.
*/
BOOST_AUTO_TEST_CASE(TestSQLColAttributePrecisionAndScaleAfterPrepare)
{
CheckSQLColAttributePrecisionAndScale(&OdbcTestSuite::PrepareQuery);
}
/**
* Check that SQLColAttribute return valid scale and precision for columns of different type after Execute.
*
* 1. Start node.
* 2. Connect to node using ODBC.
* 3. Create table with decimal and char columns with specified size and scale.
* 4. Execute statement.
* 5. Check precision and scale of every column using SQLColAttribute. */
BOOST_AUTO_TEST_CASE(TestSQLColAttributePrecisionAndScaleAfterExec)
{
CheckSQLColAttributePrecisionAndScale(&OdbcTestSuite::ExecQuery);
}
BOOST_AUTO_TEST_SUITE_END()