Repository: phoenix Updated Branches: refs/heads/calcite d94c45220 -> 421ddc977
PHOENIX-2197 Support DML in Phoenix/Calcite integration (part 2: bind parameters in VALUES clause) Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/421ddc97 Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/421ddc97 Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/421ddc97 Branch: refs/heads/calcite Commit: 421ddc977fc69e398273f3807c082595f61ff971 Parents: d94c452 Author: maryannxue <[email protected]> Authored: Wed Jun 1 14:39:20 2016 -0400 Committer: maryannxue <[email protected]> Committed: Wed Jun 1 14:39:20 2016 -0400 ---------------------------------------------------------------------- .../apache/phoenix/calcite/CalciteDMLIT.java | 29 ++++++++++++++------ .../calcite/jdbc/PhoenixCalciteFactory.java | 22 ++++++++++----- .../apache/phoenix/calcite/CalciteUtils.java | 14 ++++++++-- .../calcite/rel/PhoenixRelImplementor.java | 2 +- .../calcite/rel/PhoenixRelImplementorImpl.java | 4 +-- .../phoenix/calcite/rel/PhoenixTableScan.java | 4 +-- .../expression/BindParameterExpression.java | 8 +++++- .../phoenix/calcite/SqlOperatorBaseTest.java | 11 +++++--- 8 files changed, 67 insertions(+), 27 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/phoenix/blob/421ddc97/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteDMLIT.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteDMLIT.java b/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteDMLIT.java index 2d2a29f..8b1d0fe 100644 --- a/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteDMLIT.java +++ b/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteDMLIT.java @@ -68,9 +68,11 @@ public class CalciteDMLIT extends BaseCalciteIT { start(PROPS).sql("upsert into srcTable values(3, 30, '00300', '03000')") .executeUpdate() .close(); - start(PROPS).sql("upsert into tgtTable(pk0, pk1, f0, f2) select * from srcTable where pk1 <> 20") - .executeUpdate() - .close(); + final Sql sql = start(PROPS).sql("upsert into tgtTable(pk0, pk1, f0, f2) select * from srcTable where pk1 <> ?"); + final PreparedStatement stmt = sql.prepareStatement(); + stmt.setInt(1, 20); + stmt.executeUpdate(); + sql.close(); start(false, 1L).sql("select * from tgtTable") .resultIs(0, new Object[][] { {1, 10, "00100", null, "01000"}, @@ -78,13 +80,24 @@ public class CalciteDMLIT extends BaseCalciteIT { .close(); } - @Ignore @Test public void testUpsertWithPreparedStatement() throws Exception { final Sql sql = start(PROPS).sql("upsert into atable(organization_id, entity_id) values(?, ?)"); - PreparedStatement stmt = sql.prepareStatement(); - stmt.setString(1, "x"); - stmt.setString(2, "x"); - stmt.execute(); + final PreparedStatement stmt = sql.prepareStatement(); + stmt.setString(1, "x00000000000001"); + stmt.setString(2, "y00000000000001"); + stmt.executeUpdate(); + stmt.setString(1, "x00000000000002"); + stmt.setString(2, "y00000000000002"); + stmt.executeUpdate(); + stmt.setString(1, "x00000000000003"); + stmt.setString(2, "y00000000000003"); + stmt.executeUpdate(); sql.close(); + start(PROPS).sql("select organization_id, entity_id, a_string from atable where organization_id like 'x%'") + .resultIs(0, new Object[][] { + {"x00000000000001", "y00000000000001", null}, + {"x00000000000002", "y00000000000002", null}, + {"x00000000000003", "y00000000000003", null}}) + .close(); } } http://git-wip-us.apache.org/repos/asf/phoenix/blob/421ddc97/phoenix-core/src/main/java/org/apache/calcite/jdbc/PhoenixCalciteFactory.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/calcite/jdbc/PhoenixCalciteFactory.java b/phoenix-core/src/main/java/org/apache/calcite/jdbc/PhoenixCalciteFactory.java index 093316c..a1e1b08 100644 --- a/phoenix-core/src/main/java/org/apache/calcite/jdbc/PhoenixCalciteFactory.java +++ b/phoenix-core/src/main/java/org/apache/calcite/jdbc/PhoenixCalciteFactory.java @@ -11,6 +11,7 @@ import java.util.List; import java.util.Map; import java.util.Properties; import java.util.TimeZone; +import java.util.concurrent.ConcurrentHashMap; import org.apache.calcite.adapter.java.JavaTypeFactory; import org.apache.calcite.avatica.AvaticaConnection; @@ -34,6 +35,7 @@ import org.apache.phoenix.calcite.PhoenixSchema; import org.apache.phoenix.execute.RuntimeContext; import org.apache.phoenix.jdbc.PhoenixConnection; +import com.google.common.collect.ImmutableList; import com.google.common.collect.Maps; public class PhoenixCalciteFactory extends CalciteFactory { @@ -99,6 +101,9 @@ public class PhoenixCalciteFactory extends CalciteFactory { } private static class PhoenixCalciteConnection extends CalciteConnectionImpl { + final Map<Meta.StatementHandle, ImmutableList<RuntimeContext>> runtimeContextMap = + new ConcurrentHashMap<Meta.StatementHandle, ImmutableList<RuntimeContext>>(); + public PhoenixCalciteConnection(Driver driver, AvaticaFactory factory, String url, Properties info, CalciteSchema rootSchema, JavaTypeFactory typeFactory) { @@ -115,14 +120,17 @@ public class PhoenixCalciteFactory extends CalciteFactory { for (Ord<TypedValue> o : Ord.zip(parameterValues)) { map.put("?" + o.i, o.e.toLocal()); } - try { - for (RuntimeContext runtimeContext : RuntimeContext.THREAD_LOCAL.get()) { - runtimeContext.setBindParameterValues(map); - } - return super.enumerable(handle, signature); - } finally { - RuntimeContext.THREAD_LOCAL.get().clear(); + ImmutableList<RuntimeContext> ctxList = runtimeContextMap.get(handle); + if (ctxList == null) { + List<RuntimeContext> activeCtx = RuntimeContext.THREAD_LOCAL.get(); + ctxList = ImmutableList.copyOf(activeCtx); + runtimeContextMap.put(handle, ctxList); + activeCtx.clear(); + } + for (RuntimeContext runtimeContext : ctxList) { + runtimeContext.setBindParameterValues(map); } + return super.enumerable(handle, signature); } public void setAutoCommit(final boolean isAutoCommit) throws SQLException { http://git-wip-us.apache.org/repos/asf/phoenix/blob/421ddc97/phoenix-core/src/main/java/org/apache/phoenix/calcite/CalciteUtils.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/CalciteUtils.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/CalciteUtils.java index 87bfeab..ce5a718 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/CalciteUtils.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/CalciteUtils.java @@ -92,6 +92,10 @@ import org.apache.phoenix.parse.SequenceValueParseNode; import org.apache.phoenix.schema.PTableType; import org.apache.phoenix.schema.SortOrder; import org.apache.phoenix.schema.TypeMismatchException; +import org.apache.phoenix.schema.types.PBinary; +import org.apache.phoenix.schema.types.PBinaryArray; +import org.apache.phoenix.schema.types.PChar; +import org.apache.phoenix.schema.types.PCharArray; import org.apache.phoenix.schema.types.PDataType; import org.apache.phoenix.schema.types.PDate; import org.apache.phoenix.schema.types.PDecimal; @@ -629,8 +633,14 @@ public class CalciteUtils { RexDynamicParam param = (RexDynamicParam) node; int index = param.getIndex(); PDataType type = sqlTypeNameToPDataType(node.getType().getSqlTypeName()); - return implementor.newBindParameterExpression(index, type); - } + Integer maxLength = + (type == PChar.INSTANCE + || type == PCharArray.INSTANCE + || type == PBinary.INSTANCE + || type == PBinaryArray.INSTANCE) ? + node.getType().getPrecision() : null; + return implementor.newBindParameterExpression(index, type, maxLength); + } }); EXPRESSION_MAP.put(SqlKind.CAST, new ExpressionFactory() { http://git-wip-us.apache.org/repos/asf/phoenix/blob/421ddc97/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixRelImplementor.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixRelImplementor.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixRelImplementor.java index a086b40..2ddc3ea 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixRelImplementor.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixRelImplementor.java @@ -21,7 +21,7 @@ public interface PhoenixRelImplementor { QueryPlan visitInput(int i, PhoenixQueryRel input); ColumnExpression newColumnExpression(int index); @SuppressWarnings("rawtypes") - Expression newBindParameterExpression(int index, PDataType type); + Expression newBindParameterExpression(int index, PDataType type, Integer maxLength); @SuppressWarnings("rawtypes") Expression newFieldAccessExpression(String variableId, int index, PDataType type); SequenceValueExpression newSequenceExpression(PhoenixSequence seq, SequenceValueParseNode.Op op); http://git-wip-us.apache.org/repos/asf/phoenix/blob/421ddc97/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixRelImplementorImpl.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixRelImplementorImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixRelImplementorImpl.java index 2706258..96651e9 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixRelImplementorImpl.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixRelImplementorImpl.java @@ -54,8 +54,8 @@ public class PhoenixRelImplementorImpl implements PhoenixRelImplementor { @SuppressWarnings("rawtypes") @Override - public Expression newBindParameterExpression(int index, PDataType type) { - return new BindParameterExpression(index, type, runtimeContext); + public Expression newBindParameterExpression(int index, PDataType type, Integer maxLength) { + return new BindParameterExpression(index, type, maxLength, runtimeContext); } @SuppressWarnings("rawtypes") http://git-wip-us.apache.org/repos/asf/phoenix/blob/421ddc97/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixTableScan.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixTableScan.java b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixTableScan.java index 7859e15..4801999 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixTableScan.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixTableScan.java @@ -129,9 +129,9 @@ public class PhoenixTableScan extends TableScan implements PhoenixQueryRel { PhoenixRelImplementor tmpImplementor = new PhoenixRelImplementorImpl(null) { @SuppressWarnings("rawtypes") @Override - public Expression newBindParameterExpression(int index, PDataType type) { + public Expression newBindParameterExpression(int index, PDataType type, Integer maxLength) { try { - return LiteralExpression.newConstant(type.getSampleValue(), type); + return LiteralExpression.newConstant(type.getSampleValue(maxLength), type); } catch (SQLException e) { throw new RuntimeException(e); } http://git-wip-us.apache.org/repos/asf/phoenix/blob/421ddc97/phoenix-core/src/main/java/org/apache/phoenix/expression/BindParameterExpression.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/BindParameterExpression.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/BindParameterExpression.java index d3fac67..b353757 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/expression/BindParameterExpression.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/BindParameterExpression.java @@ -9,11 +9,14 @@ import org.apache.phoenix.schema.types.PDataType; public class BindParameterExpression extends VariableExpression { @SuppressWarnings("rawtypes") private final PDataType type; + private final Integer maxLength; public BindParameterExpression(int index, - @SuppressWarnings("rawtypes") PDataType type, RuntimeContext runtimeContext) { + @SuppressWarnings("rawtypes") PDataType type, Integer maxLength, + RuntimeContext runtimeContext) { super("?" + index, runtimeContext); this.type = type; + this.maxLength = maxLength; } @Override @@ -38,4 +41,7 @@ public class BindParameterExpression extends VariableExpression { return type; } + public Integer getMaxLength() { + return maxLength; + } } http://git-wip-us.apache.org/repos/asf/phoenix/blob/421ddc97/phoenix-core/src/test/java/org/apache/phoenix/calcite/SqlOperatorBaseTest.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/test/java/org/apache/phoenix/calcite/SqlOperatorBaseTest.java b/phoenix-core/src/test/java/org/apache/phoenix/calcite/SqlOperatorBaseTest.java index f336418..ecfe51e 100644 --- a/phoenix-core/src/test/java/org/apache/phoenix/calcite/SqlOperatorBaseTest.java +++ b/phoenix-core/src/test/java/org/apache/phoenix/calcite/SqlOperatorBaseTest.java @@ -1840,7 +1840,7 @@ public abstract class SqlOperatorBaseTest { // both are valid tester.check( "values 1 > 2 and sqrt(-4) = -2", - SqlTests.BOOLEAN_TYPE_CHECKER, + SqlTests.BOOLEAN_TYPE_CHECKER, SqlTests.ANY_PARAMETER_CHECKER, new ValueOrExceptionResultChecker( Boolean.FALSE, INVALID_ARG_FOR_POWER, CODE_2201F)); } @@ -2725,7 +2725,7 @@ public abstract class SqlOperatorBaseTest { // get error if (ENABLE_CAST_NULL_TEST) tester.check( "values 1 < cast(null as integer) or sqrt(-4) = -2", - SqlTests.BOOLEAN_TYPE_CHECKER, + SqlTests.BOOLEAN_TYPE_CHECKER, SqlTests.ANY_PARAMETER_CHECKER, new ValueOrExceptionResultChecker( null, INVALID_ARG_FOR_POWER, CODE_2201F)); @@ -2735,7 +2735,7 @@ public abstract class SqlOperatorBaseTest { // both are valid. tester.check( "values 1 < 2 or sqrt(-4) = -2", - SqlTests.BOOLEAN_TYPE_CHECKER, + SqlTests.BOOLEAN_TYPE_CHECKER, SqlTests.ANY_PARAMETER_CHECKER, new ValueOrExceptionResultChecker( Boolean.TRUE, INVALID_ARG_FOR_POWER, CODE_2201F)); @@ -2745,7 +2745,7 @@ public abstract class SqlOperatorBaseTest { // both are valid. if (ENABLE_CAST_NULL_TEST) tester.check( "values 1 < cast(null as integer) or sqrt(4) = -2", - SqlTests.BOOLEAN_TYPE_CHECKER, + SqlTests.BOOLEAN_TYPE_CHECKER, SqlTests.ANY_PARAMETER_CHECKER, new ValueOrExceptionResultChecker( null, INVALID_ARG_FOR_POWER, CODE_2201F)); @@ -5270,6 +5270,7 @@ public abstract class SqlOperatorBaseTest { query = SqlTesterImpl.buildQuery(s); } tester.check(query, SqlTests.ANY_TYPE_CHECKER, + SqlTests.ANY_PARAMETER_CHECKER, SqlTests.ANY_RESULT_CHECKER); } } catch (Error e) { @@ -5387,10 +5388,12 @@ public abstract class SqlOperatorBaseTest { @Override public void check( String query, TypeChecker typeChecker, + ParameterChecker paramChecker, ResultChecker resultChecker) { super.check( query, typeChecker, + paramChecker, resultChecker); Statement statement = null; try {
