You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by ma...@apache.org on 2015/08/23 19:16:05 UTC
[40/40] phoenix git commit: Fix conflicts and bugs after merge
Fix conflicts and bugs after merge
Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo
Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/ab97f1cc
Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/ab97f1cc
Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/ab97f1cc
Branch: refs/heads/calcite
Commit: ab97f1ccdbe9d74c04a897e98d5ade6e0c9b7dd5
Parents: aa26d84 aa86c89
Author: maryannxue <we...@intel.com>
Authored: Sun Aug 23 13:14:46 2015 -0400
Committer: maryannxue <we...@intel.com>
Committed: Sun Aug 23 13:14:46 2015 -0400
----------------------------------------------------------------------
dev/make_rc.sh | 59 +-
phoenix-assembly/pom.xml | 2 +-
phoenix-core/pom.xml | 2 +-
.../apache/phoenix/end2end/AlterTableIT.java | 929 +--------------
.../phoenix/end2end/AlterTableWithViewsIT.java | 1118 ++++++++++++++++++
.../org/apache/phoenix/end2end/ArrayIT.java | 201 +++-
.../org/apache/phoenix/end2end/BaseQueryIT.java | 10 -
.../end2end/BaseTenantSpecificViewIndexIT.java | 33 +-
.../apache/phoenix/end2end/CreateTableIT.java | 25 +
.../end2end/GetSetByteBitFunctionEnd2EndIT.java | 100 ++
.../org/apache/phoenix/end2end/InListIT.java | 53 +-
.../phoenix/end2end/LikeExpressionIT.java | 38 +
.../apache/phoenix/end2end/LpadFunctionIT.java | 48 +-
.../end2end/OctetLengthFunctionEnd2EndIT.java | 73 ++
.../apache/phoenix/end2end/RTrimFunctionIT.java | 71 ++
.../org/apache/phoenix/end2end/SequenceIT.java | 33 +
.../org/apache/phoenix/end2end/SortOrderIT.java | 171 ++-
.../end2end/StringToArrayFunctionIT.java | 423 +++++++
.../apache/phoenix/end2end/TenantIdTypeIT.java | 226 ++++
.../end2end/TenantSpecificTablesDDLIT.java | 59 +-
.../end2end/TenantSpecificViewIndexIT.java | 5 +
.../apache/phoenix/mapreduce/IndexToolIT.java | 42 +-
.../org/apache/phoenix/rpc/UpdateCacheIT.java | 17 +
.../apache/phoenix/calcite/CalciteUtils.java | 26 +-
.../phoenix/calcite/rel/PhoenixValues.java | 4 +-
.../apache/phoenix/compile/DeleteCompiler.java | 3 +-
.../phoenix/compile/ExpressionCompiler.java | 17 +-
.../apache/phoenix/compile/HavingCompiler.java | 2 +-
.../org/apache/phoenix/compile/KeyPart.java | 8 +-
.../phoenix/compile/ListJarsQueryPlan.java | 17 +
.../apache/phoenix/compile/QueryCompiler.java | 4 +-
.../org/apache/phoenix/compile/ScanRanges.java | 7 +-
.../apache/phoenix/compile/UpsertCompiler.java | 3 +-
.../apache/phoenix/compile/WhereCompiler.java | 2 +-
.../apache/phoenix/compile/WhereOptimizer.java | 121 +-
.../coprocessor/MetaDataEndpointImpl.java | 805 ++++++++-----
.../UngroupedAggregateRegionObserver.java | 39 +-
.../phoenix/exception/SQLExceptionCode.java | 3 +-
.../apache/phoenix/execute/BaseQueryPlan.java | 14 +-
.../DescVarLengthFastByteComparisons.java | 12 +
.../apache/phoenix/execute/HashJoinPlan.java | 6 +-
.../execute/LiteralResultIterationPlan.java | 118 ++
.../LiteralResultIterationQueryPlan.java | 118 --
.../apache/phoenix/execute/MutationState.java | 23 +-
.../expression/ArrayConstructorExpression.java | 28 +-
.../phoenix/expression/BaseExpression.java | 43 +-
.../phoenix/expression/CoerceExpression.java | 39 +-
.../expression/ComparisonExpression.java | 36 +-
.../phoenix/expression/ExpressionType.java | 14 +-
.../phoenix/expression/InListExpression.java | 26 +-
.../phoenix/expression/LiteralExpression.java | 40 +-
.../expression/function/ArrayFillFunction.java | 17 +
.../expression/function/GetBitFunction.java | 96 ++
.../expression/function/GetByteFunction.java | 96 ++
.../expression/function/InvertFunction.java | 14 +-
.../function/OctetLengthFunction.java | 66 ++
.../expression/function/PrefixFunction.java | 37 +-
.../expression/function/RTrimFunction.java | 64 +-
.../function/RoundDateExpression.java | 12 +-
.../function/RoundDecimalExpression.java | 22 +-
.../expression/function/SetBitFunction.java | 81 ++
.../expression/function/SetByteFunction.java | 81 ++
.../function/StringToArrayFunction.java | 91 ++
.../visitor/CloneExpressionVisitor.java | 2 +-
.../apache/phoenix/filter/SkipScanFilter.java | 13 +-
.../apache/phoenix/iterate/ExplainTable.java | 4 +-
.../phoenix/jdbc/PhoenixDatabaseMetaData.java | 2 +-
.../phoenix/mapreduce/index/IndexTool.java | 6 +-
.../index/PhoenixIndexImportMapper.java | 2 +-
.../util/ColumnInfoToStringEncoderDecoder.java | 41 +-
.../util/PhoenixConfigurationUtil.java | 135 ++-
.../mapreduce/util/PhoenixMapReduceUtil.java | 2 +-
.../phoenix/parse/DeleteJarStatement.java | 17 +
.../query/ConnectionQueryServicesImpl.java | 36 +-
.../java/org/apache/phoenix/query/KeyRange.java | 42 +-
.../org/apache/phoenix/query/QueryServices.java | 1 +
.../phoenix/query/QueryServicesOptions.java | 4 +-
.../apache/phoenix/schema/MetaDataClient.java | 4 +-
.../org/apache/phoenix/schema/PTableImpl.java | 33 +-
.../org/apache/phoenix/schema/Sequence.java | 3 +-
.../phoenix/schema/SequenceAllocation.java | 19 +-
.../phoenix/schema/types/PArrayDataType.java | 34 +-
.../apache/phoenix/schema/types/PBinary.java | 30 +-
.../phoenix/schema/types/PBinaryBase.java | 98 ++
.../org/apache/phoenix/schema/types/PChar.java | 11 +
.../apache/phoenix/schema/types/PDataType.java | 8 +-
.../apache/phoenix/schema/types/PDouble.java | 18 +-
.../org/apache/phoenix/schema/types/PFloat.java | 18 +-
.../apache/phoenix/schema/types/PVarbinary.java | 2 +-
.../phoenix/schema/types/PhoenixArray.java | 4 -
.../org/apache/phoenix/util/PhoenixRuntime.java | 49 +-
.../java/org/apache/phoenix/util/ScanUtil.java | 97 +-
.../org/apache/phoenix/util/SchemaUtil.java | 2 +-
.../org/apache/phoenix/util/StringUtil.java | 7 -
.../org/apache/phoenix/util/UpgradeUtil.java | 261 ++--
.../phoenix/compile/WhereOptimizerTest.java | 53 +-
.../DescVarLengthFastByteComparisonsTest.java | 45 +
.../expression/ArrayToStringFunctionTest.java | 7 +-
.../expression/GetSetByteBitFunctionTest.java | 189 +++
.../phoenix/expression/NullValueTest.java | 59 +
.../expression/OctetLengthFunctionTest.java | 67 ++
.../expression/SortOrderExpressionTest.java | 13 +-
.../expression/StringToArrayFunctionTest.java | 275 +++++
.../hbase/index/write/TestIndexWriter.java | 2 +-
.../ColumnInfoToStringEncoderDecoderTest.java | 42 +-
.../util/PhoenixConfigurationUtilTest.java | 5 +-
.../java/org/apache/phoenix/query/BaseTest.java | 16 +
.../phoenix/schema/SequenceAllocationTest.java | 17 +
.../phoenix/schema/types/PDataTypeTest.java | 33 +
.../util/TenantIdByteConversionTest.java | 294 +++++
.../java/org/apache/phoenix/util/TestUtil.java | 5 +-
phoenix-flume/pom.xml | 2 +-
phoenix-pherf/cluster/pherf.sh | 4 +-
phoenix-pherf/config/env.sh | 4 +-
phoenix-pherf/pom.xml | 550 +++------
.../org/apache/phoenix/pherf/DataIngestIT.java | 71 +-
phoenix-pherf/src/main/assembly/cluster.xml | 11 +-
.../src/main/assembly/components-minimal.xml | 33 +
phoenix-pherf/src/main/assembly/minimal.xml | 31 +
phoenix-pherf/src/main/assembly/standalone.xml | 13 +-
.../java/org/apache/phoenix/pherf/Pherf.java | 23 +-
.../apache/phoenix/pherf/PherfConstants.java | 5 +
.../phoenix/pherf/configuration/Scenario.java | 25 +-
.../pherf/configuration/XMLConfigParser.java | 23 +-
.../apache/phoenix/pherf/util/PhoenixUtil.java | 86 +-
.../phoenix/pherf/workload/QueryExecutor.java | 3 +-
.../apache/phoenix/pherf/workload/Workload.java | 17 +
.../phoenix/pherf/workload/WriteWorkload.java | 64 +-
.../org/apache/phoenix/pherf/PherfTest.java | 2 +-
.../datamodel/test_schema_mt_table.sql | 31 +
.../resources/datamodel/test_schema_mt_view.sql | 1 +
.../test/resources/scenario/test_scenario.xml | 22 +
phoenix-pig/pom.xml | 2 +-
.../phoenix/pig/PhoenixHBaseLoaderIT.java | 136 ++-
.../phoenix/pig/udf/ReserveNSequenceTestIT.java | 16 +-
.../apache/phoenix/pig/PhoenixHBaseLoader.java | 2 +-
.../apache/phoenix/pig/PhoenixHBaseStorage.java | 3 +-
.../phoenix/pig/util/PhoenixPigSchemaUtil.java | 14 +-
.../org/apache/phoenix/pig/util/TypeUtil.java | 5 +-
.../pig/util/PhoenixPigSchemaUtilTest.java | 30 +-
phoenix-server-client/pom.xml | 2 +-
phoenix-server/pom.xml | 2 +-
phoenix-spark/pom.xml | 2 +-
.../phoenix/spark/ConfigurationUtil.scala | 18 +-
.../phoenix/spark/DataFrameFunctions.scala | 35 +-
.../phoenix/spark/PhoenixRecordWritable.scala | 20 +-
.../phoenix/spark/ProductRDDFunctions.scala | 28 +-
pom.xml | 17 +-
148 files changed, 6968 insertions(+), 2505 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/phoenix/blob/ab97f1cc/phoenix-core/pom.xml
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/phoenix/blob/ab97f1cc/phoenix-core/src/main/java/org/apache/phoenix/calcite/CalciteUtils.java
----------------------------------------------------------------------
diff --cc phoenix-core/src/main/java/org/apache/phoenix/calcite/CalciteUtils.java
index 3aa2404,0000000..d3666d2
mode 100644,000000..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
@@@ -1,824 -1,0 +1,824 @@@
+package org.apache.phoenix.calcite;
+
+import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.calcite.avatica.util.ByteString;
+import org.apache.calcite.rex.RexCall;
+import org.apache.calcite.rex.RexInputRef;
+import org.apache.calcite.rex.RexLiteral;
+import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.sql.SqlAggFunction;
+import org.apache.calcite.sql.SqlFunction;
+import org.apache.calcite.sql.SqlKind;
+import org.apache.calcite.sql.SqlOperator;
+import org.apache.calcite.sql.fun.SqlStdOperatorTable;
+import org.apache.calcite.sql.type.SqlTypeName;
+import org.apache.calcite.util.NlsString;
+import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
+import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
+import org.apache.phoenix.calcite.rel.PhoenixRel.Implementor;
+import org.apache.phoenix.expression.AndExpression;
+import org.apache.phoenix.expression.CoerceExpression;
+import org.apache.phoenix.expression.ComparisonExpression;
+import org.apache.phoenix.expression.DateAddExpression;
+import org.apache.phoenix.expression.DateSubtractExpression;
+import org.apache.phoenix.expression.DecimalAddExpression;
+import org.apache.phoenix.expression.DecimalDivideExpression;
+import org.apache.phoenix.expression.DecimalMultiplyExpression;
+import org.apache.phoenix.expression.DecimalSubtractExpression;
+import org.apache.phoenix.expression.Determinism;
+import org.apache.phoenix.expression.DoubleAddExpression;
+import org.apache.phoenix.expression.DoubleDivideExpression;
+import org.apache.phoenix.expression.DoubleMultiplyExpression;
+import org.apache.phoenix.expression.DoubleSubtractExpression;
+import org.apache.phoenix.expression.Expression;
+import org.apache.phoenix.expression.ExpressionType;
+import org.apache.phoenix.expression.IsNullExpression;
+import org.apache.phoenix.expression.LiteralExpression;
+import org.apache.phoenix.expression.LongAddExpression;
+import org.apache.phoenix.expression.LongDivideExpression;
+import org.apache.phoenix.expression.LongMultiplyExpression;
+import org.apache.phoenix.expression.LongSubtractExpression;
+import org.apache.phoenix.expression.NotExpression;
+import org.apache.phoenix.expression.OrExpression;
+import org.apache.phoenix.expression.StringBasedLikeExpression;
+import org.apache.phoenix.expression.TimestampAddExpression;
+import org.apache.phoenix.expression.TimestampSubtractExpression;
+import org.apache.phoenix.expression.function.AbsFunction;
+import org.apache.phoenix.expression.function.AggregateFunction;
+import org.apache.phoenix.expression.function.CeilDateExpression;
+import org.apache.phoenix.expression.function.CeilDecimalExpression;
+import org.apache.phoenix.expression.function.CeilTimestampExpression;
+import org.apache.phoenix.expression.function.CoalesceFunction;
+import org.apache.phoenix.expression.function.CountAggregateFunction;
+import org.apache.phoenix.expression.function.CurrentDateFunction;
+import org.apache.phoenix.expression.function.CurrentTimeFunction;
+import org.apache.phoenix.expression.function.ExpFunction;
+import org.apache.phoenix.expression.function.FloorDateExpression;
+import org.apache.phoenix.expression.function.FloorDecimalExpression;
+import org.apache.phoenix.expression.function.FunctionExpression;
+import org.apache.phoenix.expression.function.LnFunction;
+import org.apache.phoenix.expression.function.LowerFunction;
+import org.apache.phoenix.expression.function.MaxAggregateFunction;
+import org.apache.phoenix.expression.function.MinAggregateFunction;
+import org.apache.phoenix.expression.function.PowerFunction;
+import org.apache.phoenix.expression.function.RoundDecimalExpression;
+import org.apache.phoenix.expression.function.RoundTimestampExpression;
+import org.apache.phoenix.expression.function.SqrtFunction;
+import org.apache.phoenix.expression.function.TrimFunction;
+import org.apache.phoenix.expression.function.UpperFunction;
+import org.apache.phoenix.schema.SortOrder;
+import org.apache.phoenix.schema.TypeMismatchException;
+import org.apache.phoenix.schema.types.PDataType;
+import org.apache.phoenix.schema.types.PDate;
+import org.apache.phoenix.schema.types.PDecimal;
+import org.apache.phoenix.schema.types.PDouble;
+import org.apache.phoenix.schema.types.PLong;
+import org.apache.phoenix.schema.types.PTimestamp;
+import org.apache.phoenix.schema.types.PUnsignedTimestamp;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
+/**
+ * Utilities for interacting with Calcite.
+ */
+public class CalciteUtils {
+ private CalciteUtils() {}
+
+ private static AtomicInteger tempAliasCounter = new AtomicInteger(0);
+
+ public static String createTempAlias() {
+ return "$" + tempAliasCounter.incrementAndGet();
+ }
+
+ @SuppressWarnings("rawtypes")
+ public static PDataType sqlTypeNameToPDataType(SqlTypeName sqlTypeName) {
+ return PDataType.fromTypeId(sqlTypeName.getJdbcOrdinal());
+ }
+
+ private static final Map<SqlKind, ExpressionFactory> EXPRESSION_MAP = Maps
+ .newHashMapWithExpectedSize(ExpressionType.values().length);
+ private static final ExpressionFactory getFactory(RexNode node) {
+ ExpressionFactory eFactory = EXPRESSION_MAP.get(node.getKind());
+ if (eFactory == null) {
+ throw new UnsupportedOperationException("Unsupported RexNode: "
+ + node);
+ }
+ return eFactory;
+ }
+ static {
+ EXPRESSION_MAP.put(SqlKind.AND, new ExpressionFactory() {
+
+ @Override
+ public Expression newExpression(RexNode node, Implementor implementor) {
+ try {
+ return AndExpression.create(convertChildren((RexCall) node, implementor));
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ });
+ EXPRESSION_MAP.put(SqlKind.OR, new ExpressionFactory() {
+
+ @Override
+ public Expression newExpression(RexNode node, Implementor implementor) {
+ return new OrExpression(convertChildren((RexCall) node, implementor));
+ }
+
+ });
+ EXPRESSION_MAP.put(SqlKind.EQUALS, new ExpressionFactory() {
+
+ @Override
+ public Expression newExpression(RexNode node, Implementor implementor) {
+ ImmutableBytesWritable ptr = new ImmutableBytesWritable();
+ try {
- return ComparisonExpression.create(CompareOp.EQUAL, convertChildren((RexCall) node, implementor), ptr);
++ return ComparisonExpression.create(CompareOp.EQUAL, convertChildren((RexCall) node, implementor), ptr, implementor.getTableRef().getTable().rowKeyOrderOptimizable());
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ });
+ EXPRESSION_MAP.put(SqlKind.NOT_EQUALS, new ExpressionFactory() {
+
+ @Override
+ public Expression newExpression(RexNode node, Implementor implementor) {
+ ImmutableBytesWritable ptr = new ImmutableBytesWritable();
+ try {
- return ComparisonExpression.create(CompareOp.NOT_EQUAL, convertChildren((RexCall) node, implementor), ptr);
++ return ComparisonExpression.create(CompareOp.NOT_EQUAL, convertChildren((RexCall) node, implementor), ptr, implementor.getTableRef().getTable().rowKeyOrderOptimizable());
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ });
+ EXPRESSION_MAP.put(SqlKind.GREATER_THAN, new ExpressionFactory() {
+
+ @Override
+ public Expression newExpression(RexNode node, Implementor implementor) {
+ ImmutableBytesWritable ptr = new ImmutableBytesWritable();
+ try {
- return ComparisonExpression.create(CompareOp.GREATER, convertChildren((RexCall) node, implementor), ptr);
++ return ComparisonExpression.create(CompareOp.GREATER, convertChildren((RexCall) node, implementor), ptr, implementor.getTableRef().getTable().rowKeyOrderOptimizable());
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ });
+ EXPRESSION_MAP.put(SqlKind.GREATER_THAN_OR_EQUAL, new ExpressionFactory() {
+
+ @Override
+ public Expression newExpression(RexNode node, Implementor implementor) {
+ ImmutableBytesWritable ptr = new ImmutableBytesWritable();
+ try {
- return ComparisonExpression.create(CompareOp.GREATER_OR_EQUAL, convertChildren((RexCall) node, implementor), ptr);
++ return ComparisonExpression.create(CompareOp.GREATER_OR_EQUAL, convertChildren((RexCall) node, implementor), ptr, implementor.getTableRef().getTable().rowKeyOrderOptimizable());
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ });
+ EXPRESSION_MAP.put(SqlKind.LESS_THAN, new ExpressionFactory() {
+
+ @Override
+ public Expression newExpression(RexNode node, Implementor implementor) {
+ ImmutableBytesWritable ptr = new ImmutableBytesWritable();
+ try {
- return ComparisonExpression.create(CompareOp.LESS, convertChildren((RexCall) node, implementor), ptr);
++ return ComparisonExpression.create(CompareOp.LESS, convertChildren((RexCall) node, implementor), ptr, implementor.getTableRef().getTable().rowKeyOrderOptimizable());
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ });
+ EXPRESSION_MAP.put(SqlKind.LESS_THAN_OR_EQUAL, new ExpressionFactory() {
+
+ @Override
+ public Expression newExpression(RexNode node, Implementor implementor) {
+ ImmutableBytesWritable ptr = new ImmutableBytesWritable();
+ try {
- return ComparisonExpression.create(CompareOp.LESS_OR_EQUAL, convertChildren((RexCall) node, implementor), ptr);
++ return ComparisonExpression.create(CompareOp.LESS_OR_EQUAL, convertChildren((RexCall) node, implementor), ptr, implementor.getTableRef().getTable().rowKeyOrderOptimizable());
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ });
+ EXPRESSION_MAP.put(SqlKind.PLUS, new ExpressionFactory() {
+
+ @SuppressWarnings("rawtypes")
+ @Override
+ public Expression newExpression(RexNode node, Implementor implementor) {
+ try {
+ List<Expression> children = convertChildren((RexCall) node, implementor);
+ Expression expr = null;
+ boolean foundDate = false;
+ Determinism determinism = Determinism.ALWAYS;
+ PDataType theType = null;
+ for(int i = 0; i < children.size(); i++) {
+ Expression e = children.get(i);
+ determinism = determinism.combine(e.getDeterminism());
+ PDataType type = e.getDataType();
+ if (type == null) {
+ continue;
+ } else if (type.isCoercibleTo(PTimestamp.INSTANCE)) {
+ if (foundDate) {
+ throw TypeMismatchException.newException(type, node.toString());
+ }
+ if (theType == null || (theType != PTimestamp.INSTANCE && theType != PUnsignedTimestamp.INSTANCE)) {
+ theType = type;
+ }
+ foundDate = true;
+ }else if (type == PDecimal.INSTANCE) {
+ if (theType == null || !theType.isCoercibleTo(PTimestamp.INSTANCE)) {
+ theType = PDecimal.INSTANCE;
+ }
+ } else if (type.isCoercibleTo(PLong.INSTANCE)) {
+ if (theType == null) {
+ theType = PLong.INSTANCE;
+ }
+ } else if (type.isCoercibleTo(PDouble.INSTANCE)) {
+ if (theType == null) {
+ theType = PDouble.INSTANCE;
+ }
+ } else {
+ throw TypeMismatchException.newException(type, node.toString());
+ }
+ }
+ if (theType == PDecimal.INSTANCE) {
+ expr = new DecimalAddExpression(children);
+ } else if (theType == PLong.INSTANCE) {
+ expr = new LongAddExpression(children);
+ } else if (theType == PDouble.INSTANCE) {
+ expr = new DoubleAddExpression(children);
+ } else if (theType == null) {
+ expr = LiteralExpression.newConstant(null, theType, determinism);
+ } else if (theType == PTimestamp.INSTANCE || theType == PUnsignedTimestamp.INSTANCE) {
+ expr = new TimestampAddExpression(children);
+ } else if (theType.isCoercibleTo(PDate.INSTANCE)) {
+ expr = new DateAddExpression(children);
+ } else {
+ throw TypeMismatchException.newException(theType, node.toString());
+ }
+
+ PDataType targetType = sqlTypeNameToPDataType(node.getType().getSqlTypeName());
- return cast(targetType, expr);
++ return cast(targetType, expr, implementor);
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ });
+ EXPRESSION_MAP.put(SqlKind.MINUS, new ExpressionFactory() {
+
+ @SuppressWarnings("rawtypes")
+ @Override
+ public Expression newExpression(RexNode node, Implementor implementor) {
+ try {
+ List<Expression> children = convertChildren((RexCall) node, implementor);
+ Expression expr = null;
+ int i = 0;
+ PDataType theType = null;
+ Expression e1 = children.get(0);
+ Expression e2 = children.get(1);
+ Determinism determinism = e1.getDeterminism().combine(e2.getDeterminism());
+ PDataType type1 = e1.getDataType();
+ PDataType type2 = e2.getDataType();
+ // TODO: simplify this special case for DATE conversion
+ /**
+ * For date1-date2, we want to coerce to a LONG because this
+ * cannot be compared against another date. It has essentially
+ * become a number. For date1-5, we want to preserve the DATE
+ * type because this can still be compared against another date
+ * and cannot be multiplied or divided. Any other time occurs is
+ * an error. For example, 5-date1 is an error. The nulls occur if
+ * we have bind variables.
+ */
+ boolean isType1Date =
+ type1 != null
+ && type1 != PTimestamp.INSTANCE
+ && type1 != PUnsignedTimestamp.INSTANCE
+ && type1.isCoercibleTo(PDate.INSTANCE);
+ boolean isType2Date =
+ type2 != null
+ && type2 != PTimestamp.INSTANCE
+ && type2 != PUnsignedTimestamp.INSTANCE
+ && type2.isCoercibleTo(PDate.INSTANCE);
+ if (isType1Date || isType2Date) {
+ if (isType1Date && isType2Date) {
+ i = 2;
+ theType = PDecimal.INSTANCE;
+ } else if (isType1Date && type2 != null
+ && type2.isCoercibleTo(PDecimal.INSTANCE)) {
+ i = 2;
+ theType = PDate.INSTANCE;
+ } else if (type1 == null || type2 == null) {
+ /*
+ * FIXME: Could be either a Date or BigDecimal, but we
+ * don't know if we're comparing to a date or a number
+ * which would be disambiguate it.
+ */
+ i = 2;
+ theType = null;
+ }
+ } else if(type1 == PTimestamp.INSTANCE || type2 == PTimestamp.INSTANCE) {
+ i = 2;
+ theType = PTimestamp.INSTANCE;
+ } else if(type1 == PUnsignedTimestamp.INSTANCE || type2 == PUnsignedTimestamp.INSTANCE) {
+ i = 2;
+ theType = PUnsignedTimestamp.INSTANCE;
+ }
+
+ for (; i < children.size(); i++) {
+ // This logic finds the common type to which all child types are coercible
+ // without losing precision.
+ Expression e = children.get(i);
+ determinism = determinism.combine(e.getDeterminism());
+ PDataType type = e.getDataType();
+ if (type == null) {
+ continue;
+ } else if (type.isCoercibleTo(PLong.INSTANCE)) {
+ if (theType == null) {
+ theType = PLong.INSTANCE;
+ }
+ } else if (type == PDecimal.INSTANCE) {
+ // Coerce return type to DECIMAL from LONG or DOUBLE if DECIMAL child found,
+ // unless we're doing date arithmetic.
+ if (theType == null
+ || !theType.isCoercibleTo(PDate.INSTANCE)) {
+ theType = PDecimal.INSTANCE;
+ }
+ } else if (type.isCoercibleTo(PDouble.INSTANCE)) {
+ // Coerce return type to DOUBLE from LONG if DOUBLE child found,
+ // unless we're doing date arithmetic or we've found another child of type DECIMAL
+ if (theType == null
+ || (theType != PDecimal.INSTANCE && !theType.isCoercibleTo(PDate.INSTANCE) )) {
+ theType = PDouble.INSTANCE;
+ }
+ } else {
+ throw TypeMismatchException.newException(type, node.toString());
+ }
+ }
+ if (theType == PDecimal.INSTANCE) {
+ expr = new DecimalSubtractExpression(children);
+ } else if (theType == PLong.INSTANCE) {
+ expr = new LongSubtractExpression(children);
+ } else if (theType == PDouble.INSTANCE) {
+ expr = new DoubleSubtractExpression(children);
+ } else if (theType == null) {
+ expr = LiteralExpression.newConstant(null, theType, determinism);
+ } else if (theType == PTimestamp.INSTANCE || theType == PUnsignedTimestamp.INSTANCE) {
+ expr = new TimestampSubtractExpression(children);
+ } else if (theType.isCoercibleTo(PDate.INSTANCE)) {
+ expr = new DateSubtractExpression(children);
+ } else {
+ throw TypeMismatchException.newException(theType, node.toString());
+ }
+ PDataType targetType = sqlTypeNameToPDataType(node.getType().getSqlTypeName());
- return cast(targetType, expr);
++ return cast(targetType, expr, implementor);
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ });
+ EXPRESSION_MAP.put(SqlKind.TIMES, new ExpressionFactory() {
+
+ @SuppressWarnings("rawtypes")
+ @Override
+ public Expression newExpression(RexNode node, Implementor implementor) {
+ try {
+ List<Expression> children = convertChildren((RexCall) node, implementor);
+ Expression expr = null;
+ PDataType theType = null;
+ Determinism determinism = Determinism.ALWAYS;
+ for(int i = 0; i < children.size(); i++) {
+ Expression e = children.get(i);
+ determinism = determinism.combine(e.getDeterminism());
+ PDataType type = e.getDataType();
+ if (type == null) {
+ continue;
+ } else if (type == PDecimal.INSTANCE) {
+ theType = PDecimal.INSTANCE;
+ } else if (type.isCoercibleTo(PLong.INSTANCE)) {
+ if (theType == null) {
+ theType = PLong.INSTANCE;
+ }
+ } else if (type.isCoercibleTo(PDouble.INSTANCE)) {
+ if (theType == null) {
+ theType = PDouble.INSTANCE;
+ }
+ } else {
+ throw TypeMismatchException.newException(type, node.toString());
+ }
+ }
+ if (theType == PDecimal.INSTANCE) {
+ expr = new DecimalMultiplyExpression(children);
+ } else if (theType == PLong.INSTANCE) {
+ expr = new LongMultiplyExpression(children);
+ } else if (theType == PDouble.INSTANCE) {
+ expr = new DoubleMultiplyExpression(children);
+ } else {
+ expr = LiteralExpression.newConstant(null, theType, determinism);
+ }
+ PDataType targetType = sqlTypeNameToPDataType(node.getType().getSqlTypeName());
- return cast(targetType, expr);
++ return cast(targetType, expr, implementor);
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ });
+ EXPRESSION_MAP.put(SqlKind.DIVIDE, new ExpressionFactory() {
+
+ @SuppressWarnings("rawtypes")
+ @Override
+ public Expression newExpression(RexNode node, Implementor implementor) {
+ try {
+ List<Expression> children = convertChildren((RexCall) node, implementor);
+ Expression expr = null;
+ PDataType theType = null;
+ Determinism determinism = Determinism.ALWAYS;
+ for(int i = 0; i < children.size(); i++) {
+ Expression e = children.get(i);
+ determinism = determinism.combine(e.getDeterminism());
+ PDataType type = e.getDataType();
+ if (type == null) {
+ continue;
+ } else if (type == PDecimal.INSTANCE) {
+ theType = PDecimal.INSTANCE;
+ } else if (type.isCoercibleTo(PLong.INSTANCE)) {
+ if (theType == null) {
+ theType = PLong.INSTANCE;
+ }
+ } else if (type.isCoercibleTo(PDouble.INSTANCE)) {
+ if (theType == null) {
+ theType = PDouble.INSTANCE;
+ }
+ } else {
+ throw TypeMismatchException.newException(type, node.toString());
+ }
+ }
+ if (theType == PDecimal.INSTANCE) {
+ expr = new DecimalDivideExpression( children);
+ } else if (theType == PLong.INSTANCE) {
+ expr = new LongDivideExpression( children);
+ } else if (theType == PDouble.INSTANCE) {
+ expr = new DoubleDivideExpression(children);
+ } else {
+ expr = LiteralExpression.newConstant(null, theType, determinism);
+ }
+ PDataType targetType = sqlTypeNameToPDataType(node.getType().getSqlTypeName());
- return cast(targetType, expr);
++ return cast(targetType, expr, implementor);
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ });
+ EXPRESSION_MAP.put(SqlKind.LITERAL, new ExpressionFactory() {
+
+ @SuppressWarnings("rawtypes")
+ @Override
+ public Expression newExpression(RexNode node, Implementor implementor) {
+ RexLiteral lit = (RexLiteral) node;
+ PDataType targetType = sqlTypeNameToPDataType(node.getType().getSqlTypeName());
+ Object o = lit.getValue();
+ if (o instanceof NlsString) {
+ o = ((NlsString) o).getValue();
+ } else if (o instanceof ByteString) {
+ o = ((ByteString) o).getBytes();
+ }
+ try {
+ return LiteralExpression.newConstant(o, targetType);
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ });
+ EXPRESSION_MAP.put(SqlKind.INPUT_REF, new ExpressionFactory() {
+
+ @Override
+ public Expression newExpression(RexNode node, Implementor implementor) {
+ RexInputRef ref = (RexInputRef) node;
+ int index = ref.getIndex();
+ return implementor.newColumnExpression(index);
+ }
+
+ });
+ EXPRESSION_MAP.put(SqlKind.CAST, new ExpressionFactory() {
+
+ @SuppressWarnings("rawtypes")
+ @Override
+ public Expression newExpression(RexNode node,
+ Implementor implementor) {
+ List<Expression> children = convertChildren((RexCall) node, implementor);
+ PDataType targetType = sqlTypeNameToPDataType(node.getType().getSqlTypeName());
+ try {
- return cast(targetType, children.get(0));
++ return cast(targetType, children.get(0), implementor);
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ });
+ EXPRESSION_MAP.put(SqlKind.OTHER_FUNCTION, new ExpressionFactory() {
+ @Override
+ public Expression newExpression(RexNode node,
+ Implementor implementor) {
+ RexCall call = (RexCall) node;
+ List<Expression> children = convertChildren(call, implementor);
+ SqlOperator op = call.getOperator();
+ try {
+ if (op == SqlStdOperatorTable.SQRT) {
+ return new SqrtFunction(children);
+ } else if (op == SqlStdOperatorTable.POWER) {
+ return new PowerFunction(children);
+ } else if (op == SqlStdOperatorTable.LN) {
+ return new LnFunction(children);
+ } else if (op == SqlStdOperatorTable.EXP) {
+ return new ExpFunction(children);
+ } else if (op == SqlStdOperatorTable.ABS) {
+ return new AbsFunction(children);
+ } else if (op == SqlStdOperatorTable.CURRENT_DATE) {
+ return new CurrentDateFunction();
+ } else if (op == SqlStdOperatorTable.CURRENT_TIME) {
+ return new CurrentTimeFunction();
+ } else if (op == SqlStdOperatorTable.LOWER) {
+ return new LowerFunction(children);
+ } else if (op == SqlStdOperatorTable.UPPER) {
+ return new UpperFunction(children);
+ } else if (op == SqlStdOperatorTable.COALESCE) {
+ return new CoalesceFunction(children);
+ }
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+
+ throw new UnsupportedOperationException(
+ "Unsupported SqlFunction: " + op.getName());
+ }
+ });
+ EXPRESSION_MAP.put(SqlKind.NOT, new ExpressionFactory() {
+ @Override
+ public Expression newExpression(RexNode node, Implementor implementor) {
+ return new NotExpression(convertChildren((RexCall) node, implementor));
+ }
+ });
+ EXPRESSION_MAP.put(SqlKind.IS_TRUE, new ExpressionFactory() {
+ @Override
+ public Expression newExpression(RexNode node, Implementor implementor) {
+ List<Expression> children = convertChildren((RexCall) node, implementor);
+ return children.get(0);
+ }
+ });
+ EXPRESSION_MAP.put(SqlKind.IS_NOT_TRUE, new ExpressionFactory() {
+ @Override
+ public Expression newExpression(RexNode node, Implementor implementor) {
+ return new NotExpression(convertChildren((RexCall) node, implementor));
+ }
+ });
+ EXPRESSION_MAP.put(SqlKind.IS_FALSE, new ExpressionFactory() {
+ @Override
+ public Expression newExpression(RexNode node, Implementor implementor) {
+ return new NotExpression(convertChildren((RexCall) node, implementor));
+ }
+ });
+ EXPRESSION_MAP.put(SqlKind.IS_NOT_FALSE, new ExpressionFactory() {
+ @Override
+ public Expression newExpression(RexNode node, Implementor implementor) {
+ List<Expression> children = convertChildren((RexCall) node, implementor);
+ return children.get(0);
+ }
+ });
+ //TODO different kind of LikeExpression based on configuration
+ EXPRESSION_MAP.put(SqlKind.LIKE, new ExpressionFactory() {
+ @Override
+ public Expression newExpression(RexNode node, Implementor implementor) {
+ List<Expression> children = convertChildren((RexCall) node, implementor);
+ return new StringBasedLikeExpression(children);
+ }
+ });
+ EXPRESSION_MAP.put(SqlKind.IS_NULL, new ExpressionFactory() {
+ @Override
+ public Expression newExpression(RexNode node, Implementor implementor) {
+ return new IsNullExpression(convertChildren((RexCall) node, implementor), false);
+ }
+ });
+ EXPRESSION_MAP.put(SqlKind.IS_NOT_NULL, new ExpressionFactory() {
+ @Override
+ public Expression newExpression(RexNode node, Implementor implementor) {
+ return new IsNullExpression(convertChildren((RexCall) node, implementor), true);
+ }
+ });
+ EXPRESSION_MAP.put(SqlKind.TRIM, new ExpressionFactory() {
+ @Override
+ public Expression newExpression(RexNode node, Implementor implementor) {
+ //TODO Phoenix only support separate arguments.
+ try {
+ return new TrimFunction(convertChildren((RexCall) node, implementor));
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ });
+ EXPRESSION_MAP.put(SqlKind.CEIL, new ExpressionFactory() {
+ @Override
+ public Expression newExpression(RexNode node, Implementor implementor) {
+ //TODO Phoenix only support separate arguments.
+ List<Expression> children = convertChildren((RexCall) node, implementor);
+ final Expression firstChild = children.get(0);
+ final PDataType firstChildDataType = firstChild.getDataType();
+ try {
+ if (firstChildDataType.isCoercibleTo(PDate.INSTANCE)) {
+ return CeilDateExpression.create(children);
+ } else if (firstChildDataType == PTimestamp.INSTANCE
+ || firstChildDataType == PUnsignedTimestamp.INSTANCE) {
+ return CeilTimestampExpression.create(children);
+ } else if (firstChildDataType.isCoercibleTo(PDecimal.INSTANCE)) {
+ return CeilDecimalExpression.create(children);
+ } else {
+ throw TypeMismatchException.newException(firstChildDataType, "1");
+ }
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ });
+ EXPRESSION_MAP.put(SqlKind.FLOOR, new ExpressionFactory() {
+ @Override
+ public Expression newExpression(RexNode node, Implementor implementor) {
+ // TODO Phoenix only support separate arguments.
+ List<Expression> children = convertChildren((RexCall) node, implementor);
+ final Expression firstChild = children.get(0);
+ final PDataType firstChildDataType = firstChild.getDataType();
+ try {
+ if (firstChildDataType.isCoercibleTo(PTimestamp.INSTANCE)) {
+ return FloorDateExpression.create(children);
+ } else if (firstChildDataType.isCoercibleTo(PDecimal.INSTANCE)) {
+ return FloorDecimalExpression.create(children);
+ } else {
+ throw TypeMismatchException.newException(firstChildDataType, "1");
+ }
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ });
+ // TODO: SqlKind.CASE
+ }
+
+ private static final Map<String, FunctionFactory> FUNCTION_MAP = Maps
+ .newHashMapWithExpectedSize(ExpressionType.values().length);
+ private static final FunctionFactory getFactory(SqlFunction func) {
+ FunctionFactory fFactory = FUNCTION_MAP.get(func.getName());
+ if (fFactory == null) {
+ throw new UnsupportedOperationException("Unsupported SqlFunction: "
+ + func);
+ }
+ return fFactory;
+ }
+ static {
+ FUNCTION_MAP.put("COUNT", new FunctionFactory() {
+ @Override
+ public FunctionExpression newFunction(SqlFunction sqlFunc,
+ List<Expression> args) {
+ if (args.isEmpty()) {
+ args = Lists.asList(LiteralExpression.newConstant(1), new Expression[0]);
+ }
+ return new CountAggregateFunction(args);
+ }
+ });
+ // TODO Buggy. Disable for now.
+ //FUNCTION_MAP.put("$SUM0", new FunctionFactory() {
+ // @Override
+ // public FunctionExpression newFunction(SqlFunction sqlFunc,
+ // List<Expression> args) {
+ // return new SumAggregateFunction(args);
+ // }
+ //});
+ FUNCTION_MAP.put("MAX", new FunctionFactory() {
+ @Override
+ public FunctionExpression newFunction(SqlFunction sqlFunc,
+ List<Expression> args) {
+ return new MaxAggregateFunction(args, null);
+ }
+ });
+ FUNCTION_MAP.put("MIN", new FunctionFactory() {
+ @Override
+ public FunctionExpression newFunction(SqlFunction sqlFunc,
+ List<Expression> args) {
+ return new MinAggregateFunction(args, null);
+ }
+ });
+ }
+
+ private static List<Expression> convertChildren(RexCall call, Implementor implementor) {
+ List<Expression> children = Lists.newArrayListWithExpectedSize(call.getOperands().size());
+ for (RexNode op : call.getOperands()) {
+ Expression child = getFactory(op).newExpression(op, implementor);
+ children.add(child);
+ }
+ return children;
+ }
+
+ @SuppressWarnings("rawtypes")
- private static Expression cast(PDataType targetDataType, Expression childExpr) throws SQLException {
++ private static Expression cast(PDataType targetDataType, Expression childExpr, Implementor implementor) throws SQLException {
+ PDataType fromDataType = childExpr.getDataType();
+
+ Expression expr = childExpr;
+ if(fromDataType != null) {
+ expr = convertToRoundExpressionIfNeeded(fromDataType, targetDataType, childExpr);
+ }
- return CoerceExpression.create(expr, targetDataType, SortOrder.getDefault(), expr.getMaxLength());
++ return CoerceExpression.create(expr, targetDataType, SortOrder.getDefault(), expr.getMaxLength(), implementor.getTableRef().getTable().rowKeyOrderOptimizable());
+ }
+
+ @SuppressWarnings("rawtypes")
+ private static Expression convertToRoundExpressionIfNeeded(PDataType fromDataType, PDataType targetDataType, Expression expr) throws SQLException {
+ if(fromDataType == targetDataType) {
+ return expr;
+ } else if((fromDataType == PDecimal.INSTANCE || fromDataType == PTimestamp.INSTANCE || fromDataType == PUnsignedTimestamp.INSTANCE) && targetDataType.isCoercibleTo(
+ PLong.INSTANCE)) {
+ return RoundDecimalExpression.create(Arrays.asList(expr));
+ } else if((fromDataType == PDecimal.INSTANCE || fromDataType == PTimestamp.INSTANCE || fromDataType == PUnsignedTimestamp.INSTANCE) && targetDataType.isCoercibleTo(
+ PDate.INSTANCE)) {
+ return RoundTimestampExpression.create(Arrays.asList(expr));
+ } else if(fromDataType.isCastableTo(targetDataType)) {
+ return expr;
+ } else {
+ throw TypeMismatchException.newException(fromDataType, targetDataType, expr.toString());
+ }
+ }
+
+ public static boolean isExpressionSupported(RexNode node) {
+ try {
+ getFactory(node);
+ } catch (UnsupportedOperationException e) {
+ return false;
+ }
+ if (node instanceof RexCall) {
+ for (RexNode op : ((RexCall) node).getOperands()) {
+ if (!isExpressionSupported(op)) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ public static boolean isAggregateFunctionSupported(SqlAggFunction aggFunc) {
+ try {
+ getFactory(aggFunc);
+ } catch (UnsupportedOperationException e) {
+ return false;
+ }
+
+ return true;
+ }
+
+ public static Expression toExpression(RexNode node, Implementor implementor) {
+ ExpressionFactory eFactory = getFactory(node);
+ Expression expression = eFactory.newExpression(node, implementor);
+ return expression;
+ }
+
+ public static AggregateFunction toAggregateFunction(SqlAggFunction aggFunc, List<Integer> args, Implementor implementor) {
+ FunctionFactory fFactory = getFactory(aggFunc);
+ List<Expression> exprs = Lists.newArrayListWithExpectedSize(args.size());
+ for (Integer index : args) {
+ exprs.add(implementor.newColumnExpression(index));
+ }
+
+ return (AggregateFunction) (fFactory.newFunction(aggFunc, exprs));
+ }
+
+ public static Object evaluateStatelessExpression(RexNode node) {
+ try {
+ Expression expression = toExpression(node, null);
+ if (expression.isStateless() && expression.getDeterminism() == Determinism.ALWAYS) {
+ ImmutableBytesWritable ptr = new ImmutableBytesWritable();
+ expression.evaluate(null, ptr);
+ return expression.getDataType().toObject(ptr);
+ }
+ } catch (Exception e) {
+ // Expression is not stateless. do nothing.
+ }
+
+ return null;
+ }
+
+ public static interface ExpressionFactory {
+ public Expression newExpression(RexNode node, Implementor implementor);
+ }
+
+ public static interface FunctionFactory {
+ public FunctionExpression newFunction(SqlFunction sqlFunc, List<Expression> args);
+ }
+}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/ab97f1cc/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixValues.java
----------------------------------------------------------------------
diff --cc phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixValues.java
index 44480b8,0000000..b65b1b8
mode 100644,000000..100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixValues.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/calcite/rel/PhoenixValues.java
@@@ -1,129 -1,0 +1,129 @@@
+package org.apache.phoenix.calcite.rel;
+
+import static org.apache.phoenix.util.PhoenixRuntime.CONNECTIONLESS;
+import static org.apache.phoenix.util.PhoenixRuntime.JDBC_PROTOCOL;
+import static org.apache.phoenix.util.PhoenixRuntime.JDBC_PROTOCOL_SEPARATOR;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.calcite.plan.RelOptCluster;
+import org.apache.calcite.plan.RelOptCost;
+import org.apache.calcite.plan.RelOptPlanner;
+import org.apache.calcite.plan.RelTraitSet;
+import org.apache.calcite.rel.RelCollation;
+import org.apache.calcite.rel.RelCollationTraitDef;
+import org.apache.calcite.rel.RelDistribution;
+import org.apache.calcite.rel.RelDistributionTraitDef;
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.core.Values;
+import org.apache.calcite.rel.metadata.RelMdCollation;
+import org.apache.calcite.rel.metadata.RelMdDistribution;
+import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.rex.RexLiteral;
+import org.apache.hadoop.hbase.KeyValue;
+import org.apache.hadoop.hbase.client.Scan;
+import org.apache.phoenix.calcite.CalciteUtils;
+import org.apache.phoenix.compile.OrderByCompiler.OrderBy;
+import org.apache.phoenix.compile.ColumnResolver;
+import org.apache.phoenix.compile.FromCompiler;
+import org.apache.phoenix.compile.QueryPlan;
+import org.apache.phoenix.compile.RowProjector;
+import org.apache.phoenix.compile.SequenceManager;
+import org.apache.phoenix.compile.StatementContext;
- import org.apache.phoenix.execute.LiteralResultIterationQueryPlan;
++import org.apache.phoenix.execute.LiteralResultIterationPlan;
+import org.apache.phoenix.execute.TupleProjector;
+import org.apache.phoenix.expression.Expression;
+import org.apache.phoenix.jdbc.PhoenixConnection;
+import org.apache.phoenix.jdbc.PhoenixStatement;
+import org.apache.phoenix.parse.SelectStatement;
+import org.apache.phoenix.schema.TableRef;
+import org.apache.phoenix.schema.tuple.SingleKeyValueTuple;
+import org.apache.phoenix.schema.tuple.Tuple;
+
+import com.google.common.base.Supplier;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+
+/**
+ * Implementation of {@link org.apache.calcite.rel.core.Values}
+ * relational expression in Phoenix.
+ */
+public class PhoenixValues extends Values implements PhoenixRel {
+
+ private static final PhoenixConnection phoenixConnection;
+ static {
+ try {
+ Class.forName("org.apache.phoenix.jdbc.PhoenixDriver");
+ final Connection connection =
+ DriverManager.getConnection(JDBC_PROTOCOL + JDBC_PROTOCOL_SEPARATOR + CONNECTIONLESS);
+ phoenixConnection =
+ connection.unwrap(PhoenixConnection.class);
+ } catch (ClassNotFoundException e) {
+ throw new RuntimeException(e);
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static PhoenixValues create(RelOptCluster cluster, final RelDataType rowType, final ImmutableList<ImmutableList<RexLiteral>> tuples) {
+ final RelTraitSet traits =
+ cluster.traitSetOf(PhoenixRel.CLIENT_CONVENTION)
+ .replaceIfs(RelCollationTraitDef.INSTANCE,
+ new Supplier<List<RelCollation>>() {
+ public List<RelCollation> get() {
+ return RelMdCollation.values(rowType, tuples);
+ }
+ })
+ .replaceIf(RelDistributionTraitDef.INSTANCE,
+ new Supplier<RelDistribution>() {
+ public RelDistribution get() {
+ return RelMdDistribution.values(rowType, tuples);
+ }
+ });
+ return new PhoenixValues(cluster, rowType, tuples, traits);
+ }
+
+ private PhoenixValues(RelOptCluster cluster, RelDataType rowType, ImmutableList<ImmutableList<RexLiteral>> tuples, RelTraitSet traits) {
+ super(cluster, rowType, tuples, traits);
+ }
+
+ @Override
+ public PhoenixValues copy(RelTraitSet traitSet, List<RelNode> inputs) {
+ assert inputs.isEmpty();
+ return create(getCluster(), rowType, tuples);
+ }
+
+ @Override
+ public RelOptCost computeSelfCost(RelOptPlanner planner) {
+ return super.computeSelfCost(planner).multiplyBy(PHOENIX_FACTOR);
+ }
+
+ @Override
+ public QueryPlan implement(Implementor implementor) {
+ List<Tuple> literalResult = Lists.newArrayList();
+ Iterator<ImmutableList<RexLiteral>> iter = getTuples().iterator();
+ Tuple baseTuple = new SingleKeyValueTuple(KeyValue.LOWESTKEY);
+ while (iter.hasNext()) {
+ ImmutableList<RexLiteral> row = iter.next();
+ List<Expression> exprs = Lists.newArrayListWithExpectedSize(row.size());
+ for (RexLiteral rexLiteral : row) {
+ exprs.add(CalciteUtils.toExpression(rexLiteral, implementor));
+ }
+ TupleProjector projector = implementor.project(exprs);
+ literalResult.add(projector.projectResults(baseTuple));
+ }
+
+ try {
+ PhoenixStatement stmt = new PhoenixStatement(phoenixConnection);
+ ColumnResolver resolver = FromCompiler.getResolver(implementor.getTableRef());
+ StatementContext context = new StatementContext(stmt, resolver, new Scan(), new SequenceManager(stmt));
- return new LiteralResultIterationQueryPlan(literalResult.iterator(), context, SelectStatement.SELECT_ONE, TableRef.EMPTY_TABLE_REF, RowProjector.EMPTY_PROJECTOR, null, OrderBy.EMPTY_ORDER_BY, null);
++ return new LiteralResultIterationPlan(literalResult.iterator(), context, SelectStatement.SELECT_ONE, TableRef.EMPTY_TABLE_REF, RowProjector.EMPTY_PROJECTOR, null, OrderBy.EMPTY_ORDER_BY, null);
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/ab97f1cc/phoenix-core/src/main/java/org/apache/phoenix/compile/ListJarsQueryPlan.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/phoenix/blob/ab97f1cc/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereCompiler.java
----------------------------------------------------------------------
diff --cc phoenix-core/src/main/java/org/apache/phoenix/compile/WhereCompiler.java
index 16405c0,13963d7..3089b03
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereCompiler.java
@@@ -232,10 -232,10 +232,10 @@@ public class WhereCompiler
* @param context the shared context during query compilation
* @param whereClause the final where clause expression.
*/
- private static void setScanFilter(StatementContext context, FilterableStatement statement, Expression whereClause, boolean disambiguateWithFamily, boolean hashJoinOptimization) {
+ public static void setScanFilter(StatementContext context, FilterableStatement statement, Expression whereClause, boolean disambiguateWithFamily, boolean hashJoinOptimization) {
Scan scan = context.getScan();
- if (LiteralExpression.isFalse(whereClause)) {
+ if (LiteralExpression.isBooleanFalseOrNull(whereClause)) {
context.setScanRanges(ScanRanges.NOTHING);
} else if (whereClause != null && !LiteralExpression.isTrue(whereClause) && !hashJoinOptimization) {
Filter filter = null;
http://git-wip-us.apache.org/repos/asf/phoenix/blob/ab97f1cc/phoenix-core/src/main/java/org/apache/phoenix/execute/HashJoinPlan.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/phoenix/blob/ab97f1cc/phoenix-core/src/main/java/org/apache/phoenix/execute/LiteralResultIterationPlan.java
----------------------------------------------------------------------
diff --cc phoenix-core/src/main/java/org/apache/phoenix/execute/LiteralResultIterationPlan.java
index 0000000,e7230cc..58c78d2
mode 000000,100644..100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/execute/LiteralResultIterationPlan.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/execute/LiteralResultIterationPlan.java
@@@ -1,0 -1,108 +1,118 @@@
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ package org.apache.phoenix.execute;
+
+ import java.sql.SQLException;
+ import java.util.Collections;
+ import java.util.Iterator;
+ import java.util.List;
+
+ import org.apache.hadoop.hbase.KeyValue;
+ import org.apache.hadoop.hbase.client.Scan;
+ import org.apache.phoenix.compile.GroupByCompiler.GroupBy;
+ import org.apache.phoenix.compile.OrderByCompiler.OrderBy;
++import org.apache.phoenix.compile.QueryPlan;
+ import org.apache.phoenix.compile.RowProjector;
+ import org.apache.phoenix.compile.StatementContext;
+ import org.apache.phoenix.iterate.ParallelIteratorFactory;
+ import org.apache.phoenix.iterate.ParallelScanGrouper;
+ import org.apache.phoenix.iterate.ResultIterator;
+ import org.apache.phoenix.iterate.SequenceResultIterator;
+ import org.apache.phoenix.parse.FilterableStatement;
+ import org.apache.phoenix.query.KeyRange;
+ import org.apache.phoenix.schema.TableRef;
+ import org.apache.phoenix.schema.tuple.SingleKeyValueTuple;
+ import org.apache.phoenix.schema.tuple.Tuple;
+
+ public class LiteralResultIterationPlan extends BaseQueryPlan {
+ protected final Iterator<Tuple> tupleIterator;
+
+ public LiteralResultIterationPlan(StatementContext context,
+ FilterableStatement statement, TableRef tableRef, RowProjector projection,
+ Integer limit, OrderBy orderBy, ParallelIteratorFactory parallelIteratorFactory) {
+ this(Collections.<Tuple> singletonList(new SingleKeyValueTuple(KeyValue.LOWESTKEY)).iterator(),
+ context, statement, tableRef, projection, limit, orderBy, parallelIteratorFactory);
+ }
+
+ public LiteralResultIterationPlan(Iterator<Tuple> tupleIterator, StatementContext context,
+ FilterableStatement statement, TableRef tableRef, RowProjector projection,
+ Integer limit, OrderBy orderBy, ParallelIteratorFactory parallelIteratorFactory) {
+ super(context, statement, tableRef, projection, context.getBindManager().getParameterMetaData(), limit, orderBy, GroupBy.EMPTY_GROUP_BY, parallelIteratorFactory);
+ this.tupleIterator = tupleIterator;
+ }
+
+ @Override
+ public List<KeyRange> getSplits() {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public List<List<Scan>> getScans() {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public boolean useRoundRobinIterator() throws SQLException {
+ return false;
+ }
+
+ @Override
+ protected ResultIterator newIterator(ParallelScanGrouper scanGrouper)
+ throws SQLException {
+ ResultIterator scanner = new ResultIterator() {
+ private boolean closed = false;
+ private int count = 0;
+
+ @Override
+ public void close() throws SQLException {
+ this.closed = true;;
+ }
+
+ @Override
+ public Tuple next() throws SQLException {
+ if (!this.closed
+ && (limit == null || count++ < limit)
+ && tupleIterator.hasNext()) {
+ return tupleIterator.next();
+ }
+ return null;
+ }
+
+ @Override
+ public void explain(List<String> planSteps) {
+ }
+
+ };
+
+ if (context.getSequenceManager().getSequenceCount() > 0) {
+ scanner = new SequenceResultIterator(scanner, context.getSequenceManager());
+ }
+
+ return scanner;
+ }
+
++ @Override
++ public QueryPlan limit(Integer limit) {
++ if (limit == this.limit || (limit != null && limit.equals(this.limit)))
++ return this;
++
++ return new LiteralResultIterationPlan(this.tupleIterator, this.context, this.statement, this.tableRef,
++ this.projection, limit, this.orderBy, this.parallelIteratorFactory);
++ }
++
+ }
http://git-wip-us.apache.org/repos/asf/phoenix/blob/ab97f1cc/phoenix-core/src/test/java/org/apache/phoenix/query/BaseTest.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/phoenix/blob/ab97f1cc/pom.xml
----------------------------------------------------------------------