ignite-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From voze...@apache.org
Subject ignite git commit: IGNITE-6375: SQL: Fixed co-location issue in CREATE TABLE command. This closes #2660.
Date Thu, 28 Sep 2017 08:00:55 GMT
Repository: ignite
Updated Branches:
  refs/heads/master f96a9a4ce -> b7bb79232


IGNITE-6375: SQL: Fixed co-location issue in CREATE TABLE command. This closes #2660.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/b7bb7923
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/b7bb7923
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/b7bb7923

Branch: refs/heads/master
Commit: b7bb7923246198fb424570ed9735f238d4f520e5
Parents: f96a9a4
Author: devozerov <vozerov@gridgain.com>
Authored: Thu Sep 28 11:00:46 2017 +0300
Committer: devozerov <vozerov@gridgain.com>
Committed: Thu Sep 28 11:00:46 2017 +0300

----------------------------------------------------------------------
 .../query/h2/dml/UpdatePlanBuilder.java         |  49 ++----
 .../processors/query/h2/sql/DmlAstUtils.java    |  16 ++
 .../processors/query/h2/sql/GridSqlMerge.java   |   5 +-
 .../query/h2/sql/GridSqlQueryParser.java        |  28 ++-
 ...niteCacheAbstractInsertSqlQuerySelfTest.java |  15 +-
 .../cache/index/DynamicColumnsAbstractTest.java |   5 +-
 .../H2DynamicColumnsAbstractBasicSelfTest.java  |   5 -
 .../query/h2/sql/GridQueryParsingTest.java      | 171 ++++++-------------
 8 files changed, 131 insertions(+), 163 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/b7bb7923/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/dml/UpdatePlanBuilder.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/dml/UpdatePlanBuilder.java
b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/dml/UpdatePlanBuilder.java
index 285a0b0..804f7d8 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/dml/UpdatePlanBuilder.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/dml/UpdatePlanBuilder.java
@@ -21,7 +21,6 @@ import java.lang.reflect.Constructor;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
-import javax.cache.CacheException;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.binary.BinaryObject;
 import org.apache.ignite.binary.BinaryObjectBuilder;
