diff --git a/src/markdown/index.md b/src/markdown/index.md index 7d9eee16b..794786831 100644 --- a/src/markdown/index.md +++ b/src/markdown/index.md @@ -89,7 +89,7 @@ fields in an existing collection. To regenerate or clear the existing schema, pl ## SQL and ODBC Limitations The Amazon DocumentDB ODBC driver has a number of important limitations. See the -[SQL limitations documentation](https://github.com/aws/amazon-documentdb-jdbc-driver/blob/develop/src/markdown/sql/sql-limitations.md). +[SQL limitations documentation](https://github.com/aws/amazon-documentdb-jdbc-driver/blob/develop/src/markdown/sql/sql-limitations.md), and [ODBC limitations documentation](support/odbc-limitations.md) ## Troubleshooting Guide diff --git a/src/markdown/support/odbc-limitations.md b/src/markdown/support/odbc-limitations.md new file mode 100644 index 000000000..4c772a77e --- /dev/null +++ b/src/markdown/support/odbc-limitations.md @@ -0,0 +1,23 @@ +# ODBC Support and Limitations + +// TODO create user Documentation + +//https://bitquill.atlassian.net/browse/AD-682 + +Table of statement attributes supported by the Amazon DocumentDB ODBC driver.\ +Related function: `SQLSetStmtAttr` +| Statement attribute | Default | Support Value Change| +|--------|------|-------| +|SQL_ATTR_PARAM_BIND_OFFSET_PTR| | | +|SQL_ATTR_PARAM_BIND_TYPE| | | +|SQL_ATTR_PARAM_OPERATION_PTR| | | +|SQL_ATTR_PARAM_STATUS_PTR| | | +|SQL_ATTR_PARAMS_PROCESSED_PTR| | | +|SQL_ATTR_PARAMSET_SIZE| | | +|SQL_ATTR_ROW_ARRAY_SIZE| 1 | No | +|SQL_ATTR_ROW_BIND_OFFSET_PTR| | | +|SQL_ATTR_ROW_BIND_TYPE| | | +|SQL_ATTR_ROW_OPERATION_PTR| | | +|SQL_ATTR_ROW_STATUS_PTR| | | +|SQL_ATTR_ROWS_FETCHED_PTR| | | + diff --git a/src/odbc-test/src/api_robustness_test.cpp b/src/odbc-test/src/api_robustness_test.cpp index 42c7dec71..d72169228 100644 --- a/src/odbc-test/src/api_robustness_test.cpp +++ b/src/odbc-test/src/api_robustness_test.cpp @@ -146,8 +146,8 @@ SQLSMALLINT unsupportedSql[] = {SQL_WVARCHAR, BOOST_FIXTURE_TEST_SUITE(ApiRobustnessTestSuite, ApiRobustnessTestSuiteFixture) -BOOST_AUTO_TEST_CASE(TestSQLSetStmtAttrGetStmtAttr) { - // check that statement array size is set correctly +BOOST_AUTO_TEST_CASE(TestSQLSetStmtAttrRowArraySize) { + // check that statement array size cannot be set to values other than 1 std::string dsnConnectionString; CreateDsnConnectionStringForLocalServer(dsnConnectionString); @@ -157,22 +157,38 @@ BOOST_AUTO_TEST_CASE(TestSQLSetStmtAttrGetStmtAttr) { SQLINTEGER actual_row_array_size; SQLINTEGER resLen = 0; + // check that statement array size cannot be set to values not equal to 1 // repeat test for different values - SQLULEN valList[5] = {10, 52, 81, 103, 304}; + SQLULEN valList[5] = {0, 2, 3, 4, 5}; for (SQLULEN val : valList) { SQLRETURN ret = SQLSetStmtAttr(stmt, SQL_ATTR_ROW_ARRAY_SIZE, reinterpret_cast< SQLPOINTER >(val), sizeof(val)); - ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt); + BOOST_CHECK_EQUAL(ret, SQL_ERROR); ret = SQLGetStmtAttr(stmt, SQL_ATTR_ROW_ARRAY_SIZE, &actual_row_array_size, sizeof(actual_row_array_size), &resLen); ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt); - BOOST_CHECK_EQUAL(actual_row_array_size, val); + BOOST_CHECK_EQUAL(actual_row_array_size, 1); } + + // check that setting row array size to 1 is successful + SQLULEN val = 1; + SQLRETURN ret = + SQLSetStmtAttr(stmt, SQL_ATTR_ROW_ARRAY_SIZE, + reinterpret_cast< SQLPOINTER >(val), sizeof(val)); + + BOOST_CHECK_EQUAL(ret, SQL_SUCCESS); + + ret = SQLGetStmtAttr(stmt, SQL_ATTR_ROW_ARRAY_SIZE, &actual_row_array_size, + sizeof(actual_row_array_size), &resLen); + + ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt); + + BOOST_CHECK_EQUAL(actual_row_array_size, val); } BOOST_AUTO_TEST_CASE(TestSQLDriverConnect, *disabled()) { diff --git a/src/odbc/include/ignite/odbc/jni/java.h b/src/odbc/include/ignite/odbc/jni/java.h index d31802e34..9f53f0f91 100644 --- a/src/odbc/include/ignite/odbc/jni/java.h +++ b/src/odbc/include/ignite/odbc/jni/java.h @@ -488,20 +488,21 @@ class IGNITE_IMPORT_EXPORT JniContext { static void Detach(); static void Release(jobject obj); - std::string JavaStringToCppString(const SharedPointer< GlobalJObject >& jstring); + std::string JavaStringToCppString( + const SharedPointer< GlobalJObject >& jstring, JniErrorInfo& errInfo); int64_t TargetInLongOutLong(jobject obj, int type, int64_t memPtr, - JniErrorInfo* errInfo = NULL); + JniErrorInfo* errInfo); int64_t TargetInStreamOutLong(jobject obj, int type, int64_t memPtr, - JniErrorInfo* errInfo = NULL); + JniErrorInfo* errInfo); jobject TargetOutObject(jobject obj, int opType, - JniErrorInfo* errInfo = NULL); + JniErrorInfo* errInfo); void TargetInStreamOutStream(jobject obj, int opType, int64_t inMemPtr, - int64_t outMemPtr, JniErrorInfo* errInfo = NULL); + int64_t outMemPtr, JniErrorInfo* errInfo); jobject TargetInStreamOutObject(jobject obj, int type, int64_t memPtr, - JniErrorInfo* errInfo = NULL); + JniErrorInfo* errInfo); void TargetOutStream(jobject obj, int opType, int64_t memPtr, - JniErrorInfo* errInfo = NULL); + JniErrorInfo* errInfo); JniErrorCode DriverManagerGetConnection( const char* connectionString, SharedPointer< GlobalJObject >& connection, @@ -692,9 +693,9 @@ class IGNITE_IMPORT_EXPORT JniContext { JniErrorInfo& errInfo); jobject CacheOutOpQueryCursor(jobject obj, int type, int64_t memPtr, - JniErrorInfo* errInfo = NULL); + JniErrorInfo* errInfo); jobject CacheOutOpContinuousQuery(jobject obj, int type, int64_t memPtr, - JniErrorInfo* errInfo = NULL); + JniErrorInfo* errInfo); jobject Acquire(jobject obj); @@ -704,7 +705,7 @@ class IGNITE_IMPORT_EXPORT JniContext { JniContext(JniJvm* jvm, JniHandlers const& hnds); - JNIEnv* Attach(); + JNIEnv* Attach(JniErrorInfo& errInfo); void ExceptionCheck(JNIEnv* env); void ExceptionCheck(JNIEnv* env, JniErrorInfo* errInfo); diff --git a/src/odbc/src/impl/cache/query/continuous/continuous_query_handle_impl.cpp b/src/odbc/src/impl/cache/query/continuous/continuous_query_handle_impl.cpp index 42ae7de72..0c99141c9 100644 --- a/src/odbc/src/impl/cache/query/continuous/continuous_query_handle_impl.cpp +++ b/src/odbc/src/impl/cache/query/continuous/continuous_query_handle_impl.cpp @@ -56,7 +56,8 @@ namespace ignite ContinuousQueryHandleImpl::~ContinuousQueryHandleImpl() { - env.Get()->Context()->TargetInLongOutLong(javaRef, Command::CLOSE, 0); + JniErrorInfo err; + env.Get()->Context()->TargetInLongOutLong(javaRef, Command::CLOSE, 0, &err); JniContext::Release(javaRef); diff --git a/src/odbc/src/impl/cache/query/query_impl.cpp b/src/odbc/src/impl/cache/query/query_impl.cpp index 18c91923f..ee1f8665a 100644 --- a/src/odbc/src/impl/cache/query/query_impl.cpp +++ b/src/odbc/src/impl/cache/query/query_impl.cpp @@ -65,7 +65,8 @@ namespace ignite delete batch; // 2. Close the cursor. - env.Get()->Context()->TargetInLongOutLong(javaRef, OP_ITERATOR_CLOSE, 0); + JniErrorInfo err; + env.Get()->Context()->TargetInLongOutLong(javaRef, OP_ITERATOR_CLOSE, 0, &err); // 3. Release Java reference. JniContext::Release(javaRef); diff --git a/src/odbc/src/jni/documentdb_query_mapping_service.cpp b/src/odbc/src/jni/documentdb_query_mapping_service.cpp index 15e78095c..351c5bef9 100644 --- a/src/odbc/src/jni/documentdb_query_mapping_service.cpp +++ b/src/odbc/src/jni/documentdb_query_mapping_service.cpp @@ -73,7 +73,10 @@ bool ReadListOfString(SharedPointer< JniContext >& _jniContext, if (success != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { return false; } - std::string value = _jniContext.Get()->JavaStringToCppString(operation); + std::string value = _jniContext.Get()->JavaStringToCppString(operation, errInfo); + if (errInfo.code != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { + return false; + } targetList.push_back(value); } diff --git a/src/odbc/src/jni/java.cpp b/src/odbc/src/jni/java.cpp index fb120f2ac..98f4686b3 100644 --- a/src/odbc/src/jni/java.cpp +++ b/src/odbc/src/jni/java.cpp @@ -1066,11 +1066,15 @@ void JniContext::Detach() { } std::string JniContext::JavaStringToCppString( - const SharedPointer< GlobalJObject >& value) { + const SharedPointer< GlobalJObject >& value, JniErrorInfo& errInfo) { LOG_DEBUG_MSG("JavaStringToCppString is called"); - int len; - JNIEnv* env = Attach(); + JNIEnv* env = Attach(errInfo); + if (errInfo.code != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { + return std::string(); + } + LOG_DEBUG_MSG("JavaStringToCppString exiting"); + int len; return JavaStringToCString(env, static_cast< jstring >(value.Get()->GetRef()), len); } @@ -1080,7 +1084,10 @@ JniErrorCode JniContext::DriverManagerGetConnection( JniErrorInfo& errInfo) { LOG_DEBUG_MSG("DriverManagerGetConnection is called"); - JNIEnv* env = Attach(); + JNIEnv* env = Attach(errInfo); + if (errInfo.code != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { + return errInfo.code; + } // TODO enable string logging and hide the user password. // https://bitquill.atlassian.net/browse/AD-702 @@ -1116,7 +1123,11 @@ JniErrorCode JniContext::ConnectionClose( return errInfo.code; } - JNIEnv* env = Attach(); + JNIEnv* env = Attach(errInfo); + if (errInfo.code != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { + return errInfo.code; + } + env->CallVoidMethod(connection.Get()->GetRef(), jvm->GetMembers().m_ConnectionClose); ExceptionCheck(env, &errInfo); @@ -1141,7 +1152,11 @@ JniErrorCode JniContext::DocumentDbConnectionIsSshTunnelActive( return errInfo.code; } - JNIEnv* env = Attach(); + JNIEnv* env = Attach(errInfo); + if (errInfo.code != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { + return errInfo.code; + } + jboolean res = env->CallBooleanMethod( connection.Get()->GetRef(), jvm->GetMembers().m_DocumentDbConnectionIsSshTunnelActive); @@ -1169,7 +1184,11 @@ JniErrorCode JniContext::DocumentDbConnectionGetSshLocalPort( return errInfo.code; } - JNIEnv* env = Attach(); + JNIEnv* env = Attach(errInfo); + if (errInfo.code != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { + return errInfo.code; + } + result = env->CallIntMethod( connection.Get()->GetRef(), jvm->GetMembers().m_DocumentDbConnectionGetSshLocalPort); @@ -1194,7 +1213,11 @@ JniErrorCode JniContext::DocumentDbConnectionGetDatabaseMetadata( return errInfo.code; } - JNIEnv* env = Attach(); + JNIEnv* env = Attach(errInfo); + if (errInfo.code != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { + return errInfo.code; + } + jobject result = env->CallObjectMethod( connection.Get()->GetRef(), jvm->GetMembers().m_DocumentDbConnectionGetDatabaseMetadata); @@ -1232,7 +1255,11 @@ JniErrorCode JniContext::DocumentDbConnectionGetConnectionProperties( return errInfo.code; } - JNIEnv* env = Attach(); + JNIEnv* env = Attach(errInfo); + if (errInfo.code != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { + return errInfo.code; + } + jobject result = env->CallObjectMethod( connection.Get()->GetRef(), jvm->GetMembers().m_DocumentDbConnectionGetConnectionProperties); @@ -1266,7 +1293,11 @@ JniErrorCode JniContext::DocumentDbDatabaseSchemaMetadataGetSchemaName( return errInfo.code; } - JNIEnv* env = Attach(); + JNIEnv* env = Attach(errInfo); + if (errInfo.code != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { + return errInfo.code; + } + jobject result = env->CallObjectMethod( databaseMetadata.Get()->GetRef(), jvm->GetMembers().m_DocumentDbDatabaseSchemaMetadataGetSchemaName); @@ -1301,7 +1332,11 @@ JniErrorCode JniContext::ConnectionGetMetaData( return errInfo.code; } - JNIEnv* env = Attach(); + JNIEnv* env = Attach(errInfo); + if (errInfo.code != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { + return errInfo.code; + } + jobject result = env->CallObjectMethod( connection.Get()->GetRef(), jvm->GetMembers().m_ConnectionGetMetaData); ExceptionCheck(env, &errInfo); @@ -1342,7 +1377,11 @@ JniErrorCode JniContext::DatabaseMetaDataGetTables( return errInfo.code; } - JNIEnv* env = Attach(); + JNIEnv* env = Attach(errInfo); + if (errInfo.code != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { + return errInfo.code; + } + jstring jCatalog = catalog ? env->NewStringUTF(catalog->c_str()) : nullptr; jstring jSchemaPattern = schemaPattern ? env->NewStringUTF(schemaPattern->c_str()) : nullptr; @@ -1405,7 +1444,11 @@ JniErrorCode JniContext::DatabaseMetaDataGetColumns( return errInfo.code; } - JNIEnv* env = Attach(); + JNIEnv* env = Attach(errInfo); + if (errInfo.code != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { + return errInfo.code; + } + jstring jCatalog = catalog ? env->NewStringUTF(catalog->c_str()) : nullptr; jstring jSchemaPattern = schemaPattern ? env->NewStringUTF(schemaPattern->c_str()) : nullptr; @@ -1457,7 +1500,11 @@ JniErrorCode JniContext::DatabaseMetaDataGetPrimaryKeys( return errInfo.code; } - JNIEnv* env = Attach(); + JNIEnv* env = Attach(errInfo); + if (errInfo.code != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { + return errInfo.code; + } + jstring jCatalog = catalog ? env->NewStringUTF(catalog->c_str()) : nullptr; jstring jSchema = schema ? env->NewStringUTF(schema->c_str()) : nullptr; jstring jTableName = table ? env->NewStringUTF(table->c_str()) : nullptr; @@ -1505,7 +1552,11 @@ JniErrorCode JniContext::DatabaseMetaDataGetImportedKeys( return errInfo.code; } - JNIEnv* env = Attach(); + JNIEnv* env = Attach(errInfo); + if (errInfo.code != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { + return errInfo.code; + } + jstring jCatalog = catalog ? env->NewStringUTF(catalog->c_str()) : nullptr; jstring jSchema = schema ? env->NewStringUTF(schema->c_str()) : nullptr; jstring jTable = env->NewStringUTF(table.c_str()); @@ -1548,7 +1599,11 @@ JniErrorCode JniContext::ResultSetClose( return errInfo.code; } - JNIEnv* env = Attach(); + JNIEnv* env = Attach(errInfo); + if (errInfo.code != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { + return errInfo.code; + } + env->CallVoidMethod(resultSet.Get()->GetRef(), jvm->GetMembers().m_ResultSetClose); ExceptionCheck(env, &errInfo); @@ -1572,7 +1627,11 @@ JniErrorCode JniContext::ResultSetNext( return errInfo.code; } - JNIEnv* env = Attach(); + JNIEnv* env = Attach(errInfo); + if (errInfo.code != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { + return errInfo.code; + } + jboolean res = env->CallBooleanMethod(resultSet.Get()->GetRef(), jvm->GetMembers().m_ResultSetNext); ExceptionCheck(env, &errInfo); @@ -1601,7 +1660,11 @@ JniErrorCode JniContext::ResultSetGetString( } value = boost::none; - JNIEnv* env = Attach(); + JNIEnv* env = Attach(errInfo); + if (errInfo.code != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { + return errInfo.code; + } + jobject result = env->CallObjectMethod( resultSet.Get()->GetRef(), jvm->GetMembers().m_ResultSetGetStringByIndex, columnIndex); @@ -1637,7 +1700,11 @@ JniErrorCode JniContext::ResultSetGetString( return errInfo.code; } value = boost::none; - JNIEnv* env = Attach(); + JNIEnv* env = Attach(errInfo); + if (errInfo.code != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { + return errInfo.code; + } + jstring jColumnName = env->NewStringUTF(columnName.c_str()); jobject result = env->CallObjectMethod( resultSet.Get()->GetRef(), jvm->GetMembers().m_ResultSetGetStringByName, @@ -1675,7 +1742,11 @@ JniErrorCode JniContext::ResultSetGetInt( } value = boost::none; - JNIEnv* env = Attach(); + JNIEnv* env = Attach(errInfo); + if (errInfo.code != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { + return errInfo.code; + } + jint result = env->CallIntMethod(resultSet.Get()->GetRef(), jvm->GetMembers().m_ResultSetGetIntByIndex, columnIndex); @@ -1709,7 +1780,11 @@ JniErrorCode JniContext::ResultSetGetInt( } value = boost::none; - JNIEnv* env = Attach(); + JNIEnv* env = Attach(errInfo); + if (errInfo.code != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { + return errInfo.code; + } + jstring jColumnName = env->NewStringUTF(columnName.c_str()); jint result = env->CallIntMethod(resultSet.Get()->GetRef(), jvm->GetMembers().m_ResultSetGetIntByName, @@ -1745,7 +1820,11 @@ JniErrorCode JniContext::ResultSetGetRow( } value = boost::none; - JNIEnv* env = Attach(); + JNIEnv* env = Attach(errInfo); + if (errInfo.code != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { + return errInfo.code; + } + jint result = env->CallIntMethod(resultSet.Get()->GetRef(), jvm->GetMembers().m_ResultSetGetRow); ExceptionCheck(env, &errInfo); @@ -1777,7 +1856,11 @@ JniErrorCode JniContext::ResultSetWasNull( return errInfo.code; } - JNIEnv* env = Attach(); + JNIEnv* env = Attach(errInfo); + if (errInfo.code != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { + return errInfo.code; + } + jboolean res = env->CallBooleanMethod(resultSet.Get()->GetRef(), jvm->GetMembers().m_ResultSetWasNull); ExceptionCheck(env, &errInfo); @@ -1803,7 +1886,11 @@ JniErrorCode JniContext::ListSize(const SharedPointer< GlobalJObject >& list, return errInfo.code; } - JNIEnv* env = Attach(); + JNIEnv* env = Attach(errInfo); + if (errInfo.code != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { + return errInfo.code; + } + jint res = env->CallIntMethod(list.Get()->GetRef(), jvm->GetMembers().m_ListSize); ExceptionCheck(env, &errInfo); @@ -1831,7 +1918,11 @@ JniErrorCode JniContext::ListGet(const SharedPointer< GlobalJObject >& list, return errInfo.code; } - JNIEnv* env = Attach(); + JNIEnv* env = Attach(errInfo); + if (errInfo.code != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { + return errInfo.code; + } + jobject result = env->CallObjectMethod(list.Get()->GetRef(), jvm->GetMembers().m_ListGet, index); ExceptionCheck(env, &errInfo); @@ -1868,7 +1959,11 @@ JniContext::DocumentdbMqlQueryContextGetAggregateOperationsAsStrings( return errInfo.code; } - JNIEnv* env = Attach(); + JNIEnv* env = Attach(errInfo); + if (errInfo.code != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { + return errInfo.code; + } + jobject result = env->CallObjectMethod( mqlQueryContext.Get()->GetRef(), jvm->GetMembers() @@ -1907,7 +2002,11 @@ JniErrorCode JniContext::DocumentdbMqlQueryContextGetColumnMetadata( return errInfo.code; } - JNIEnv* env = Attach(); + JNIEnv* env = Attach(errInfo); + if (errInfo.code != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { + return errInfo.code; + } + jobject result = env->CallObjectMethod( mqlQueryContext.Get()->GetRef(), jvm->GetMembers().m_DocumentDbMqlQueryContextGetColumnMetadata); @@ -1944,7 +2043,11 @@ JniErrorCode JniContext::DocumentdbMqlQueryContextGetCollectionName( return errInfo.code; } - JNIEnv* env = Attach(); + JNIEnv* env = Attach(errInfo); + if (errInfo.code != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { + return errInfo.code; + } + jstring result = static_cast< jstring >(env->CallObjectMethod( mqlQueryContext.Get()->GetRef(), jvm->GetMembers().m_DocumentDbMqlQueryContextGetCollectionName)); @@ -1981,7 +2084,11 @@ JniErrorCode JniContext::DocumentdbMqlQueryContextGetPaths( return errInfo.code; } - JNIEnv* env = Attach(); + JNIEnv* env = Attach(errInfo); + if (errInfo.code != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { + return errInfo.code; + } + jobject result = env->CallObjectMethod( mqlQueryContext.Get()->GetRef(), jvm->GetMembers().m_DocumentDbMqlQueryContextGetPaths); @@ -2020,7 +2127,11 @@ JniErrorCode JniContext::DocumentDbQueryMappingServiceCtor( return errInfo.code; } - JNIEnv* env = Attach(); + JNIEnv* env = Attach(errInfo); + if (errInfo.code != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { + return errInfo.code; + } + jobject result = env->NewObject( jvm->GetMembers().c_DocumentDbQueryMappingService, jvm->GetMembers().m_DocumentDbQueryMappingServiceCtor, @@ -2058,7 +2169,11 @@ JniErrorCode JniContext::DocumentDbQueryMappingServiceGet( return errInfo.code; } - JNIEnv* env = Attach(); + JNIEnv* env = Attach(errInfo); + if (errInfo.code != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { + return errInfo.code; + } + jstring sqlString = env->NewStringUTF(sql.c_str()); jlong maxRowCountLong = maxRowCount; jobject result = env->CallObjectMethod( @@ -2098,7 +2213,11 @@ JniErrorCode JniContext::JdbcColumnMetadataGetOrdinal( return errInfo.code; } - JNIEnv* env = Attach(); + JNIEnv* env = Attach(errInfo); + if (errInfo.code != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { + return errInfo.code; + } + jint result = env->CallIntMethod(jdbcColumnMetadata.Get()->GetRef(), jvm->GetMembers().m_JdbcColumnMetadataGetOrdinal); @@ -2132,7 +2251,11 @@ JniErrorCode JniContext::CallBooleanMethod( return errInfo.code; } - JNIEnv* env = Attach(); + JNIEnv* env = Attach(errInfo); + if (errInfo.code != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { + return errInfo.code; + } + jboolean result = env->CallBooleanMethod(object.Get()->GetRef(), method); ExceptionCheck(env, &errInfo); if (errInfo.code != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { @@ -2162,7 +2285,11 @@ JniErrorCode JniContext::CallIntMethod( return errInfo.code; } - JNIEnv* env = Attach(); + JNIEnv* env = Attach(errInfo); + if (errInfo.code != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { + return errInfo.code; + } + jint result = env->CallIntMethod(object.Get()->GetRef(), method); ExceptionCheck(env, &errInfo); if (errInfo.code != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { @@ -2194,7 +2321,11 @@ JniErrorCode JniContext::CallStringMethod( return errInfo.code; } - JNIEnv* env = Attach(); + JNIEnv* env = Attach(errInfo); + if (errInfo.code != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { + return errInfo.code; + } + auto result = static_cast< jstring >( env->CallObjectMethod(object.Get()->GetRef(), method)); ExceptionCheck(env, &errInfo); @@ -2442,7 +2573,10 @@ jobject JniContext::LocalToGlobal(JNIEnv* env, jobject localRef) { int64_t JniContext::TargetInLongOutLong(jobject obj, int opType, int64_t val, JniErrorInfo* err) { - JNIEnv* env = Attach(); + JNIEnv* env = Attach(*err); + if (err->code != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { + return 0; + } int64_t res = env->CallLongMethod( obj, jvm->GetMembers().m_PlatformTarget_inLongOutLong, opType, val); @@ -2454,7 +2588,10 @@ int64_t JniContext::TargetInLongOutLong(jobject obj, int opType, int64_t val, int64_t JniContext::TargetInStreamOutLong(jobject obj, int opType, int64_t memPtr, JniErrorInfo* err) { - JNIEnv* env = Attach(); + JNIEnv* env = Attach(*err); + if (err->code != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { + return 0; + } int64_t res = env->CallLongMethod( obj, jvm->GetMembers().m_PlatformTarget_inStreamOutLong, opType, memPtr); @@ -2466,7 +2603,10 @@ int64_t JniContext::TargetInStreamOutLong(jobject obj, int opType, jobject JniContext::TargetOutObject(jobject obj, int opType, JniErrorInfo* err) { - JNIEnv* env = Attach(); + JNIEnv* env = Attach(*err); + if (err->code != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { + return nullptr; + } jobject res = env->CallObjectMethod( obj, jvm->GetMembers().m_PlatformTarget_outObject, opType); @@ -2479,7 +2619,10 @@ jobject JniContext::TargetOutObject(jobject obj, int opType, void JniContext::TargetInStreamOutStream(jobject obj, int opType, int64_t inMemPtr, int64_t outMemPtr, JniErrorInfo* err) { - JNIEnv* env = Attach(); + JNIEnv* env = Attach(*err); + if (err->code != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { + return; + } env->CallVoidMethod(obj, jvm->GetMembers().m_PlatformTarget_inStreamOutStream, opType, inMemPtr, outMemPtr); @@ -2489,7 +2632,10 @@ void JniContext::TargetInStreamOutStream(jobject obj, int opType, jobject JniContext::TargetInStreamOutObject(jobject obj, int opType, int64_t memPtr, JniErrorInfo* err) { - JNIEnv* env = Attach(); + JNIEnv* env = Attach(*err); + if (err->code != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { + return nullptr; + } jobject res = env->CallObjectMethod( obj, jvm->GetMembers().m_PlatformTarget_inStreamOutObject, opType, @@ -2502,7 +2648,10 @@ jobject JniContext::TargetInStreamOutObject(jobject obj, int opType, void JniContext::TargetOutStream(jobject obj, int opType, int64_t memPtr, JniErrorInfo* err) { - JNIEnv* env = Attach(); + JNIEnv* env = Attach(*err); + if (err->code != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { + return; + } env->CallVoidMethod(obj, jvm->GetMembers().m_PlatformTarget_outStream, opType, memPtr); @@ -2512,7 +2661,10 @@ void JniContext::TargetOutStream(jobject obj, int opType, int64_t memPtr, jobject JniContext::CacheOutOpQueryCursor(jobject obj, int type, int64_t memPtr, JniErrorInfo* err) { - JNIEnv* env = Attach(); + JNIEnv* env = Attach(*err); + if (err->code != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { + return nullptr; + } jobject res = env->CallObjectMethod( obj, jvm->GetMembers().m_PlatformTarget_inStreamOutObject, type, memPtr); @@ -2525,7 +2677,10 @@ jobject JniContext::CacheOutOpQueryCursor(jobject obj, int type, int64_t memPtr, jobject JniContext::CacheOutOpContinuousQuery(jobject obj, int type, int64_t memPtr, JniErrorInfo* err) { - JNIEnv* env = Attach(); + JNIEnv* env = Attach(*err); + if (err->code != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { + return nullptr; + } jobject res = env->CallObjectMethod( obj, jvm->GetMembers().m_PlatformTarget_inStreamOutObject, type, memPtr); @@ -2539,15 +2694,22 @@ jobject JniContext::Acquire(jobject obj) { LOG_DEBUG_MSG("Acquire is called"); if (obj) { - JNIEnv* env = Attach(); + JniErrorInfo errInfo; + JNIEnv* env = Attach(errInfo); + if (errInfo.code != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { + return nullptr; + } - jobject obj0 = env->NewGlobalRef(obj); - ExceptionCheck(env); + if (env) { + jobject obj0 = env->NewGlobalRef(obj); + + ExceptionCheck(env); - LOG_DEBUG_MSG("Acquire exiting with obj0 variable."); + LOG_DEBUG_MSG("Acquire exiting with obj0 variable."); - return obj0; + return obj0; + } } LOG_ERROR_MSG("Acquire exiting with nullptr."); @@ -2580,7 +2742,7 @@ void JniContext::Release(jobject obj) { /** * Attach thread to JVM. */ -JNIEnv* JniContext::Attach() { +JNIEnv* JniContext::Attach(JniErrorInfo& errInfo) { LOG_DEBUG_MSG("Attach is called"); JNIEnv* env; @@ -2588,11 +2750,17 @@ JNIEnv* JniContext::Attach() { jint attachRes = jvm->GetJvm()->AttachCurrentThread( reinterpret_cast< void** >(&env), nullptr); - if (attachRes == JNI_OK) + if (attachRes == JNI_OK) { AttachHelper::OnThreadAttach(); + errInfo.code = JniErrorCode::IGNITE_JNI_ERR_SUCCESS; + } else { + errInfo.code = JniErrorCode::IGNITE_JNI_ERR_JVM_ATTACH; + errInfo.errMsg = "Failed to connect to JVM"; + LOG_ERROR_MSG(errInfo.errMsg); + if (hnds.error) - hnds.error(hnds.target, JniErrorCode::IGNITE_JNI_ERR_JVM_ATTACH, nullptr, + hnds.error(hnds.target, errInfo.code, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0); } LOG_DEBUG_MSG("Attach exiting"); diff --git a/src/odbc/src/query/column_metadata_query.cpp b/src/odbc/src/query/column_metadata_query.cpp index 9822f631b..2aee5ebc0 100644 --- a/src/odbc/src/query/column_metadata_query.cpp +++ b/src/odbc/src/query/column_metadata_query.cpp @@ -201,9 +201,8 @@ SqlResult::Type ColumnMetadataQuery::FetchNextRow( if (!fetched) fetched = true; - else + else if (cursor != meta.end()) ++cursor; - if (cursor == meta.end()) return SqlResult::AI_NO_DATA; diff --git a/src/odbc/src/query/foreign_keys_query.cpp b/src/odbc/src/query/foreign_keys_query.cpp index 0c95bd2ce..2ca7bbf8c 100644 --- a/src/odbc/src/query/foreign_keys_query.cpp +++ b/src/odbc/src/query/foreign_keys_query.cpp @@ -91,6 +91,7 @@ ForeignKeysQuery::ForeignKeysQuery(diagnostic::DiagnosableAdapter& diag, schema(schema), table(table), executed(false), + fetched(false), columnsMeta() { using namespace ignite::odbc::impl::binary; using namespace ignite::odbc::type_traits; @@ -168,9 +169,8 @@ SqlResult::Type ForeignKeysQuery::FetchNextRow( if (!fetched) fetched = true; - else + else if (cursor != meta.end()) ++cursor; - if (cursor == meta.end()) return SqlResult::AI_NO_DATA; diff --git a/src/odbc/src/query/primary_keys_query.cpp b/src/odbc/src/query/primary_keys_query.cpp index e83f9a67e..e54d8fbba 100644 --- a/src/odbc/src/query/primary_keys_query.cpp +++ b/src/odbc/src/query/primary_keys_query.cpp @@ -60,6 +60,7 @@ PrimaryKeysQuery::PrimaryKeysQuery(diagnostic::DiagnosableAdapter& diag, schema(schema), table(table), executed(false), + fetched(false), columnsMeta() { using namespace ignite::odbc::impl::binary; using namespace ignite::odbc::type_traits; @@ -121,9 +122,8 @@ SqlResult::Type PrimaryKeysQuery::FetchNextRow( if (!fetched) fetched = true; - else + else if (cursor != meta.end()) ++cursor; - if (cursor == meta.end()) return SqlResult::AI_NO_DATA; diff --git a/src/odbc/src/query/table_metadata_query.cpp b/src/odbc/src/query/table_metadata_query.cpp index 57dd76b98..66365fbad 100644 --- a/src/odbc/src/query/table_metadata_query.cpp +++ b/src/odbc/src/query/table_metadata_query.cpp @@ -134,9 +134,8 @@ SqlResult::Type TableMetadataQuery::FetchNextRow( if (!fetched) fetched = true; - else + else if (cursor != meta.end()) ++cursor; - if (cursor == meta.end()) return SqlResult::AI_NO_DATA; diff --git a/src/odbc/src/query/type_info_query.cpp b/src/odbc/src/query/type_info_query.cpp index 2339407a9..9310acb5f 100644 --- a/src/odbc/src/query/type_info_query.cpp +++ b/src/odbc/src/query/type_info_query.cpp @@ -228,9 +228,8 @@ SqlResult::Type TypeInfoQuery::FetchNextRow( if (!fetched) fetched = true; - else + else if (cursor != types.end()) ++cursor; - if (cursor == types.end()) return SqlResult::AI_NO_DATA; diff --git a/src/odbc/src/statement.cpp b/src/odbc/src/statement.cpp index 9fd43f20c..ff554fe0c 100644 --- a/src/odbc/src/statement.cpp +++ b/src/odbc/src/statement.cpp @@ -230,14 +230,15 @@ SqlResult::Type Statement::InternalSetAttribute(int attr, void* value, LOG_MSG("SQL_ATTR_ROW_ARRAY_SIZE: " << val); - if (val < 1) { - AddStatusRecord(SqlState::SHY092_OPTION_TYPE_OUT_OF_RANGE, - "Array size value can not be less than 1"); + if (val != 1) { + AddStatusRecord( + SqlState::SIM001_FUNCTION_NOT_SUPPORTED, + "Array size value cannot be set to a value other than 1"); return SqlResult::AI_ERROR; - } - - rowArraySize = val; + } else if (rowArraySize != 1) + // val is 1 + rowArraySize = 1; break; }