PHOENIX-3925 Disallow usage of ON DUPLICATE KEY clause on tables with global 
secondary indexes


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

Branch: refs/heads/4.x-HBase-0.98
Commit: 03d162f3e1cc939501715d86aee029a461c912ff
Parents: 2d7c585
Author: James Taylor <jamestay...@apache.org>
Authored: Thu Jun 8 12:56:28 2017 -0700
Committer: James Taylor <jamestay...@apache.org>
Committed: Thu Jun 8 13:23:37 2017 -0700

----------------------------------------------------------------------
 .../apache/phoenix/end2end/OnDuplicateKeyIT.java   |  6 ------
 .../org/apache/phoenix/compile/UpsertCompiler.java |  9 +++++++--
 .../apache/phoenix/exception/SQLExceptionCode.java |  1 +
 .../java/org/apache/phoenix/util/SchemaUtil.java   | 12 ++++++++++--
 .../apache/phoenix/compile/QueryCompilerTest.java  | 17 +++++++++++++++--
 5 files changed, 33 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/03d162f3/phoenix-core/src/it/java/org/apache/phoenix/end2end/OnDuplicateKeyIT.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/it/java/org/apache/phoenix/end2end/OnDuplicateKeyIT.java 
b/phoenix-core/src/it/java/org/apache/phoenix/end2end/OnDuplicateKeyIT.java
index d3cb0af..2477f56 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/OnDuplicateKeyIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/OnDuplicateKeyIT.java
@@ -58,12 +58,6 @@ public class OnDuplicateKeyIT extends 
ParallelStatsDisabledIT {
                 "",
         });
         testCases.add(new String[] {
-                "create index %s_IDX on %s(counter1) include (counter2)",
-        });
-        testCases.add(new String[] {
-                "create index %s_IDX on %s(counter1, counter2)",
-        });
-        testCases.add(new String[] {
                 "create local index %s_IDX on %s(counter1) include (counter2)",
         });
         testCases.add(new String[] {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/03d162f3/phoenix-core/src/main/java/org/apache/phoenix/compile/UpsertCompiler.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/compile/UpsertCompiler.java 
b/phoenix-core/src/main/java/org/apache/phoenix/compile/UpsertCompiler.java
index ca15e4f..1742da2 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/UpsertCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/UpsertCompiler.java
@@ -73,7 +73,6 @@ import org.apache.phoenix.parse.NamedTableNode;
 import org.apache.phoenix.parse.ParseNode;
 import org.apache.phoenix.parse.SelectStatement;
 import org.apache.phoenix.parse.SequenceValueParseNode;
-import org.apache.phoenix.parse.TableName;
 import org.apache.phoenix.parse.UpsertStatement;
 import org.apache.phoenix.query.ConnectionQueryServices;
 import org.apache.phoenix.query.QueryServices;
@@ -95,10 +94,10 @@ import org.apache.phoenix.schema.PTableImpl;
 import org.apache.phoenix.schema.PTableKey;
 import org.apache.phoenix.schema.PTableType;
 import org.apache.phoenix.schema.ReadOnlyTableException;
-import org.apache.phoenix.schema.UpsertColumnsValuesMismatchException;
 import org.apache.phoenix.schema.SortOrder;
 import org.apache.phoenix.schema.TableRef;
 import org.apache.phoenix.schema.TypeMismatchException;
+import org.apache.phoenix.schema.UpsertColumnsValuesMismatchException;
 import org.apache.phoenix.schema.tuple.Tuple;
 import org.apache.phoenix.schema.types.PDataType;
 import org.apache.phoenix.schema.types.PLong;
@@ -941,6 +940,12 @@ public class UpsertCompiler {
                 .setTableName(table.getTableName().getString())
                 .build().buildException();
             }
+            if (SchemaUtil.hasGlobalIndex(table)) {
+                throw new 
SQLExceptionInfo.Builder(SQLExceptionCode.CANNOT_USE_ON_DUP_KEY_WITH_GLOBAL_IDX)
+                .setSchemaName(table.getSchemaName().getString())
+                .setTableName(table.getTableName().getString())
+                .build().buildException();
+            }
             if (onDupKeyPairs.isEmpty()) { // ON DUPLICATE KEY IGNORE
                 onDupKeyBytesToBe = 
PhoenixIndexBuilder.serializeOnDupKeyIgnore();
             } else {                       // ON DUPLICATE KEY UPDATE

http://git-wip-us.apache.org/repos/asf/phoenix/blob/03d162f3/phoenix-core/src/main/java/org/apache/phoenix/exception/SQLExceptionCode.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/exception/SQLExceptionCode.java 
b/phoenix-core/src/main/java/org/apache/phoenix/exception/SQLExceptionCode.java
index 841fd5d..d6297bb 100644
--- 
a/phoenix-core/src/main/java/org/apache/phoenix/exception/SQLExceptionCode.java
+++ 
b/phoenix-core/src/main/java/org/apache/phoenix/exception/SQLExceptionCode.java
@@ -335,6 +335,7 @@ public enum SQLExceptionCode {
     DUPLICATE_COLUMN_IN_ON_DUP_KEY(1221, "42Z21", "Duplicate column in ON 
DUPLICATE KEY UPDATE." ),
     AGGREGATION_NOT_ALLOWED_IN_ON_DUP_KEY(1222, "42Z22", "Aggregation in ON 
DUPLICATE KEY UPDATE is not allowed." ),
     CANNOT_SET_SCN_IN_ON_DUP_KEY(1223, "42Z23", "The CURRENT_SCN may not be 
set for statement using ON DUPLICATE KEY." ),
+    CANNOT_USE_ON_DUP_KEY_WITH_GLOBAL_IDX(1224, "42Z24", "The ON DUPLICATE KEY 
clause may not be used when a table has a global index." ),
 
     /** Parser error. (errorcode 06, sqlState 42P) */
     PARSER_ERROR(601, "42P00", "Syntax error.", Factory.SYNTAX_ERROR),

http://git-wip-us.apache.org/repos/asf/phoenix/blob/03d162f3/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java 
b/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java
index 24e60be..6696cc7 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java
@@ -68,10 +68,9 @@ import org.apache.phoenix.schema.PDatum;
 import org.apache.phoenix.schema.PName;
 import org.apache.phoenix.schema.PNameFactory;
 import org.apache.phoenix.schema.PTable;
+import org.apache.phoenix.schema.PTable.IndexType;
 import org.apache.phoenix.schema.PTableType;
 import org.apache.phoenix.schema.RowKeySchema;
-import org.apache.phoenix.schema.PTable.QualifierEncodingScheme;
-import org.apache.phoenix.schema.PTable.ImmutableStorageScheme;
 import org.apache.phoenix.schema.RowKeySchema.RowKeySchemaBuilder;
 import org.apache.phoenix.schema.SaltingUtil;
 import org.apache.phoenix.schema.SortOrder;
@@ -1094,4 +1093,13 @@ public class SchemaUtil {
             }
         }
     }
+
+    public static boolean hasGlobalIndex(PTable table) {
+        for (PTable index : table.getIndexes()) {
+            if (index.getIndexType() == IndexType.GLOBAL) {
+                return true;
+            }
+        }
+        return false;
+    }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/03d162f3/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryCompilerTest.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryCompilerTest.java 
b/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryCompilerTest.java
index 9d0e3d2..6c7978a 100644
--- 
a/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryCompilerTest.java
+++ 
b/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryCompilerTest.java
@@ -63,10 +63,8 @@ import org.apache.phoenix.expression.aggregator.Aggregator;
 import org.apache.phoenix.expression.aggregator.CountAggregator;
 import org.apache.phoenix.expression.aggregator.ServerAggregators;
 import org.apache.phoenix.expression.function.TimeUnit;
-import org.apache.phoenix.filter.ColumnProjectionFilter;
 import org.apache.phoenix.filter.EncodedQualifiersColumnProjectionFilter;
 import org.apache.phoenix.jdbc.PhoenixConnection;
-import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData;
 import org.apache.phoenix.jdbc.PhoenixPreparedStatement;
 import org.apache.phoenix.jdbc.PhoenixStatement;
 import org.apache.phoenix.query.BaseConnectionlessQueryTest;
@@ -2721,6 +2719,21 @@ public class QueryCompilerTest extends 
BaseConnectionlessQueryTest {
     }
 
     @Test
+    public void testOnDupKeyWithGlobalIndex() throws Exception {
+        Connection conn = DriverManager.getConnection(getUrl());
+        try {
+            conn.createStatement().execute("CREATE TABLE t1 (k integer not 
null primary key, v bigint)");
+            conn.createStatement().execute("CREATE INDEX idx ON t1 (v)");
+            conn.createStatement().execute("UPSERT INTO t1 VALUES(0,0) ON 
DUPLICATE KEY UPDATE v = v + 1");
+            fail();
+        } catch (SQLException e) {
+            
assertEquals(SQLExceptionCode.CANNOT_USE_ON_DUP_KEY_WITH_GLOBAL_IDX.getErrorCode(),
 e.getErrorCode());
+        } finally {
+            conn.close();
+        }
+    }
+
+    @Test
     public void testUpdatePKOnDupKey() throws Exception {
         Connection conn = DriverManager.getConnection(getUrl());
         try {

Reply via email to