You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by td...@apache.org on 2018/12/12 01:05:50 UTC
phoenix git commit: PHOENIX-4983: Allow using a connection with a SCN
set to write data to tables EXCEPT transactional tables or mutable tables
with indexes or tables with ROW_TIMESTAMP column.
Repository: phoenix
Updated Branches:
refs/heads/4.x-HBase-1.2 40cdb7b87 -> f257f5e02
PHOENIX-4983: Allow using a connection with a SCN set to write data to tables EXCEPT transactional tables or mutable tables with indexes or tables with ROW_TIMESTAMP column.
Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo
Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/f257f5e0
Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/f257f5e0
Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/f257f5e0
Branch: refs/heads/4.x-HBase-1.2
Commit: f257f5e02898aecd5a4ae0079f1d63a6549cc6e5
Parents: 40cdb7b
Author: s.kadam <s....@salesforce.com>
Authored: Mon Dec 10 14:40:17 2018 -0800
Committer: Thomas D'Silva <td...@apache.org>
Committed: Tue Dec 11 17:04:07 2018 -0800
----------------------------------------------------------------------
.../apache/phoenix/end2end/UpsertWithSCNIT.java | 139 +++++++++++++++++++
.../apache/phoenix/compile/UpsertCompiler.java | 23 ++-
.../phoenix/exception/SQLExceptionCode.java | 13 +-
.../apache/phoenix/jdbc/PhoenixConnection.java | 2 +-
4 files changed, 172 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/phoenix/blob/f257f5e0/phoenix-core/src/it/java/org/apache/phoenix/end2end/UpsertWithSCNIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/UpsertWithSCNIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/UpsertWithSCNIT.java
new file mode 100644
index 0000000..6f231ff
--- /dev/null
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/UpsertWithSCNIT.java
@@ -0,0 +1,139 @@
+package org.apache.phoenix.end2end;
+
+import org.apache.phoenix.exception.SQLExceptionCode;
+import org.apache.phoenix.exception.SQLExceptionInfo;
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import java.sql.Connection;
+import java.sql.Date;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Properties;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+
+public class UpsertWithSCNIT extends ParallelStatsDisabledIT {
+
+ @Rule
+ public final ExpectedException exception = ExpectedException.none();
+ Properties props = null;
+ PreparedStatement prep = null;
+ String tableName =null;
+
+ private void helpTestUpserWithSCNIT(boolean rowColumn, boolean txTable,
+ boolean mutable, boolean local, boolean global)
+ throws SQLException {
+
+ tableName = generateUniqueName();
+ String indx;
+ String createTable = "CREATE TABLE "+tableName+" ("
+ + (rowColumn ? "CREATED_DATE DATE NOT NULL, ":"")
+ + "METRIC_ID CHAR(15) NOT NULL,METRIC_VALUE VARCHAR(50) CONSTRAINT PK PRIMARY KEY("
+ + (rowColumn? "CREATED_DATE ROW_TIMESTAMP, ":"") + "METRIC_ID)) "
+ + (mutable? "IMMUTABLE_ROWS=false":"" )
+ + (txTable ? "TRANSACTION_PROVIDER='TEPHRA',TRANSACTIONAL=true":"");
+ props = new Properties();
+ Connection conn = DriverManager.getConnection(getUrl(), props);
+ conn.createStatement().execute(createTable);
+
+ if(local || global ){
+ indx = "CREATE "+ (local? "LOCAL " : "") + "INDEX "+tableName+"_idx ON " +
+ ""+tableName+" (METRIC_VALUE)";
+ conn.createStatement().execute(indx);
+ }
+
+ props.setProperty("CurrentSCN", Long.toString(System.currentTimeMillis()));
+ conn = DriverManager.getConnection(getUrl(), props);
+ conn.setAutoCommit(true);
+ String upsert = "UPSERT INTO "+tableName+" (METRIC_ID, METRIC_VALUE) VALUES (?,?)";
+ prep = conn.prepareStatement(upsert);
+ prep.setString(1,"abc");
+ prep.setString(2,"This is the first comment!");
+ }
+
+ @Test // See https://issues.apache.org/jira/browse/PHOENIX-4983
+ public void testUpsertOnSCNSetTxnTable() throws SQLException {
+
+ helpTestUpserWithSCNIT(false, true, false, false, false);
+ exception.expect(SQLException.class);
+ exception.expectMessage(containsString(String.valueOf(
+ SQLExceptionCode
+ .CANNOT_SPECIFY_SCN_FOR_TXN_TABLE
+ .getErrorCode())));
+ prep.executeUpdate();
+ }
+
+ @Test
+ public void testUpsertOnSCNSetMutTableWithoutIdx() throws Exception {
+
+ helpTestUpserWithSCNIT(false, false, true, false, false);
+ prep.executeUpdate();
+ props = new Properties();
+ Connection conn = DriverManager.getConnection(getUrl(),props);
+ ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM "+tableName);
+ assertTrue(rs.next());
+ assertEquals("abc", rs.getString(1));
+ assertEquals("This is the first comment!", rs.getString(2));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testUpsertOnSCNSetTable() throws Exception {
+
+ helpTestUpserWithSCNIT(false, false, false, false, false);
+ prep.executeUpdate();
+ props = new Properties();
+ Connection conn = DriverManager.getConnection(getUrl(),props);
+ ResultSet rs = conn.createStatement().executeQuery("SELECT * FROM "+tableName);
+ assertTrue(rs.next());
+ assertEquals("abc", rs.getString(1));
+ assertEquals("This is the first comment!", rs.getString(2));
+ assertFalse(rs.next());
+ }
+
+ @Test
+ public void testUpsertOnSCNSetMutTableWithLocalIdx() throws Exception {
+
+ helpTestUpserWithSCNIT(false, false, true, true, false);
+ exception.expect(SQLException.class);
+ exception.expectMessage(containsString(String.valueOf(
+ SQLExceptionCode
+ .CANNOT_UPSERT_WITH_SCN_FOR_MUTABLE_TABLE_WITH_INDEXES
+ .getErrorCode())));
+ prep.executeUpdate();
+ }
+ @Test
+ public void testUpsertOnSCNSetMutTableWithGlobalIdx() throws Exception {
+
+ helpTestUpserWithSCNIT(false, false, true, false, true);
+ exception.expect(SQLException.class);
+ exception.expectMessage(containsString(String.valueOf(
+ SQLExceptionCode
+ .CANNOT_UPSERT_WITH_SCN_FOR_MUTABLE_TABLE_WITH_INDEXES
+ .getErrorCode())));
+ prep.executeUpdate();
+
+ }
+ @Test
+ public void testUpsertOnSCNSetWithRowTSColumn() throws Exception {
+
+ helpTestUpserWithSCNIT(true, false, false, false, false);
+ exception.expect(SQLException.class);
+ exception.expectMessage(containsString(String.valueOf(
+ SQLExceptionCode
+ .CANNOT_UPSERT_WITH_SCN_FOR_ROW_TIMSTAMP_COLUMN
+ .getErrorCode())));
+ prep.executeUpdate();
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/phoenix/blob/f257f5e0/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 a770339..ec0c67c 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
@@ -366,6 +366,8 @@ public class UpsertCompiler {
// Cannot update:
// - read-only VIEW
// - transactional table with a connection having an SCN
+ // - mutable table with indexes and SCN set
+ // - tables with ROW_TIMESTAMP columns
if (table.getType() == PTableType.VIEW && table.getViewType().isReadOnly()) {
throw new ReadOnlyTableException(schemaName,tableName);
} else if (connection.isBuildingIndex() && table.getType() != PTableType.INDEX) {
@@ -374,8 +376,25 @@ public class UpsertCompiler {
.setTableName(tableName)
.build().buildException();
} else if (table.isTransactional() && connection.getSCN() != null) {
- throw new SQLExceptionInfo.Builder(SQLExceptionCode.CANNOT_SPECIFY_SCN_FOR_TXN_TABLE).setSchemaName(schemaName)
- .setTableName(tableName).build().buildException();
+ throw new SQLExceptionInfo.Builder(SQLExceptionCode
+ .CANNOT_SPECIFY_SCN_FOR_TXN_TABLE)
+ .setSchemaName(schemaName)
+ .setTableName(tableName).build().buildException();
+ } else if (!table.isImmutableRows() && connection.getSCN() != null
+ && !table.getIndexes().isEmpty() && !connection.isRunningUpgrade()
+ && !connection.isBuildingIndex()) {
+ throw new SQLExceptionInfo
+ .Builder(SQLExceptionCode
+ .CANNOT_UPSERT_WITH_SCN_FOR_MUTABLE_TABLE_WITH_INDEXES)
+ .setSchemaName(schemaName)
+ .setTableName(tableName).build().buildException();
+ } else if(connection.getSCN() != null && !connection.isRunningUpgrade()
+ && !connection.isBuildingIndex() && table.getRowTimestampColPos() >= 0) {
+ throw new SQLExceptionInfo
+ .Builder(SQLExceptionCode
+ .CANNOT_UPSERT_WITH_SCN_FOR_ROW_TIMSTAMP_COLUMN)
+ .setSchemaName(schemaName)
+ .setTableName(tableName).build().buildException();
}
boolean isSalted = table.getBucketNum() != null;
isTenantSpecific = table.isMultiTenant() && connection.getTenantId() != null;
http://git-wip-us.apache.org/repos/asf/phoenix/blob/f257f5e0/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 5bffed5..cf0b9ae 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
@@ -289,7 +289,8 @@ public enum SQLExceptionCode {
TRANSACTION_FAILED(1077, "44A08", "Transaction Failure "),
CANNOT_CREATE_TXN_TABLE_IF_TXNS_DISABLED(1078, "44A09", "Cannot create a transactional table if transactions are disabled."),
CANNOT_ALTER_TO_BE_TXN_IF_TXNS_DISABLED(1079, "44A10", "Cannot alter table to be transactional table if transactions are disabled."),
- CANNOT_CREATE_TXN_TABLE_WITH_ROW_TIMESTAMP(1080, "44A11", "Cannot create a transactional table if transactions are disabled."),
+ CANNOT_CREATE_TXN_TABLE_WITH_ROW_TIMESTAMP(1080, "44A11", "Cannot create a transactional" +
+ " table with ROW_TIMESTAMP column."),
CANNOT_ALTER_TO_BE_TXN_WITH_ROW_TIMESTAMP(1081, "44A12", "Cannot alter table to be transactional table if transactions are disabled."),
TX_MUST_BE_ENABLED_TO_SET_TX_CONTEXT(1082, "44A13", "Cannot set transaction context if transactions are disabled."),
TX_MUST_BE_ENABLED_TO_SET_AUTO_FLUSH(1083, "44A14", "Cannot set auto flush if transactions are disabled."),
@@ -461,7 +462,15 @@ public enum SQLExceptionCode {
MAX_MUTATION_SIZE_EXCEEDED(729, "LIM01", "MutationState size is bigger than maximum allowed number of rows"),
MAX_MUTATION_SIZE_BYTES_EXCEEDED(730, "LIM02", "MutationState size is bigger than maximum allowed number of bytes"),
INSUFFICIENT_MEMORY(999, "50M01", "Unable to allocate enough memory."),
- HASH_JOIN_CACHE_NOT_FOUND(900, "HJ01", "Hash Join cache not found");
+ HASH_JOIN_CACHE_NOT_FOUND(900, "HJ01", "Hash Join cache not found"),
+
+ CANNOT_UPSERT_WITH_SCN_FOR_ROW_TIMSTAMP_COLUMN(901,"43M12",
+ "Cannot use a connection with SCN set to upsert data for " +
+ "table with ROW_TIMESTAMP column."),
+ CANNOT_UPSERT_WITH_SCN_FOR_MUTABLE_TABLE_WITH_INDEXES(903,"43M14",
+ "Cannot use a connection with SCN set to " +
+ "upsert data for a mutable table with indexes.");
+
private final int errorCode;
private final String sqlState;
http://git-wip-us.apache.org/repos/asf/phoenix/blob/f257f5e0/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java
index 6da579f..596e27c 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java
@@ -858,7 +858,7 @@ public class PhoenixConnection implements Connection, MetaDataMutated, SQLClosea
@Override
public boolean isReadOnly() throws SQLException {
- return readOnly || (scn != null && !buildingIndex && !isRunningUpgrade);
+ return readOnly;
}
@Override