@@ -60,7 +59,9 @@ import static org.apache.ignite.internal.processors.query.h2.opt.GridH2KeyValueR
  * Logic for building update plans performed by {@link DmlStatementsProcessor}.
  */
 public final class UpdatePlanBuilder {
-    /** */
+    /**
+     * Constructor.
+     */
     private UpdatePlanBuilder() {
         // No-op.
     }
@@ -111,7 +112,7 @@ public final class UpdatePlanBuilder {
             GridSqlInsert ins = (GridSqlInsert) stmt;
             target = ins.into();
 
-            tbl = gridTableForElement(target);
+            tbl = DmlAstUtils.gridTableForElement(target);
             desc = tbl.dataTable().rowDescriptor();
 
             cols = ins.columns();
@@ -124,24 +125,18 @@ public final class UpdatePlanBuilder {
 
             target = merge.into();
 
-            tbl = gridTableForElement(target);
+            tbl = DmlAstUtils.gridTableForElement(target);
             desc = tbl.dataTable().rowDescriptor();
 
-            // This check also protects us from attempts to update key or its fields directly
-
-            // when no key except cache key can be used, it will serve only for uniqueness
checks,
-            // not for updates, and hence will allow putting new pairs only.
-            // We don't quote _key and _val column names on CREATE TABLE, so they are always
uppercase here.
-            GridSqlColumn[] keys = merge.keys();
-            if (keys.length != 1 || !desc.isKeyColumn(tbl.dataTable().getColumn(keys[0].columnName()).getColumnId()))
-                throw new CacheException("SQL MERGE does not support arbitrary keys");
-
             cols = merge.columns();
             sel = DmlAstUtils.selectForInsertOrMerge(cols, merge.rows(), merge.query());
             isTwoStepSubqry = (merge.query() != null);
             rowsNum = isTwoStepSubqry ? 0 : merge.rows().size();
         }
-        else throw new IgniteSQLException("Unexpected DML operation [cls=" + stmt.getClass().getName()
+ ']',
+        else {
+            throw new IgniteSQLException("Unexpected DML operation [cls=" + stmt.getClass().getName()
+ ']',
                 IgniteQueryErrorCode.UNEXPECTED_OPERATION);
+        }
 
         // Let's set the flag only for subqueries that have their FROM specified.
         isTwoStepSubqry = (isTwoStepSubqry && (sel instanceof GridSqlUnion ||
@@ -212,7 +207,8 @@ public final class UpdatePlanBuilder {
      * @return Update plan.
      * @throws IgniteCheckedException if failed.
      */
-    private static UpdatePlan planForUpdate(GridSqlStatement stmt, @Nullable Integer errKeysPos)
throws IgniteCheckedException {
+    private static UpdatePlan planForUpdate(GridSqlStatement stmt, @Nullable Integer errKeysPos)
+        throws IgniteCheckedException {
         GridSqlElement target;
 
         FastUpdateArguments fastUpdate;
@@ -238,7 +234,7 @@ public final class UpdatePlanBuilder {
             throw new IgniteSQLException("Unexpected DML operation [cls=" + stmt.getClass().getName()
+ ']',
                 IgniteQueryErrorCode.UNEXPECTED_OPERATION);
 
-        GridSqlTable tbl = gridTableForElement(target);
+        GridSqlTable tbl = DmlAstUtils.gridTableForElement(target);
 
         GridH2Table gridTbl = tbl.dataTable();
 
@@ -267,8 +263,9 @@ public final class UpdatePlanBuilder {
 
                     colTypes[i] = updatedCols.get(i).resultType().type();
 
-                    Column column = updatedCols.get(i).column();
-                    if (desc.isValueColumn(column.getColumnId()))
+                    Column col = updatedCols.get(i).column();
+
+                    if (desc.isValueColumn(col.getColumnId()))
                         valColIdx = i;
                 }
 
@@ -441,21 +438,6 @@ public final class UpdatePlanBuilder {
     }
 
     /**
-     * @param target Expression to extract the table from.
-     * @return Back end table for this element.
-     */
-    private static GridSqlTable gridTableForElement(GridSqlElement target) {
-        Set<GridSqlTable> tbls = new HashSet<>();
-
-        DmlAstUtils.collectAllGridTablesInTarget(target, tbls);
-
-        if (tbls.size() != 1)
-            throw new IgniteSQLException("Failed to determine target table", IgniteQueryErrorCode.TABLE_NOT_FOUND);
-
-        return tbls.iterator().next();
-    }
-
-    /**
      * Check that UPDATE statement affects no key columns.
      *
      * @param statement Statement.
@@ -473,7 +455,8 @@ public final class UpdatePlanBuilder {
         DmlAstUtils.collectAllGridTablesInTarget(updTarget, tbls);
 
         if (tbls.size() != 1)
-            throw new IgniteSQLException("Failed to determine target table for UPDATE", IgniteQueryErrorCode.TABLE_NOT_FOUND);
+            throw new IgniteSQLException("Failed to determine target table for UPDATE",
+                IgniteQueryErrorCode.TABLE_NOT_FOUND);
 
         GridSqlTable tbl = tbls.iterator().next();
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/b7bb7923/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/DmlAstUtils.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/DmlAstUtils.java
b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/DmlAstUtils.java
index edbf56b..4537ffc 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/DmlAstUtils.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/DmlAstUtils.java
@@ -23,6 +23,7 @@ import java.util.List;
 import java.util.Set;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.IgniteException;
+import org.apache.ignite.internal.processors.cache.query.IgniteQueryErrorCode;
 import org.apache.ignite.internal.processors.query.IgniteSQLException;
 import org.apache.ignite.internal.processors.query.h2.dml.FastUpdateArgument;
 import org.apache.ignite.internal.processors.query.h2.dml.FastUpdateArguments;
@@ -590,6 +591,21 @@ public final class DmlAstUtils {
         });
     }
 
+    /**
+     * @param target Expression to extract the table from.
+     * @return Back end table for this element.
+     */
+    public static GridSqlTable gridTableForElement(GridSqlElement target) {
+        Set<GridSqlTable> tbls = new HashSet<>();
+
+        collectAllGridTablesInTarget(target, tbls);
+
+        if (tbls.size() != 1)
+            throw new IgniteSQLException("Failed to determine target table", IgniteQueryErrorCode.TABLE_NOT_FOUND);
+
+        return tbls.iterator().next();
+    }
+
     /** Simple constant value based operand. */
     private final static class ValueArgument implements FastUpdateArgument {
         /** Value to return. */

http://git-wip-us.apache.org/repos/asf/ignite/blob/b7bb7923/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlMerge.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlMerge.java
b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlMerge.java
index 4cdb314..f9b084b 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlMerge.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlMerge.java
@@ -55,9 +55,8 @@ public class GridSqlMerge extends GridSqlStatement {
             buff.append("KEY(\n");
             buff.resetCount();
             for (GridSqlColumn c : keys) {
-                buff.appendExceptFirst(", ");
-                buff.append(c.getSQL())
-                    .append('\n');
+                buff.appendExceptFirst(",\n");
+                buff.append(c.getSQL());
             }
             buff.append(")\n");
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/b7bb7923/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQueryParser.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQueryParser.java
b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQueryParser.java
index 5cec625..a379a91 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQueryParser.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQueryParser.java
@@ -36,6 +36,8 @@ import org.apache.ignite.cache.QueryIndexType;
 import org.apache.ignite.internal.processors.cache.query.IgniteQueryErrorCode;
 import org.apache.ignite.internal.processors.query.IgniteSQLException;
 import org.apache.ignite.internal.processors.query.QueryUtils;
+import org.apache.ignite.internal.processors.query.h2.opt.GridH2RowDescriptor;
+import org.apache.ignite.internal.processors.query.h2.opt.GridH2Table;
 import org.apache.ignite.internal.util.typedef.F;
 import org.h2.command.Command;
 import org.h2.command.CommandContainer;
@@ -678,9 +680,24 @@ public class GridSqlQueryParser {
 
         Column[] srcKeys = MERGE_KEYS.get(merge);
 
+        GridH2Table intoTbl = DmlAstUtils.gridTableForElement(tbl).dataTable();
+
+        GridH2RowDescriptor rowDesc = intoTbl.rowDescriptor();
+
         GridSqlColumn[] keys = new GridSqlColumn[srcKeys.length];
-        for (int i = 0; i < srcKeys.length; i++)
-            keys[i] = new GridSqlColumn(srcKeys[i], tbl, null, null, srcKeys[i].getName());
+
+        for (int i = 0; i < srcKeys.length; i++) {
+            String colName = srcKeys[i].getName();
+
+            int colId = intoTbl.getColumn(colName).getColumnId();
+
+            if (!rowDesc.isKeyColumn(colId) && !F.eq(colName, rowDesc.type().affinityKey()))
+                throw new IgniteSQLException("Invalid column name in KEYS clause of MERGE
- it may include only " +
+                    "key and/or affinity columns: " + colName, IgniteQueryErrorCode.PARSING);
+
+            keys[i] = new GridSqlColumn(srcKeys[i], tbl, null, null, colName);
+        }
+
         res.keys(keys);
 
         List<Expression[]> srcRows = MERGE_ROWS.get(merge);
@@ -996,6 +1013,13 @@ public class GridSqlQueryParser {
             throw new IgniteSQLException("Key and value type names " +
                 "should be different for CREATE TABLE: " + res.valueTypeName(), IgniteQueryErrorCode.PARSING);
 
+        if (res.affinityKey() == null) {
+            LinkedHashSet<String> pkCols0 = res.primaryKeyColumns();
+
+            if (!F.isEmpty(pkCols0) && pkCols0.size() == 1)
+                res.affinityKey(pkCols0.iterator().next());
+        }
+
         return res;
     }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/b7bb7923/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractInsertSqlQuerySelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractInsertSqlQuerySelfTest.java
b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractInsertSqlQuerySelfTest.java
index eab00df..9113e9b 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractInsertSqlQuerySelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractInsertSqlQuerySelfTest.java
@@ -26,14 +26,17 @@ import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.binary.BinaryObjectBuilder;
 import org.apache.ignite.binary.BinaryTypeConfiguration;
 import org.apache.ignite.cache.CacheAtomicityMode;
+import org.apache.ignite.cache.CacheKeyConfiguration;
 import org.apache.ignite.cache.CacheMode;
 import org.apache.ignite.cache.QueryEntity;
 import org.apache.ignite.cache.QueryIndex;
+import org.apache.ignite.cache.affinity.AffinityKeyMapped;
 import org.apache.ignite.cache.query.annotations.QuerySqlField;
 import org.apache.ignite.configuration.BinaryConfiguration;
 import org.apache.ignite.configuration.CacheConfiguration;
 import org.apache.ignite.configuration.IgniteConfiguration;
 import org.apache.ignite.internal.binary.BinaryMarshaller;
+import org.apache.ignite.internal.processors.query.QueryUtils;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.marshaller.Marshaller;
 import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
@@ -303,13 +306,22 @@ public abstract class IgniteCacheAbstractInsertSqlQuerySelfTest extends
GridComm
      * @return Cache configuration.
      */
     static CacheConfiguration cacheConfig(String name, boolean partitioned, boolean escapeSql,
Class<?>... idxTypes) {
-        return new CacheConfiguration(DEFAULT_CACHE_NAME)
+        CacheConfiguration res = new CacheConfiguration(DEFAULT_CACHE_NAME)
             .setName(name)
             .setCacheMode(partitioned ? CacheMode.PARTITIONED : CacheMode.REPLICATED)
             .setAtomicityMode(CacheAtomicityMode.ATOMIC)
             .setBackups(1)
             .setSqlEscapeAll(escapeSql)
             .setIndexedTypes(idxTypes);
+
+        for (int i = 0; i < idxTypes.length / 2; i++) {
+            Class<?> keyType = idxTypes[i];
+
+            if (!QueryUtils.isSqlType(keyType))
+                res.setKeyConfiguration(new CacheKeyConfiguration(keyType));
+        }
+
+        return res;
     }
 
     /**
@@ -326,6 +338,7 @@ public abstract class IgniteCacheAbstractInsertSqlQuerySelfTest extends
GridComm
 
         /** */
         @QuerySqlField
+        @AffinityKeyMapped
         public final int key;
 
         /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/b7bb7923/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsAbstractTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsAbstractTest.java
b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsAbstractTest.java
index 4831d02..b25359a 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsAbstractTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsAbstractTest.java
@@ -302,7 +302,10 @@ public abstract class DynamicColumnsAbstractTest extends GridCommonAbstractTest
      * @return result.
      */
     protected List<List<?>> run(IgniteCache<?, ?> cache, String sql, Object...
args) {
-        return cache.query(new SqlFieldsQuery(sql).setSchema(QueryUtils.DFLT_SCHEMA).setArgs(args)).getAll();
+        SqlFieldsQuery qry = new SqlFieldsQuery(sql).setSchema(QueryUtils.DFLT_SCHEMA).setArgs(args)
+            .setDistributedJoins(true);
+
+        return cache.query(qry).getAll();
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/b7bb7923/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2DynamicColumnsAbstractBasicSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2DynamicColumnsAbstractBasicSelfTest.java
b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2DynamicColumnsAbstractBasicSelfTest.java
index 7329fa8..5e64959 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2DynamicColumnsAbstractBasicSelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2DynamicColumnsAbstractBasicSelfTest.java
@@ -159,9 +159,7 @@ public abstract class H2DynamicColumnsAbstractBasicSelfTest extends DynamicColum
         run(cache, "ALTER TABLE Person ADD COLUMN city varchar");
 
         run(cache, "INSERT INTO Person (id, name, city) values (1, 'John Doe', 'New York')");
-
         run(cache, "INSERT INTO Person (id, name, city) values (2, 'Mike Watts', 'Denver')");
-
         run(cache, "INSERT INTO Person (id, name, city) values (3, 'Ann Pierce', 'New York')");
 
         run(cache, "CREATE INDEX pidx1 ON Person(name, city desc)");
@@ -205,11 +203,8 @@ public abstract class H2DynamicColumnsAbstractBasicSelfTest extends DynamicColum
         run(cache, "CREATE INDEX pidx2 on Person(age desc)");
 
         run(cache, "DROP INDEX pidx2");
-
         run(cache, "DROP INDEX pidx1");
-
         run(cache, "DROP INDEX cidx2");
-
         run(cache, "DROP INDEX cidx1");
 
         run(cache, "DELETE FROM Person where age > 10");

http://git-wip-us.apache.org/repos/asf/ignite/blob/b7bb7923/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/GridQueryParsingTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/GridQueryParsingTest.java
b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/GridQueryParsingTest.java
index 61694dd..a1fe04b 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/GridQueryParsingTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/GridQueryParsingTest.java
@@ -31,9 +31,11 @@ import java.util.Map;
 import java.util.concurrent.Callable;
 import org.apache.ignite.Ignite;
 import org.apache.ignite.cache.CacheAtomicityMode;
+import org.apache.ignite.cache.CacheKeyConfiguration;
 import org.apache.ignite.cache.CacheMode;
 import org.apache.ignite.cache.QueryIndex;
 import org.apache.ignite.cache.QueryIndexType;
+import org.apache.ignite.cache.affinity.AffinityKeyMapped;
 import org.apache.ignite.cache.query.annotations.QuerySqlField;
 import org.apache.ignite.cache.query.annotations.QuerySqlFunction;
 import org.apache.ignite.configuration.CacheConfiguration;
@@ -42,19 +44,16 @@ import org.apache.ignite.internal.GridKernalContext;
 import org.apache.ignite.internal.IgniteEx;
 import org.apache.ignite.internal.processors.query.GridQueryProcessor;
 import org.apache.ignite.internal.processors.query.IgniteSQLException;
+import org.apache.ignite.internal.processors.query.QueryUtils;
 import org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing;
-import org.apache.ignite.internal.util.GridStringBuilder;
 import org.apache.ignite.internal.util.typedef.F;
-import org.apache.ignite.internal.util.typedef.internal.SB;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
 import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder;
 import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
 import org.apache.ignite.testframework.GridTestUtils;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
-import org.h2.command.Parser;
 import org.h2.command.Prepared;
-import org.h2.command.ddl.CreateTable;
 import org.h2.engine.Session;
 import org.h2.jdbc.JdbcConnection;
 import org.h2.message.DbException;
@@ -88,7 +87,8 @@ public class GridQueryParsingTest extends GridCommonAbstractTest {
 
         c.setCacheConfiguration(
             cacheConfiguration(DEFAULT_CACHE_NAME, "SCH1", String.class, Person.class),
-            cacheConfiguration("addr", "SCH2", String.class, Address.class));
+            cacheConfiguration("addr", "SCH2", String.class, Address.class),
+            cacheConfiguration("aff", "SCH3", PersonKey.class, Person.class));
 
         return c;
     }
@@ -99,7 +99,9 @@ public class GridQueryParsingTest extends GridCommonAbstractTest {
      * @param clsV Value class.
      * @return Cache configuration.
      */
-    private CacheConfiguration cacheConfiguration(@NotNull String name, String sqlSchema,
Class<?> clsK, Class<?> clsV) {
+    @SuppressWarnings("unchecked")
+    private CacheConfiguration cacheConfiguration(@NotNull String name, String sqlSchema,
Class<?> clsK,
+        Class<?> clsV) {
         CacheConfiguration cc = defaultCacheConfiguration();
 
         cc.setName(name);
@@ -112,6 +114,9 @@ public class GridQueryParsingTest extends GridCommonAbstractTest {
         cc.setSqlFunctionClasses(GridQueryParsingTest.class);
         cc.setIndexedTypes(clsK, clsV);
 
+        if (!QueryUtils.isSqlType(clsK))
+            cc.setKeyConfiguration(new CacheKeyConfiguration(clsK));
+
         return cc;
     }
 
@@ -410,13 +415,25 @@ public class GridQueryParsingTest extends GridCommonAbstractTest {
         checkQuery("merge into Person(old, name) select ASCII(parentName), INSERT(parentName,
4, 4, 'Max') from " +
             "Person where date='2011-03-12'");
 
+        /* KEY clause. */
+        checkQuery("merge into Person(_key, old, name) key(_key) values('a', 5, 'John')");
+        checkQuery("merge into SCH3.Person(id, old, name) key(id) values(1, 5, 'John')");
+        checkQuery("merge into SCH3.Person(_key, old, name) key(_key) values(?, 5, 'John')");
+        checkQuery("merge into SCH3.Person(_key, id, old, name) key(_key, id) values(?, ?,
5, 'John')");
+        assertParseThrows("merge into Person(old, name) key(name) values(5, 'John')", IgniteSQLException.class,
+            "Invalid column name in KEYS clause of MERGE - it may include only key and/or
affinity columns: NAME");
+        assertParseThrows("merge into SCH3.Person(id, stuff, old, name) key(stuff) values(1,
'x', 5, 'John')",
+            IgniteSQLException.class, "Invalid column name in KEYS clause of MERGE - it may
include only key and/or " +
+                "affinity columns: STUFF");
+
         /* Subqueries. */
         checkQuery("merge into Person(old, name) select old, parentName from Person");
         checkQuery("merge into Person(old, name) select old, parentName from Person where
old > 5");
         checkQuery("merge into Person(old, name) select 5, 'John'");
         checkQuery("merge into Person(old, name) select p1.old, 'Name' from person p1 join
person p2 on " +
             "p2.name = p1.parentName where p2.old > 30");
-        checkQuery("merge into Person(old) select 5 from Person UNION select street from
sch2.Address limit ? offset ?");
+        checkQuery("merge into Person(old) select 5 from Person UNION select street from
sch2.Address limit ? " +
+            "offset ?");
     }
 
     /** */
@@ -445,8 +462,8 @@ public class GridQueryParsingTest extends GridCommonAbstractTest {
         checkQuery("insert into Person(date, old, name, parentName, addrId) values " +
             "(TRUNCATE(TIMESTAMP '2015-12-31 23:59:59'), POWER(3,12), NULL, DEFAULT, DEFAULT)");
         checkQuery("insert into Person SET old = 5, name = 'John'");
-        checkQuery("insert into Person SET name = CONCAT('Fyodor', null, UPPER(CONCAT(SQRT(?),
'dostoevsky'))), old = " +
-            "select (5, 6)");
+        checkQuery("insert into Person SET name = CONCAT('Fyodor', null, UPPER(CONCAT(SQRT(?),
'dostoevsky'))), " +
+            "old = select (5, 6)");
         checkQuery("insert into Person(old, name) select ASCII(parentName), INSERT(parentName,
4, 4, 'Max') from " +
             "Person where date='2011-03-12'");
 
@@ -457,7 +474,8 @@ public class GridQueryParsingTest extends GridCommonAbstractTest {
         checkQuery("insert into Person(old, name) select 5, 'John'");
         checkQuery("insert into Person(old, name) select p1.old, 'Name' from person p1 join
person p2 on " +
             "p2.name = p1.parentName where p2.old > 30");
-        checkQuery("insert into Person(old) select 5 from Person UNION select street from
sch2.Address limit ? offset ?");
+        checkQuery("insert into Person(old) select 5 from Person UNION select street from
sch2.Address limit ? " +
+            "offset ?");
     }
 
     /** */
@@ -479,8 +497,8 @@ public class GridQueryParsingTest extends GridCommonAbstractTest {
         checkQuery("update Person p set name='Peter', old = length('zzz') limit 20");
         checkQuery("update Person p set name=DEFAULT, old = null limit ?");
         checkQuery("update Person p set name=? where old >= ? and old < ? limit ?");
-        checkQuery("update Person p set name=(select a.Street from sch2.Address a where a.id=p.addrId),
old = (select 42)" +
-            " where old = sqrt(?)");
+        checkQuery("update Person p set name=(select a.Street from sch2.Address a where a.id=p.addrId),
old = " +
+            "(select 42) where old = sqrt(?)");
         checkQuery("update Person p set (name, old) = (select 'Peter', 42)");
         checkQuery("update Person p set (name, old) = (select street, id from sch2.Address
where id > 5 and id <= ?)");
     }
@@ -655,7 +673,7 @@ public class GridQueryParsingTest extends GridCommonAbstractTest {
             IgniteSQLException.class, "ALTER TABLE ADD COLUMN BEFORE/AFTER is not supported");
 
         // No such schema.
-        assertParseThrows("ALTER TABLE SCH3.\"Person\" ADD (city varchar)", DbException.class,
null);
+        assertParseThrows("ALTER TABLE SCH5.\"Person\" ADD (city varchar)", DbException.class,
null);
     }
 
     /**
@@ -936,8 +954,8 @@ public class GridQueryParsingTest extends GridCommonAbstractTest {
     /**
      *
      */
-    private static GridSqlCreateIndex buildCreateIndex(String name, String tblName, String
schemaName, boolean ifNotExists,
-        QueryIndexType type, Object... flds) {
+    private static GridSqlCreateIndex buildCreateIndex(String name, String tblName, String
schemaName,
+        boolean ifNotExists, QueryIndexType type, Object... flds) {
         QueryIndex idx = new QueryIndex();
 
         idx.setName(name);
@@ -980,6 +998,7 @@ public class GridQueryParsingTest extends GridCommonAbstractTest {
     /**
      * @param sql Sql.
      */
+    @SuppressWarnings("unchecked")
     private <T extends Prepared> T parse(String sql) throws Exception {
         Session ses = (Session)connection().getSession();
 
@@ -987,12 +1006,12 @@ public class GridQueryParsingTest extends GridCommonAbstractTest {
     }
 
     /**
-     * @param sql1 Sql 1.
-     * @param sql2 Sql 2.
+     * @param exp Sql 1.
+     * @param actual Sql 2.
      */
-    private void assertSqlEquals(String sql1, String sql2) {
-        String nsql1 = normalizeSql(sql1);
-        String nsql2 = normalizeSql(sql2);
+    private void assertSqlEquals(String exp, String actual) {
+        String nsql1 = normalizeSql(exp);
+        String nsql2 = normalizeSql(actual);
 
         assertEquals(nsql1, nsql2);
     }
@@ -1011,87 +1030,6 @@ public class GridQueryParsingTest extends GridCommonAbstractTest {
     }
 
     /**
-     * @param createTbl {@code CREATE TABLE} command.
-     * @return Corresponding SQL.
-     */
-    private static String createTableToSql(GridSqlCreateTable createTbl) {
-        GridStringBuilder b = new SB("CREATE TABLE ")
-            .a(createTbl.ifNotExists() ? "IF NOT EXISTS " : "")
-            .a("\n")
-            .a(Parser.quoteIdentifier(createTbl.schemaName()))
-            .a('.')
-            .a(Parser.quoteIdentifier(createTbl.tableName()))
-            .a("\n(");
-
-        boolean singleColPk = false;
-
-        boolean first = true;
-
-        for (GridSqlColumn col : createTbl.columns().values()) {
-            if (!first)
-                b.a(",\n");
-            else
-                first = false;
-
-            if (col.column().isPrimaryKey()) {
-                // Only one column may be marked PRIMARY KEY - multi-col PK is defined separately
-                assert !singleColPk;
-
-                singleColPk = true;
-            }
-
-            b.a('\t')
-                .a(col.getSQL())
-                .a(' ')
-                .a(col.resultType().sql())
-                .a(col.column().isPrimaryKey() ? " PRIMARY KEY" : "");
-        }
-
-        first = true;
-
-        if (!singleColPk && !F.isEmpty(createTbl.primaryKeyColumns())) {
-            b.a(",\n")
-                .a('\t')
-                .a("PRIMARY KEY (\n");
-
-            for (String col : createTbl.primaryKeyColumns()) {
-                GridSqlColumn pkCol = createTbl.columns().get(col);
-
-                assert pkCol != null;
-
-                if (!first)
-                    b.a(",\n");
-                else
-                    first = false;
-
-                b.a("\t\t")
-                    .a(pkCol.getSQL());
-            }
-
-            b.a("\n\t)");
-        }
-
-        b.a("\n)");
-
-        if (!F.isEmpty(createTbl.params())) {
-            b.a("\nWITH ");
-
-            first = true;
-
-            for (String p : createTbl.params()) {
-                if (!first)
-                    b.a(',');
-                else
-                    first = false;
-
-                b.a(Parser.quoteIdentifier(p));
-            }
-        }
-
-        return b.toString();
-    }
-
-    /**
      * @param qry Query.
      */
     private void checkQuery(String qry) throws Exception {
@@ -1106,23 +1044,6 @@ public class GridQueryParsingTest extends GridCommonAbstractTest {
         assertSqlEquals(U.firstNotNull(prepared.getPlanSQL(), prepared.getSQL()), res);
     }
 
-    /**
-     * @param qry Query.
-     */
-    private void checkCreateTable(String qry) throws Exception {
-        Prepared prepared = parse(qry);
-
-        assertTrue(prepared instanceof CreateTable);
-
-        GridSqlStatement gridStmt = new GridSqlQueryParser(false).parse(prepared);
-
-        String res = createTableToSql((GridSqlCreateTable)gridStmt);
-
-        System.out.println(normalizeSql(res));
-
-        assertSqlEquals(U.firstNotNull(prepared.getPlanSQL(), prepared.getSQL()), res);
-    }
-
     @QuerySqlFunction
     public static int cool1() {
         return 1;
@@ -1136,6 +1057,20 @@ public class GridQueryParsingTest extends GridCommonAbstractTest {
     /**
      *
      */
+    public static class PersonKey implements Serializable {
+        /** */
+        @QuerySqlField
+        @AffinityKeyMapped
+        public int id;
+
+        /** Should not be allowed in KEY clause of MERGE. */
+        @QuerySqlField
+        public String stuff;
+    }
+
+    /**
+     *
+     */
     public static class Person implements Serializable {
         @QuerySqlField(index = true)
         public Date date = new Date(System.currentTimeMillis());


Mime
View raw message