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 2017/03/16 21:12:12 UTC
[50/50] [abbrv] phoenix git commit: Fix merge conflicts;
fix compilation errors; fix test failures
Fix merge conflicts; fix compilation errors; fix test failures
Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo
Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/db78bd6f
Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/db78bd6f
Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/db78bd6f
Branch: refs/heads/calcite
Commit: db78bd6fd9c4661c550024e35f82a2b812b548df
Parents: 5e47b46 bc814f1
Author: maryannxue <ma...@gmail.com>
Authored: Thu Mar 16 14:11:10 2017 -0700
Committer: maryannxue <ma...@gmail.com>
Committed: Thu Mar 16 14:11:10 2017 -0700
----------------------------------------------------------------------
LICENSE | 10 -
phoenix-assembly/pom.xml | 6 +-
.../src/build/components/all-common-jars.xml | 8 +
phoenix-client/pom.xml | 2 +-
phoenix-core/pom.xml | 2 +-
.../apache/phoenix/calcite/BaseCalciteIT.java | 27 +-
.../phoenix/calcite/BaseCalciteIndexIT.java | 2 +-
.../phoenix/calcite/CalciteGlobalIndexIT.java | 14 +-
.../org/apache/phoenix/calcite/CalciteIT.java | 151 +-
.../phoenix/calcite/CalciteLocalIndexIT.java | 16 +-
.../phoenix/end2end/AggregateQueryIT.java | 74 +-
.../AlterMultiTenantTableWithViewsIT.java | 25 +-
.../apache/phoenix/end2end/AlterTableIT.java | 491 +-
.../phoenix/end2end/AlterTableWithViewsIT.java | 133 +-
.../org/apache/phoenix/end2end/ArrayIT.java | 28 +
.../org/apache/phoenix/end2end/BaseJoinIT.java | 4 +-
.../org/apache/phoenix/end2end/BaseQueryIT.java | 98 +-
.../apache/phoenix/end2end/CaseStatementIT.java | 54 +-
.../apache/phoenix/end2end/CastAndCoerceIT.java | 34 +-
.../end2end/ClientTimeArithmeticQueryIT.java | 76 +-
.../end2end/ColumnEncodedBytesPropIT.java | 112 +
.../end2end/CountDistinctCompressionIT.java | 2 +-
.../apache/phoenix/end2end/CreateTableIT.java | 136 +
.../phoenix/end2end/CsvBulkLoadToolIT.java | 36 +
.../org/apache/phoenix/end2end/DateTimeIT.java | 2 +-
.../phoenix/end2end/DefaultColumnValueIT.java | 1 +
.../apache/phoenix/end2end/DerivedTableIT.java | 2 +-
.../apache/phoenix/end2end/DistinctCountIT.java | 4 +-
.../apache/phoenix/end2end/DropSchemaIT.java | 11 +
.../apache/phoenix/end2end/DynamicColumnIT.java | 63 +
.../phoenix/end2end/ExtendedQueryExecIT.java | 8 +-
.../apache/phoenix/end2end/FunkyNamesIT.java | 2 +-
.../apache/phoenix/end2end/GroupByCaseIT.java | 66 +-
.../org/apache/phoenix/end2end/GroupByIT.java | 162 +-
.../phoenix/end2end/ImmutableTablePropIT.java | 130 -
.../end2end/ImmutableTablePropertiesIT.java | 189 +
.../apache/phoenix/end2end/MutableQueryIT.java | 424 ++
.../phoenix/end2end/NativeHBaseTypesIT.java | 2 +-
.../org/apache/phoenix/end2end/NotQueryIT.java | 28 +-
.../org/apache/phoenix/end2end/OrderByIT.java | 2 -
.../apache/phoenix/end2end/PercentileIT.java | 4 +-
.../phoenix/end2end/PhoenixRuntimeIT.java | 4 +-
.../phoenix/end2end/PointInTimeQueryIT.java | 78 +-
.../phoenix/end2end/ProductMetricsIT.java | 2 +-
.../end2end/QueryDatabaseMetaDataIT.java | 16 +-
.../org/apache/phoenix/end2end/QueryIT.java | 112 +-
.../phoenix/end2end/ReadIsolationLevelIT.java | 2 +-
.../phoenix/end2end/RegexBulkLoadToolIT.java | 371 ++
.../apache/phoenix/end2end/RenewLeaseIT.java | 7 +-
.../phoenix/end2end/RowValueConstructorIT.java | 36 +-
.../org/apache/phoenix/end2end/ScanQueryIT.java | 93 +-
.../phoenix/end2end/StatsCollectorIT.java | 124 +-
.../apache/phoenix/end2end/StoreNullsIT.java | 310 +-
.../phoenix/end2end/StoreNullsPropIT.java | 51 +
...SysTableNamespaceMappedStatsCollectorIT.java | 4 +-
.../java/org/apache/phoenix/end2end/TopNIT.java | 6 +-
.../phoenix/end2end/UpperLowerFunctionIT.java | 119 +
.../apache/phoenix/end2end/UpsertSelectIT.java | 10 +-
.../apache/phoenix/end2end/UpsertValuesIT.java | 51 +-
.../phoenix/end2end/UserDefinedFunctionsIT.java | 3 +-
.../phoenix/end2end/VariableLengthPKIT.java | 38 +-
.../phoenix/end2end/index/DropColumnIT.java | 517 ++
.../phoenix/end2end/index/DropMetadataIT.java | 215 -
.../phoenix/end2end/index/ImmutableIndexIT.java | 20 +-
.../end2end/index/IndexExpressionIT.java | 28 +-
.../apache/phoenix/end2end/index/IndexIT.java | 58 +-
.../phoenix/end2end/index/IndexTestUtil.java | 11 +-
.../phoenix/end2end/index/LocalIndexIT.java | 79 +
.../end2end/index/MutableIndexFailureIT.java | 2 +
.../phoenix/end2end/index/MutableIndexIT.java | 96 +-
.../phoenix/end2end/salted/SaltedTableIT.java | 2 +-
.../EndToEndCoveredColumnsIndexBuilderIT.java | 2 +-
.../iterate/RenewLeaseOnlyTableIterator.java | 17 +-
.../phoenix/monitoring/PhoenixMetricsIT.java | 39 +-
.../SystemCatalogWALEntryFilterIT.java | 185 +
.../phoenix/trace/PhoenixTracingEndToEndIT.java | 6 +-
.../phoenix/tx/ParameterizedTransactionIT.java | 518 ++
.../org/apache/phoenix/tx/TransactionIT.java | 589 +-
.../org/apache/phoenix/tx/TxCheckpointIT.java | 42 +-
.../calcite/jdbc/PhoenixCalciteFactory.java | 28 -
.../DataTableLocalIndexRegionScanner.java | 86 +
.../IndexHalfStoreFileReaderGenerator.java | 72 +-
.../regionserver/wal/IndexedWALEditCodec.java | 20 +-
.../apache/phoenix/cache/ServerCacheClient.java | 2 +
.../org/apache/phoenix/cache/TenantCache.java | 2 +-
.../apache/phoenix/cache/TenantCacheImpl.java | 4 +-
.../apache/phoenix/calcite/PhoenixSchema.java | 2 +-
.../apache/phoenix/calcite/TableMapping.java | 21 +-
.../calcite/rel/PhoenixRelImplementorImpl.java | 10 +-
.../phoenix/calcite/rel/PhoenixTableModify.java | 10 +-
.../phoenix/calcite/rel/PhoenixTableScan.java | 2 +-
.../phoenix/compile/CreateTableCompiler.java | 10 +-
.../apache/phoenix/compile/DeleteCompiler.java | 2 +-
.../phoenix/compile/ExpressionCompiler.java | 18 +-
.../apache/phoenix/compile/FromCompiler.java | 54 +-
.../apache/phoenix/compile/JoinCompiler.java | 15 +-
.../phoenix/compile/ListJarsQueryPlan.java | 6 +-
.../apache/phoenix/compile/PostDDLCompiler.java | 11 +-
.../compile/PostLocalIndexDDLCompiler.java | 9 +-
.../phoenix/compile/ProjectionCompiler.java | 35 +-
.../apache/phoenix/compile/TraceQueryPlan.java | 4 +-
.../compile/TupleProjectionCompiler.java | 43 +-
.../apache/phoenix/compile/UnionCompiler.java | 7 +-
.../apache/phoenix/compile/UpsertCompiler.java | 32 +-
.../apache/phoenix/compile/WhereCompiler.java | 24 +-
.../coprocessor/BaseScannerRegionObserver.java | 54 +-
.../GroupedAggregateRegionObserver.java | 42 +-
.../coprocessor/HashJoinRegionScanner.java | 25 +-
.../coprocessor/MetaDataEndpointImpl.java | 273 +-
.../phoenix/coprocessor/MetaDataProtocol.java | 6 +-
.../coprocessor/MetaDataRegionObserver.java | 34 +-
.../phoenix/coprocessor/ScanRegionObserver.java | 33 +-
.../coprocessor/ServerCachingEndpointImpl.java | 2 +-
.../coprocessor/ServerCachingProtocol.java | 2 +-
.../UngroupedAggregateRegionObserver.java | 147 +-
.../coprocessor/generated/PTableProtos.java | 1474 ++++-
.../generated/ServerCachingProtos.java | 5125 +++++++++++++++++-
.../phoenix/exception/SQLExceptionCode.java | 9 +-
.../apache/phoenix/execute/BaseQueryPlan.java | 27 +-
.../apache/phoenix/execute/CorrelatePlan.java | 2 +-
.../apache/phoenix/execute/MutationState.java | 16 +-
.../phoenix/execute/SortMergeJoinPlan.java | 2 +-
.../apache/phoenix/execute/TupleProjector.java | 72 +-
.../apache/phoenix/execute/UnnestArrayPlan.java | 3 +-
.../expression/ArrayConstructorExpression.java | 82 +-
.../phoenix/expression/CoerceExpression.java | 7 +-
.../phoenix/expression/ExpressionType.java | 5 +-
.../expression/KeyValueColumnExpression.java | 32 +-
.../phoenix/expression/LiteralExpression.java | 11 +-
.../expression/ProjectedColumnExpression.java | 1 +
.../expression/SingleCellColumnExpression.java | 182 +
.../SingleCellConstructorExpression.java | 102 +
.../function/ArrayElemRefExpression.java | 4 +-
.../expression/function/ArrayIndexFunction.java | 4 +-
.../expression/util/regex/JONIPattern.java | 18 +-
.../visitor/BaseExpressionVisitor.java | 6 +
.../visitor/CloneExpressionVisitor.java | 12 +
.../CloneNonDeterministicExpressionVisitor.java | 1 +
.../expression/visitor/ExpressionVisitor.java | 6 +
.../StatelessTraverseAllExpressionVisitor.java | 12 +
.../StatelessTraverseNoExpressionVisitor.java | 12 +
.../phoenix/filter/ColumnProjectionFilter.java | 24 +-
...EncodedQualifiersColumnProjectionFilter.java | 151 +
.../MultiEncodedCQKeyValueComparisonFilter.java | 369 ++
.../filter/MultiKeyValueComparisonFilter.java | 6 +-
.../SingleCQKeyValueComparisonFilter.java | 3 +-
.../filter/SingleKeyValueComparisonFilter.java | 4 +-
.../apache/phoenix/filter/SkipScanFilter.java | 15 +-
.../org/apache/phoenix/hbase/index/Indexer.java | 7 +-
.../apache/phoenix/hbase/index/ValueGetter.java | 1 +
.../hbase/index/covered/LocalTableState.java | 14 +-
.../phoenix/hbase/index/covered/TableState.java | 4 +-
.../example/CoveredColumnIndexCodec.java | 4 +-
.../hbase/index/scanner/ScannerBuilder.java | 8 +-
.../hbase/index/util/IndexManagementUtil.java | 2 +-
.../hbase/index/util/KeyValueBuilder.java | 1 +
.../apache/phoenix/index/IndexMaintainer.java | 538 +-
.../phoenix/index/IndexMetaDataCacheClient.java | 1 +
.../index/IndexMetaDataCacheFactory.java | 4 +-
.../phoenix/index/PhoenixIndexBuilder.java | 2 +-
.../apache/phoenix/index/PhoenixIndexCodec.java | 26 +-
.../index/PhoenixIndexFailurePolicy.java | 2 +-
.../phoenix/index/PhoenixIndexMetaData.java | 9 +-
.../index/PhoenixTransactionalIndexer.java | 18 +-
.../phoenix/iterate/BaseResultIterators.java | 111 +-
.../iterate/LookAheadResultIterator.java | 2 +-
.../phoenix/iterate/MappedByteBufferQueue.java | 1 +
.../phoenix/iterate/OrderedResultIterator.java | 3 +-
.../iterate/RegionScannerResultIterator.java | 19 +-
.../phoenix/iterate/TableResultIterator.java | 186 +-
.../apache/phoenix/jdbc/PhoenixConnection.java | 2 +
.../phoenix/jdbc/PhoenixDatabaseMetaData.java | 14 +-
.../org/apache/phoenix/jdbc/PhoenixDriver.java | 3 -
.../phoenix/jdbc/PhoenixEmbeddedDriver.java | 39 +-
.../apache/phoenix/jdbc/PhoenixResultSet.java | 2 +-
.../apache/phoenix/join/HashCacheFactory.java | 2 +-
.../phoenix/mapreduce/AbstractBulkLoadTool.java | 2 +-
.../mapreduce/FormatToBytesWritableMapper.java | 54 +-
.../mapreduce/FormatToKeyValueReducer.java | 58 +-
.../mapreduce/MultiHfileOutputFormat.java | 2 +-
.../phoenix/mapreduce/PhoenixInputFormat.java | 69 +-
.../phoenix/mapreduce/PhoenixInputSplit.java | 23 +-
.../phoenix/mapreduce/RegexBulkLoadTool.java | 74 +
.../mapreduce/RegexToKeyValueMapper.java | 135 +
.../phoenix/mapreduce/index/IndexTool.java | 12 +-
.../index/PhoenixIndexPartialBuildMapper.java | 4 +-
.../util/PhoenixConfigurationUtil.java | 11 +
.../phoenix/monitoring/GlobalClientMetrics.java | 8 +-
.../apache/phoenix/monitoring/MetricType.java | 5 +-
.../query/ConnectionQueryServicesImpl.java | 184 +-
.../query/ConnectionlessQueryServicesImpl.java | 1 -
.../java/org/apache/phoenix/query/KeyRange.java | 72 +-
.../apache/phoenix/query/QueryConstants.java | 59 +-
.../org/apache/phoenix/query/QueryServices.java | 12 +-
.../phoenix/query/QueryServicesOptions.java | 10 +-
.../SystemCatalogWALEntryFilter.java | 69 +
.../org/apache/phoenix/schema/ColumnRef.java | 16 +-
.../phoenix/schema/ColumnValueDecoder.java | 31 +
.../phoenix/schema/ColumnValueEncoder.java | 45 +
.../apache/phoenix/schema/DelegateColumn.java | 4 +
.../apache/phoenix/schema/DelegateTable.java | 24 +-
.../apache/phoenix/schema/MetaDataClient.java | 594 +-
.../java/org/apache/phoenix/schema/PColumn.java | 4 +-
.../apache/phoenix/schema/PColumnFamily.java | 14 +-
.../phoenix/schema/PColumnFamilyImpl.java | 49 +-
.../org/apache/phoenix/schema/PColumnImpl.java | 29 +-
.../apache/phoenix/schema/PMetaDataImpl.java | 4 +-
.../java/org/apache/phoenix/schema/PTable.java | 435 +-
.../org/apache/phoenix/schema/PTableImpl.java | 480 +-
.../org/apache/phoenix/schema/PTableKey.java | 6 +-
.../apache/phoenix/schema/ProjectedColumn.java | 12 +-
.../org/apache/phoenix/schema/RowKeySchema.java | 10 +-
.../org/apache/phoenix/schema/SaltingUtil.java | 2 +-
.../apache/phoenix/schema/TableProperty.java | 42 +
.../apache/phoenix/schema/tuple/BaseTuple.java | 39 +
.../phoenix/schema/tuple/DelegateTuple.java | 7 +
.../tuple/EncodedColumnQualiferCellsList.java | 581 ++
.../schema/tuple/MultiKeyValueTuple.java | 1 +
.../tuple/PositionBasedMultiKeyValueTuple.java | 90 +
.../schema/tuple/PositionBasedResultTuple.java | 125 +
.../phoenix/schema/tuple/ResultTuple.java | 20 +-
.../org/apache/phoenix/schema/tuple/Tuple.java | 4 +
.../phoenix/schema/types/PArrayDataType.java | 340 +-
.../schema/types/PArrayDataTypeDecoder.java | 102 +
.../schema/types/PArrayDataTypeEncoder.java | 170 +
.../apache/phoenix/util/EncodedColumnsUtil.java | 205 +
.../java/org/apache/phoenix/util/IndexUtil.java | 105 +-
.../org/apache/phoenix/util/KeyValueUtil.java | 2 -
.../org/apache/phoenix/util/MetaDataUtil.java | 10 +
.../org/apache/phoenix/util/PhoenixRuntime.java | 12 +-
.../org/apache/phoenix/util/RepairUtil.java | 40 +
.../org/apache/phoenix/util/ResultUtil.java | 60 -
.../java/org/apache/phoenix/util/ScanUtil.java | 29 +-
.../org/apache/phoenix/util/SchemaUtil.java | 31 +-
.../phoenix/util/regex/RegexUpsertExecutor.java | 80 +
.../wal/IndexedWALEditCodecTest.java | 32 +
.../apache/phoenix/cache/TenantCacheTest.java | 6 +-
.../phoenix/compile/HavingCompilerTest.java | 2 +-
.../phoenix/compile/QueryCompilerTest.java | 70 +-
.../phoenix/compile/QueryOptimizerTest.java | 51 +
.../compile/SelectStatementRewriterTest.java | 11 +-
.../phoenix/compile/WhereCompilerTest.java | 44 +-
.../phoenix/execute/CorrelatePlanTest.java | 12 +-
.../execute/LiteralResultIteratorPlanTest.java | 12 +-
.../phoenix/execute/MutationStateTest.java | 4 +-
.../phoenix/execute/UnnestArrayPlanTest.java | 8 +-
.../ArrayConstructorExpressionTest.java | 20 +-
.../expression/ColumnExpressionTest.java | 27 +-
.../phoenix/filter/SkipScanFilterTest.java | 229 +-
.../index/covered/TestLocalTableState.java | 10 +-
.../phoenix/index/IndexMaintainerTest.java | 7 +-
.../iterate/AggregateResultScannerTest.java | 2 +-
.../phoenix/jdbc/PhoenixEmbeddedDriverTest.java | 14 +
.../phoenix/jdbc/SecureUserConnectionsTest.java | 66 +-
.../query/BaseConnectionlessQueryTest.java | 18 +-
.../java/org/apache/phoenix/query/BaseTest.java | 61 +-
.../phoenix/query/ConnectionlessTest.java | 18 +-
.../EncodedColumnQualifierCellsListTest.java | 608 +++
.../apache/phoenix/query/KeyRangeMoreTest.java | 263 +
.../phoenix/query/ScannerLeaseRenewalTest.java | 21 +-
.../schema/ImmutableStorageSchemeTest.java | 182 +
.../schema/types/PDataTypeForArraysTest.java | 38 +-
.../apache/phoenix/util/PhoenixRuntimeTest.java | 7 +-
.../util/QualifierEncodingSchemeTest.java | 119 +
.../java/org/apache/phoenix/util/TestUtil.java | 89 +-
phoenix-flume/pom.xml | 12 +-
.../phoenix/flume/CsvEventSerializerIT.java | 416 ++
.../org/apache/phoenix/flume/PhoenixSinkIT.java | 2 +-
.../apache/phoenix/flume/FlumeConstants.java | 14 +-
.../flume/serializer/CsvEventSerializer.java | 196 +
.../flume/serializer/EventSerializers.java | 4 +-
phoenix-hive/pom.xml | 15 +-
.../phoenix/hive/BaseHivePhoenixStoreIT.java | 165 +
.../apache/phoenix/hive/HiveMapReduceIT.java | 34 +
.../apache/phoenix/hive/HivePhoenixStoreIT.java | 330 +-
.../org/apache/phoenix/hive/HiveTestUtil.java | 22 +-
.../java/org/apache/phoenix/hive/HiveTezIT.java | 34 +
.../apache/phoenix/hive/PhoenixMetaHook.java | 37 +-
.../org/apache/phoenix/hive/PhoenixSerDe.java | 9 +-
.../apache/phoenix/hive/PhoenixSerializer.java | 4 +
.../phoenix/hive/PhoenixStorageHandler.java | 5 +
.../hive/mapreduce/PhoenixInputFormat.java | 56 +-
.../hive/mapreduce/PhoenixRecordReader.java | 1 +
.../hive/mapreduce/PhoenixResultWritable.java | 12 +-
.../phoenix/hive/query/PhoenixQueryBuilder.java | 370 +-
.../phoenix/hive/util/ColumnMappingUtils.java | 76 +
.../hive/util/PhoenixConnectionUtil.java | 19 +
.../hive/util/PhoenixStorageHandlerUtil.java | 46 +-
.../hive/query/PhoenixQueryBuilderTest.java | 97 +-
phoenix-kafka/pom.xml | 435 ++
.../apache/phoenix/kafka/PhoenixConsumerIT.java | 276 +
phoenix-kafka/src/it/resources/consumer.props | 32 +
phoenix-kafka/src/it/resources/producer.props | 24 +
.../apache/phoenix/kafka/KafkaConstants.java | 52 +
.../phoenix/kafka/consumer/PhoenixConsumer.java | 276 +
.../kafka/consumer/PhoenixConsumerTool.java | 107 +
phoenix-pherf/pom.xml | 2 +-
phoenix-pig/pom.xml | 2 +-
phoenix-protocol/src/main/PTable.proto | 9 +
.../src/main/ServerCachingService.proto | 35 +
phoenix-queryserver-client/pom.xml | 2 +-
.../queryserver/client/SqllineWrapper.java | 18 +-
phoenix-queryserver/pom.xml | 2 +-
.../phoenix/queryserver/server/QueryServer.java | 5 +-
phoenix-server/pom.xml | 2 +-
phoenix-spark/pom.xml | 2 +-
.../org/apache/phoenix/spark/PhoenixRDD.scala | 4 +
phoenix-tracing-webapp/pom.xml | 2 +-
pom.xml | 13 +-
309 files changed, 22228 insertions(+), 4292 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/phoenix/blob/db78bd6f/phoenix-core/pom.xml
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/phoenix/blob/db78bd6f/phoenix-core/src/it/java/org/apache/phoenix/calcite/BaseCalciteIT.java
----------------------------------------------------------------------
diff --cc phoenix-core/src/it/java/org/apache/phoenix/calcite/BaseCalciteIT.java
index 4c89f8d,0000000..e8f6cd6
mode 100644,000000..100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/calcite/BaseCalciteIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/calcite/BaseCalciteIT.java
@@@ -1,758 -1,0 +1,777 @@@
+/*
+ * 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.calcite;
+
+import static org.apache.phoenix.util.PhoenixRuntime.PHOENIX_TEST_DRIVER_URL_PARAM;
+import static org.apache.phoenix.util.TestUtil.TEST_PROPERTIES;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.PrintWriter;
+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.sql.Statement;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.text.DecimalFormat;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.calcite.avatica.util.ArrayImpl;
+import org.apache.calcite.config.CalciteConnectionProperty;
+import org.apache.phoenix.calcite.rel.PhoenixRel;
+import org.apache.phoenix.end2end.BaseHBaseManagedTimeIT;
+import org.apache.phoenix.end2end.BaseJoinIT;
+import org.apache.phoenix.query.QueryServices;
+import org.apache.phoenix.schema.TableAlreadyExistsException;
+import org.apache.phoenix.util.PhoenixRuntime;
+import org.apache.phoenix.util.PropertiesUtil;
+import org.apache.phoenix.util.QueryUtil;
+import org.apache.phoenix.util.ReadOnlyProps;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
+public class BaseCalciteIT extends BaseHBaseManagedTimeIT {
+
+ @BeforeClass
+ public static void doSetup() throws Exception {
+ Map<String,String> props = Maps.newHashMapWithExpectedSize(5);
+ props.put(QueryServices.STATS_USE_CURRENT_TIME_ATTRIB, Boolean.FALSE.toString());
+ props.put(QueryServices.RUN_UPDATE_STATS_ASYNC, Boolean.FALSE.toString());
+ props.put(QueryServices.STATS_GUIDEPOST_WIDTH_BYTES_ATTRIB, Long.toString(1000));
+ props.put(QueryServices.THREAD_POOL_SIZE_ATTRIB, Integer.toString(200));
+ setUpTestDriver(new ReadOnlyProps(props.entrySet().iterator()));
+ }
+
+ public static Start start(boolean materializationEnabled, float rowCountFactor) {
+ return new Start(getConnectionProps(materializationEnabled, rowCountFactor));
+ }
+
+ public static Start start(Properties props) {
+ return new Start(props);
+ }
+
+ public static Start startPhoenixStandalone(Properties props) {
+ return new Start(props) {
+ Connection createConnection() throws Exception {
+ return DriverManager.getConnection(
+ getOldUrl(),
+ props);
+ }
+
+ String getExplainPlanString() {
+ return "explain";
+ }
+ };
+ }
+
+ public static class Start {
+ protected final Properties props;
+ private Connection connection;
+
+ Start(Properties props) {
+ this.props = props;
+ }
+
+ Connection createConnection() throws Exception {
+ // FIXME Cannot get correct stats with 'test=true' property
+ final String testProp = PhoenixRuntime.JDBC_PROTOCOL_TERMINATOR + PHOENIX_TEST_DRIVER_URL_PARAM;
+ final String url = getUrl().replaceAll(testProp, "");
+ return DriverManager.getConnection(url, props);
+ }
+
+ String getExplainPlanString() {
+ return "explain plan for";
+ }
+
+ public Sql sql(String sql) {
+ return new Sql(this, sql);
+ }
+
+ public Connection getConnection() {
+ if (connection == null) {
+ try {
+ connection = createConnection();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ return connection;
+ }
+
+ public void commit() {
+ if (connection != null) {
+ try {
+ connection.commit();
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ public void close() {
+ if (connection != null) {
+ try {
+ connection.commit();
+ connection.close();
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ }
+
+ /** Fluid class for a test that has specified a SQL query. */
+ static class Sql {
+ private final Start start;
+ private final String sql;
+
+ public Sql(Start start, String sql) {
+ this.start = start;
+ this.sql = sql;
+ }
+
+ private static void populateResult(ResultSet resultSet, List<Object[]> list) throws SQLException {
+ final int columnCount = resultSet.getMetaData().getColumnCount();
+ while (resultSet.next()) {
+ Object[] row = new Object[columnCount];
+ for (int i = 0; i < columnCount; i++) {
+ row[i] = resultSet.getObject(i + 1);
+ }
+ list.add(row);
+ }
+ }
+
+ public Sql explainIs(String expected) throws SQLException {
- return checkExplain(expected, true);
++ return checkExplain(expected, false);
+ }
+
+ public Sql explainMatches(String expected) throws SQLException {
- return checkExplain(expected, false);
++ return checkExplain(expected, true);
+ }
+
- private Sql checkExplain(String expected, boolean exact) throws SQLException {
++ private Sql checkExplain(String expected, boolean regex) throws SQLException {
+ final Statement statement = start.getConnection().createStatement();
+ final ResultSet resultSet = statement.executeQuery(start.getExplainPlanString() + " " + sql);
+ String explain = QueryUtil.getExplainPlan(resultSet);
+ resultSet.close();
+ statement.close();
- if (exact) {
++ if (!regex) {
+ Assert.assertEquals(explain, expected);
+ } else {
+ Assert.assertTrue(
+ "Explain plan \"" + explain
+ + "\" does not match \"" + expected + "\"",
+ explain.matches(expected));
+ }
+ return this;
+ }
+
++ public Sql explainIsAny(List<String> expected, boolean regex) throws SQLException {
++ final Statement statement = start.getConnection().createStatement();
++ final ResultSet resultSet = statement.executeQuery(start.getExplainPlanString() + " " + sql);
++ String explain = QueryUtil.getExplainPlan(resultSet);
++ resultSet.close();
++ statement.close();
++ boolean match = false;
++ for (String s : expected) {
++ if ((!regex && explain.equals(s))
++ || (regex && explain.matches(s))) {
++ match = true;
++ }
++ }
++ if (!match) {
++ Assert.fail(explain + " did not match any of the expected plans: " + expected);
++ }
++ return this;
++ }
++
+ public List<Object[]> getResult() throws SQLException {
+ final Statement statement = start.getConnection().createStatement();
+ final ResultSet resultSet = statement.executeQuery(sql);
+ final List<Object[]> list = Lists.newArrayList();
+ populateResult(resultSet, list);
+ resultSet.close();
+ statement.close();
+ return list;
+ }
+
+ public Sql execute() throws SQLException {
+ final Statement statement = start.getConnection().createStatement();
+ statement.execute(sql);
+ statement.close();
+ return this;
+ }
+
+ public Sql executeUpdate() throws SQLException {
+ final Statement statement = start.getConnection().createStatement();
+ statement.executeUpdate(sql);
+ statement.close();
+ return this;
+ }
+
+ public PreparedStatement prepareStatement() throws SQLException {
+ return start.getConnection().prepareStatement(sql);
+ }
+
+ public void commit() {
+ start.commit();
+ }
+
+ public void close() {
+ start.close();
+ }
+
+ public Sql resultIs(Object[][] expected) throws SQLException {
+ final Statement statement = start.getConnection().createStatement();
+ final ResultSet resultSet = statement.executeQuery(sql);
+ checkResultOrdered(resultSet, expected);
+ resultSet.close();
+ statement.close();
+ return this;
+ }
+
+ public Sql resultIs(int orderedCount, Object[][] expected) throws SQLException {
+ final Statement statement = start.getConnection().createStatement();
+ final ResultSet resultSet = statement.executeQuery(sql);
+ checkResultUnordered(resultSet, expected, orderedCount, null);
+ resultSet.close();
+ statement.close();
+ return this;
+ }
+
+ public Sql resultIsSomeOf(int count, Object[][] expected) throws SQLException {
+ final Statement statement = start.getConnection().createStatement();
+ final ResultSet resultSet = statement.executeQuery(sql);
+ checkResultUnordered(resultSet, expected, 0, count);
+ resultSet.close();
+ statement.close();
+ return this;
+ }
+
+ public Sql sameResultAsPhoenixStandalone() throws SQLException {
+ Start phoenixStart = startPhoenixStandalone(this.start.props);
+ List<Object[]> result = phoenixStart.sql(this.sql).getResult();
+ phoenixStart.close();
+ return resultIs(result.toArray(new Object[result.size()][]));
+ }
+
+ public Sql sameResultAsPhoenixStandalone(int orderedCount) throws SQLException {
+ Start phoenixStart = startPhoenixStandalone(this.start.props);
+ List<Object[]> result = phoenixStart.sql(this.sql).getResult();
+ phoenixStart.close();
+ return resultIs(orderedCount, result.toArray(new Object[result.size()][]));
+ }
+
+ private void checkResultOrdered(ResultSet resultSet, Object[][] expected) throws SQLException {
+ int expectedCount = expected.length;
+ int count = 0;
+ for (int i = 0; i < expectedCount; i++) {
+ assertTrue(
+ "Expected " + expectedCount + " rows, but got " + count + " rows.",
+ resultSet.next());
+ count++;
+ Object[] row = expected[i];
+ for (int j = 0; j < row.length; j++) {
+ Object obj = resultSet.getObject(j + 1);
+ Assert.assertEquals(canonicalize(row[j]), canonicalize(obj));
+ }
+ }
+ assertFalse("Got more rows than expected.", resultSet.next());
+ }
+
+ private void checkResultUnordered(ResultSet resultSet, Object[][] expected, int orderedCount, Integer checkContains) throws SQLException {
+ List<List<Object>> expectedResults = Lists.newArrayList();
+ List<List<Object>> actualResults = Lists.newArrayList();
+ List<List<Object>> errorResults = Lists.newArrayList();
+ int columnCount = expected.length > 0 ? expected[0].length : 0;
+ for (Object[] e : expected) {
+ List<Object> row = Lists.newArrayList();
+ for (int i = orderedCount; i < e.length; i++) {
+ row.add(canonicalize(e[i]));
+ }
+ expectedResults.add(row);
+ }
+ while (resultSet.next()) {
+ if (actualResults.size() >= expected.length) {
+ fail("Got more rows than expected after getting results: " + actualResults);
+ }
+ // check the ordered part
+ Object[] row = expected[actualResults.size()];
+ for (int i = 0; i < orderedCount; i++) {
+ Object obj = resultSet.getObject(i + 1);
+ Assert.assertEquals(canonicalize(row[i]), canonicalize(obj));
+ }
+ // check the unordered part
+ List<Object> result = Lists.newArrayList();
+ for (int i = orderedCount; i < columnCount; i++) {
+ result.add(canonicalize(resultSet.getObject(i+1)));
+ }
+ if (!expectedResults.remove(result)) {
+ errorResults.add(result);
+ }
+ actualResults.add(result);
+ }
+ boolean allContainedInExpected = errorResults.isEmpty();
+ boolean allExpectedFound = checkContains == null ? expectedResults.isEmpty() : checkContains == actualResults.size();
+ assertTrue(
+ (allContainedInExpected ? "" : "Could not find " + errorResults + " in expected results.\n") +
+ (allExpectedFound ? "" :
+ (checkContains == null
+ ? ("Count not find " + expectedResults + " in actual results: " + actualResults + ".\n")
+ : ("Expected " + checkContains + " rows, but got " + actualResults.size() + " rows."))),
+ allContainedInExpected && allExpectedFound);
+ }
+
+ private Object canonicalize(Object obj) {
+ if (obj == null) {
+ return obj;
+ }
+
+ if (obj instanceof ArrayImpl) {
+ return obj.toString();
+ }
+
+ if (obj.getClass().isArray()) {
+ final StringBuilder buf = new StringBuilder("[");
+ for (Object o : (Object[]) obj) {
+ if (buf.length() > 1) {
+ buf.append(", ");
+ }
+ String s = o.toString();
+ // Remove nano suffix
+ if (o instanceof Timestamp) {
+ s = s.substring(0, s.lastIndexOf('.'));
+ }
+ buf.append(s);
+ }
+ return buf.append("]").toString();
+ }
+
+ return obj;
+ }
+ }
+
+ private static final String FOODMART_SCHEMA = " {\n"
+ + " type: 'jdbc',\n"
+ + " name: 'foodmart',\n"
+ + " jdbcDriver: 'org.hsqldb.jdbcDriver',\n"
+ + " jdbcUser: 'FOODMART',\n"
+ + " jdbcPassword: 'FOODMART',\n"
+ + " jdbcUrl: 'jdbc:hsqldb:res:foodmart',\n"
+ + " jdbcCatalog: null,\n"
+ + " jdbcSchema: 'foodmart'\n"
+ + " }";
+
+ private static final String getPhoenixSchema() {
+ return " {\n"
+ + " name: 'phoenix',\n"
+ + " type: 'custom',\n"
+ + " factory: 'org.apache.phoenix.calcite.PhoenixSchema$Factory',\n"
+ + " operand: {\n"
+ + " url: \"" + getOldUrl() + "\"\n"
+ + " }\n"
+ + " }";
+ }
+
+ protected static Connection connectUsingModel(Properties props) throws Exception {
+ final File file = File.createTempFile("model", ".json");
+ final String url = getOldUrl();
+ final PrintWriter pw = new PrintWriter(new FileWriter(file));
+ pw.print(
+ "{\n"
+ + " version: '1.0',\n"
+ + " defaultSchema: 'HR',\n"
+ + " schemas: [\n"
+ + " {\n"
+ + " name: 'HR',\n"
+ + " type: 'custom',\n"
+ + " factory: 'org.apache.phoenix.calcite.PhoenixSchema$Factory',\n"
+ + " operand: {\n"
+ + " url: \"" + url + "\",\n"
+ + " user: \"scott\",\n"
+ + " password: \"tiger\"\n"
+ + " }\n"
+ + " }\n"
+ + " ]\n"
+ + "}\n");
+ pw.close();
+ final Connection connection =
+ DriverManager.getConnection("jdbc:phoenixcalcite:model=" + file.getAbsolutePath(), props);
+ return connection;
+ }
+
+ protected static Connection connectWithHsqldbUsingModel(Properties props) throws Exception {
+ final File file = File.createTempFile("model", ".json");
+ final PrintWriter pw = new PrintWriter(new FileWriter(file));
+ pw.print(
+ "{\n"
+ + " version: '1.0',\n"
+ + " defaultSchema: 'phoenix',\n"
+ + " schemas: [\n"
+ + getPhoenixSchema() + ",\n"
+ + FOODMART_SCHEMA + "\n"
+ + " ]\n"
+ + "}\n");
+ pw.close();
+ final Connection connection =
+ DriverManager.getConnection("jdbc:phoenixcalcite:model=" + file.getAbsolutePath(), props);
+ return connection;
+ }
+
+ protected static Properties getConnectionProps(boolean enableMaterialization, float rowCountFactor) {
+ Properties props = new Properties();
+ if (!enableMaterialization) {
+ props.setProperty(
+ CalciteConnectionProperty.MATERIALIZATIONS_ENABLED.camelName(),
+ Boolean.toString(enableMaterialization));
+ }
+ props.setProperty(
+ CalciteConnectionProperty.CREATE_MATERIALIZATIONS.camelName(),
+ Boolean.toString(false));
+ props.setProperty(PhoenixRel.ROW_COUNT_FACTOR, Float.toString(rowCountFactor));
+ return props;
+ }
+
+ protected static final String SCORES_TABLE_NAME = "scores";
+
+ protected void initJoinTableValues(String url) throws Exception {
+ Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
+ Connection conn = DriverManager.getConnection(url, props);
+ try {
+ for (String tableName : new String[] {
+ BaseJoinIT.JOIN_CUSTOMER_TABLE_FULL_NAME,
+ BaseJoinIT.JOIN_ITEM_TABLE_FULL_NAME,
+ BaseJoinIT.JOIN_ORDER_TABLE_FULL_NAME,
+ BaseJoinIT.JOIN_SUPPLIER_TABLE_FULL_NAME}) {
+ try {
+ BaseJoinIT.createTable(conn, tableName, tableName);
+ } catch (TableAlreadyExistsException e) {
+ }
+ BaseJoinIT.initValues(conn, tableName, tableName);
+ }
+ } finally {
+ conn.close();
+ }
+ }
+
+ protected void initArrayTable(String url) throws Exception {
+ Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
+ Connection conn = DriverManager.getConnection(url, props);
+ try {
+ conn.createStatement().execute(
+ "CREATE TABLE " + SCORES_TABLE_NAME
+ + "(student_id INTEGER NOT NULL, subject_id INTEGER NOT NULL, scores INTEGER[], exam_date DATE[], exam_time TIME[], exam_timestamp TIMESTAMP[] CONSTRAINT pk PRIMARY KEY (student_id, subject_id))");
+ PreparedStatement stmt = conn.prepareStatement(
+ "UPSERT INTO " + SCORES_TABLE_NAME
+ + " VALUES(?, ?, ?, ?, ?, ?)");
+ stmt.setInt(1, 1);
+ stmt.setInt(2, 1);
+ stmt.setArray(3, conn.createArrayOf("INTEGER", new Integer[] {85, 80, 82}));
+ stmt.setArray(4, conn.createArrayOf("DATE", new Date[] {Date.valueOf("2016-3-22"), Date.valueOf("2016-5-23"), Date.valueOf("2016-7-24")}));
+ stmt.setArray(5, conn.createArrayOf("TIME", new Time[] {Time.valueOf("15:30:28"), Time.valueOf("13:26:50"), Time.valueOf("16:20:00")}));
+ stmt.setArray(6, conn.createArrayOf("TIMESTAMP", new Timestamp[] {Timestamp.valueOf("2016-3-22 15:30:28"), Timestamp.valueOf("2016-5-23 13:26:50"), Timestamp.valueOf("2016-7-24 16:20:00")}));
+ stmt.execute();
+ stmt.setInt(1, 2);
+ stmt.setInt(2, 1);
+ stmt.setArray(3, null);
+ stmt.setArray(4, null);
+ stmt.setArray(5, null);
+ stmt.setArray(6, null);
+ stmt.execute();
+ stmt.setInt(1, 3);
+ stmt.setInt(2, 2);
+ stmt.setArray(3, conn.createArrayOf("INTEGER", new Integer[] {87, 88, 80}));
+ stmt.setArray(4, conn.createArrayOf("DATE", new Date[] {Date.valueOf("2016-3-22"), Date.valueOf("2016-5-23"), Date.valueOf("2016-7-24")}));
+ stmt.setArray(5, conn.createArrayOf("TIME", new Time[] {Time.valueOf("15:30:16"), Time.valueOf("13:26:52"), Time.valueOf("16:20:40")}));
+ stmt.setArray(6, conn.createArrayOf("TIMESTAMP", new Timestamp[] {Timestamp.valueOf("2016-3-22 15:30:16"), Timestamp.valueOf("2016-5-23 13:26:52"), Timestamp.valueOf("2016-7-24 16:20:40")}));
+ stmt.execute();
+ conn.commit();
+ } catch (TableAlreadyExistsException e) {
+ }
+ conn.close();
+ }
+
+ protected static final String NOSALT_TABLE_NAME = "nosalt_test_table";
+ protected static final String NOSALT_TABLE_SALTED_INDEX_NAME = "idxsalted_nosalt_test_table";
+ protected static final String SALTED_TABLE_NAME = "salted_test_table";
+ protected static final String SALTED_TABLE_NOSALT_INDEX_NAME = "idx_salted_test_table";
+ protected static final String SALTED_TABLE_SALTED_INDEX_NAME = "idxsalted_salted_test_table";
+
+ protected void initSaltedTables(String url, String index) throws SQLException {
+ Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
+ Connection conn = DriverManager.getConnection(url, props);
+ try {
+ conn.createStatement().execute(
+ "CREATE TABLE " + NOSALT_TABLE_NAME + " (mypk0 INTEGER NOT NULL, mypk1 INTEGER NOT NULL, col0 INTEGER, col1 INTEGER CONSTRAINT pk PRIMARY KEY (mypk0, mypk1))");
+ PreparedStatement stmt = conn.prepareStatement(
+ "UPSERT INTO " + NOSALT_TABLE_NAME
+ + " VALUES(?, ?, ?, ?)");
+ for (int i = 0; i < 1000; i++) {
+ stmt.setInt(1, i + 1);
+ stmt.setInt(2, i + 2);
+ stmt.setInt(3, i + 3);
+ stmt.setInt(4, i + 4);
+ stmt.execute();
+ }
+ conn.commit();
+
+ if (index != null) {
+ conn.createStatement().execute(
+ "CREATE " + index + " " + NOSALT_TABLE_SALTED_INDEX_NAME + " ON " + NOSALT_TABLE_NAME + " (col0)"
+ + (index.toUpperCase().startsWith("LOCAL") ? "" : " SALT_BUCKETS=4"));
+ conn.commit();
+ }
+
+ conn.createStatement().execute(
+ "CREATE TABLE " + SALTED_TABLE_NAME + " (mypk0 INTEGER NOT NULL, mypk1 INTEGER NOT NULL, col0 INTEGER, col1 INTEGER CONSTRAINT pk PRIMARY KEY (mypk0, mypk1)) SALT_BUCKETS=4");
+ stmt = conn.prepareStatement(
+ "UPSERT INTO " + SALTED_TABLE_NAME
+ + " VALUES(?, ?, ?, ?)");
+ for (int i = 0; i < 1000; i++) {
+ stmt.setInt(1, i + 1);
+ stmt.setInt(2, i + 2);
+ stmt.setInt(3, i + 3);
+ stmt.setInt(4, i + 4);
+ stmt.execute();
+ }
+ conn.commit();
+
+ if (index != null) {
+ conn.createStatement().execute("CREATE " + index + " " + SALTED_TABLE_NOSALT_INDEX_NAME + " ON " + SALTED_TABLE_NAME + " (col0)");
+ conn.createStatement().execute(
+ "CREATE " + index + " " + SALTED_TABLE_SALTED_INDEX_NAME + " ON " + SALTED_TABLE_NAME + " (col1) INCLUDE (col0)"
+ + (index.toUpperCase().startsWith("LOCAL") ? "" : " SALT_BUCKETS=4"));
+ conn.commit();
+ }
+ } catch (TableAlreadyExistsException e) {
+ }
+ conn.close();
+ }
+
+ protected static final String KEY_ORDERING_TABLE_1_NAME = "key_ordering_test_table_1";
+ protected static final String KEY_ORDERING_TABLE_2_NAME = "key_ordering_test_table_2";
+
+ protected void initKeyOrderingTable(String url) throws Exception {
+ Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
+ Connection conn = DriverManager.getConnection(url, props);
+ try {
+ conn.createStatement().execute(
+ "CREATE TABLE " + KEY_ORDERING_TABLE_1_NAME
+ + "(k0 BIGINT NOT NULL, k1 INTEGER NOT NULL, v0 INTEGER, v1 BIGINT CONSTRAINT pk PRIMARY KEY (k0 DESC, k1))");
+ conn.createStatement().execute(
+ "CREATE TABLE " + KEY_ORDERING_TABLE_2_NAME
+ + "(k0 BIGINT NOT NULL, k1 BIGINT NOT NULL, v0 INTEGER, v1 BIGINT CONSTRAINT pk PRIMARY KEY (k0 DESC, k1 DESC))");
+ PreparedStatement stmt = conn.prepareStatement(
+ "UPSERT INTO " + KEY_ORDERING_TABLE_1_NAME
+ + " VALUES(?, ?, ?, ?)");
+ stmt.setInt(1, 1);
+ stmt.setInt(2, 2);
+ stmt.setInt(3, 1);
+ stmt.setInt(4, 2);
+ stmt.execute();
+ stmt.setInt(1, 1);
+ stmt.setInt(2, 3);
+ stmt.setInt(3, 1);
+ stmt.setInt(4, 3);
+ stmt.execute();
+ stmt.setInt(1, 1);
+ stmt.setInt(2, 4);
+ stmt.setInt(3, 1);
+ stmt.setInt(4, 4);
+ stmt.execute();
+ stmt.setInt(1, 1);
+ stmt.setInt(2, 5);
+ stmt.setInt(3, 1);
+ stmt.setInt(4, 5);
+ stmt.execute();
+ stmt.setInt(1, 2);
+ stmt.setInt(2, 3);
+ stmt.setInt(3, 2);
+ stmt.setInt(4, 3);
+ stmt.execute();
+ stmt.setInt(1, 2);
+ stmt.setInt(2, 5);
+ stmt.setInt(3, 2);
+ stmt.setInt(4, 5);
+ stmt.execute();
+ stmt.setInt(1, 3);
+ stmt.setInt(2, 2);
+ stmt.setInt(3, 3);
+ stmt.setInt(4, 2);
+ stmt.execute();
+ stmt.setInt(1, 5);
+ stmt.setInt(2, 2);
+ stmt.setInt(3, 5);
+ stmt.setInt(4, 2);
+ stmt.execute();
+ stmt.setInt(1, 5);
+ stmt.setInt(2, 5);
+ stmt.setInt(3, 5);
+ stmt.setInt(4, 5);
+ stmt.execute();
+ conn.commit();
+ stmt = conn.prepareStatement(
+ "UPSERT INTO " + KEY_ORDERING_TABLE_2_NAME
+ + " VALUES(?, ?, ?, ?)");
+ stmt.setInt(1, 1);
+ stmt.setInt(2, 2);
+ stmt.setInt(3, 1);
+ stmt.setInt(4, 2);
+ stmt.execute();
+ stmt.setInt(1, 1);
+ stmt.setInt(2, 5);
+ stmt.setInt(3, 1);
+ stmt.setInt(4, 5);
+ stmt.execute();
+ stmt.setInt(1, 2);
+ stmt.setInt(2, 2);
+ stmt.setInt(3, 2);
+ stmt.setInt(4, 2);
+ stmt.execute();
+ stmt.setInt(1, 2);
+ stmt.setInt(2, 3);
+ stmt.setInt(3, 2);
+ stmt.setInt(4, 3);
+ stmt.execute();
+ stmt.setInt(1, 2);
+ stmt.setInt(2, 4);
+ stmt.setInt(3, 2);
+ stmt.setInt(4, 4);
+ stmt.execute();
+ stmt.setInt(1, 2);
+ stmt.setInt(2, 5);
+ stmt.setInt(3, 2);
+ stmt.setInt(4, 5);
+ stmt.execute();
+ stmt.setInt(1, 4);
+ stmt.setInt(2, 3);
+ stmt.setInt(3, 4);
+ stmt.setInt(4, 3);
+ stmt.execute();
+ stmt.setInt(1, 5);
+ stmt.setInt(2, 4);
+ stmt.setInt(3, 5);
+ stmt.setInt(4, 4);
+ stmt.execute();
+ stmt.setInt(1, 5);
+ stmt.setInt(2, 5);
+ stmt.setInt(3, 5);
+ stmt.setInt(4, 5);
+ stmt.execute();
+ conn.commit();
+ } catch (TableAlreadyExistsException e) {
+ }
+ conn.close();
+ }
+
+ protected static final String MULTI_TENANT_TABLE = "multitenant_test_table";
+ protected static final String MULTI_TENANT_TABLE_INDEX = "idx_multitenant_test_table";
+ protected static final String MULTI_TENANT_VIEW1 = "s1.multitenant_test_view1";
+ protected static final String MULTI_TENANT_VIEW1_INDEX = "idx_multitenant_test_view1";
+ protected static final String MULTI_TENANT_VIEW2 = "s2.multitenant_test_view2";
+ protected static final String MULTI_TENANT_VIEW2_INDEX = "idx_multitenant_test_view2";
+
+ protected void initMultiTenantTables(String url, String index) throws SQLException {
+ Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
+ Connection conn = DriverManager.getConnection(url, props);
+ try {
+ conn.createStatement().execute(
+ "CREATE TABLE " + MULTI_TENANT_TABLE + " (tenant_id VARCHAR NOT NULL, id VARCHAR NOT NULL, col0 INTEGER, col1 INTEGER, col2 INTEGER CONSTRAINT pk PRIMARY KEY (tenant_id, id)) MULTI_TENANT=true");
+ PreparedStatement stmt = conn.prepareStatement(
+ "UPSERT INTO " + MULTI_TENANT_TABLE
+ + " VALUES(?, ?, ?, ?, ?)");
+ DecimalFormat formatter = new DecimalFormat("0000");
+ for (int i = 0; i < 1000; i++) {
+ stmt.setString(1, "10");
+ stmt.setString(2, formatter.format(2 + i));
+ stmt.setInt(3, 3 + i);
+ stmt.setInt(4, 4 + i);
+ stmt.setInt(5, 5 + i);
+ stmt.execute();
+ }
+ for (int i = 0; i < 1000; i++) {
+ stmt.setString(1, "15");
+ stmt.setString(2, formatter.format(3 + i));
+ stmt.setInt(3, 4 + i);
+ stmt.setInt(4, 5 + i);
+ stmt.setInt(5, 6 + i);
+ stmt.execute();
+ }
+ for (int i = 0; i < 1000; i++) {
+ stmt.setString(1, "20");
+ stmt.setString(2, formatter.format(4 + i));
+ stmt.setInt(3, 5 + i);
+ stmt.setInt(4, 6 + i);
+ stmt.setInt(5, 7 + i);
+ stmt.execute();
+ }
+ conn.commit();
+
+ if (index != null) {
+ conn.createStatement().execute(
+ "CREATE " + index + " " + MULTI_TENANT_TABLE_INDEX
+ + " ON " + MULTI_TENANT_TABLE + "(col1) INCLUDE (col0, col2)");
+ conn.commit();
+ }
+
+ conn.close();
+ props.setProperty("TenantId", "10");
+ conn = DriverManager.getConnection(getOldUrl(), props);
+ conn.createStatement().execute("CREATE VIEW " + MULTI_TENANT_VIEW1
+ + " AS select * from " + MULTI_TENANT_TABLE);
+ conn.commit();
+
+ if (index != null) {
+ conn.createStatement().execute(
+ "CREATE " + index + " " + MULTI_TENANT_VIEW1_INDEX
+ + " ON " + MULTI_TENANT_VIEW1 + "(col0)");
+ conn.commit();
+ }
+
+ conn.close();
+ props.setProperty("TenantId", "20");
+ conn = DriverManager.getConnection(getOldUrl(), props);
+ conn.createStatement().execute("CREATE VIEW " + MULTI_TENANT_VIEW2
+ + " AS select * from " + MULTI_TENANT_TABLE + " where col2 > 7");
+ conn.commit();
+
+ if (index != null) {
+ conn.createStatement().execute(
+ "CREATE " + index + " " + MULTI_TENANT_VIEW2_INDEX
+ + " ON " + MULTI_TENANT_VIEW2 + "(col0)");
+ conn.commit();
+ }
+ } catch (TableAlreadyExistsException e) {
+ } finally {
+ conn.close();
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/db78bd6f/phoenix-core/src/it/java/org/apache/phoenix/calcite/BaseCalciteIndexIT.java
----------------------------------------------------------------------
diff --cc phoenix-core/src/it/java/org/apache/phoenix/calcite/BaseCalciteIndexIT.java
index b7e5955,0000000..bef3335
mode 100644,000000..100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/calcite/BaseCalciteIndexIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/calcite/BaseCalciteIndexIT.java
@@@ -1,64 -1,0 +1,64 @@@
+/*
+ * 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.calcite;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.util.Properties;
+
+import org.apache.phoenix.util.TestUtil;
+import org.junit.Before;
+
+public class BaseCalciteIndexIT extends BaseCalciteIT {
+
+ private final boolean localIndex;
+
+ public BaseCalciteIndexIT(boolean localIndex) {
+ this.localIndex = localIndex;
+ }
+
+ @Before
+ public void initTable() throws Exception {
+ final String url = getOldUrl();
+ final String index = localIndex ? "LOCAL INDEX" : "INDEX";
- initATableValues(TestUtil.ATABLE_NAME, getOrganizationId(), null, null, null, url);
++ initATableValues(TestUtil.ATABLE_NAME, getOrganizationId(), null, null, null, url, null);
+ initSaltedTables(url, index);
+ initMultiTenantTables(url, index);
+ Connection connection = DriverManager.getConnection(url);
+ connection.createStatement().execute("CREATE " + index + " IF NOT EXISTS IDX1 ON aTable (a_string) INCLUDE (b_string, x_integer)");
+ connection.createStatement().execute("CREATE " + index + " IF NOT EXISTS IDX2 ON aTable (b_string) INCLUDE (a_string, y_integer)");
+ connection.createStatement().execute("CREATE " + index + " IF NOT EXISTS IDX_FULL ON aTable (b_string) INCLUDE (a_string, a_integer, a_date, a_time, a_timestamp, x_decimal, x_long, x_integer, y_integer, a_byte, a_short, a_float, a_double, a_unsigned_float, a_unsigned_double)");
+ connection.createStatement().execute("UPDATE STATISTICS ATABLE");
+ connection.createStatement().execute("UPDATE STATISTICS " + NOSALT_TABLE_NAME);
+ connection.createStatement().execute("UPDATE STATISTICS " + SALTED_TABLE_NAME);
+ connection.createStatement().execute("UPDATE STATISTICS " + MULTI_TENANT_TABLE);
+ connection.close();
+
+ Properties props = new Properties();
+ props.setProperty("TenantId", "10");
+ connection = DriverManager.getConnection(url, props);
+ connection.createStatement().execute("UPDATE STATISTICS " + MULTI_TENANT_VIEW1);
+ connection.close();
+
+ props.setProperty("TenantId", "20");
+ connection = DriverManager.getConnection(url, props);
+ connection.createStatement().execute("UPDATE STATISTICS " + MULTI_TENANT_VIEW2);
+ connection.close();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/db78bd6f/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteGlobalIndexIT.java
----------------------------------------------------------------------
diff --cc phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteGlobalIndexIT.java
index d5a95ff,0000000..21eef12
mode 100644,000000..100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteGlobalIndexIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/calcite/CalciteGlobalIndexIT.java
@@@ -1,259 -1,0 +1,259 @@@
+/*
+ * 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.calcite;
+
+import static org.junit.Assert.fail;
+
+import java.sql.SQLException;
+import java.util.Properties;
+
+import org.junit.Test;
+
+public class CalciteGlobalIndexIT extends BaseCalciteIndexIT {
+
+ public CalciteGlobalIndexIT() {
+ super(false);
+ }
+
+ @Test public void testIndex() throws Exception {
+ start(true, 1000f).sql("select * from aTable where b_string = 'b'")
+ .explainIs("PhoenixToEnumerableConverter\n" +
+ " PhoenixServerProject(ORGANIZATION_ID=[$1], ENTITY_ID=[$2], A_STRING=[$3], B_STRING=[$0], A_INTEGER=[$4], A_DATE=[$5], A_TIME=[$6], A_TIMESTAMP=[$7], X_DECIMAL=[$8], X_LONG=[$9], X_INTEGER=[$10], Y_INTEGER=[$11], A_BYTE=[$12], A_SHORT=[$13], A_FLOAT=[$14], A_DOUBLE=[$15], A_UNSIGNED_FLOAT=[$16], A_UNSIGNED_DOUBLE=[$17])\n" +
+ " PhoenixTableScan(table=[[phoenix, IDX_FULL]], filter=[=($0, 'b')])\n")
+ .close();
+ start(true, 1000f).sql("select x_integer from aTable")
+ .explainIs("PhoenixToEnumerableConverter\n" +
+ " PhoenixServerProject(0:X_INTEGER=[$4])\n" +
+ " PhoenixTableScan(table=[[phoenix, IDX1]])\n")
+ .close();
+ start(true, 1000f).sql("select a_string from aTable order by a_string")
+ .explainIs("PhoenixToEnumerableConverter\n" +
+ " PhoenixServerProject(0:A_STRING=[$0])\n" +
+ " PhoenixTableScan(table=[[phoenix, IDX1]], scanOrder=[FORWARD])\n")
+ .close();
+ start(true, 1000000f).sql("select a_string from aTable order by organization_id")
+ .explainIs("PhoenixToEnumerableConverter\n" +
+ " PhoenixServerProject(A_STRING=[$2], ORGANIZATION_ID=[$0])\n" +
+ " PhoenixTableScan(table=[[phoenix, ATABLE]], scanOrder=[FORWARD])\n")
+ .close();
+ start(true, 1000f).sql("select a_integer from aTable order by a_string")
+ .explainIs("PhoenixToEnumerableConverter\n" +
+ " PhoenixServerSort(sort0=[$1], dir0=[ASC])\n" +
- " PhoenixServerProject(A_INTEGER=[$4], A_STRING=[$3])\n" +
- " PhoenixTableScan(table=[[phoenix, IDX_FULL]])\n")
++ " PhoenixServerProject(A_INTEGER=[$4], A_STRING=[$2])\n" +
++ " PhoenixTableScan(table=[[phoenix, ATABLE]])\n")
+ .close();
+ start(true, 1000f).sql("select a_string, b_string from aTable where a_string = 'a'")
+ .explainIs("PhoenixToEnumerableConverter\n" +
+ " PhoenixServerProject(0:A_STRING=[$0], 0:B_STRING=[$3])\n" +
+ " PhoenixTableScan(table=[[phoenix, IDX1]], filter=[=($0, 'a')])\n")
+ .close();
+ start(true, 1000f).sql("select a_string, b_string from aTable where b_string = 'b'")
+ .explainIs("PhoenixToEnumerableConverter\n" +
+ " PhoenixServerProject(A_STRING=[$3], B_STRING=[$0])\n" +
+ " PhoenixTableScan(table=[[phoenix, IDX2]], filter=[=($0, 'b')])\n")
+ .close();
+ start(true, 1000f).sql("select a_string, b_string, x_integer, y_integer from aTable where b_string = 'b'")
+ .explainIs("PhoenixToEnumerableConverter\n" +
+ " PhoenixServerProject(A_STRING=[$3], B_STRING=[$0], X_INTEGER=[$10], Y_INTEGER=[$11])\n" +
+ " PhoenixTableScan(table=[[phoenix, IDX_FULL]], filter=[=($0, 'b')])\n")
+ .close();
+ start(true, 1000f).sql("select a_string, count(*) from aTable group by a_string")
+ .explainIs("PhoenixToEnumerableConverter\n" +
+ " PhoenixServerAggregate(group=[{0}], EXPR$1=[COUNT()], isOrdered=[true])\n" +
+ " PhoenixTableScan(table=[[phoenix, IDX1]], scanOrder=[FORWARD])\n")
+ .close();
+ }
+
+ @Test public void testSaltedIndex() throws Exception {
+ start(true, 1f).sql("select count(*) from " + NOSALT_TABLE_NAME + " where col0 > 3")
+ .explainIs("PhoenixToEnumerableConverter\n" +
+ " PhoenixServerAggregate(group=[{}], EXPR$0=[COUNT()])\n" +
+ " PhoenixTableScan(table=[[phoenix, IDXSALTED_NOSALT_TEST_TABLE]], filter=[>(CAST($0):INTEGER, 3)])\n")
+ .resultIs(0, new Object[][]{{999L}})
+ .close();
+ start(true, 1f).sql("select mypk0, mypk1, col0 from " + NOSALT_TABLE_NAME + " where col0 <= 4")
+ .explainIs("PhoenixToEnumerableConverter\n" +
+ " PhoenixServerProject(MYPK0=[$1], MYPK1=[$2], COL0=[CAST($0):INTEGER])\n" +
+ " PhoenixTableScan(table=[[phoenix, IDXSALTED_NOSALT_TEST_TABLE]], filter=[<=(CAST($0):INTEGER, 4)])\n")
+ .resultIs(0, new Object[][] {
+ {2, 3, 4},
+ {1, 2, 3}})
+ .close();
+ start(true, 1f).sql("select * from " + SALTED_TABLE_NAME + " where mypk0 < 3")
+ .explainIs("PhoenixToEnumerableConverter\n" +
+ " PhoenixTableScan(table=[[phoenix, SALTED_TEST_TABLE]], filter=[<($0, 3)])\n")
+ .resultIs(0, new Object[][] {
+ {1, 2, 3, 4},
+ {2, 3, 4, 5}})
+ .close();
+ start(true, 1f).sql("select count(*) from " + SALTED_TABLE_NAME + " where col0 > 3")
+ .explainIs("PhoenixToEnumerableConverter\n" +
+ " PhoenixServerAggregate(group=[{}], EXPR$0=[COUNT()])\n" +
+ " PhoenixTableScan(table=[[phoenix, IDX_SALTED_TEST_TABLE]], filter=[>(CAST($0):INTEGER, 3)])\n")
+ .resultIs(0, new Object[][]{{999L}})
+ .close();
+ start(true, 1f).sql("select mypk0, mypk1, col0 from " + SALTED_TABLE_NAME + " where col0 <= 4")
+ .explainIs("PhoenixToEnumerableConverter\n" +
+ " PhoenixServerProject(MYPK0=[$1], MYPK1=[$2], COL0=[CAST($0):INTEGER])\n" +
+ " PhoenixTableScan(table=[[phoenix, IDX_SALTED_TEST_TABLE]], filter=[<=(CAST($0):INTEGER, 4)])\n")
+ .resultIs(0, new Object[][] {
+ {2, 3, 4},
+ {1, 2, 3}})
+ .close();
+ start(true, 1f).sql("select count(*) from " + SALTED_TABLE_NAME + " where col1 > 4")
+ .explainIs("PhoenixToEnumerableConverter\n" +
+ " PhoenixServerAggregate(group=[{}], EXPR$0=[COUNT()])\n" +
+ " PhoenixTableScan(table=[[phoenix, IDXSALTED_SALTED_TEST_TABLE]], filter=[>(CAST($0):INTEGER, 4)])\n")
+ .resultIs(0, new Object[][]{{999L}})
+ .close();
+ start(true, 1f).sql("select * from " + SALTED_TABLE_NAME + " where col1 <= 5 order by col1")
+ .explainIs("PhoenixToEnumerableConverter\n" +
+ " PhoenixServerProject(MYPK0=[$1], MYPK1=[$2], COL0=[$3], COL1=[CAST($0):INTEGER])\n" +
+ " PhoenixTableScan(table=[[phoenix, IDXSALTED_SALTED_TEST_TABLE]], filter=[<=(CAST($0):INTEGER, 5)], scanOrder=[FORWARD])\n")
+ .resultIs(new Object[][] {
+ {1, 2, 3, 4},
+ {2, 3, 4, 5}})
+ .close();
+ start(true, 1f).sql("select * from " + SALTED_TABLE_NAME + " s1, " + SALTED_TABLE_NAME + " s2 where s1.mypk1 = s2.mypk1 and s1.mypk0 > 500 and s2.col1 < 505")
+ .explainIs("PhoenixToEnumerableConverter\n" +
+ " PhoenixServerJoin(condition=[=($1, $5)], joinType=[inner])\n" +
+ " PhoenixTableScan(table=[[phoenix, SALTED_TEST_TABLE]], filter=[>($0, 500)])\n" +
+ " PhoenixServerProject(MYPK0=[$1], MYPK1=[$2], COL0=[$3], COL1=[CAST($0):INTEGER])\n" +
+ " PhoenixTableScan(table=[[phoenix, IDXSALTED_SALTED_TEST_TABLE]], filter=[<(CAST($0):INTEGER, 505)])\n")
+ .resultIs(0, new Object[][] {
+ {501, 502, 503, 504, 501, 502, 503, 504}})
+ .close();
+ }
+
+ @Test public void testMultiTenant() throws Exception {
+ Properties props = getConnectionProps(true, 1f);
+ start(props).sql("select * from " + MULTI_TENANT_TABLE + " where tenant_id = '10' and id <= '0004'")
+ .explainIs("PhoenixToEnumerableConverter\n" +
- " PhoenixTableScan(table=[[phoenix, MULTITENANT_TEST_TABLE]], filter=[AND(=(CAST($0):VARCHAR(2) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\" NOT NULL, '10'), <=($1, '0004'))])\n")
++ " PhoenixTableScan(table=[[phoenix, MULTITENANT_TEST_TABLE]], filter=[AND(=($0, CAST('10'):VARCHAR CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\" NOT NULL), <=($1, '0004'))])\n")
+ .resultIs(0, new Object[][] {
+ {"10", "0002", 3, 4, 5},
+ {"10", "0003", 4, 5, 6},
+ {"10", "0004", 5, 6, 7}})
+ .close();
+
+ start(props).sql("select * from " + MULTI_TENANT_TABLE + " where tenant_id = '20' and col1 < 8")
+ .explainIs("PhoenixToEnumerableConverter\n" +
+ " PhoenixServerProject(TENANT_ID=[$0], ID=[$2], COL0=[$3], COL1=[CAST($1):INTEGER], COL2=[$4])\n" +
- " PhoenixTableScan(table=[[phoenix, IDX_MULTITENANT_TEST_TABLE]], filter=[AND(=(CAST($0):VARCHAR(2) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\" NOT NULL, '20'), <(CAST($1):INTEGER, 8))])\n")
++ " PhoenixTableScan(table=[[phoenix, IDX_MULTITENANT_TEST_TABLE]], filter=[AND(=($0, CAST('20'):VARCHAR CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\" NOT NULL), <(CAST($1):INTEGER, 8))])\n")
+ .resultIs(0, new Object[][] {
+ {"20", "0004", 5, 6, 7},
+ {"20", "0005", 6, 7, 8}})
+ .close();
+
+ try {
+ start(props).sql("select * from " + MULTI_TENANT_VIEW1)
+ .explainIs("")
+ .close();
+ fail("Should have got SQLException.");
+ } catch (SQLException e) {
+ }
+
+ props.setProperty("TenantId", "15");
+ start(props).sql("select * from " + MULTI_TENANT_TABLE + " where id = '0284'")
+ .explainIs("PhoenixToEnumerableConverter\n" +
- " PhoenixTableScan(table=[[phoenix, MULTITENANT_TEST_TABLE]], filter=[=(CAST($0):VARCHAR(4) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\" NOT NULL, '0284')])\n")
++ " PhoenixTableScan(table=[[phoenix, MULTITENANT_TEST_TABLE]], filter=[=($0, CAST('0284'):VARCHAR CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\" NOT NULL)])\n")
+ .resultIs(0, new Object[][] {
+ {"0284", 285, 286, 287}})
+ .close();
+
+ start(props).sql("select * from " + MULTI_TENANT_TABLE + " where col1 > 1000")
+ .explainIs("PhoenixToEnumerableConverter\n" +
+ " PhoenixServerProject(ID=[$1], COL0=[$2], COL1=[CAST($0):INTEGER], COL2=[$3])\n" +
+ " PhoenixTableScan(table=[[phoenix, IDX_MULTITENANT_TEST_TABLE]], filter=[>(CAST($0):INTEGER, 1000)])\n")
+ .resultIs(0, new Object[][] {
+ {"0999", 1000, 1001, 1002},
+ {"1000", 1001, 1002, 1003},
+ {"1001", 1002, 1003, 1004},
+ {"1002", 1003, 1004, 1005}})
+ .close();
+
+ try {
+ start(props).sql("select * from " + MULTI_TENANT_VIEW1)
+ .explainIs("")
+ .close();
+ fail("Should have got SQLException.");
+ } catch (SQLException e) {
+ }
+
+ props.setProperty("TenantId", "10");
+ start(props).sql("select * from " + MULTI_TENANT_VIEW1 + " where id = '0512'")
+ .explainIs("PhoenixToEnumerableConverter\n" +
- " PhoenixTableScan(table=[[phoenix, MULTITENANT_TEST_TABLE]], filter=[=(CAST($0):VARCHAR(4) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\" NOT NULL, '0512')])\n")
++ " PhoenixTableScan(table=[[phoenix, MULTITENANT_TEST_TABLE]], filter=[=($0, CAST('0512'):VARCHAR CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\" NOT NULL)])\n")
+ .resultIs(0, new Object[][] {
+ {"0512", 513, 514, 515}})
+ .close();
+
+ start(props).sql("select * from " + MULTI_TENANT_TABLE + " where col1 <= 6")
+ .explainIs("PhoenixToEnumerableConverter\n" +
+ " PhoenixServerProject(ID=[$1], COL0=[$2], COL1=[CAST($0):INTEGER], COL2=[$3])\n" +
+ " PhoenixTableScan(table=[[phoenix, IDX_MULTITENANT_TEST_TABLE]], filter=[<=(CAST($0):INTEGER, 6)])\n")
+ .resultIs(0, new Object[][] {
+ {"0002", 3, 4, 5},
+ {"0003", 4, 5, 6},
+ {"0004", 5, 6, 7}})
+ .close();
+
+ start(props).sql("select id, col0 from " + MULTI_TENANT_VIEW1 + " where col0 >= 1000")
+ .explainIs("PhoenixToEnumerableConverter\n" +
+ " PhoenixServerProject(ID=[$1], COL0=[CAST($0):INTEGER])\n" +
+ " PhoenixTableScan(table=[[phoenix, S1, IDX_MULTITENANT_TEST_VIEW1]], filter=[>=(CAST($0):INTEGER, 1000)])\n")
+ .resultIs(0, new Object[][] {
+ {"0999", 1000},
+ {"1000", 1001},
+ {"1001", 1002}})
+ .close();
+
+ props.setProperty("TenantId", "20");
+ start(props).sql("select * from " + MULTI_TENANT_VIEW2 + " where id = '0765'")
+ .explainIs("PhoenixToEnumerableConverter\n" +
- " PhoenixTableScan(table=[[phoenix, MULTITENANT_TEST_TABLE]], filter=[AND(>($3, 7), =(CAST($0):VARCHAR(4) CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\" NOT NULL, '0765'))])\n")
++ " PhoenixTableScan(table=[[phoenix, MULTITENANT_TEST_TABLE]], filter=[AND(>($3, 7), =($0, CAST('0765'):VARCHAR CHARACTER SET \"ISO-8859-1\" COLLATE \"ISO-8859-1$en_US$primary\" NOT NULL))])\n")
+ .resultIs(0, new Object[][] {
+ {"0765", 766, 767, 768}})
+ .close();
+
+ start(props).sql("select id, col0 from " + MULTI_TENANT_VIEW2 + " where col0 between 272 and 275")
+ .explainIs("PhoenixToEnumerableConverter\n" +
+ " PhoenixServerProject(ID=[$1], COL0=[CAST($0):INTEGER])\n" +
+ " PhoenixTableScan(table=[[phoenix, S2, IDX_MULTITENANT_TEST_VIEW2]], filter=[AND(>=(CAST($0):INTEGER, 272), <=(CAST($0):INTEGER, 275))])\n")
+ .resultIs(0, new Object[][] {
+ {"0271", 272},
+ {"0272", 273},
+ {"0273", 274},
+ {"0274", 275}})
+ .close();
+
+ start(props).sql("select id, col0 from " + MULTI_TENANT_VIEW2 + " order by col0 limit 5")
+ .explainIs("PhoenixToEnumerableConverter\n" +
+ " PhoenixLimit(fetch=[5])\n" +
+ " PhoenixServerProject(ID=[$1], COL0=[CAST($0):INTEGER])\n" +
+ " PhoenixTableScan(table=[[phoenix, S2, IDX_MULTITENANT_TEST_VIEW2]], scanOrder=[FORWARD])\n")
+ .resultIs(new Object[][] {
+ {"0005", 6},
+ {"0006", 7},
+ {"0007", 8},
+ {"0008", 9},
+ {"0009", 10}})
+ .close();
+ }
+
+}