PHOENIX-4551 Possible ColumnAlreadyExistsException is thrown from delete when autocommit off(Rajeshbabu)
Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/bf655187 Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/bf655187 Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/bf655187 Branch: refs/heads/4.x-cdh5.11.2 Commit: bf655187db159b03c61db516d7b55e25e8648012 Parents: 26c284c Author: Rajeshbabu Chintaguntla <[email protected]> Authored: Tue Jan 23 18:45:01 2018 +0000 Committer: Pedro Boado <[email protected]> Committed: Wed Jan 31 22:24:48 2018 +0000 ---------------------------------------------------------------------- .../org/apache/phoenix/end2end/DeleteIT.java | 29 ++++++++++++++++++++ .../apache/phoenix/compile/DeleteCompiler.java | 17 ++++++++---- 2 files changed, 40 insertions(+), 6 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/phoenix/blob/bf655187/phoenix-core/src/it/java/org/apache/phoenix/end2end/DeleteIT.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/DeleteIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/DeleteIT.java index 9eac0af..e111e7a 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/DeleteIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/DeleteIT.java @@ -20,6 +20,7 @@ package org.apache.phoenix.end2end; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import java.sql.Connection; import java.sql.Date; @@ -734,6 +735,34 @@ public class DeleteIT extends ParallelStatsDisabledIT { } } + + @Test + public void testClientSideDeleteShouldNotFailWhenSameColumnPresentInMultipleIndexes() + throws Exception { + String tableName = generateUniqueName(); + String indexName1 = generateUniqueName(); + String indexName2 = generateUniqueName(); + String ddl = + "CREATE TABLE IF NOT EXISTS " + + tableName + + " (pk1 DECIMAL NOT NULL, v1 VARCHAR, v2 VARCHAR CONSTRAINT PK PRIMARY KEY (pk1))"; + String idx1 = "CREATE INDEX " + indexName1 + " ON " + tableName + "(v1)"; + String idx2 = "CREATE INDEX " + indexName2 + " ON " + tableName + "(v1, v2)"; + try (Connection conn = DriverManager.getConnection(getUrl())) { + conn.createStatement().execute(ddl); + conn.createStatement().execute(idx1); + conn.createStatement().execute(idx2); + Statement stmt = conn.createStatement(); + stmt.executeUpdate("UPSERT INTO " + tableName + " VALUES (1,'value', 'value2')"); + conn.commit(); + conn.setAutoCommit(false); + try { + conn.createStatement().execute("DELETE FROM " + tableName + " WHERE pk1 > 0"); + } catch (Exception e) { + fail("Should not throw any exception"); + } + } + } } http://git-wip-us.apache.org/repos/asf/phoenix/blob/bf655187/phoenix-core/src/main/java/org/apache/phoenix/compile/DeleteCompiler.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/DeleteCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/DeleteCompiler.java index 7a880e9..fd80238 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/compile/DeleteCompiler.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/DeleteCompiler.java @@ -25,6 +25,7 @@ import java.sql.SQLException; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; +import java.util.LinkedHashSet; import java.util.List; import java.util.Set; @@ -466,7 +467,7 @@ public class DeleteCompiler { for (PTable index : immutableIndexes) { selectColumnCount += index.getPKColumns().size() - pkColumnCount; } - List<PColumn> projectedColumns = Lists.newArrayListWithExpectedSize(selectColumnCount + pkColumnOffset); + Set<PColumn> projectedColumns = new LinkedHashSet<PColumn>(selectColumnCount + pkColumnOffset); List<AliasedNode> aliasedNodes = Lists.newArrayListWithExpectedSize(selectColumnCount); for (int i = isSalted ? 1 : 0; i < pkColumnOffset; i++) { PColumn column = table.getPKColumns().get(i); @@ -487,8 +488,10 @@ public class DeleteCompiler { String columnName = columnInfo.getSecond(); boolean hasNoColumnFamilies = table.getColumnFamilies().isEmpty(); PColumn column = hasNoColumnFamilies ? table.getColumnForColumnName(columnName) : table.getColumnFamily(familyName).getPColumnForColumnName(columnName); - projectedColumns.add(column); - aliasedNodes.add(FACTORY.aliasedNode(null, FACTORY.column(hasNoColumnFamilies ? null : TableName.create(null, familyName), '"' + columnName + '"', null))); + if(!projectedColumns.contains(column)) { + projectedColumns.add(column); + aliasedNodes.add(FACTORY.aliasedNode(null, FACTORY.column(hasNoColumnFamilies ? null : TableName.create(null, familyName), '"' + columnName + '"', null))); + } } } } @@ -598,9 +601,11 @@ public class DeleteCompiler { final DeletingParallelIteratorFactory parallelIteratorFactory = parallelIteratorFactoryToBe; List<PColumn> adjustedProjectedColumns = Lists.newArrayListWithExpectedSize(projectedColumns.size()); final int offset = table.getBucketNum() == null ? 0 : 1; - for (int i = 0; i < projectedColumns.size(); i++) { - final int position = i; - adjustedProjectedColumns.add(new DelegateColumn(projectedColumns.get(i)) { + Iterator<PColumn> projectedColsItr = projectedColumns.iterator(); + int i = 0; + while(projectedColsItr.hasNext()) { + final int position = i++; + adjustedProjectedColumns.add(new DelegateColumn(projectedColsItr.next()) { @Override public int getPosition() { return position + offset;
