IGNITE-11304: SQL: cache fields metadata for both distributed and local queries....
authordevozerov <vozerov@gridgain.com>
Wed, 13 Feb 2019 13:00:30 +0000 (16:00 +0300)
committerdevozerov <vozerov@gridgain.com>
Wed, 13 Feb 2019 13:00:30 +0000 (16:00 +0300)
modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/QueryParser.java
modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/QueryParserResultSelect.java

index c876d3c..88a72e8 100644 (file)
@@ -474,6 +474,7 @@ public class IgniteH2Indexing implements GridQueryIndexing {
         final String schemaName,
         String qry,
         @Nullable final Collection<Object> params,
+        @Nullable List<GridQueryFieldMetadata> meta,
         final IndexingQueryFilter filter,
         boolean enforceJoinOrder,
         boolean startTx,
@@ -582,21 +583,6 @@ public class IgniteH2Indexing implements GridQueryIndexing {
                 }
             }
 
-            List<GridQueryFieldMetadata> meta;
-
-            try {
-                meta = H2Utils.meta(stmt.getMetaData());
-
-                if (forUpdate) {
-                    assert meta.size() >= 1;
-
-                    meta = meta.subList(0, meta.size() - 1);
-                }
-            }
-            catch (SQLException e) {
-                throw new IgniteCheckedException("Cannot prepare query metadata", e);
-            }
-
             GridNearTxLocal tx0 = tx;
             MvccQueryTracker mvccTracker0 = mvccTracker;
             GridNearTxSelectForUpdateFuture sfuFut0 = sfuFut;
