From e2311e5d82d2910ed1746e52e553ee7ede01b09d Mon Sep 17 00:00:00 2001 From: Jerry Leung Date: Mon, 22 Mar 2021 15:50:22 -0700 Subject: [PATCH 1/2] Added tests for SQLPrepare & SQLDescribeParams --- .../ITODBCExecution/test_odbc_execution.cpp | 99 +++++++------------ .../ITODBCHelper/it_odbc_helper.h | 2 + src/odfesqlodbc/es_apifunc.h | 2 +- src/odfesqlodbc/execute.c | 2 +- src/odfesqlodbc/odbcapi.c | 2 +- src/odfesqlodbc/odbcapiw.c | 2 +- 6 files changed, 40 insertions(+), 69 deletions(-) diff --git a/src/IntegrationTests/ITODBCExecution/test_odbc_execution.cpp b/src/IntegrationTests/ITODBCExecution/test_odbc_execution.cpp index aee1fe20a..1042b220d 100644 --- a/src/IntegrationTests/ITODBCExecution/test_odbc_execution.cpp +++ b/src/IntegrationTests/ITODBCExecution/test_odbc_execution.cpp @@ -57,44 +57,6 @@ class TestSQLExecute : public testing::Test { SQLHDBC m_conn = SQL_NULL_HDBC; SQLHSTMT m_hstmt = SQL_NULL_HSTMT; }; - -class TestSQLPrepare : public testing::Test { - public: - TestSQLPrepare() { - } - - void SetUp() { - ASSERT_NO_THROW(AllocStatement((SQLTCHAR*)conn_string.c_str(), &m_env, - &m_conn, &m_hstmt, true, true)); - } - - void TearDown() { - CloseCursor(&m_hstmt, true, true); - SQLFreeHandle(SQL_HANDLE_STMT, m_hstmt); - SQLDisconnect(m_conn); - SQLFreeHandle(SQL_HANDLE_ENV, m_env); - } - - ~TestSQLPrepare() { - // cleanup any pending stuff, but no exceptions allowed - } - - std::wstring m_query = - L"SELECT Origin FROM kibana_sample_data_flights LIMIT 5"; - std::wstring m_1_col = - L"SELECT Origin FROM kibana_sample_data_flights LIMIT 5"; - std::wstring m_2_col = - L"SELECT Origin, AvgTicketPrice FROM kibana_sample_data_flights LIMIT " - L"5"; - std::wstring m_all_col = - L"SELECT * FROM kibana_sample_data_flights LIMIT 5"; - const SQLSMALLINT m_1_col_cnt = 1; - const SQLSMALLINT m_2_col_cnt = 2; - const SQLSMALLINT m_all_col_cnt = 25; - SQLHENV m_env = SQL_NULL_HENV; - SQLHDBC m_conn = SQL_NULL_HDBC; - SQLHSTMT m_hstmt = SQL_NULL_HSTMT; -}; */ class Fixture : public testing::Test { public: @@ -117,6 +79,10 @@ class TestSQLFetch : public Fixture {}; class TestSQLExecDirect : public Fixture {}; +class TestSQLPrepare : public Fixture {}; + +class TestSQLDescribeParam : public Fixture {}; + /*class TestSQLSetCursorName : public testing::Test { public: TestSQLSetCursorName() { @@ -240,49 +206,52 @@ TEST_F(TestSQLExecute, ResetPrepareError) { EXPECT_EQ(SQL_ERROR, ret); LogAnyDiagnostics(SQL_HANDLE_STMT, m_hstmt, ret); } - -TEST_F(TestSQLPrepare, Success) { - SQLRETURN ret = SQLPrepare(m_hstmt, (SQLTCHAR*)m_query.c_str(), SQL_NTS); +*/ +TEST_F(TestSQLPrepare, SUCCESS_NO_PARAM) { + std::wstring query = L"SELECT 1 FROM ODBCTest.IoT LIMIT 1"; + SQLRETURN ret = SQLPrepare(m_hstmt, (SQLTCHAR*)query.c_str(), SQL_NTS); EXPECT_EQ(SQL_SUCCESS, ret); LogAnyDiagnostics(SQL_HANDLE_STMT, m_hstmt, ret); } -TEST_F(TestSQLPrepare, PrepareMetadata) { - SQLRETURN ret = SQLPrepare(m_hstmt, (SQLTCHAR*)m_all_col.c_str(), SQL_NTS); - EXPECT_EQ(SQL_SUCCESS, ret); - LogAnyDiagnostics(SQL_HANDLE_STMT, m_hstmt, ret); - SQLSMALLINT column_count = 0; - EXPECT_TRUE(SQL_SUCCEEDED(SQLNumResultCols(m_hstmt, &column_count))); - EXPECT_EQ(column_count, m_all_col_cnt); - EXPECT_TRUE(SQL_SUCCEEDED(SQLFreeStmt(m_hstmt, SQL_CLOSE))); - - ret = SQLPrepare(m_hstmt, (SQLTCHAR*)m_2_col.c_str(), SQL_NTS); - EXPECT_EQ(SQL_SUCCESS, ret); +TEST_F(TestSQLPrepare, ERROR_WITH_PARAM) { + std::wstring query = L"SELECT 1 FROM ODBCTest.IoT where time = ? LIMIT 1"; + SQLRETURN ret = SQLPrepare(m_hstmt, (SQLTCHAR*)query.c_str(), SQL_NTS); + EXPECT_EQ(SQL_ERROR, ret); LogAnyDiagnostics(SQL_HANDLE_STMT, m_hstmt, ret); - EXPECT_TRUE(SQL_SUCCEEDED(SQLNumResultCols(m_hstmt, &column_count))); - EXPECT_EQ(column_count, m_2_col_cnt); - EXPECT_TRUE(SQL_SUCCEEDED(SQLFreeStmt(m_hstmt, SQL_CLOSE))); +} - ret = SQLPrepare(m_hstmt, (SQLTCHAR*)m_all_col.c_str(), SQL_NTS); +TEST_F(TestSQLPrepare, PREPARE_METADATA) { + std::wstring query = L"SELECT 1, 2, 3, 4 FROM ODBCTest.IoT LIMIT 1"; + SQLRETURN ret = SQLPrepare(m_hstmt, (SQLTCHAR*)query.c_str(), SQL_NTS); EXPECT_EQ(SQL_SUCCESS, ret); LogAnyDiagnostics(SQL_HANDLE_STMT, m_hstmt, ret); + SQLSMALLINT column_count = 0; EXPECT_TRUE(SQL_SUCCEEDED(SQLNumResultCols(m_hstmt, &column_count))); - EXPECT_EQ(column_count, m_all_col_cnt); + EXPECT_EQ(4, column_count); EXPECT_TRUE(SQL_SUCCEEDED(SQLFreeStmt(m_hstmt, SQL_CLOSE))); +} - ret = SQLPrepare(m_hstmt, (SQLTCHAR*)m_1_col.c_str(), SQL_NTS); - EXPECT_EQ(SQL_SUCCESS, ret); +TEST_F(TestSQLPrepare, ERROR_NULL_QUERY) { + SQLRETURN ret = SQLPrepare(m_hstmt, NULL, SQL_NTS); + EXPECT_EQ(SQL_ERROR, ret); + EXPECT_TRUE(CheckSQLSTATE(SQL_HANDLE_STMT, m_hstmt, SQLSTATE_MEMORY_ALLOCATION_ERROR)); LogAnyDiagnostics(SQL_HANDLE_STMT, m_hstmt, ret); - EXPECT_TRUE(SQL_SUCCEEDED(SQLNumResultCols(m_hstmt, &column_count))); - EXPECT_EQ(column_count, m_1_col_cnt); - EXPECT_TRUE(SQL_SUCCEEDED(SQLFreeStmt(m_hstmt, SQL_CLOSE))); } -TEST_F(TestSQLPrepare, NullQueryError) { - SQLRETURN ret = SQLPrepare(m_hstmt, NULL, SQL_NTS); +TEST_F(TestSQLDescribeParam, DESCRIBE_PARAM) { + std::wstring query = L"SELECT 1 FROM ODBCTest.IoT where time = ? LIMIT 1"; + SQLRETURN ret = SQLPrepare(m_hstmt, (SQLTCHAR*)query.c_str(), SQL_NTS); EXPECT_EQ(SQL_ERROR, ret); + SQLSMALLINT sqlType; + SQLULEN paramDef; + SQLSMALLINT scale; + SQLSMALLINT nullable; + ret = SQLDescribeParam(m_hstmt, 1, &sqlType, ¶mDef, &scale, &nullable); + EXPECT_EQ(SQL_ERROR, ret); + EXPECT_TRUE(CheckSQLSTATE(SQL_HANDLE_STMT, m_hstmt, SQLSTATE_COLUMN_ERROR)); LogAnyDiagnostics(SQL_HANDLE_STMT, m_hstmt, ret); -}*/ +} TEST_F(TestSQLFetch, INVALID_HANDLE) { EXPECT_EQ(SQL_INVALID_HANDLE, SQLFetch(nullptr)); diff --git a/src/IntegrationTests/ITODBCHelper/it_odbc_helper.h b/src/IntegrationTests/ITODBCHelper/it_odbc_helper.h index 89e520c97..19cd9b4fd 100644 --- a/src/IntegrationTests/ITODBCHelper/it_odbc_helper.h +++ b/src/IntegrationTests/ITODBCHelper/it_odbc_helper.h @@ -31,8 +31,10 @@ // SQLSTATEs #define SQLSTATE_STRING_DATA_RIGHT_TRUNCATED (SQLWCHAR*)L"01004" #define SQLSTATE_RESTRICTED_DATA_TYPE_ERROR (SQLWCHAR*)L"07006" +#define SQLSTATE_COLUMN_ERROR (SQLWCHAR*)L"07009" #define SQLSTATE_INVALID_DESCRIPTOR_INDEX (SQLWCHAR*)L"07009" #define SQLSTATE_GENERAL_ERROR (SQLWCHAR*)L"HY000" +#define SQLSTATE_MEMORY_ALLOCATION_ERROR (SQLWCHAR*)L"HY001" #define SQLSTATE_INVALID_STRING_OR_BUFFER_LENGTH (SQLWCHAR*)L"HY090" #define SQLSTATE_INVALID_DESCRIPTOR_FIELD_IDENTIFIER (SQLWCHAR*)L"HY091" #define SQLSTATE_NUMERIC_VALUE_OUT_OF_RANGE (SQLWCHAR*) L"HY019" diff --git a/src/odfesqlodbc/es_apifunc.h b/src/odfesqlodbc/es_apifunc.h index abfa7195a..ea275b3c8 100644 --- a/src/odfesqlodbc/es_apifunc.h +++ b/src/odfesqlodbc/es_apifunc.h @@ -131,7 +131,7 @@ RETCODE SQL_API ESAPI_ColAttributes(HSTMT hstmt, SQLUSMALLINT icol, SQLUSMALLINT fDescType, PTR rgbDesc, SQLSMALLINT cbDescMax, SQLSMALLINT *pcbDesc, SQLLEN *pfDesc); -RETCODE SQL_API ESAPI_Prepare(HSTMT hstmt, const SQLCHAR *szSqlStr, +RETCODE SQL_API API_Prepare(HSTMT hstmt, const SQLCHAR *szSqlStr, SQLINTEGER cbSqlStr); RETCODE SQL_API ESAPI_ColumnPrivileges( HSTMT hstmt, const SQLCHAR *szCatalogName, SQLSMALLINT cbCatalogName, diff --git a/src/odfesqlodbc/execute.c b/src/odfesqlodbc/execute.c index c0118f277..9808af8d9 100644 --- a/src/odfesqlodbc/execute.c +++ b/src/odfesqlodbc/execute.c @@ -34,7 +34,7 @@ #include "qresult.h" #include "statement.h" -RETCODE SQL_API ESAPI_Prepare(HSTMT hstmt, const SQLCHAR *stmt_str, +RETCODE SQL_API API_Prepare(HSTMT hstmt, const SQLCHAR *stmt_str, SQLINTEGER stmt_sz) { if (hstmt == NULL) return SQL_ERROR; diff --git a/src/odfesqlodbc/odbcapi.c b/src/odfesqlodbc/odbcapi.c index 9169d999e..3a1b5d1b7 100644 --- a/src/odfesqlodbc/odbcapi.c +++ b/src/odfesqlodbc/odbcapi.c @@ -495,7 +495,7 @@ RETCODE SQL_API SQLPrepare(HSTMT StatementHandle, SQLCHAR *StatementText, // Prepare statement if statement is ready RETCODE ret = SQL_ERROR; if (!SC_opencheck(stmt, func)) - ret = ESAPI_Prepare(StatementHandle, StatementText, TextLength); + ret = API_Prepare(StatementHandle, StatementText, TextLength); // Exit critical LEAVE_STMT_CS(stmt); diff --git a/src/odfesqlodbc/odbcapiw.c b/src/odfesqlodbc/odbcapiw.c index b782eccf4..a5ef9254d 100644 --- a/src/odfesqlodbc/odbcapiw.c +++ b/src/odfesqlodbc/odbcapiw.c @@ -407,7 +407,7 @@ RETCODE SQL_API SQLPrepareW(HSTMT StatementHandle, SQLWCHAR *StatementText, // Prepare statement if statement is ready RETCODE ret = SQL_ERROR; if (!SC_opencheck(stmt, func)) - ret = ESAPI_Prepare(StatementHandle, (const SQLCHAR *)stxt, + ret = API_Prepare(StatementHandle, (const SQLCHAR *)stxt, (SQLINTEGER)slen); // Exit critical From 25c91a6e99e47c78a71945586b28467f8ce9b17d Mon Sep 17 00:00:00 2001 From: Jerry Leung Date: Tue, 23 Mar 2021 10:05:10 -0700 Subject: [PATCH 2/2] Added test cases for SQLNumParams --- .../ITODBCExecution/test_odbc_execution.cpp | 12 ++++++++++++ src/IntegrationTests/ITODBCHelper/it_odbc_helper.h | 1 + 2 files changed, 13 insertions(+) diff --git a/src/IntegrationTests/ITODBCExecution/test_odbc_execution.cpp b/src/IntegrationTests/ITODBCExecution/test_odbc_execution.cpp index 1042b220d..48db05d73 100644 --- a/src/IntegrationTests/ITODBCExecution/test_odbc_execution.cpp +++ b/src/IntegrationTests/ITODBCExecution/test_odbc_execution.cpp @@ -83,6 +83,8 @@ class TestSQLPrepare : public Fixture {}; class TestSQLDescribeParam : public Fixture {}; +class TestSQLNumParams : public Fixture {}; + /*class TestSQLSetCursorName : public testing::Test { public: TestSQLSetCursorName() { @@ -253,6 +255,16 @@ TEST_F(TestSQLDescribeParam, DESCRIBE_PARAM) { LogAnyDiagnostics(SQL_HANDLE_STMT, m_hstmt, ret); } +TEST_F(TestSQLNumParams, NUM_PARAMS) { + SQLSMALLINT num = 0; + SQLRETURN ret = SQLNumParams(nullptr, &num); + EXPECT_EQ(SQL_ERROR, ret); + ret = SQLNumParams(m_hstmt, &num); + EXPECT_EQ(SQL_SUCCESS_WITH_INFO, ret); + EXPECT_TRUE(CheckSQLSTATE(SQL_HANDLE_STMT, m_hstmt, SQLSTATE_NOT_IMPLEMENTED_ERROR)); + LogAnyDiagnostics(SQL_HANDLE_STMT, m_hstmt, ret); +} + TEST_F(TestSQLFetch, INVALID_HANDLE) { EXPECT_EQ(SQL_INVALID_HANDLE, SQLFetch(nullptr)); } diff --git a/src/IntegrationTests/ITODBCHelper/it_odbc_helper.h b/src/IntegrationTests/ITODBCHelper/it_odbc_helper.h index 19cd9b4fd..394bf17ba 100644 --- a/src/IntegrationTests/ITODBCHelper/it_odbc_helper.h +++ b/src/IntegrationTests/ITODBCHelper/it_odbc_helper.h @@ -38,6 +38,7 @@ #define SQLSTATE_INVALID_STRING_OR_BUFFER_LENGTH (SQLWCHAR*)L"HY090" #define SQLSTATE_INVALID_DESCRIPTOR_FIELD_IDENTIFIER (SQLWCHAR*)L"HY091" #define SQLSTATE_NUMERIC_VALUE_OUT_OF_RANGE (SQLWCHAR*) L"HY019" +#define SQLSTATE_NOT_IMPLEMENTED_ERROR (SQLWCHAR*)L"HYC00" #define SQLSTATE_STRING_CONVERSION_ERROR (SQLWCHAR*)L"22018" #define SQLSTATE_INVALID_CURSUR_STATE (SQLWCHAR*)L"07005" #define SQLSTATE_FRACTIONAL_TRUNCATION (SQLWCHAR*)L"01S07"