PHOENIX-4068 Atomic Upsert salted table with error(java.lang.NullPointerException)
Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/f1d2b6f0 Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/f1d2b6f0 Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/f1d2b6f0 Branch: refs/heads/4.x-HBase-1.2 Commit: f1d2b6f03123eee2f49a02cd442f58a2ad0a3694 Parents: 41c0521 Author: Sergey Soldatov <s...@apache.org> Authored: Thu Aug 10 22:06:49 2017 -0700 Committer: Sergey Soldatov <s...@apache.org> Committed: Tue Sep 5 13:39:49 2017 -0700 ---------------------------------------------------------------------- .../phoenix/end2end/OnDuplicateKeyIT.java | 33 +++++++++++++++++++- .../apache/phoenix/compile/UpsertCompiler.java | 9 +++--- .../phoenix/index/PhoenixIndexBuilder.java | 3 +- 3 files changed, 39 insertions(+), 6 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/phoenix/blob/f1d2b6f0/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 2477f56..f1ee0e7 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 @@ -21,6 +21,7 @@ import static org.apache.phoenix.util.TestUtil.TEST_PROPERTIES; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import java.sql.Connection; import java.sql.Date; @@ -549,6 +550,36 @@ public class OnDuplicateKeyIT extends ParallelStatsDisabledIT { conn.close(); } - + @Test + public void testDuplicateUpdateWithSaltedTable() throws Exception { + Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES); + final Connection conn = DriverManager.getConnection(getUrl(), props); + String tableName = generateUniqueName(); + try { + String ddl = "create table " + tableName + " (id varchar not null,id1 varchar not null, counter1 bigint, counter2 bigint CONSTRAINT pk PRIMARY KEY (id,id1)) SALT_BUCKETS=6"; + conn.createStatement().execute(ddl); + createIndex(conn, tableName); + String dml = "UPSERT INTO " + tableName + " (id,id1, counter1, counter2) VALUES ('abc','123', 0, 0) ON DUPLICATE KEY UPDATE counter1 = counter1 + 1, counter2 = counter2 + 1"; + conn.createStatement().execute(dml); + conn.commit(); + ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM " + tableName); + assertTrue(rs.next()); + assertEquals("0",rs.getString(3)); + assertEquals("0",rs.getString(4)); + conn.createStatement().execute(dml); + conn.commit(); + rs = conn.createStatement().executeQuery("SELECT * FROM " + tableName); + assertTrue(rs.next()); + assertEquals("1",rs.getString(3)); + assertEquals("1",rs.getString(4)); + + } catch (Exception e) { + fail(); + } finally { + conn.close(); + } + } + + } http://git-wip-us.apache.org/repos/asf/phoenix/blob/f1d2b6f0/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 0d09e9d..c384292 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 @@ -916,15 +916,16 @@ public class UpsertCompiler { } if (onDupKeyPairs.isEmpty()) { // ON DUPLICATE KEY IGNORE onDupKeyBytesToBe = PhoenixIndexBuilder.serializeOnDupKeyIgnore(); - } else { // ON DUPLICATE KEY UPDATE - int position = 1; + } else { // ON DUPLICATE KEY UPDATE; + int position = table.getBucketNum() == null ? 0 : 1; UpdateColumnCompiler compiler = new UpdateColumnCompiler(context); int nColumns = onDupKeyPairs.size(); List<Expression> updateExpressions = Lists.newArrayListWithExpectedSize(nColumns); LinkedHashSet<PColumn> updateColumns = Sets.newLinkedHashSetWithExpectedSize(nColumns + 1); updateColumns.add(new PColumnImpl( - table.getPKColumns().get(0).getName(), // Use first PK column name as we know it won't conflict with others - null, PVarbinary.INSTANCE, null, null, false, 0, SortOrder.getDefault(), 0, null, false, null, false, false, null)); + table.getPKColumns().get(position).getName(), // Use first PK column name as we know it won't conflict with others + null, PVarbinary.INSTANCE, null, null, false, position, SortOrder.getDefault(), 0, null, false, null, false, false, null)); + position++; for (Pair<ColumnName,ParseNode> columnPair : onDupKeyPairs) { ColumnName colName = columnPair.getFirst(); PColumn updateColumn = resolver.resolveColumn(null, colName.getFamilyName(), colName.getColumnName()).getColumn(); http://git-wip-us.apache.org/repos/asf/phoenix/blob/f1d2b6f0/phoenix-core/src/main/java/org/apache/phoenix/index/PhoenixIndexBuilder.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/index/PhoenixIndexBuilder.java b/phoenix-core/src/main/java/org/apache/phoenix/index/PhoenixIndexBuilder.java index 1c05155..679c5df 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/index/PhoenixIndexBuilder.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/index/PhoenixIndexBuilder.java @@ -224,11 +224,12 @@ public class PhoenixIndexBuilder extends NonTxIndexBuilder { Collections.sort(flattenedCells,KeyValue.COMPARATOR); } PRow row = table.newRow(GenericKeyValueBuilder.INSTANCE, ts, ptr, false); + int adjust = table.getBucketNum() == null ? 1 : 2; for (int i = 0; i < expressions.size(); i++) { Expression expression = expressions.get(i); ptr.set(ByteUtil.EMPTY_BYTE_ARRAY); expression.evaluate(tuple, ptr); - PColumn column = table.getColumns().get(i + 1); + PColumn column = table.getColumns().get(i + adjust); Object value = expression.getDataType().toObject(ptr, column.getSortOrder()); // We are guaranteed that the two column will have the // same type.