@@ -809,28 +795,11 @@ public class IgniteH2Indexing implements GridQueryIndexing {
             QueryCursorImpl<List<?>> stepCur = new QueryCursorImpl<>(new Iterable<List<?>>() {
                 @Override public Iterator<List<?>> iterator() {
                     try {
-                        Object[] params = args != null ? args : X.EMPTY_OBJECT_ARRAY;
+                        assert F.isEmpty(plan.selectQuery());
 
-                        Iterator<List<?>> it;
-
-                        if (!F.isEmpty(plan.selectQuery())) {
-                            GridQueryFieldsResult res = executeQueryLocal0(
-                                schema(cctx.name()),
-                                plan.selectQuery(),
-                                F.asList(params),
-                                null,
-                                false,
-                                false,
-                                0,
-                                null,
-                                null,
-                                null
-                            );
+                        Object[] params = args != null ? args : X.EMPTY_OBJECT_ARRAY;
 
-                            it = res.iterator();
-                        }
-                        else
-                            it = plan.createRows(params).iterator();
+                        Iterator<List<?>> it = plan.createRows(params).iterator();
 
                         return new GridQueryCacheObjectsIterator(it, objectContext(), cctx.keepBinary());
                     }
@@ -1092,6 +1061,7 @@ public class IgniteH2Indexing implements GridQueryIndexing {
     private FieldsQueryCursor<List<?>> executeQueryLocal(
         String schemaName,
         SqlFieldsQuery qry,
+        List<GridQueryFieldMetadata> meta,
         final boolean keepBinary,
         IndexingQueryFilter filter,
         GridQueryCancel cancel,
@@ -1103,6 +1073,7 @@ public class IgniteH2Indexing implements GridQueryIndexing {
             schemaName,
             qry.getSql(),
             F.asList(qry.getArgs()),
+            meta,
             filter,
             qry.isEnforceJoinOrder(),
             startTx,
@@ -1579,10 +1550,10 @@ public class IgniteH2Indexing implements GridQueryIndexing {
         // Execute SQL.
         assert select != null;
 
-        GridCacheTwoStepQuery twoStepQry = select.twoStepQuery();
-
-        if (twoStepQry != null) {
+        if (!select.isLocal()) {
             // Distributed query.
+            GridCacheTwoStepQuery twoStepQry = select.twoStepQuery();
+
             if (ctx.security().enabled())
                 checkSecurity(twoStepQry.cacheIds());
 
@@ -1590,7 +1561,7 @@ public class IgniteH2Indexing implements GridQueryIndexing {
                 schemaName,
                 qry,
                 twoStepQry,
-                select.twoStepQueryMeta(),
+                select.meta(),
                 keepBinary,
                 startTx,
                 mvccTracker,
@@ -1608,6 +1579,7 @@ public class IgniteH2Indexing implements GridQueryIndexing {
                 FieldsQueryCursor<List<?>> res = executeQueryLocal(
                     schemaName,
                     qry,
+                    select.meta(),
                     keepBinary,
                     filter,
                     cancel,
@@ -1743,13 +1715,31 @@ public class IgniteH2Indexing implements GridQueryIndexing {
                 .setTimeout(fldsQry.getTimeout(), TimeUnit.MILLISECONDS)
                 .setDataPageScanEnabled(fldsQry.isDataPageScanEnabled());
 
-            cur = (QueryCursorImpl<List<?>>)querySqlFields(schema, newFieldsQry, null, true, true,
-                new StaticMvccQueryTracker(planCctx, mvccSnapshot), cancel, false).get(0);
+            cur = (QueryCursorImpl<List<?>>)querySqlFields(
+                schema,
+                newFieldsQry,
+                null,
+                true,
+                true,
+                new StaticMvccQueryTracker(planCctx, mvccSnapshot),
+                cancel,
+                false
+            ).get(0);
         }
         else {
-            final GridQueryFieldsResult res = executeQueryLocal0(schema, plan.selectQuery(),
-                F.asList(fldsQry.getArgs()), filter, fldsQry.isEnforceJoinOrder(), false, fldsQry.getTimeout(), cancel,
-                new StaticMvccQueryTracker(planCctx, mvccSnapshot), null);
+            GridQueryFieldsResult res = executeQueryLocal0(
+                schema,
+                plan.selectQuery(),
+                F.asList(fldsQry.getArgs()),
+                null,
+                filter,
+                fldsQry.isEnforceJoinOrder(),
+                false,
+                fldsQry.getTimeout(),
+                cancel,
+                new StaticMvccQueryTracker(planCctx, mvccSnapshot),
+                null
+            );
 
             cur = new QueryCursorImpl<>(new Iterable<List<?>>() {
                 @Override public Iterator<List<?>> iterator() {
@@ -2832,9 +2822,19 @@ public class IgniteH2Indexing implements GridQueryIndexing {
         else if (plan.hasRows())
             cur = plan.createRows(fieldsQry.getArgs());
         else {
-            final GridQueryFieldsResult res = executeQueryLocal0(schemaName, plan.selectQuery(),
-                F.asList(fieldsQry.getArgs()), filters, fieldsQry.isEnforceJoinOrder(), false, fieldsQry.getTimeout(),
-                cancel, null, null);
+            final GridQueryFieldsResult res = executeQueryLocal0(
+                schemaName,
+                plan.selectQuery(),
+                F.asList(fieldsQry.getArgs()),
+                null,
+                filters,
+                fieldsQry.isEnforceJoinOrder(),
+                false,
+                fieldsQry.getTimeout(),
+                cancel,
+                null,
+                null
+            );
 
             cur = new QueryCursorImpl<>(new Iterable<List<?>>() {
                 @Override public Iterator<List<?>> iterator() {
index 7ab2696..35fec00 100644 (file)
@@ -190,7 +190,7 @@ public class QueryParser {
                 || nativeCmd instanceof SqlCreateUserCommand
                 || nativeCmd instanceof SqlAlterUserCommand
                 || nativeCmd instanceof SqlDropUserCommand)
-                )
+            )
                 return null;
 
             SqlFieldsQuery newQry = cloneFieldsQuery(qry).setSql(parser.lastCommandSql());
@@ -364,40 +364,31 @@ public class QueryParser {
                 IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
         }
 
-        // At this point only SELECT is possible.
-        if (loc) {
-            // No two-step for local query for now.
-            QueryParserResultSelect select = new QueryParserResultSelect(null, null, prepared);
-
-            return new QueryParserResult(newQry, remainingQry, select, null, null);
-        }
-
-        // Only distirbuted SELECT are possible at this point.
+        // Parse SELECT.
         try {
-            GridCacheTwoStepQuery twoStepQry = GridSqlQuerySplitter.split(
-                connMgr.connectionForThread().connection(newQry.getSchema()),
-                prepared,
-                newQry.getArgs(),
-                newQry.isCollocated(),
-                newQry.isDistributedJoins(),
-                newQry.isEnforceJoinOrder(),
-                newQry.isLocal(),
-                idx
-            );
+            GridCacheTwoStepQuery twoStepQry = null;
+
+            if (!loc) {
+                twoStepQry = GridSqlQuerySplitter.split(
+                    connMgr.connectionForThread().connection(newQry.getSchema()),
+                    prepared,
+                    newQry.getArgs(),
+                    newQry.isCollocated(),
+                    newQry.isDistributedJoins(),
+                    newQry.isEnforceJoinOrder(),
+                    newQry.isLocal(),
+                    idx
+                );
+            }
 
             List<GridQueryFieldMetadata> meta = H2Utils.meta(stmt.getMetaData());
 
-            QueryParserResultSelect select = new QueryParserResultSelect(
-                twoStepQry,
-                meta,
-                prepared
-            );
+            QueryParserResultSelect select = new QueryParserResultSelect(twoStepQry, meta);
 
             return new QueryParserResult(newQry, remainingQry, select, null, null);
         }
         catch (IgniteCheckedException e) {
-            throw new IgniteSQLException("Failed to bind parameters: [qry=" + newQry.getSql() + ", params=" +
-                Arrays.deepToString(newQry.getArgs()) + "]", IgniteQueryErrorCode.PARSING, e);
+            throw new IgniteSQLException("Failed to parse query: " + newQry.getSql(), IgniteQueryErrorCode.PARSING, e);
         }
         catch (SQLException e) {
             throw new IgniteSQLException(e);
index 3805fba..ba95552 100644 (file)
@@ -19,7 +19,7 @@ package org.apache.ignite.internal.processors.query.h2;
 
 import org.apache.ignite.internal.processors.cache.query.GridCacheTwoStepQuery;
 import org.apache.ignite.internal.processors.query.GridQueryFieldMetadata;
-import org.h2.command.Prepared;
+import org.jetbrains.annotations.Nullable;
 
 import java.util.List;
 
@@ -32,39 +32,37 @@ public class QueryParserResultSelect {
     private final GridCacheTwoStepQuery twoStepQry;
 
     /** Metadata for two-step query, or {@code} null if this result is for local query. */
-    private final List<GridQueryFieldMetadata> twoStepQryMeta;
+    private final List<GridQueryFieldMetadata> meta;
 
-    /** Prepared statement for local query. */
-    private final Prepared locPrepared;
-
-    public QueryParserResultSelect(
-        GridCacheTwoStepQuery twoStepQry,
-        List<GridQueryFieldMetadata> twoStepQryMeta,
-        Prepared locPrepared
-    ) {
+    /**
+     * Constructor.
+     *
+     * @param twoStepQry Distributed query plan.
+     * @param meta Fields metadata.
+     */
+    public QueryParserResultSelect(@Nullable GridCacheTwoStepQuery twoStepQry, List<GridQueryFieldMetadata> meta) {
         this.twoStepQry = twoStepQry;
-        this.twoStepQryMeta = twoStepQryMeta;
-        this.locPrepared = locPrepared;
+        this.meta = meta;
     }
 
     /**
      * @return Two-step query, or {@code} null if this result is for local query.
      */
-    public GridCacheTwoStepQuery twoStepQuery() {
+    @Nullable public GridCacheTwoStepQuery twoStepQuery() {
         return twoStepQry;
     }
 
     /**
      * @return Two-step query metadata.
      */
-    public List<GridQueryFieldMetadata> twoStepQueryMeta() {
-        return twoStepQryMeta;
+    public List<GridQueryFieldMetadata> meta() {
+        return meta;
     }
 
     /**
-     * @return Prepared statement for local query.
+     * @return Whether this is a local query.
      */
-    public Prepared localPrepared() {
-        return locPrepared;
+    public boolean isLocal() {
+        return twoStepQry == null;
     }
 }