diff --git a/.gitignore b/.gitignore index 6c985b267..b4902bec9 100644 --- a/.gitignore +++ b/.gitignore @@ -22,6 +22,7 @@ lib64/* *.tlog include/* packages/* +odbc_test_result.xml # Visual Studio .vs/* src/.vs/* diff --git a/src/odbc-test/src/meta_queries_test.cpp b/src/odbc-test/src/meta_queries_test.cpp index 824fdf0d5..1587ce483 100644 --- a/src/odbc-test/src/meta_queries_test.cpp +++ b/src/odbc-test/src/meta_queries_test.cpp @@ -31,6 +31,7 @@ #include "ignite/odbc/common/fixed_size_array.h" #include "ignite/ignition.h" #include "ignite/odbc/impl/binary/binary_utils.h" +#include "ignite/odbc/type_traits.h" #include "odbc_test_suite.h" #include "test_type.h" #include "test_utils.h" @@ -765,6 +766,154 @@ BOOST_AUTO_TEST_CASE(TestGetDataWithTablesReturnsOneWithTableTypes) { CheckSingleRowResultSetWithGetData(stmt, 3, "meta_queries_test_001"); } +BOOST_AUTO_TEST_CASE(TestDataTypes) { + std::string dsnConnectionString; + std::string databaseName("odbc-test"); + CreateDsnConnectionStringForLocalServer(dsnConnectionString, databaseName); + + Connect(dsnConnectionString); + + SQLCHAR table[] = "meta_queries_test_001"; + SQLCHAR empty[] = ""; + SQLCHAR *schemaName = (SQLCHAR *)databaseName.c_str(); + + + SQLRETURN ret = SQLColumns(stmt, empty, SQL_NTS, schemaName, SQL_NTS, table, + SQL_NTS, empty, SQL_NTS); + + if (!SQL_SUCCEEDED(ret)) + BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); + + char column_name[C_STR_LEN_DEFAULT]{}; + SQLLEN column_name_len = sizeof(column_name); + SQLSMALLINT data_type = 0; + SQLLEN data_type_len = sizeof(data_type); + char type_name[C_STR_LEN_DEFAULT]{}; + SQLLEN type_name_len = sizeof(type_name); + + ret = SQLBindCol(stmt, 4, SQL_C_CHAR, column_name, C_STR_LEN_DEFAULT, + &column_name_len); + BOOST_CHECK(SQL_SUCCEEDED(ret)); + ret = SQLBindCol(stmt, 5, SQL_SMALLINT, &data_type, sizeof(data_type), + &data_type_len); + BOOST_CHECK(SQL_SUCCEEDED(ret)); + ret = SQLBindCol(stmt, 6, SQL_C_CHAR, type_name, C_STR_LEN_DEFAULT, + &type_name_len); + BOOST_CHECK(SQL_SUCCEEDED(ret)); + + 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)); + + using namespace ignite::odbc::type_traits; + BOOST_CHECK_EQUAL("meta_queries_test_001__id", column_name); // COLUMN_NAME + BOOST_CHECK_EQUAL(SQL_VARCHAR, data_type); // DATA_TYPE + BOOST_CHECK_EQUAL(SqlTypeName::VARCHAR, type_name); // TYPE_NAME + + ret = SQLFetch(stmt); + if (!SQL_SUCCEEDED(ret)) + BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); + + BOOST_CHECK_EQUAL("fieldDecimal128", column_name); // COLUMN_NAME + BOOST_CHECK_EQUAL(SQL_DECIMAL, data_type); // DATA_TYPE + BOOST_CHECK_EQUAL(SqlTypeName::DECIMAL, type_name); // TYPE_NAME + + ret = SQLFetch(stmt); + if (!SQL_SUCCEEDED(ret)) + BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); + + BOOST_CHECK_EQUAL("fieldDouble", column_name); // COLUMN_NAME + BOOST_CHECK_EQUAL(SQL_DOUBLE, data_type); // DATA_TYPE + BOOST_CHECK_EQUAL(SqlTypeName::DOUBLE, type_name); // TYPE_NAME + + ret = SQLFetch(stmt); + if (!SQL_SUCCEEDED(ret)) + BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); + + BOOST_CHECK_EQUAL("fieldString", column_name); // COLUMN_NAME + BOOST_CHECK_EQUAL(SQL_VARCHAR, data_type); // DATA_TYPE + BOOST_CHECK_EQUAL(SqlTypeName::VARCHAR, type_name); // TYPE_NAME + + ret = SQLFetch(stmt); + if (!SQL_SUCCEEDED(ret)) + BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); + + BOOST_CHECK_EQUAL("fieldObjectId", column_name); // COLUMN_NAME + BOOST_CHECK_EQUAL(SQL_VARCHAR, data_type); // DATA_TYPE + BOOST_CHECK_EQUAL(SqlTypeName::VARCHAR, type_name); // TYPE_NAME + + ret = SQLFetch(stmt); + if (!SQL_SUCCEEDED(ret)) + BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); + + BOOST_CHECK_EQUAL("fieldBoolean", column_name); // COLUMN_NAME + BOOST_CHECK_EQUAL(SQL_BIT, data_type); // DATA_TYPE + BOOST_CHECK_EQUAL(SqlTypeName::BIT, type_name); // TYPE_NAME + + ret = SQLFetch(stmt); + if (!SQL_SUCCEEDED(ret)) + BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); + + BOOST_CHECK_EQUAL("fieldDate", column_name); // COLUMN_NAME + BOOST_CHECK_EQUAL(SQL_TYPE_TIMESTAMP, data_type); // DATA_TYPE + BOOST_CHECK_EQUAL(SqlTypeName::TIMESTAMP, type_name); // TYPE_NAME + + ret = SQLFetch(stmt); + if (!SQL_SUCCEEDED(ret)) + BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); + + BOOST_CHECK_EQUAL("fieldInt", column_name); // COLUMN_NAME + BOOST_CHECK_EQUAL(SQL_INTEGER, data_type); // DATA_TYPE + BOOST_CHECK_EQUAL(SqlTypeName::INTEGER, type_name); // TYPE_NAME + + ret = SQLFetch(stmt); + if (!SQL_SUCCEEDED(ret)) + BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); + + BOOST_CHECK_EQUAL("fieldLong", column_name); // COLUMN_NAME + BOOST_CHECK_EQUAL(SQL_BIGINT, data_type); // DATA_TYPE + BOOST_CHECK_EQUAL(SqlTypeName::BIGINT, type_name); // TYPE_NAME + + ret = SQLFetch(stmt); + if (!SQL_SUCCEEDED(ret)) + BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); + + BOOST_CHECK_EQUAL("fieldMaxKey", column_name); // COLUMN_NAME + BOOST_CHECK_EQUAL(SQL_VARCHAR, data_type); // DATA_TYPE + BOOST_CHECK_EQUAL(SqlTypeName::VARCHAR, type_name); // TYPE_NAME + + ret = SQLFetch(stmt); + if (!SQL_SUCCEEDED(ret)) + BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); + + BOOST_CHECK_EQUAL("fieldMinKey", column_name); // COLUMN_NAME + BOOST_CHECK_EQUAL(SQL_VARCHAR, data_type); // DATA_TYPE + BOOST_CHECK_EQUAL(SqlTypeName::VARCHAR, type_name); // TYPE_NAME + + ret = SQLFetch(stmt); + if (!SQL_SUCCEEDED(ret)) + BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); + + BOOST_CHECK_EQUAL("fieldNull", column_name); // COLUMN_NAME + BOOST_CHECK_EQUAL(SQL_TYPE_NULL, data_type); // DATA_TYPE + BOOST_CHECK_EQUAL(SqlTypeName::SQL_NULL, type_name); // TYPE_NAME + + ret = SQLFetch(stmt); + if (!SQL_SUCCEEDED(ret)) + BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); + + BOOST_CHECK_EQUAL("fieldBinary", column_name); // COLUMN_NAME + BOOST_CHECK_EQUAL(SQL_VARBINARY, data_type); // DATA_TYPE + BOOST_CHECK_EQUAL(SqlTypeName::VARBINARY, type_name); // TYPE_NAME + + ret = SQLFetch(stmt); + + BOOST_REQUIRE_EQUAL(ret, SQL_NO_DATA); +} + BOOST_AUTO_TEST_CASE(TestGetDataWithTablesReturnsOneForQuotedTypes) { SQLCHAR empty[] = ""; SQLCHAR table[] = "meta_queries_test_001"; diff --git a/src/odbc/include/ignite/odbc/meta/column_meta.h b/src/odbc/include/ignite/odbc/meta/column_meta.h index 99a494b0c..c9a46591f 100644 --- a/src/odbc/include/ignite/odbc/meta/column_meta.h +++ b/src/odbc/include/ignite/odbc/meta/column_meta.h @@ -205,7 +205,7 @@ class ColumnMeta { * Get data type. * @return Data type. */ - int8_t GetDataType() const { + int16_t GetDataType() const { return dataType; } diff --git a/src/odbc/include/ignite/odbc/type_traits.h b/src/odbc/include/ignite/odbc/type_traits.h index 531dc6964..a5dacdff2 100644 --- a/src/odbc/include/ignite/odbc/type_traits.h +++ b/src/odbc/include/ignite/odbc/type_traits.h @@ -151,6 +151,9 @@ class SqlTypeName { /** BINARY SQL type name constant. */ static const std::string BINARY; + /** VARBINARY SQL type name constant. */ + static const std::string VARBINARY; + /** LONGVARBINARY SQL type name constant. */ static const std::string LONGVARBINARY; diff --git a/src/odbc/src/query/column_metadata_query.cpp b/src/odbc/src/query/column_metadata_query.cpp index bd3f34553..50e6ef5ec 100644 --- a/src/odbc/src/query/column_metadata_query.cpp +++ b/src/odbc/src/query/column_metadata_query.cpp @@ -232,7 +232,7 @@ SqlResult::Type ColumnMetadataQuery::GetColumn( } const meta::ColumnMeta& currentColumn = *cursor; - uint8_t columnType = currentColumn.GetDataType(); + int16_t columnType = currentColumn.GetDataType(); switch (columnIdx) { case ResultColumn::TABLE_CAT: { @@ -262,7 +262,7 @@ SqlResult::Type ColumnMetadataQuery::GetColumn( case ResultColumn::TYPE_NAME: { buffer.PutString( - type_traits::BinaryTypeToSqlTypeName(currentColumn.GetDataType())); + type_traits::BinaryTypeToSqlTypeName(columnType)); break; } diff --git a/src/odbc/src/type_traits.cpp b/src/odbc/src/type_traits.cpp index 774ef1443..0c338c244 100644 --- a/src/odbc/src/type_traits.cpp +++ b/src/odbc/src/type_traits.cpp @@ -50,7 +50,9 @@ const std::string SqlTypeName::VARCHAR("VARCHAR"); const std::string SqlTypeName::LONGVARCHAR("LONGVARCHAR"); -const std::string SqlTypeName::BINARY("VARBINARY"); +const std::string SqlTypeName::BINARY("BINARY"); + +const std::string SqlTypeName::VARBINARY("VARBINARY"); const std::string SqlTypeName::LONGVARBINARY("LONGVARBINARY"); @@ -173,8 +175,10 @@ const std::string& BinaryTypeToSqlTypeName(int16_t binaryType) { case JDBC_TYPE_NULL: return SqlTypeName::SQL_NULL; - case JDBC_TYPE_BINARY: case JDBC_TYPE_VARBINARY: + return SqlTypeName::VARBINARY; + + case JDBC_TYPE_BINARY: case JDBC_TYPE_BLOB: case JDBC_TYPE_CLOB: case JDBC_TYPE_ARRAY: @@ -449,8 +453,10 @@ int16_t BinaryToSqlType(int16_t binaryType) { case JDBC_TYPE_NULL: return SQL_TYPE_NULL; - case JDBC_TYPE_BINARY: case JDBC_TYPE_VARBINARY: + return SQL_VARBINARY; + + case JDBC_TYPE_BINARY: case JDBC_TYPE_BLOB: case JDBC_TYPE_CLOB: case JDBC_TYPE_ARRAY: