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/3138ad44 Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/3138ad44 Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/3138ad44 Branch: refs/heads/4.x-HBase-1.1 Commit: 3138ad44b685a875b30eeafdf331a6b7f6b243da Parents: f2be6bb 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:25:06 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/3138ad44/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/3138ad44/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 116091d..d3bfc2d 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/3138ad44/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/3138ad44/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/3138ad44/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 {