You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by vo...@apache.org on 2019/03/27 14:25:09 UTC

[ignite] branch master updated: IGNITE-11552: ODBC: Fixed quoted schema handling. This closes #6348.

This is an automated email from the ASF dual-hosted git repository.

vozerov pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git


The following commit(s) were added to refs/heads/master by this push:
     new 8abb80c  IGNITE-11552: ODBC: Fixed quoted schema handling. This closes #6348.
8abb80c is described below

commit 8abb80cfa3f546a3e56d14627ce80b93ac4b414c
Author: Igor Sapego <ig...@gmail.com>
AuthorDate: Wed Mar 27 17:24:56 2019 +0300

    IGNITE-11552: ODBC: Fixed quoted schema handling. This closes #6348.
---
 .../processors/odbc/odbc/OdbcRequestHandler.java   | 18 +++---
 .../internal/processors/odbc/odbc/OdbcUtils.java   | 12 ++++
 .../cpp/odbc-test/src/api_robustness_test.cpp      | 68 +++++++++++++++-------
 3 files changed, 68 insertions(+), 30 deletions(-)

diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcRequestHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcRequestHandler.java
index d1ebaa9..869af22 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcRequestHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcRequestHandler.java
@@ -53,7 +53,6 @@ import org.apache.ignite.internal.processors.query.GridQueryProperty;
 import org.apache.ignite.internal.processors.query.GridQueryTypeDescriptor;
 import org.apache.ignite.internal.processors.query.IgniteSQLException;
 import org.apache.ignite.internal.processors.query.NestedTxMode;
-import org.apache.ignite.internal.processors.query.QueryUtils;
 import org.apache.ignite.internal.processors.query.SqlClientContext;
 import org.apache.ignite.internal.util.GridSpinBusyLock;
 import org.apache.ignite.internal.util.future.GridFutureAdapter;
@@ -352,7 +351,7 @@ public class OdbcRequestHandler implements ClientListenerRequestHandler {
         qry.setReplicatedOnly(cliCtx.isReplicatedOnly());
         qry.setCollocated(cliCtx.isCollocated());
         qry.setLazy(cliCtx.isLazy());
-        qry.setSchema(F.isEmpty(schema) ? QueryUtils.DFLT_SCHEMA : schema);
+        qry.setSchema(OdbcUtils.prepareSchema(schema));
         qry.setSkipReducerOnUpdate(cliCtx.isSkipReducerOnUpdate());
         qry.setNestedTxMode(nestedTxMode);
 
@@ -557,7 +556,7 @@ public class OdbcRequestHandler implements ClientListenerRequestHandler {
             assert cliCtx.isStream();
 
             ctx.query().streamBatchedUpdateQuery(
-                qry.getSchema(),
+                OdbcUtils.prepareSchema(qry.getSchema()),
                 cliCtx,
                 qry.getSql(),
                 qry.batchedArguments()
@@ -654,16 +653,16 @@ public class OdbcRequestHandler implements ClientListenerRequestHandler {
                 // Parsing two-part table name.
                 String[] parts = req.tablePattern().split("\\.");
 
-                schemaPattern = OdbcUtils.removeQuotationMarksIfNeeded(parts[0]);
-
+                schemaPattern = parts[0];
                 tablePattern = parts[1];
             }
             else {
-                schemaPattern = OdbcUtils.removeQuotationMarksIfNeeded(req.schemaPattern());
-
+                schemaPattern = req.schemaPattern();
                 tablePattern = req.tablePattern();
             }
 
+            schemaPattern = OdbcUtils.removeQuotationMarksIfNeeded(schemaPattern);
+
             for (String cacheName : ctx.cache().publicCacheNames()) {
                 for (GridQueryTypeDescriptor table : ctx.query().types(cacheName)) {
                     if (!matches(table.schemaName(), schemaPattern) ||
@@ -741,7 +740,10 @@ public class OdbcRequestHandler implements ClientListenerRequestHandler {
      */
     private ClientListenerResponse getParamsMeta(OdbcQueryGetParamsMetaRequest req) {
         try {
-            PreparedStatement stmt = ctx.query().getIndexing().prepareNativeStatement(req.schema(), req.query());
+            String sql = OdbcEscapeUtils.parse(req.query());
+            String schema = OdbcUtils.prepareSchema(req.schema());
+
+            PreparedStatement stmt = ctx.query().getIndexing().prepareNativeStatement(schema, sql);
 
             ParameterMetaData pmd = stmt.getParameterMetaData();
 
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcUtils.java
index c55ff1d..a687b96 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/odbc/OdbcUtils.java
@@ -26,6 +26,7 @@ import org.apache.ignite.internal.processors.cache.query.IgniteQueryErrorCode;
 import org.apache.ignite.internal.processors.odbc.SqlListenerDataTypes;
 import org.apache.ignite.internal.processors.odbc.SqlListenerUtils;
 import org.apache.ignite.internal.processors.query.IgniteSQLException;
+import org.apache.ignite.internal.processors.query.QueryUtils;
 import org.apache.ignite.internal.util.typedef.F;
 
 /**
@@ -74,6 +75,17 @@ public class OdbcUtils {
     }
 
     /**
+     * Prepare client's schema for processing.
+     * @param schema Schema.
+     * @return Prepared schema.
+     */
+    public static String prepareSchema(String schema) {
+        String schema0 = removeQuotationMarksIfNeeded(schema);
+
+        return F.isEmpty(schema0) ? QueryUtils.DFLT_SCHEMA : schema0;
+    }
+
+    /**
      * Private constructor.
      */
     private OdbcUtils() {
diff --git a/modules/platforms/cpp/odbc-test/src/api_robustness_test.cpp b/modules/platforms/cpp/odbc-test/src/api_robustness_test.cpp
index 963b67f..9148ba9 100644
--- a/modules/platforms/cpp/odbc-test/src/api_robustness_test.cpp
+++ b/modules/platforms/cpp/odbc-test/src/api_robustness_test.cpp
@@ -220,7 +220,7 @@ BOOST_AUTO_TEST_CASE(TestSQLConnect)
     SQLCHAR buffer[ODBC_BUFFER_SIZE];
     SQLSMALLINT resLen = 0;
 
-    // Everyting is ok.
+    // Everything is ok.
     SQLRETURN ret = SQLGetInfo(dbc, SQL_DRIVER_NAME, buffer, ODBC_BUFFER_SIZE, &resLen);
 
     ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
@@ -250,7 +250,7 @@ BOOST_AUTO_TEST_CASE(TestSQLPrepare)
 
     SQLCHAR sql[] = "SELECT strField FROM TestType";
 
-    // Everyting is ok.
+    // Everything is ok.
     SQLRETURN ret = SQLPrepare(stmt, sql, sizeof(sql));
 
     ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);
@@ -282,7 +282,7 @@ BOOST_AUTO_TEST_CASE(TestSQLExecDirect)
 
     SQLCHAR sql[] = "SELECT strField FROM TestType";
 
-    // Everyting is ok.
+    // Everything is ok.
     SQLRETURN ret = SQLExecDirect(stmt, sql, sizeof(sql));
 
     ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);
@@ -330,7 +330,7 @@ BOOST_AUTO_TEST_CASE(TestSQLExtendedFetch)
     SQLULEN rowCount;
     SQLUSMALLINT rowStatus[16];
 
-    // Everyting is ok.
+    // Everything is ok.
     ret = SQLExtendedFetch(stmt, SQL_FETCH_NEXT, 0, &rowCount, rowStatus);
 
     ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);
@@ -369,7 +369,7 @@ BOOST_AUTO_TEST_CASE(TestSQLNumResultCols)
 
     SQLSMALLINT columnCount;
 
-    // Everyting is ok.
+    // Everything is ok.
     ret = SQLNumResultCols(stmt, &columnCount);
 
     ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);
@@ -390,7 +390,7 @@ BOOST_AUTO_TEST_CASE(TestSQLTables)
     SQLCHAR tableName[] = "";
     SQLCHAR tableType[] = "";
 
-    // Everithing is ok.
+    // Everything is ok.
     SQLRETURN ret = SQLTables(stmt, catalogName, sizeof(catalogName), schemaName,
         sizeof(schemaName), tableName, sizeof(tableName), tableType, sizeof(tableType));
 
@@ -418,7 +418,7 @@ BOOST_AUTO_TEST_CASE(TestSQLColumns)
     SQLCHAR tableName[] = "";
     SQLCHAR columnName[] = "";
 
-    // Everithing is ok.
+    // Everything is ok.
     SQLRETURN ret = SQLColumns(stmt, catalogName, sizeof(catalogName), schemaName,
         sizeof(schemaName), tableName, sizeof(tableName), columnName, sizeof(columnName));
 
@@ -444,7 +444,7 @@ BOOST_AUTO_TEST_CASE(TestSQLBindCol)
     SQLINTEGER ind1;
     SQLLEN len1 = 0;
 
-    // Everithing is ok.
+    // Everything is ok.
     SQLRETURN ret = SQLBindCol(stmt, 1, SQL_C_SLONG, &ind1, sizeof(ind1), &len1);
 
     ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);
@@ -485,7 +485,7 @@ BOOST_AUTO_TEST_CASE(TestSQLBindParameter)
     SQLINTEGER ind1;
     SQLLEN len1 = 0;
 
-    // Everithing is ok.
+    // Everything is ok.
     SQLRETURN ret = SQLBindParameter(stmt, 1, SQL_PARAM_INPUT,
         SQL_C_SLONG, SQL_INTEGER, 100, 100, &ind1, sizeof(ind1), &len1);
 
@@ -533,7 +533,7 @@ BOOST_AUTO_TEST_CASE(TestSQLNativeSql)
     SQLCHAR buffer[ODBC_BUFFER_SIZE];
     SQLINTEGER resLen = 0;
 
-    // Everithing is ok.
+    // Everything is ok.
     SQLRETURN ret = SQLNativeSql(dbc, sql, sizeof(sql), buffer, sizeof(buffer), &resLen);
 
     ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);
@@ -574,12 +574,12 @@ BOOST_AUTO_TEST_CASE(TestSQLColAttribute)
     SQLSMALLINT resLen = 0;
     SQLLEN numericAttr = 0;
 
-    // Everithing is ok. Character attribute.
+    // Everything is ok. Character attribute.
     ret = SQLColAttribute(stmt, 1, SQL_COLUMN_TABLE_NAME, buffer, sizeof(buffer), &resLen, &numericAttr);
 
     ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);
 
-    // Everithing is ok. Numeric attribute.
+    // Everything is ok. Numeric attribute.
     ret = SQLColAttribute(stmt, 1, SQL_DESC_COUNT, buffer, sizeof(buffer), &resLen, &numericAttr);
 
     ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);
@@ -617,7 +617,7 @@ BOOST_AUTO_TEST_CASE(TestSQLDescribeCol)
     SQLSMALLINT decimalDigits = 0;
     SQLSMALLINT nullable = 0;
 
-    // Everithing is ok.
+    // Everything is ok.
     ret = SQLDescribeCol(stmt, 1, columnName, sizeof(columnName),
         &columnNameLen, &dataType, &columnSize, &decimalDigits, &nullable);
 
@@ -648,7 +648,7 @@ BOOST_AUTO_TEST_CASE(TestSQLRowCount)
 
     SQLLEN rows = 0;
 
-    // Everithing is ok.
+    // Everything is ok.
     ret = SQLRowCount(stmt, &rows);
 
     ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);
@@ -667,7 +667,7 @@ BOOST_AUTO_TEST_CASE(TestSQLForeignKeys)
     SQLCHAR schemaName[] = "cache";
     SQLCHAR tableName[] = "TestType";
 
-    // Everithing is ok.
+    // Everything is ok.
     SQLRETURN ret = SQLForeignKeys(stmt, catalogName, sizeof(catalogName), schemaName, sizeof(schemaName),
         tableName, sizeof(tableName), catalogName, sizeof(catalogName),
         schemaName, sizeof(schemaName), tableName, sizeof(tableName));
@@ -751,7 +751,7 @@ BOOST_AUTO_TEST_CASE(TestSQLGetStmtAttr)
     SQLCHAR buffer[ODBC_BUFFER_SIZE];
     SQLINTEGER resLen = 0;
 
-    // Everithing is ok.
+    // Everything is ok.
     SQLRETURN ret = SQLGetStmtAttr(stmt, SQL_ATTR_ROW_ARRAY_SIZE, buffer, sizeof(buffer), &resLen);
 
     ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);
@@ -771,7 +771,7 @@ BOOST_AUTO_TEST_CASE(TestSQLSetStmtAttr)
 
     SQLULEN val = 1;
 
-    // Everithing is ok.
+    // Everything is ok.
     SQLRETURN ret = SQLSetStmtAttr(stmt, SQL_ATTR_ROW_ARRAY_SIZE, reinterpret_cast<SQLPOINTER>(val), sizeof(val));
 
     ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);
@@ -792,7 +792,7 @@ BOOST_AUTO_TEST_CASE(TestSQLPrimaryKeys)
     SQLCHAR schemaName[] = "cache";
     SQLCHAR tableName[] = "TestType";
 
-    // Everithing is ok.
+    // Everything is ok.
     SQLRETURN ret = SQLPrimaryKeys(stmt, catalogName, sizeof(catalogName), schemaName, sizeof(schemaName),
         tableName, sizeof(tableName));
 
@@ -816,14 +816,38 @@ BOOST_AUTO_TEST_CASE(TestSQLNumParams)
 
     SQLCHAR sql[] = "SELECT strField FROM TestType";
 
-    // Everyting is ok.
+    // Everything is ok.
     SQLRETURN ret = SQLPrepare(stmt, sql, sizeof(sql));
 
     ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);
 
     SQLSMALLINT params;
 
-    // Everithing is ok.
+    // Everything is ok.
+    ret = SQLNumParams(stmt, &params);
+
+    ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);
+
+    SQLNumParams(stmt, 0);
+}
+
+BOOST_AUTO_TEST_CASE(TestSQLNumParamsEscaped)
+{
+    // There are no checks because we do not really care what is the result of these
+    // calls as long as they do not cause segmentation fault.
+
+    Connect("DRIVER={Apache Ignite};address=127.0.0.1:11110;schema=cache");
+
+    SQLCHAR sql[] = "SELECT {fn NOW()}";
+
+    // Everything is ok.
+    SQLRETURN ret = SQLPrepare(stmt, sql, sizeof(sql));
+
+    ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);
+
+    SQLSMALLINT params;
+
+    // Everything is ok.
     ret = SQLNumParams(stmt, &params);
 
     ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt);
@@ -846,7 +870,7 @@ BOOST_AUTO_TEST_CASE(TestSQLGetDiagField)
     SQLCHAR buffer[ODBC_BUFFER_SIZE];
     SQLSMALLINT resLen = 0;
 
-    // Everithing is ok
+    // Everything is ok
     ret = SQLGetDiagField(SQL_HANDLE_STMT, stmt, 1, SQL_DIAG_MESSAGE_TEXT, buffer, sizeof(buffer), &resLen);
 
     BOOST_REQUIRE_EQUAL(ret, SQL_SUCCESS);
@@ -870,7 +894,7 @@ BOOST_AUTO_TEST_CASE(TestSQLGetDiagRec)
     SQLRETURN ret = SQLGetTypeInfo(stmt, SQL_INTERVAL_MONTH);
     BOOST_REQUIRE_EQUAL(ret, SQL_ERROR);
 
-    // Everithing is ok.
+    // Everything is ok.
     ret = SQLGetDiagRec(SQL_HANDLE_STMT, stmt, 1, state, &nativeError, message, sizeof(message), &messageLen);
     BOOST_REQUIRE_EQUAL(ret, SQL_SUCCESS);