You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by sh...@apache.org on 2023/12/28 22:17:57 UTC

(phoenix) branch PHOENIX-6883-feature updated (83134d9731 -> 813e764047)

This is an automated email from the ASF dual-hosted git repository.

shahrs87 pushed a change to branch PHOENIX-6883-feature
in repository https://gitbox.apache.org/repos/asf/phoenix.git


    from 83134d9731 PHOENIX-7115 Create separate handler thread pool for invalidating server metadata cache (#1748)
     add e21763aca9 PHOENIX-7143 Detect JVM version and add the necessary module flags in startup scripts
     add 7cd93529be PHOENIX-6053 Split Server Side Code into a Separate Module
     add 087a88ffc7 PHOENIX-7144 Fixing tableNames for Index Tables for phoenix client Metrics (#1755)
     add 8839ebf377 PHOENIX-7140 Update Apache Parent and Maven Plugin Versions in Core
     add 75e085b93c PHOENIX-7153 Fix Warnings Flagged as Errors by Eclipse
     add 0ed534f4cf PHOENIX-6721 CSV bulkload tool fails with FileNotFoundException if --output points to the S3 location
     add 2426212be2 PHOENIX-7152 SchemaExtractionProcessor package does not match directory
     new 813e764047 Merge branch 'master' into PHOENIX-6883-feature

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 bin/performance.py                                 |   41 +-
 bin/pherf-standalone.py                            |   37 +-
 bin/phoenix_utils.py                               |   78 +
 bin/psql.py                                        |   38 +-
 bin/sqlline.py                                     |   35 +-
 .../phoenix-client-embedded/pom.xml                |    2 +-
 phoenix-core-client/pom.xml                        |  434 ++
 .../src/build/phoenix-core.xml                     |    0
 .../src/main/antlr3/PhoenixSQL.g                   |    0
 .../org/apache/hadoop/hbase/PhoenixTagType.java    |    0
 .../apache/hadoop/hbase/client/RegionInfoUtil.java |    0
 .../ipc/controller/ClientRpcControllerFactory.java |    0
 .../hbase/ipc/controller/IndexRpcController.java   |   57 +
 ...InterRegionServerIndexRpcControllerFactory.java |    0
 .../InvalidateMetadataCacheController.java         |   51 +
 .../InvalidateMetadataCacheControllerFactory.java  |    0
 .../ipc/controller/MetadataRpcController.java      |   74 +
 .../controller/ServerSideRPCControllerFactory.java |    0
 .../controller/ServerToServerRpcController.java    |    0
 .../ServerToServerRpcControllerImpl.java           |   75 +
 .../java/org/apache/phoenix/cache/HashCache.java   |    0
 .../apache/phoenix/cache/IndexMetaDataCache.java   |    0
 .../apache/phoenix/cache/JodaTimezoneCache.java    |    0
 .../apache/phoenix/cache/ServerCacheClient.java    |  553 ++
 .../apache/phoenix/cache/ServerMetadataCache.java  |  193 +
 .../java/org/apache/phoenix/cache/TenantCache.java |   42 +
 .../org/apache/phoenix/cache/TenantCacheImpl.java  |  287 +
 .../java/org/apache/phoenix/call/CallRunner.java   |    0
 .../java/org/apache/phoenix/call/CallWrapper.java  |    0
 .../apache/phoenix/compile/AggregationManager.java |  115 +
 .../apache/phoenix/compile/BaseMutationPlan.java   |    0
 .../org/apache/phoenix/compile/BindManager.java    |    0
 .../phoenix/compile/CloseStatementCompiler.java    |    0
 .../ColumnNameTrackingExpressionCompiler.java      |    0
 .../apache/phoenix/compile/ColumnProjector.java    |    0
 .../org/apache/phoenix/compile/ColumnResolver.java |    0
 .../org/apache/phoenix/compile/CompiledOffset.java |    0
 .../phoenix/compile/CreateFunctionCompiler.java    |    0
 .../phoenix/compile/CreateIndexCompiler.java       |    0
 .../phoenix/compile/CreateSchemaCompiler.java      |    0
 .../phoenix/compile/CreateSequenceCompiler.java    |    0
 .../phoenix/compile/CreateTableCompiler.java       |    0
 .../phoenix/compile/DeclareCursorCompiler.java     |    0
 .../phoenix/compile/DelegateMutationPlan.java      |    0
 .../org/apache/phoenix/compile/DeleteCompiler.java | 1030 ++++
 .../phoenix/compile/DropSequenceCompiler.java      |    0
 .../org/apache/phoenix/compile/ExplainPlan.java    |    0
 .../phoenix/compile/ExplainPlanAttributes.java     |    0
 .../apache/phoenix/compile/ExpressionCompiler.java |    0
 .../apache/phoenix/compile/ExpressionManager.java  |    0
 .../phoenix/compile/ExpressionProjector.java       |    0
 .../org/apache/phoenix/compile/FromCompiler.java   | 1233 ++++
 .../apache/phoenix/compile/GroupByCompiler.java    |  476 ++
 .../org/apache/phoenix/compile/HavingCompiler.java |    0
 .../phoenix/compile/IndexExpressionCompiler.java   |    0
 .../phoenix/compile/IndexStatementRewriter.java    |    0
 .../org/apache/phoenix/compile/JoinCompiler.java   | 1589 +++++
 .../java/org/apache/phoenix/compile/KeyPart.java   |    0
 .../org/apache/phoenix/compile/LimitCompiler.java  |    0
 .../apache/phoenix/compile/ListJarsQueryPlan.java  |    0
 .../compile/MutatingParallelIteratorFactory.java   |    0
 .../org/apache/phoenix/compile/MutationPlan.java   |    0
 .../org/apache/phoenix/compile/OffsetCompiler.java |    0
 .../phoenix/compile/OpenStatementCompiler.java     |    0
 .../apache/phoenix/compile/OrderByCompiler.java    |    0
 .../phoenix/compile/OrderPreservingTracker.java    |    0
 .../apache/phoenix/compile/PostDDLCompiler.java    |  372 ++
 .../phoenix/compile/PostIndexDDLCompiler.java      |    0
 .../phoenix/compile/PostLocalIndexDDLCompiler.java |  133 +
 .../apache/phoenix/compile/ProjectionCompiler.java |  796 +++
 .../org/apache/phoenix/compile/QueryCompiler.java  |  814 +++
 .../java/org/apache/phoenix/compile/QueryPlan.java |    0
 .../apache/phoenix/compile/RVCOffsetCompiler.java  |    0
 .../org/apache/phoenix/compile/RowProjector.java   |    0
 .../org/apache/phoenix/compile/ScanRanges.java     |  785 +++
 .../apache/phoenix/compile/SequenceManager.java    |    0
 .../phoenix/compile/SequenceValueExpression.java   |    0
 .../phoenix/compile/ServerBuildIndexCompiler.java  |  161 +
 .../ServerBuildTransformingTableCompiler.java      |   99 +
 .../compile/StatelessExpressionCompiler.java       |    0
 .../apache/phoenix/compile/StatementContext.java   |    0
 .../phoenix/compile/StatementNormalizer.java       |    0
 .../org/apache/phoenix/compile/StatementPlan.java  |    0
 .../apache/phoenix/compile/SubqueryRewriter.java   |    0
 .../apache/phoenix/compile/SubselectRewriter.java  |    0
 .../org/apache/phoenix/compile/TraceQueryPlan.java |    0
 .../phoenix/compile/TupleProjectionCompiler.java   |    0
 .../org/apache/phoenix/compile/UnionCompiler.java  |    0
 .../org/apache/phoenix/compile/UpsertCompiler.java | 1455 +++++
 .../org/apache/phoenix/compile/WhereCompiler.java  |  958 +++
 .../org/apache/phoenix/compile/WhereOptimizer.java |    0
 .../BaseScannerRegionObserverConstants.java        |  157 +
 .../HashJoinCacheNotFoundException.java            |   45 +
 .../InvalidateServerMetadataCacheRequest.java      |   53 +
 .../MetaDataEndpointImplConstants.java             |   35 +
 .../coprocessorclient/MetaDataProtocol.java        |  521 ++
 .../ScanRegionObserverConstants.java               |   29 +
 .../SequenceRegionObserverConstants.java           |   25 +
 .../coprocessorclient/ServerCachingProtocol.java   |   61 +
 .../phoenix/coprocessorclient/TableInfo.java       |   79 +
 .../UngroupedAggregateRegionObserverHelper.java    |   59 +
 .../coprocessorclient/WhereConstantParser.java     |  110 +
 .../metrics/MetricsMetadataCachingSource.java      |  230 +
 .../metrics/MetricsMetadataCachingSourceImpl.java  |  122 +
 .../MetricsPhoenixCoprocessorSourceFactory.java    |   57 +
 .../metrics/MetricsPhoenixTTLSource.java           |   59 +
 .../metrics/MetricsPhoenixTTLSourceImpl.java       |   58 +
 .../tasks/IndexRebuildTaskConstants.java           |   25 +
 .../exception/DataExceedsCapacityException.java    |    0
 .../phoenix/exception/FailoverSQLException.java    |    0
 .../InvalidRegionSplitPolicyException.java         |    0
 .../phoenix/exception/PhoenixIOException.java      |    0
 .../PhoenixNonRetryableRuntimeException.java       |    0
 .../phoenix/exception/PhoenixParserException.java  |    0
 .../exception/RetriableUpgradeException.java       |    0
 .../apache/phoenix/exception/SQLExceptionCode.java |  697 +++
 .../apache/phoenix/exception/SQLExceptionInfo.java |    0
 .../exception/StaleMetadataCacheException.java     |    0
 .../exception/UndecodableByteException.java        |    0
 .../exception/UnknownFunctionException.java        |    0
 .../exception/UpgradeInProgressException.java      |   31 +
 .../exception/UpgradeNotRequiredException.java     |    0
 .../exception/UpgradeRequiredException.java        |    0
 .../org/apache/phoenix/execute/AggregatePlan.java  |  405 ++
 .../org/apache/phoenix/execute/BaseQueryPlan.java  |  579 ++
 .../phoenix/execute/ClientAggregatePlan.java       |  384 ++
 .../phoenix/execute/ClientProcessingPlan.java      |    0
 .../org/apache/phoenix/execute/ClientScanPlan.java |    0
 .../apache/phoenix/execute/CommitException.java    |    0
 .../apache/phoenix/execute/CursorFetchPlan.java    |    0
 .../org/apache/phoenix/execute/DelegateHTable.java |    0
 .../apache/phoenix/execute/DelegateQueryPlan.java  |    0
 .../execute/DescVarLengthFastByteComparisons.java  |    0
 .../org/apache/phoenix/execute/HashJoinPlan.java   |  700 +++
 .../execute/LiteralResultIterationPlan.java        |    0
 .../org/apache/phoenix/execute/MutationState.java  | 2309 +++++++
 .../execute/PhoenixTxIndexMutationGenerator.java   |  522 ++
 .../org/apache/phoenix/execute/RuntimeContext.java |    0
 .../apache/phoenix/execute/RuntimeContextImpl.java |    0
 .../java/org/apache/phoenix/execute/ScanPlan.java  |  405 ++
 .../apache/phoenix/execute/SortMergeJoinPlan.java  |    0
 .../phoenix/execute/TupleProjectionPlan.java       |    0
 .../org/apache/phoenix/execute/TupleProjector.java |  495 ++
 .../java/org/apache/phoenix/execute/UnionPlan.java |    0
 .../apache/phoenix/execute/UnnestArrayPlan.java    |    0
 .../execute/visitor/AvgRowWidthVisitor.java        |    0
 .../phoenix/execute/visitor/ByteCountVisitor.java  |    0
 .../phoenix/execute/visitor/QueryPlanVisitor.java  |    0
 .../phoenix/execute/visitor/RowCountVisitor.java   |    0
 .../apache/phoenix/expression/AddExpression.java   |    0
 .../apache/phoenix/expression/AndExpression.java   |    0
 .../apache/phoenix/expression/AndOrExpression.java |    0
 .../phoenix/expression/ArithmeticExpression.java   |    0
 .../expression/ArrayConstructorExpression.java     |    0
 .../expression/BaseAddSubtractExpression.java      |    0
 .../phoenix/expression/BaseCompoundExpression.java |    0
 .../BaseDecimalAddSubtractExpression.java          |    0
 .../apache/phoenix/expression/BaseExpression.java  |    0
 .../phoenix/expression/BaseSingleExpression.java   |    0
 .../phoenix/expression/BaseTerminalExpression.java |    0
 .../expression/ByteBasedLikeExpression.java        |    0
 .../apache/phoenix/expression/CaseExpression.java  |    0
 .../phoenix/expression/CoerceExpression.java       |    0
 .../phoenix/expression/ColumnExpression.java       |    0
 .../phoenix/expression/ComparisonExpression.java   |    0
 .../CorrelateVariableFieldAccessExpression.java    |    0
 .../expression/CurrentDateTimeFunction.java        |    0
 .../phoenix/expression/DateAddExpression.java      |    0
 .../phoenix/expression/DateSubtractExpression.java |    0
 .../phoenix/expression/DecimalAddExpression.java   |    0
 .../expression/DecimalDivideExpression.java        |    0
 .../expression/DecimalMultiplyExpression.java      |    0
 .../expression/DecimalSubtractExpression.java      |    0
 .../phoenix/expression/DelegateExpression.java     |    0
 .../org/apache/phoenix/expression/Determinism.java |    0
 .../phoenix/expression/DivideExpression.java       |    0
 .../phoenix/expression/DoubleAddExpression.java    |    0
 .../phoenix/expression/DoubleDivideExpression.java |    0
 .../expression/DoubleMultiplyExpression.java       |    0
 .../expression/DoubleSubtractExpression.java       |    0
 .../org/apache/phoenix/expression/Expression.java  |    0
 .../apache/phoenix/expression/ExpressionType.java  |    0
 .../phoenix/expression/InListExpression.java       |    0
 .../phoenix/expression/IsNullExpression.java       |    0
 .../expression/KeyValueColumnExpression.java       |    0
 .../apache/phoenix/expression/LikeExpression.java  |    0
 .../phoenix/expression/LiteralExpression.java      |    0
 .../phoenix/expression/LongAddExpression.java      |    0
 .../phoenix/expression/LongDivideExpression.java   |    0
 .../phoenix/expression/LongMultiplyExpression.java |    0
 .../phoenix/expression/LongSubtractExpression.java |    0
 .../phoenix/expression/ModulusExpression.java      |    0
 .../phoenix/expression/MultiplyExpression.java     |    0
 .../apache/phoenix/expression/NotExpression.java   |    0
 .../apache/phoenix/expression/OrExpression.java    |    0
 .../phoenix/expression/OrderByExpression.java      |    0
 .../expression/ProjectedColumnExpression.java      |    0
 .../phoenix/expression/RowKeyColumnExpression.java |    0
 .../phoenix/expression/RowKeyExpression.java       |    0
 .../expression/RowValueConstructorExpression.java  |  277 +
 .../expression/SingleCellColumnExpression.java     |    0
 .../SingleCellConstructorExpression.java           |    0
 .../expression/StringBasedLikeExpression.java      |    0
 .../phoenix/expression/StringConcatExpression.java |    0
 .../phoenix/expression/SubtractExpression.java     |    0
 .../phoenix/expression/TimestampAddExpression.java |    0
 .../expression/TimestampSubtractExpression.java    |    0
 .../phoenix/expression/aggregator/Aggregator.java  |    0
 .../phoenix/expression/aggregator/Aggregators.java |    0
 .../expression/aggregator/BaseAggregator.java      |    0
 .../aggregator/BaseDecimalStddevAggregator.java    |    0
 .../aggregator/BaseStddevAggregator.java           |    0
 .../expression/aggregator/ClientAggregators.java   |    0
 .../expression/aggregator/CountAggregator.java     |    0
 .../aggregator/DecimalStddevPopAggregator.java     |    0
 .../aggregator/DecimalStddevSampAggregator.java    |    0
 .../aggregator/DecimalSumAggregator.java           |    0
 .../aggregator/DistinctCountClientAggregator.java  |    0
 .../aggregator/DistinctValueClientAggregator.java  |    0
 .../DistinctValueWithCountClientAggregator.java    |    0
 .../DistinctValueWithCountServerAggregator.java    |    0
 .../expression/aggregator/DoubleSumAggregator.java |    0
 .../FirstLastValueBaseClientAggregator.java        |    0
 .../aggregator/FirstLastValueServerAggregator.java |    0
 .../expression/aggregator/IntSumAggregator.java    |    0
 .../expression/aggregator/LongSumAggregator.java   |    0
 .../expression/aggregator/MaxAggregator.java       |    0
 .../expression/aggregator/MinAggregator.java       |    0
 .../NonSizeTrackingServerAggregators.java          |    0
 .../expression/aggregator/NumberSumAggregator.java |    0
 .../aggregator/PercentRankClientAggregator.java    |    0
 .../aggregator/PercentileClientAggregator.java     |    0
 .../aggregator/PercentileDiscClientAggregator.java |    0
 .../expression/aggregator/ServerAggregators.java   |    0
 .../aggregator/SizeTrackingServerAggregators.java  |    0
 .../expression/aggregator/StddevPopAggregator.java |    0
 .../aggregator/StddevSampAggregator.java           |    0
 .../aggregator/UnsignedIntSumAggregator.java       |    0
 .../aggregator/UnsignedLongSumAggregator.java      |    0
 .../phoenix/expression/function/AbsFunction.java   |    0
 .../expression/function/AggregateFunction.java     |    0
 .../function/ArrayAllComparisonExpression.java     |    0
 .../function/ArrayAnyComparisonExpression.java     |    0
 .../expression/function/ArrayAppendFunction.java   |    0
 .../expression/function/ArrayConcatFunction.java   |    0
 .../function/ArrayElemRefExpression.java           |    0
 .../expression/function/ArrayFillFunction.java     |    0
 .../expression/function/ArrayIndexFunction.java    |    0
 .../expression/function/ArrayLengthFunction.java   |    0
 .../expression/function/ArrayModifierFunction.java |    0
 .../expression/function/ArrayPrependFunction.java  |    0
 .../expression/function/ArrayRemoveFunction.java   |    0
 .../expression/function/ArrayToStringFunction.java |    0
 .../expression/function/AvgAggregateFunction.java  |    0
 .../function/ByteBasedRegexpReplaceFunction.java   |    0
 .../function/ByteBasedRegexpSplitFunction.java     |    0
 .../function/ByteBasedRegexpSubstrFunction.java    |    0
 .../phoenix/expression/function/CbrtFunction.java  |    0
 .../expression/function/CeilDateExpression.java    |    0
 .../expression/function/CeilDecimalExpression.java |    0
 .../phoenix/expression/function/CeilFunction.java  |    0
 .../expression/function/CeilMonthExpression.java   |    0
 .../function/CeilTimestampExpression.java          |    0
 .../expression/function/CeilWeekExpression.java    |    0
 .../expression/function/CeilYearExpression.java    |    0
 .../expression/function/CoalesceFunction.java      |    0
 .../expression/function/CollationKeyFunction.java  |    0
 .../function/CompositeAggregateFunction.java       |    0
 .../function/ConvertTimezoneFunction.java          |    0
 .../phoenix/expression/function/CosFunction.java   |    0
 .../function/CountAggregateFunction.java           |    0
 .../expression/function/CurrentDateFunction.java   |    0
 .../expression/function/CurrentTimeFunction.java   |    0
 .../expression/function/DateScalarFunction.java    |    0
 .../expression/function/DayOfMonthFunction.java    |    0
 .../expression/function/DayOfWeekFunction.java     |    0
 .../expression/function/DayOfYearFunction.java     |    0
 .../expression/function/DecodeFunction.java        |    0
 .../function/DefaultValueExpression.java           |    0
 .../DelegateConstantToCountAggregateFunction.java  |    0
 .../function/DistinctCountAggregateFunction.java   |    0
 .../DistinctCountHyperLogLogAggregateFunction.java |    0
 .../function/DistinctValueAggregateFunction.java   |    0
 .../DistinctValueWithCountAggregateFunction.java   |    0
 .../phoenix/expression/function/EncodeFormat.java  |    0
 .../expression/function/EncodeFunction.java        |    0
 .../phoenix/expression/function/ExpFunction.java   |    0
 .../function/ExternalSqlTypeIdFunction.java        |    0
 .../function/FirstLastValueBaseFunction.java       |    0
 .../expression/function/FirstValueFunction.java    |    0
 .../expression/function/FirstValuesFunction.java   |    0
 .../expression/function/FloorDateExpression.java   |    0
 .../function/FloorDecimalExpression.java           |    0
 .../phoenix/expression/function/FloorFunction.java |    0
 .../expression/function/FloorMonthExpression.java  |    0
 .../expression/function/FloorWeekExpression.java   |    0
 .../expression/function/FloorYearExpression.java   |    0
 .../expression/function/FunctionArgumentType.java  |    0
 .../expression/function/FunctionExpression.java    |    0
 .../expression/function/GetBitFunction.java        |    0
 .../expression/function/GetByteFunction.java       |    0
 .../phoenix/expression/function/HourFunction.java  |    0
 .../function/IndexStateNameFunction.java           |    0
 .../phoenix/expression/function/InstrFunction.java |    0
 .../expression/function/InvertFunction.java        |    0
 .../function/JavaMathOneArgumentFunction.java      |    0
 .../function/JavaMathTwoArgumentFunction.java      |    0
 .../phoenix/expression/function/LTrimFunction.java |    0
 .../expression/function/LastValueFunction.java     |    0
 .../expression/function/LastValuesFunction.java    |    0
 .../expression/function/LengthFunction.java        |    0
 .../phoenix/expression/function/LnFunction.java    |    0
 .../phoenix/expression/function/LogFunction.java   |    0
 .../phoenix/expression/function/LowerFunction.java |    0
 .../phoenix/expression/function/LpadFunction.java  |    0
 .../phoenix/expression/function/MD5Function.java   |    0
 .../expression/function/MathPIFunction.java        |    0
 .../expression/function/MaxAggregateFunction.java  |    0
 .../expression/function/MinAggregateFunction.java  |    0
 .../expression/function/MinuteFunction.java        |    0
 .../phoenix/expression/function/MonthFunction.java |    0
 .../phoenix/expression/function/NowFunction.java   |    0
 .../expression/function/NthValueFunction.java      |    0
 .../expression/function/OctetLengthFunction.java   |    0
 .../function/PercentRankAggregateFunction.java     |    0
 .../function/PercentileContAggregateFunction.java  |    0
 .../function/PercentileDiscAggregateFunction.java  |    0
 .../function/PhoenixRowTimestampFunction.java      |    0
 .../phoenix/expression/function/PowerFunction.java |    0
 .../expression/function/PrefixFunction.java        |    0
 .../phoenix/expression/function/RTrimFunction.java |    0
 .../expression/function/RandomFunction.java        |    0
 .../expression/function/RegexpReplaceFunction.java |    0
 .../expression/function/RegexpSplitFunction.java   |    0
 .../expression/function/RegexpSubstrFunction.java  |    0
 .../expression/function/ReverseFunction.java       |    0
 .../expression/function/RoundDateExpression.java   |    0
 .../function/RoundDecimalExpression.java           |    0
 .../phoenix/expression/function/RoundFunction.java |    0
 .../function/RoundJodaDateExpression.java          |    0
 .../expression/function/RoundMonthExpression.java  |    0
 .../function/RoundTimestampExpression.java         |    0
 .../expression/function/RoundWeekExpression.java   |    0
 .../expression/function/RoundYearExpression.java   |    0
 .../function/RowKeyBytesStringFunction.java        |    0
 .../expression/function/SQLIndexTypeFunction.java  |    0
 .../expression/function/SQLTableTypeFunction.java  |    0
 .../expression/function/SQLViewTypeFunction.java   |    0
 .../expression/function/ScalarFunction.java        |    0
 .../expression/function/SecondFunction.java        |    0
 .../expression/function/SetBitFunction.java        |    0
 .../expression/function/SetByteFunction.java       |    0
 .../phoenix/expression/function/SignFunction.java  |    0
 .../phoenix/expression/function/SinFunction.java   |    0
 .../function/SingleAggregateFunction.java          |    0
 .../expression/function/SqlTypeNameFunction.java   |    0
 .../phoenix/expression/function/SqrtFunction.java  |    0
 .../expression/function/StddevPopFunction.java     |    0
 .../expression/function/StddevSampFunction.java    |    0
 .../function/StringBasedRegexpReplaceFunction.java |    0
 .../function/StringBasedRegexpSplitFunction.java   |    0
 .../function/StringBasedRegexpSubstrFunction.java  |    0
 .../expression/function/StringToArrayFunction.java |    0
 .../expression/function/SubstrFunction.java        |    0
 .../expression/function/SumAggregateFunction.java  |    0
 .../phoenix/expression/function/TanFunction.java   |    0
 .../phoenix/expression/function/TimeUnit.java      |    0
 .../function/TimezoneOffsetFunction.java           |    0
 .../expression/function/ToCharFunction.java        |    0
 .../expression/function/ToDateFunction.java        |    0
 .../expression/function/ToNumberFunction.java      |    0
 .../expression/function/ToTimeFunction.java        |    0
 .../expression/function/ToTimestampFunction.java   |    0
 .../function/TransactionProviderNameFunction.java  |    0
 .../phoenix/expression/function/TrimFunction.java  |    0
 .../phoenix/expression/function/TruncFunction.java |    0
 .../phoenix/expression/function/UDFExpression.java |    0
 .../phoenix/expression/function/UpperFunction.java |    0
 .../phoenix/expression/function/WeekFunction.java  |    0
 .../phoenix/expression/function/YearFunction.java  |    0
 .../RowValueConstructorExpressionRewriter.java     |    0
 .../expression/util/regex/AbstractBasePattern.java |    0
 .../util/regex/AbstractBaseSplitter.java           |    0
 .../expression/util/regex/GuavaSplitter.java       |    0
 .../phoenix/expression/util/regex/JONIPattern.java |    0
 .../phoenix/expression/util/regex/JavaPattern.java |    0
 .../expression/visitor/BaseExpressionVisitor.java  |    0
 .../expression/visitor/CloneExpressionVisitor.java |    0
 .../expression/visitor/ExpressionVisitor.java      |    0
 .../visitor/KeyValueExpressionVisitor.java         |    0
 .../visitor/ProjectedColumnExpressionVisitor.java  |    0
 .../ReplaceArrayFunctionExpressionVisitor.java     |    0
 .../visitor/RowKeyExpressionVisitor.java           |    0
 .../visitor/SingleAggregateFunctionVisitor.java    |    0
 .../StatelessTraverseAllExpressionVisitor.java     |    0
 .../StatelessTraverseNoExpressionVisitor.java      |    0
 .../visitor/TraverseAllExpressionVisitor.java      |    0
 .../visitor/TraverseNoExpressionVisitor.java       |    0
 .../filter/AllVersionsIndexRebuildFilter.java      |    0
 .../phoenix/filter/BooleanExpressionFilter.java    |  135 +
 .../phoenix/filter/ColumnProjectionFilter.java     |    0
 .../org/apache/phoenix/filter/DelegateFilter.java  |    0
 .../phoenix/filter/DistinctPrefixFilter.java       |    0
 .../phoenix/filter/EmptyColumnOnlyFilter.java      |    0
 .../EncodedQualifiersColumnProjectionFilter.java   |    0
 .../filter/MultiCFCQKeyValueComparisonFilter.java  |    0
 .../filter/MultiCQKeyValueComparisonFilter.java    |    0
 .../MultiEncodedCQKeyValueComparisonFilter.java    |  415 ++
 .../filter/MultiKeyValueComparisonFilter.java      |  291 +
 .../org/apache/phoenix/filter/PagingFilter.java    |    0
 .../phoenix/filter/RowKeyComparisonFilter.java     |    0
 .../filter/SingleCFCQKeyValueComparisonFilter.java |    0
 .../filter/SingleCQKeyValueComparisonFilter.java   |    0
 .../filter/SingleKeyValueComparisonFilter.java     |    0
 .../org/apache/phoenix/filter/SkipScanFilter.java  |    0
 .../filter/SystemCatalogViewIndexIdFilter.java     |  161 +
 .../apache/phoenix/filter/UnverifiedRowFilter.java |    0
 .../phoenix/hbase/index/AbstractValueGetter.java   |    0
 .../apache/phoenix/hbase/index/BaseIndexCodec.java |   34 +
 .../apache/phoenix/hbase/index/MultiMutation.java  |    0
 .../org/apache/phoenix/hbase/index/OffsetCell.java |    0
 .../apache/phoenix/hbase/index/ValueGetter.java    |    0
 .../FatalIndexBuildingFailureException.java        |    0
 .../builder/IndexBuildingFailureException.java     |    0
 .../apache/phoenix/hbase/index/covered/Batch.java  |    0
 .../phoenix/hbase/index/covered/IndexCodec.java    |   88 +
 .../phoenix/hbase/index/covered/IndexMetaData.java |   55 +
 .../phoenix/hbase/index/covered/IndexUpdate.java   |    0
 .../phoenix/hbase/index/covered/KeyValueStore.java |    0
 .../phoenix/hbase/index/covered/TableState.java    |   73 +
 .../index/covered/data/DelegateComparator.java     |    0
 .../hbase/index/covered/data/LazyValueGetter.java  |    0
 .../hbase/index/covered/data/LocalHBaseState.java  |    0
 .../filter/ApplyAndFilterDeletesFilter.java        |    0
 .../ColumnTrackingNextLargestTimestampFilter.java  |    0
 .../index/covered/filter/MaxTimestampFilter.java   |    0
 .../index/covered/filter/NewerTimestampFilter.java |    0
 .../index/covered/update/ColumnReference.java      |    0
 .../hbase/index/covered/update/ColumnTracker.java  |    0
 .../index/covered/update/IndexUpdateManager.java   |    0
 .../index/covered/update/IndexedColumnGroup.java   |    0
 .../hbase/index/exception/IndexWriteException.java |    0
 .../exception/MultiIndexWriteFailureException.java |    0
 .../SingleIndexWriteFailureException.java          |    0
 .../index/metrics/GlobalIndexCheckerSource.java    |    0
 .../metrics/GlobalIndexCheckerSourceImpl.java      |    0
 .../hbase/index/metrics/MetricsIndexerSource.java  |  212 +
 .../index/metrics/MetricsIndexerSourceFactory.java |    0
 .../index/metrics/MetricsIndexerSourceImpl.java    |    0
 .../hbase/index/parallel/BaseTaskRunner.java       |    0
 .../hbase/index/parallel/EarlyExitFailure.java     |    0
 .../index/parallel/QuickFailingTaskRunner.java     |    0
 .../apache/phoenix/hbase/index/parallel/Task.java  |    0
 .../phoenix/hbase/index/parallel/TaskBatch.java    |    0
 .../phoenix/hbase/index/parallel/TaskRunner.java   |    0
 .../hbase/index/parallel/ThreadPoolBuilder.java    |    0
 .../parallel/WaitForCompletionTaskRunner.java      |    0
 .../phoenix/hbase/index/scanner/EmptyScanner.java  |    0
 .../index/scanner/FilteredKeyValueScanner.java     |    0
 .../hbase/index/scanner/ReseekableScanner.java     |    0
 .../phoenix/hbase/index/scanner/Scanner.java       |    0
 .../hbase/index/scanner/ScannerBuilder.java        |    0
 .../phoenix/hbase/index/table/HTableFactory.java   |    0
 .../index/table/HTableInterfaceReference.java      |    0
 .../hbase/index/util/GenericKeyValueBuilder.java   |    0
 .../hbase/index/util/ImmutableBytesPtr.java        |    0
 .../hbase/index/util/IndexManagementUtil.java      |  294 +
 .../phoenix/hbase/index/util/KeyValueBuilder.java  |    0
 .../phoenix/hbase/index/util/VersionUtil.java      |    0
 .../org/apache/phoenix/index/IndexMaintainer.java  | 2299 +++++++
 .../phoenix/index/IndexMetaDataCacheClient.java    |  158 +
 .../phoenix/index/IndexMetaDataCacheFactory.java   |   82 +
 .../phoenix/index/PhoenixIndexBuilderHelper.java   |  146 +
 .../apache/phoenix/index/PhoenixIndexCodec.java    |  139 +
 .../index/PhoenixIndexFailurePolicyHelper.java     |  245 +
 .../apache/phoenix/index/PhoenixIndexMetaData.java |  101 +
 .../phoenix/iterate/AggregatingResultIterator.java |    0
 .../BaseGroupedAggregatingResultIterator.java      |    0
 .../apache/phoenix/iterate/BaseResultIterator.java |    0
 .../phoenix/iterate/BaseResultIterators.java       | 1770 ++++++
 .../org/apache/phoenix/iterate/BufferedQueue.java  |    0
 .../phoenix/iterate/BufferedSortedQueue.java       |    0
 .../apache/phoenix/iterate/BufferedTupleQueue.java |    0
 .../phoenix/iterate/ChunkedResultIterator.java     |  249 +
 .../ClientHashAggregatingResultIterator.java       |    0
 .../phoenix/iterate/ConcatResultIterator.java      |  150 +
 .../phoenix/iterate/CursorResultIterator.java      |    0
 .../iterate/DefaultParallelScanGrouper.java        |    0
 .../iterate/DefaultTableResultIteratorFactory.java |    0
 .../phoenix/iterate/DelegateResultIterator.java    |    0
 .../iterate/DistinctAggregatingResultIterator.java |    0
 .../org/apache/phoenix/iterate/ExplainTable.java   |  550 ++
 .../iterate/FilterAggregatingResultIterator.java   |    0
 .../phoenix/iterate/FilterResultIterator.java      |    0
 .../iterate/GroupedAggregatingResultIterator.java  |    0
 .../iterate/LimitingPeekingResultIterator.java     |    0
 .../phoenix/iterate/LimitingResultIterator.java    |    0
 .../phoenix/iterate/LookAheadResultIterator.java   |    0
 .../MaterializedComparableResultIterator.java      |    0
 .../iterate/MaterializedResultIterator.java        |    0
 .../phoenix/iterate/MergeSortResultIterator.java   |    0
 .../iterate/MergeSortRowKeyResultIterator.java     |    0
 .../iterate/MergeSortTopNResultIterator.java       |    0
 .../phoenix/iterate/OffsetResultIterator.java      |    0
 .../iterate/OrderedAggregatingResultIterator.java  |    0
 .../phoenix/iterate/OrderedResultIterator.java     |  426 ++
 .../phoenix/iterate/ParallelIteratorFactory.java   |    0
 .../iterate/ParallelIteratorRegionSplitter.java    |    0
 .../apache/phoenix/iterate/ParallelIterators.java  |    0
 .../phoenix/iterate/ParallelScanGrouper.java       |    0
 .../phoenix/iterate/ParallelScansCollector.java    |    0
 .../phoenix/iterate/PeekingResultIterator.java     |    0
 .../org/apache/phoenix/iterate/PhoenixQueues.java  |    0
 .../org/apache/phoenix/iterate/ResultIterator.java |    0
 .../apache/phoenix/iterate/ResultIterators.java    |    0
 .../phoenix/iterate/RoundRobinResultIterator.java  |  354 ++
 .../RowKeyOrderedAggregateResultIterator.java      |  200 +
 .../phoenix/iterate/ScanningResultIterator.java    |  236 +
 .../phoenix/iterate/ScansWithRegionLocations.java  |    0
 .../phoenix/iterate/SequenceResultIterator.java    |    0
 .../apache/phoenix/iterate/SerialIterators.java    |  231 +
 .../org/apache/phoenix/iterate/SizeAwareQueue.java |    0
 .../org/apache/phoenix/iterate/SizeBoundQueue.java |    0
 .../iterate/SpoolTooBigToDiskException.java        |    0
 .../phoenix/iterate/SpoolingResultIterator.java    |  381 ++
 .../phoenix/iterate/TableResultIterator.java       |  344 ++
 .../iterate/TableResultIteratorFactory.java        |    0
 .../phoenix/iterate/TableSamplerPredicate.java     |    0
 .../UngroupedAggregatingResultIterator.java        |    0
 .../phoenix/iterate/UnionResultIterators.java      |  166 +
 .../phoenix/jdbc/AbstractRPCConnectionInfo.java    |    0
 .../org/apache/phoenix/jdbc/ClusterRoleRecord.java |    0
 .../jdbc/ClusterRoleRecordGeneratorTool.java       |    0
 .../org/apache/phoenix/jdbc/ConnectionInfo.java    |    0
 .../apache/phoenix/jdbc/DelegateConnection.java    |    0
 .../phoenix/jdbc/DelegatePreparedStatement.java    |    0
 .../org/apache/phoenix/jdbc/DelegateResultSet.java |    0
 .../org/apache/phoenix/jdbc/DelegateStatement.java |    0
 .../phoenix/jdbc/FailoverPhoenixConnection.java    |    0
 .../org/apache/phoenix/jdbc/FailoverPolicy.java    |    0
 .../apache/phoenix/jdbc/HighAvailabilityGroup.java |    0
 .../phoenix/jdbc/HighAvailabilityPolicy.java       |    0
 .../phoenix/jdbc/LoggingPhoenixConnection.java     |    0
 .../jdbc/LoggingPhoenixPreparedStatement.java      |    0
 .../phoenix/jdbc/LoggingPhoenixResultSet.java      |    0
 .../phoenix/jdbc/LoggingPhoenixStatement.java      |    0
 .../apache/phoenix/jdbc/MasterConnectionInfo.java  |    0
 .../phoenix/jdbc/ParallelPhoenixConnection.java    |    0
 .../phoenix/jdbc/ParallelPhoenixContext.java       |    0
 .../phoenix/jdbc/ParallelPhoenixMetrics.java       |    0
 .../ParallelPhoenixNullComparingResultSet.java     |  333 +
 .../jdbc/ParallelPhoenixPreparedStatement.java     |    0
 .../phoenix/jdbc/ParallelPhoenixResultSet.java     |    0
 .../jdbc/ParallelPhoenixResultSetFactory.java      |    0
 .../phoenix/jdbc/ParallelPhoenixStatement.java     |    0
 .../apache/phoenix/jdbc/ParallelPhoenixUtil.java   |    0
 .../org/apache/phoenix/jdbc/PhoenixConnection.java |    0
 .../phoenix/jdbc/PhoenixDatabaseMetaData.java      | 1951 ++++++
 .../org/apache/phoenix/jdbc/PhoenixDriver.java     |    0
 .../apache/phoenix/jdbc/PhoenixEmbeddedDriver.java |  198 +
 .../apache/phoenix/jdbc/PhoenixHAAdminTool.java    |    0
 .../jdbc/PhoenixHAExecutorServiceProvider.java     |    0
 .../apache/phoenix/jdbc/PhoenixHAGroupMetrics.java |    0
 .../apache/phoenix/jdbc/PhoenixMetricsHolder.java  |    0
 .../org/apache/phoenix/jdbc/PhoenixMetricsLog.java |    0
 .../phoenix/jdbc/PhoenixMonitoredConnection.java   |    0
 .../jdbc/PhoenixMonitoredPreparedStatement.java    |    0
 .../phoenix/jdbc/PhoenixMonitoredResultSet.java    |    0
 .../phoenix/jdbc/PhoenixMonitoredStatement.java    |    0
 .../phoenix/jdbc/PhoenixParameterMetaData.java     |    0
 .../phoenix/jdbc/PhoenixPreparedStatement.java     |    0
 .../org/apache/phoenix/jdbc/PhoenixResultSet.java  | 1649 +++++
 .../phoenix/jdbc/PhoenixResultSetMetaData.java     |    0
 .../org/apache/phoenix/jdbc/PhoenixStatement.java  | 2650 ++++++++
 .../phoenix/jdbc/PhoenixStatementFactory.java      |    0
 .../org/apache/phoenix/jdbc/RPCConnectionInfo.java |    0
 .../org/apache/phoenix/jdbc/ZKConnectionInfo.java  |    0
 .../phoenix/job/AbstractRoundRobinQueue.java       |    0
 .../java/org/apache/phoenix/job/JobManager.java    |    0
 .../org/apache/phoenix/join/HashCacheClient.java   |  228 +
 .../org/apache/phoenix/join/HashCacheFactory.java  |  174 +
 .../java/org/apache/phoenix/join/HashJoinInfo.java |    0
 .../join/MaxServerCacheSizeExceededException.java  |    0
 .../org/apache/phoenix/log/ActivityLogInfo.java    |    0
 .../org/apache/phoenix/log/AuditQueryLogger.java   |    0
 .../apache/phoenix/log/BaseConnectionLimiter.java  |    0
 .../phoenix/log/ConnectionActivityLogger.java      |    0
 .../org/apache/phoenix/log/ConnectionLimiter.java  |    0
 .../phoenix/log/DefaultConnectionLimiter.java      |    0
 .../main/java/org/apache/phoenix/log/LogLevel.java |    0
 .../java/org/apache/phoenix/log/LogWriter.java     |    0
 .../phoenix/log/LoggingConnectionLimiter.java      |    0
 .../phoenix/log/QueryLogDetailsWorkHandler.java    |    0
 .../java/org/apache/phoenix/log/QueryLogInfo.java  |    0
 .../java/org/apache/phoenix/log/QueryLogger.java   |    0
 .../log/QueryLoggerDefaultExceptionHandler.java    |    0
 .../apache/phoenix/log/QueryLoggerDisruptor.java   |    0
 .../org/apache/phoenix/log/QueryLoggerUtil.java    |    0
 .../java/org/apache/phoenix/log/QueryStatus.java   |    0
 .../org/apache/phoenix/log/RingBufferEvent.java    |    0
 .../phoenix/log/RingBufferEventTranslator.java     |    0
 .../org/apache/phoenix/log/TableLogWriter.java     |    0
 .../phoenix/mapreduce/util/ConnectionUtil.java     |  141 +
 .../util/PhoenixConfigurationUtilHelper.java       |  148 +
 .../apache/phoenix/memory/ChildMemoryManager.java  |    0
 .../phoenix/memory/DelegatingMemoryManager.java    |    0
 .../apache/phoenix/memory/GlobalMemoryManager.java |    0
 .../memory/InsufficientMemoryException.java        |    0
 .../org/apache/phoenix/memory/MemoryManager.java   |    0
 .../org/apache/phoenix/metrics/MetricInfo.java     |    0
 .../java/org/apache/phoenix/metrics/Metrics.java   |    0
 .../apache/phoenix/monitoring/AtomicMetric.java    |    0
 .../phoenix/monitoring/CombinableMetric.java       |    0
 .../phoenix/monitoring/CombinableMetricImpl.java   |    0
 .../monitoring/ConnectionQueryServicesMetric.java  |    0
 .../ConnectionQueryServicesMetricImpl.java         |    0
 .../phoenix/monitoring/GlobalClientMetrics.java    |    0
 .../apache/phoenix/monitoring/GlobalMetric.java    |    0
 .../phoenix/monitoring/GlobalMetricImpl.java       |    0
 .../monitoring/GlobalMetricRegistriesAdapter.java  |    0
 .../phoenix/monitoring/HistogramDistribution.java  |    0
 .../monitoring/HistogramDistributionImpl.java      |    0
 .../phoenix/monitoring/JmxMetricProvider.java      |    0
 .../phoenix/monitoring/LatencyHistogram.java       |   46 +
 .../phoenix/monitoring/MemoryMetricsHolder.java    |    0
 .../java/org/apache/phoenix/monitoring/Metric.java |    0
 .../monitoring/MetricPublisherSupplierFactory.java |    0
 .../phoenix/monitoring/MetricServiceResolver.java  |    0
 .../org/apache/phoenix/monitoring/MetricType.java  |    0
 .../org/apache/phoenix/monitoring/MetricUtil.java  |    0
 .../apache/phoenix/monitoring/MetricsRegistry.java |    0
 .../phoenix/monitoring/MetricsStopWatch.java       |    0
 .../phoenix/monitoring/MutationMetricQueue.java    |    0
 .../phoenix/monitoring/NoOpGlobalMetricImpl.java   |    0
 .../monitoring/NoOpTableMetricsManager.java        |    0
 .../apache/phoenix/monitoring/NonAtomicMetric.java |    0
 .../phoenix/monitoring/OverAllQueryMetrics.java    |    0
 .../phoenix/monitoring/PhoenixTableMetric.java     |    0
 .../phoenix/monitoring/PhoenixTableMetricImpl.java |    0
 .../apache/phoenix/monitoring/RangeHistogram.java  |    0
 .../apache/phoenix/monitoring/ReadMetricQueue.java |    0
 .../phoenix/monitoring/ScanMetricsHolder.java      |    0
 .../apache/phoenix/monitoring/SizeHistogram.java   |   47 +
 .../phoenix/monitoring/SpoolingMetricsHolder.java  |    0
 .../phoenix/monitoring/TableClientMetrics.java     |    0
 .../apache/phoenix/monitoring/TableHistograms.java |    0
 .../phoenix/monitoring/TableMetricsManager.java    |    0
 .../monitoring/TaskExecutionMetricsHolder.java     |    0
 .../ConnectionQueryServicesHistogram.java          |   43 +
 .../ConnectionQueryServicesMetrics.java            |    0
 .../ConnectionQueryServicesMetricsHistograms.java  |    0
 .../ConnectionQueryServicesMetricsManager.java     |    0
 .../NoOpConnectionQueryServicesMetricsManager.java |    0
 .../java/org/apache/phoenix/optimize/Cost.java     |    0
 .../optimize/GenSubqueryParamValuesRewriter.java   |    0
 .../apache/phoenix/optimize/QueryOptimizer.java    |    0
 .../apache/phoenix/parse/AddColumnStatement.java   |    0
 .../org/apache/phoenix/parse/AddJarsStatement.java |    0
 .../org/apache/phoenix/parse/AddParseNode.java     |    0
 .../phoenix/parse/AggregateFunctionParseNode.java  |    0
 .../AggregateFunctionWithinGroupParseNode.java     |    0
 .../java/org/apache/phoenix/parse/AliasedNode.java |    0
 .../apache/phoenix/parse/AlterIndexStatement.java  |    0
 .../phoenix/parse/AlterSessionStatement.java       |    0
 .../apache/phoenix/parse/AlterTableStatement.java  |    0
 .../phoenix/parse/AndBooleanParseNodeVisitor.java  |    0
 .../org/apache/phoenix/parse/AndParseNode.java     |    0
 .../parse/AndRewriterBooleanParseNodeVisitor.java  |    0
 .../apache/phoenix/parse/ArithmeticParseNode.java  |    0
 .../phoenix/parse/ArrayAllAnyComparisonNode.java   |    0
 .../phoenix/parse/ArrayAllComparisonNode.java      |    0
 .../phoenix/parse/ArrayAnyComparisonNode.java      |    0
 .../apache/phoenix/parse/ArrayConstructorNode.java |    0
 .../org/apache/phoenix/parse/ArrayElemRefNode.java |    0
 .../phoenix/parse/ArrayModifierParseNode.java      |    0
 .../phoenix/parse/AvgAggregateParseNode.java       |    0
 .../apache/phoenix/parse/BaseParseNodeVisitor.java |    0
 .../org/apache/phoenix/parse/BetweenParseNode.java |    0
 .../org/apache/phoenix/parse/BinaryParseNode.java  |    0
 .../org/apache/phoenix/parse/BindParseNode.java    |    0
 .../org/apache/phoenix/parse/BindTableNode.java    |    0
 .../apache/phoenix/parse/BindableStatement.java    |    0
 .../phoenix/parse/BooleanParseNodeVisitor.java     |    0
 .../org/apache/phoenix/parse/CaseParseNode.java    |    0
 .../org/apache/phoenix/parse/CastParseNode.java    |    0
 .../org/apache/phoenix/parse/CeilParseNode.java    |    0
 .../apache/phoenix/parse/ChangePermsStatement.java |    0
 .../org/apache/phoenix/parse/CloseStatement.java   |    0
 .../java/org/apache/phoenix/parse/ColumnDef.java   |    0
 .../phoenix/parse/ColumnDefInPkConstraint.java     |    0
 .../org/apache/phoenix/parse/ColumnFamilyDef.java  |    0
 .../java/org/apache/phoenix/parse/ColumnName.java  |    0
 .../org/apache/phoenix/parse/ColumnParseNode.java  |    0
 .../apache/phoenix/parse/ComparisonParseNode.java  |    0
 .../apache/phoenix/parse/CompoundParseNode.java    |    0
 .../apache/phoenix/parse/ConcreteTableNode.java    |    0
 .../phoenix/parse/CreateFunctionStatement.java     |    0
 .../apache/phoenix/parse/CreateIndexStatement.java |    0
 .../phoenix/parse/CreateSchemaStatement.java       |    0
 .../phoenix/parse/CreateSequenceStatement.java     |    0
 .../apache/phoenix/parse/CreateTableStatement.java |    0
 .../apache/phoenix/parse/CurrentDateParseNode.java |    0
 .../apache/phoenix/parse/CurrentTimeParseNode.java |    0
 .../java/org/apache/phoenix/parse/CursorName.java  |    0
 .../org/apache/phoenix/parse/DMLStatement.java     |    0
 .../phoenix/parse/DeclareCursorStatement.java      |    0
 .../parse/DelegateConstantToCountParseNode.java    |    0
 .../apache/phoenix/parse/DeleteJarStatement.java   |    0
 .../org/apache/phoenix/parse/DeleteStatement.java  |    0
 .../org/apache/phoenix/parse/DerivedTableNode.java |    0
 ...DistinctCountHyperLogLogAggregateParseNode.java |    0
 .../phoenix/parse/DistinctCountParseNode.java      |    0
 .../org/apache/phoenix/parse/DivideParseNode.java  |    0
 .../apache/phoenix/parse/DropColumnStatement.java  |    0
 .../phoenix/parse/DropFunctionStatement.java       |    0
 .../apache/phoenix/parse/DropIndexStatement.java   |    0
 .../apache/phoenix/parse/DropSchemaStatement.java  |    0
 .../phoenix/parse/DropSequenceStatement.java       |    0
 .../apache/phoenix/parse/DropTableStatement.java   |    0
 .../org/apache/phoenix/parse/EqualParseNode.java   |    0
 .../phoenix/parse/ExecuteUpgradeStatement.java     |    0
 .../org/apache/phoenix/parse/ExistsParseNode.java  |    0
 .../org/apache/phoenix/parse/ExplainStatement.java |    0
 .../java/org/apache/phoenix/parse/ExplainType.java |    0
 .../phoenix/parse/FamilyWildcardParseNode.java     |    0
 .../org/apache/phoenix/parse/FetchStatement.java   |    0
 .../apache/phoenix/parse/FilterableStatement.java  |    0
 .../parse/FirstValueAggregateParseNode.java        |    0
 .../parse/FirstValuesAggregateParseNode.java       |    0
 .../org/apache/phoenix/parse/FloorParseNode.java   |    0
 .../apache/phoenix/parse/FunctionParseNode.java    |    0
 .../phoenix/parse/GreaterThanOrEqualParseNode.java |    0
 .../apache/phoenix/parse/GreaterThanParseNode.java |    0
 .../java/org/apache/phoenix/parse/HintNode.java    |    0
 .../org/apache/phoenix/parse/InListParseNode.java  |    0
 .../java/org/apache/phoenix/parse/InParseNode.java |    0
 .../parse/IndexExpressionParseNodeRewriter.java    |    0
 .../apache/phoenix/parse/IndexKeyConstraint.java   |    0
 .../org/apache/phoenix/parse/IsNullParseNode.java  |    0
 .../org/apache/phoenix/parse/JoinTableNode.java    |    0
 .../phoenix/parse/LastValueAggregateParseNode.java |    0
 .../parse/LastValuesAggregateParseNode.java        |    0
 .../phoenix/parse/LessThanOrEqualParseNode.java    |    0
 .../apache/phoenix/parse/LessThanParseNode.java    |    0
 .../org/apache/phoenix/parse/LikeParseNode.java    |    0
 .../java/org/apache/phoenix/parse/LimitNode.java   |    0
 .../apache/phoenix/parse/ListJarsStatement.java    |    0
 .../org/apache/phoenix/parse/LiteralParseNode.java |    0
 .../phoenix/parse/MaxAggregateParseNode.java       |    0
 .../phoenix/parse/MinAggregateParseNode.java       |    0
 .../org/apache/phoenix/parse/ModulusParseNode.java |    0
 .../apache/phoenix/parse/MultiplyParseNode.java    |    0
 .../org/apache/phoenix/parse/MutableStatement.java |    0
 .../java/org/apache/phoenix/parse/NamedNode.java   |    0
 .../org/apache/phoenix/parse/NamedParseNode.java   |    0
 .../org/apache/phoenix/parse/NamedTableNode.java   |    0
 .../apache/phoenix/parse/NotEqualParseNode.java    |    0
 .../org/apache/phoenix/parse/NotParseNode.java     |    0
 .../phoenix/parse/NthValueAggregateParseNode.java  |    0
 .../java/org/apache/phoenix/parse/OffsetNode.java  |    0
 .../org/apache/phoenix/parse/OpenStatement.java    |    0
 .../java/org/apache/phoenix/parse/OrParseNode.java |    0
 .../java/org/apache/phoenix/parse/OrderByNode.java |    0
 .../java/org/apache/phoenix/parse/PFunction.java   |    0
 .../java/org/apache/phoenix/parse/PSchema.java     |    0
 .../org/apache/phoenix/parse/ParseContext.java     |    0
 .../org/apache/phoenix/parse/ParseException.java   |    0
 .../java/org/apache/phoenix/parse/ParseNode.java   |    0
 .../org/apache/phoenix/parse/ParseNodeFactory.java |    0
 .../apache/phoenix/parse/ParseNodeRewriter.java    |    0
 .../org/apache/phoenix/parse/ParseNodeVisitor.java |    0
 .../parse/PhoenixRowTimestampParseNode.java        |   98 +
 .../apache/phoenix/parse/PrimaryKeyConstraint.java |    0
 .../org/apache/phoenix/parse/PropertyName.java     |    0
 .../phoenix/parse/RegexpReplaceParseNode.java      |    0
 .../apache/phoenix/parse/RegexpSplitParseNode.java |    0
 .../phoenix/parse/RegexpSubstrParseNode.java       |    0
 .../org/apache/phoenix/parse/RoundParseNode.java   |    0
 .../parse/RowValueConstructorParseNode.java        |    0
 .../java/org/apache/phoenix/parse/SQLParser.java   |    0
 .../org/apache/phoenix/parse/SelectStatement.java  |    0
 .../phoenix/parse/SelectStatementRewriter.java     |    0
 .../phoenix/parse/SequenceValueParseNode.java      |    0
 .../org/apache/phoenix/parse/ShowCreateTable.java  |    0
 .../phoenix/parse/ShowCreateTableStatement.java    |    0
 .../apache/phoenix/parse/ShowSchemasStatement.java |    0
 .../org/apache/phoenix/parse/ShowStatement.java    |    0
 .../apache/phoenix/parse/ShowTablesStatement.java  |    0
 .../apache/phoenix/parse/SingleTableStatement.java |    0
 .../StatelessTraverseAllParseNodeVisitor.java      |    0
 .../phoenix/parse/StringConcatParseNode.java       |    0
 .../apache/phoenix/parse/SubqueryParseNode.java    |    0
 .../apache/phoenix/parse/SubtractParseNode.java    |    0
 .../phoenix/parse/SumAggregateParseNode.java       |    0
 .../java/org/apache/phoenix/parse/TableName.java   |    0
 .../java/org/apache/phoenix/parse/TableNode.java   |    0
 .../org/apache/phoenix/parse/TableNodeVisitor.java |    0
 .../phoenix/parse/TableWildcardParseNode.java      |    0
 .../apache/phoenix/parse/TerminalParseNode.java    |    0
 .../org/apache/phoenix/parse/ToCharParseNode.java  |    0
 .../org/apache/phoenix/parse/ToDateParseNode.java  |    0
 .../apache/phoenix/parse/ToNumberParseNode.java    |    0
 .../org/apache/phoenix/parse/ToTimeParseNode.java  |    0
 .../apache/phoenix/parse/ToTimestampParseNode.java |    0
 .../org/apache/phoenix/parse/TraceStatement.java   |    0
 .../phoenix/parse/TraverseAllParseNodeVisitor.java |    0
 .../phoenix/parse/TraverseNoParseNodeVisitor.java  |    0
 .../org/apache/phoenix/parse/UDFParseNode.java     |    0
 .../org/apache/phoenix/parse/UnaryParseNode.java   |    0
 .../parse/UnsupportedAllParseNodeVisitor.java      |    0
 .../phoenix/parse/UpdateStatisticsStatement.java   |    0
 .../org/apache/phoenix/parse/UpsertStatement.java  |    0
 .../apache/phoenix/parse/UseSchemaStatement.java   |    0
 .../apache/phoenix/parse/WildcardParseNode.java    |    0
 .../org/apache/phoenix/protobuf/ProtobufUtil.java  |    0
 .../phoenix/query/AdminUtilWithFallback.java       |    0
 .../phoenix/query/BaseQueryServicesImpl.java       |    0
 .../query/ChildLinkMetaDataServiceCallBack.java    |    0
 .../apache/phoenix/query/ChildQueryServices.java   |    0
 .../apache/phoenix/query/ConfigurationFactory.java |    0
 .../phoenix/query/ConnectionQueryServices.java     |  237 +
 .../phoenix/query/ConnectionQueryServicesImpl.java | 6418 +++++++++++++++++++
 .../query/ConnectionlessQueryServicesImpl.java     |  834 +++
 .../query/DefaultGuidePostsCacheFactory.java       |    0
 .../query/DelegateConnectionQueryServices.java     |  442 ++
 .../phoenix/query/DelegateQueryServices.java       |    0
 .../org/apache/phoenix/query/EmptyStatsLoader.java |    0
 .../org/apache/phoenix/query/GuidePostsCache.java  |    0
 .../phoenix/query/GuidePostsCacheFactory.java      |    0
 .../apache/phoenix/query/GuidePostsCacheImpl.java  |    0
 .../phoenix/query/GuidePostsCacheProvider.java     |    0
 .../phoenix/query/GuidePostsCacheWrapper.java      |    0
 .../apache/phoenix/query/HBaseFactoryProvider.java |    0
 .../apache/phoenix/query/HConnectionFactory.java   |    0
 .../org/apache/phoenix/query/HTableFactory.java    |    0
 .../phoenix/query/ITGuidePostsCacheFactory.java    |    0
 .../java/org/apache/phoenix/query/KeyRange.java    |    0
 .../org/apache/phoenix/query/MetaDataMutated.java  |    0
 .../phoenix/query/PhoenixStatsCacheLoader.java     |    0
 .../apache/phoenix/query/PhoenixStatsLoader.java   |    0
 .../phoenix/query/PropertyNotAllowedException.java |    0
 .../org/apache/phoenix/query/PropertyPolicy.java   |    0
 .../phoenix/query/PropertyPolicyProvider.java      |    0
 .../org/apache/phoenix/query/QueryConstants.java   |  617 ++
 .../org/apache/phoenix/query/QueryServices.java    |  481 ++
 .../apache/phoenix/query/QueryServicesImpl.java    |    0
 .../apache/phoenix/query/QueryServicesOptions.java |  975 +++
 .../org/apache/phoenix/query/StatsLoaderImpl.java  |    0
 .../phoenix/schema/AmbiguousColumnException.java   |    0
 .../phoenix/schema/AmbiguousTableException.java    |    0
 .../schema/ArgumentTypeMismatchException.java      |    0
 .../schema/ColumnAlreadyExistsException.java       |    0
 .../schema/ColumnFamilyNotFoundException.java      |    0
 .../apache/phoenix/schema/ColumnMetaDataOps.java   |    0
 .../org/apache/phoenix/schema/ColumnModifier.java  |    0
 .../phoenix/schema/ColumnNotFoundException.java    |    0
 .../java/org/apache/phoenix/schema/ColumnRef.java  |    0
 .../apache/phoenix/schema/ColumnValueDecoder.java  |    0
 .../apache/phoenix/schema/ColumnValueEncoder.java  |    0
 .../schema/ConcurrentTableMutationException.java   |    0
 .../apache/phoenix/schema/ConnectionProperty.java  |    0
 .../schema/ConstraintViolationException.java       |    0
 .../org/apache/phoenix/schema/DelegateColumn.java  |    0
 .../org/apache/phoenix/schema/DelegateDatum.java   |    0
 .../phoenix/schema/DelegateSQLException.java       |    0
 .../org/apache/phoenix/schema/DelegateTable.java   |    0
 .../schema/EmptySequenceCacheException.java        |    0
 .../schema/ExecuteQueryNotApplicableException.java |    0
 .../ExecuteUpdateNotApplicableException.java       |    0
 .../schema/FunctionAlreadyExistsException.java     |    0
 .../phoenix/schema/FunctionNotFoundException.java  |    0
 .../phoenix/schema/IllegalDataException.java       |    0
 .../phoenix/schema/IndexNotFoundException.java     |    0
 .../schema/IndexUncoveredDataColumnRef.java        |    0
 .../org/apache/phoenix/schema/KeyValueSchema.java  |    0
 .../MaxMutationSizeBytesExceededException.java     |    0
 .../schema/MaxMutationSizeExceededException.java   |    0
 .../MaxPhoenixColumnSizeExceededException.java     |    0
 .../org/apache/phoenix/schema/MetaDataClient.java  | 6028 ++++++++++++++++++
 .../schema/MetaDataEntityNotFoundException.java    |    0
 .../NewerFunctionAlreadyExistsException.java       |    0
 .../schema/NewerSchemaAlreadyExistsException.java  |    0
 .../schema/NewerTableAlreadyExistsException.java   |    0
 .../java/org/apache/phoenix/schema/PColumn.java    |    0
 .../org/apache/phoenix/schema/PColumnFamily.java   |    0
 .../apache/phoenix/schema/PColumnFamilyImpl.java   |    0
 .../org/apache/phoenix/schema/PColumnImpl.java     |    0
 .../java/org/apache/phoenix/schema/PDatum.java     |    0
 .../org/apache/phoenix/schema/PIndexState.java     |    0
 .../java/org/apache/phoenix/schema/PMetaData.java  |    0
 .../org/apache/phoenix/schema/PMetaDataCache.java  |    0
 .../org/apache/phoenix/schema/PMetaDataEntity.java |    0
 .../org/apache/phoenix/schema/PMetaDataImpl.java   |    0
 .../main/java/org/apache/phoenix/schema/PName.java |    0
 .../org/apache/phoenix/schema/PNameFactory.java    |    0
 .../java/org/apache/phoenix/schema/PNameImpl.java  |    0
 .../main/java/org/apache/phoenix/schema/PRow.java  |   87 +
 .../phoenix/schema/PSynchronizedMetaData.java      |    0
 .../java/org/apache/phoenix/schema/PTable.java     |    0
 .../java/org/apache/phoenix/schema/PTableImpl.java | 2467 ++++++++
 .../java/org/apache/phoenix/schema/PTableKey.java  |    0
 .../java/org/apache/phoenix/schema/PTableRef.java  |    0
 .../apache/phoenix/schema/PTableRefFactory.java    |    0
 .../org/apache/phoenix/schema/PTableRefImpl.java   |    0
 .../java/org/apache/phoenix/schema/PTableType.java |    0
 .../org/apache/phoenix/schema/ProjectedColumn.java |    0
 .../phoenix/schema/ReadOnlyTableException.java     |    0
 .../org/apache/phoenix/schema/RowKeySchema.java    |    0
 .../apache/phoenix/schema/RowKeyValueAccessor.java |    0
 ...lueConstructorOffsetInternalErrorException.java |    0
 ...onstructorOffsetNotAllowedInQueryException.java |    0
 ...alueConstructorOffsetNotCoercibleException.java |    0
 .../org/apache/phoenix/schema/SaltingUtil.java     |    0
 .../schema/SchemaAlreadyExistsException.java       |    0
 .../phoenix/schema/SchemaNotFoundException.java    |    0
 .../java/org/apache/phoenix/schema/Sequence.java   |  639 ++
 .../apache/phoenix/schema/SequenceAllocation.java  |    0
 .../schema/SequenceAlreadyExistsException.java     |    0
 .../org/apache/phoenix/schema/SequenceInfo.java    |    0
 .../org/apache/phoenix/schema/SequenceKey.java     |    0
 .../phoenix/schema/SequenceNotFoundException.java  |    0
 .../apache/phoenix/schema/SerializedPTableRef.java |    0
 .../phoenix/schema/SerializedPTableRefFactory.java |    0
 .../java/org/apache/phoenix/schema/SortOrder.java  |    0
 .../schema/StaleRegionBoundaryCacheException.java  |    0
 .../schema/TableAlreadyExistsException.java        |    0
 .../phoenix/schema/TableNotFoundException.java     |    0
 .../org/apache/phoenix/schema/TableProperty.java   |    0
 .../java/org/apache/phoenix/schema/TableRef.java   |    0
 .../phoenix/schema/TablesNotInSyncException.java   |    0
 .../phoenix/schema/TypeMismatchException.java      |    0
 .../UpsertColumnsValuesMismatchException.java      |    0
 .../org/apache/phoenix/schema/ValueBitSet.java     |    0
 .../apache/phoenix/schema/ValueRangeExcpetion.java |    0
 .../org/apache/phoenix/schema/ValueSchema.java     |    0
 .../export/DefaultSchemaRegistryRepository.java    |    0
 .../phoenix/schema/export/DefaultSchemaWriter.java |    0
 .../phoenix/schema/export/SchemaImporter.java      |    0
 .../schema/export/SchemaRegistryRepository.java    |    0
 .../export/SchemaRegistryRepositoryFactory.java    |    0
 .../apache/phoenix/schema/export/SchemaWriter.java |    0
 .../phoenix/schema/export/SchemaWriterFactory.java |    0
 .../schema/metrics/MetricsMetadataSource.java      |    0
 .../metrics/MetricsMetadataSourceFactory.java      |    0
 .../schema/metrics/MetricsMetadataSourceImpl.java  |    0
 .../phoenix/schema/stats/GuidePostsInfo.java       |    0
 .../schema/stats/GuidePostsInfoBuilder.java        |    0
 .../apache/phoenix/schema/stats/GuidePostsKey.java |    0
 .../stats/StatisticsCollectionRunTracker.java      |    0
 .../schema/stats/StatisticsCollectionScope.java    |    0
 .../phoenix/schema/stats/StatisticsUtil.java       |  253 +
 .../StatsCollectionDisabledOnServerException.java  |    0
 .../phoenix/schema/task/SystemTaskParams.java      |    0
 .../java/org/apache/phoenix/schema/task/Task.java  |  423 ++
 .../schema/tool/SchemaExtractionProcessor.java     |    0
 .../phoenix/schema/tool/SchemaProcessor.java       |    0
 .../apache/phoenix/schema/tool/SchemaSQLUtil.java  |    0
 .../schema/tool/SchemaSynthesisProcessor.java      |    0
 .../org/apache/phoenix/schema/tool/SchemaTool.java |    0
 .../schema/transform/SystemTransformRecord.java    |    0
 .../phoenix/schema/transform/TransformClient.java  |  432 ++
 .../schema/transform/TransformMaintainer.java      |    0
 .../org/apache/phoenix/schema/tuple/BaseTuple.java |    0
 .../apache/phoenix/schema/tuple/DelegateTuple.java |    0
 .../tuple/EncodedColumnQualiferCellsList.java      |    0
 .../phoenix/schema/tuple/MultiKeyValueTuple.java   |    0
 .../tuple/PositionBasedMultiKeyValueTuple.java     |    0
 .../schema/tuple/PositionBasedResultTuple.java     |    0
 .../apache/phoenix/schema/tuple/ResultTuple.java   |    0
 .../phoenix/schema/tuple/SingleKeyValueTuple.java  |    0
 .../org/apache/phoenix/schema/tuple/Tuple.java     |    0
 .../phoenix/schema/tuple/ValueGetterTuple.java     |    0
 .../phoenix/schema/types/PArrayDataType.java       |    0
 .../schema/types/PArrayDataTypeDecoder.java        |    0
 .../schema/types/PArrayDataTypeEncoder.java        |    0
 .../org/apache/phoenix/schema/types/PBinary.java   |    0
 .../apache/phoenix/schema/types/PBinaryArray.java  |    0
 .../apache/phoenix/schema/types/PBinaryBase.java   |    0
 .../org/apache/phoenix/schema/types/PBoolean.java  |    0
 .../apache/phoenix/schema/types/PBooleanArray.java |    0
 .../org/apache/phoenix/schema/types/PChar.java     |    0
 .../apache/phoenix/schema/types/PCharArray.java    |    0
 .../org/apache/phoenix/schema/types/PDataType.java |    0
 .../phoenix/schema/types/PDataTypeFactory.java     |    0
 .../org/apache/phoenix/schema/types/PDate.java     |    0
 .../apache/phoenix/schema/types/PDateArray.java    |    0
 .../org/apache/phoenix/schema/types/PDecimal.java  |    0
 .../apache/phoenix/schema/types/PDecimalArray.java |    0
 .../org/apache/phoenix/schema/types/PDouble.java   |    0
 .../apache/phoenix/schema/types/PDoubleArray.java  |    0
 .../org/apache/phoenix/schema/types/PFloat.java    |    0
 .../apache/phoenix/schema/types/PFloatArray.java   |    0
 .../org/apache/phoenix/schema/types/PInteger.java  |    0
 .../apache/phoenix/schema/types/PIntegerArray.java |    0
 .../org/apache/phoenix/schema/types/PLong.java     |    0
 .../apache/phoenix/schema/types/PLongArray.java    |    0
 .../apache/phoenix/schema/types/PNumericType.java  |    0
 .../apache/phoenix/schema/types/PRealNumber.java   |    0
 .../org/apache/phoenix/schema/types/PSmallint.java |    0
 .../phoenix/schema/types/PSmallintArray.java       |    0
 .../org/apache/phoenix/schema/types/PTime.java     |    0
 .../apache/phoenix/schema/types/PTimeArray.java    |    0
 .../apache/phoenix/schema/types/PTimestamp.java    |    0
 .../phoenix/schema/types/PTimestampArray.java      |    0
 .../org/apache/phoenix/schema/types/PTinyint.java  |    0
 .../apache/phoenix/schema/types/PTinyintArray.java |    0
 .../apache/phoenix/schema/types/PUnsignedDate.java |    0
 .../phoenix/schema/types/PUnsignedDateArray.java   |    0
 .../phoenix/schema/types/PUnsignedDouble.java      |    0
 .../phoenix/schema/types/PUnsignedDoubleArray.java |    0
 .../phoenix/schema/types/PUnsignedFloat.java       |    0
 .../phoenix/schema/types/PUnsignedFloatArray.java  |    0
 .../apache/phoenix/schema/types/PUnsignedInt.java  |    0
 .../phoenix/schema/types/PUnsignedIntArray.java    |    0
 .../apache/phoenix/schema/types/PUnsignedLong.java |    0
 .../phoenix/schema/types/PUnsignedLongArray.java   |    0
 .../phoenix/schema/types/PUnsignedSmallint.java    |    0
 .../schema/types/PUnsignedSmallintArray.java       |    0
 .../apache/phoenix/schema/types/PUnsignedTime.java |    0
 .../phoenix/schema/types/PUnsignedTimeArray.java   |    0
 .../phoenix/schema/types/PUnsignedTimestamp.java   |    0
 .../schema/types/PUnsignedTimestampArray.java      |    0
 .../phoenix/schema/types/PUnsignedTinyint.java     |    0
 .../schema/types/PUnsignedTinyintArray.java        |    0
 .../apache/phoenix/schema/types/PVarbinary.java    |    0
 .../phoenix/schema/types/PVarbinaryArray.java      |    0
 .../org/apache/phoenix/schema/types/PVarchar.java  |    0
 .../apache/phoenix/schema/types/PVarcharArray.java |    0
 .../apache/phoenix/schema/types/PWholeNumber.java  |    0
 .../apache/phoenix/schema/types/PhoenixArray.java  |    0
 .../org/apache/phoenix/trace/MetricsInfoImpl.java  |    0
 .../apache/phoenix/trace/PhoenixMetricsSink.java   |    0
 .../java/org/apache/phoenix/trace/TraceReader.java |    0
 .../apache/phoenix/trace/TraceSpanReceiver.java    |    0
 .../java/org/apache/phoenix/trace/TraceWriter.java |    0
 .../org/apache/phoenix/trace/TracingIterator.java  |    0
 .../org/apache/phoenix/trace/TracingUtils.java     |    0
 .../phoenix/trace/util/ConfigurationAdapter.java   |    0
 .../org/apache/phoenix/trace/util/NullSpan.java    |    0
 .../org/apache/phoenix/trace/util/Tracing.java     |    0
 .../NotAvailableTransactionProvider.java           |    0
 .../transaction/OmidTransactionContext.java        |    0
 .../transaction/OmidTransactionProvider.java       |  134 +
 .../phoenix/transaction/OmidTransactionTable.java  |    0
 .../transaction/PhoenixTransactionClient.java      |    0
 .../transaction/PhoenixTransactionContext.java     |    0
 .../transaction/PhoenixTransactionProvider.java    |    0
 .../phoenix/transaction/TransactionFactory.java    |   86 +
 .../org/apache/phoenix/util/Base62Encoder.java     |    0
 .../org/apache/phoenix/util/BigDecimalUtil.java    |    0
 .../main/java/org/apache/phoenix/util/BitSet.java  |    0
 .../java/org/apache/phoenix/util/ByteUtil.java     |    0
 .../org/apache/phoenix/util/CSVCommonsLoader.java  |    0
 .../java/org/apache/phoenix/util/ClientUtil.java   |  209 +
 .../java/org/apache/phoenix/util/Closeables.java   |    0
 .../java/org/apache/phoenix/util/ColumnInfo.java   |    0
 .../java/org/apache/phoenix/util/ConfigUtil.java   |    0
 .../java/org/apache/phoenix/util/CostUtil.java     |    0
 .../java/org/apache/phoenix/util/CursorUtil.java   |    0
 .../java/org/apache/phoenix/util/DateUtil.java     |    0
 .../phoenix/util/DefaultEnvironmentEdge.java       |    0
 .../apache/phoenix/util/DeferredStringBuilder.java |    0
 .../apache/phoenix/util/EncodedColumnsUtil.java    |  207 +
 .../org/apache/phoenix/util/EnvironmentEdge.java   |    0
 .../phoenix/util/EnvironmentEdgeManager.java       |    0
 .../phoenix/util/EquiDepthStreamHistogram.java     |    0
 .../org/apache/phoenix/util/ExpressionUtil.java    |    0
 .../util/FirstLastNthValueDataContainer.java       |    0
 .../java/org/apache/phoenix/util/IndexUtil.java    | 1001 +++
 .../org/apache/phoenix/util/InstanceResolver.java  |    0
 .../java/org/apache/phoenix/util/JDBCUtil.java     |    0
 .../java/org/apache/phoenix/util/JacksonUtil.java  |    0
 .../main/java/org/apache/phoenix/util/LogUtil.java |    0
 .../org/apache/phoenix/util/MajorMinorVersion.java |    0
 .../apache/phoenix/util/ManualEnvironmentEdge.java |    0
 .../java/org/apache/phoenix/util/MetaDataUtil.java | 1185 ++++
 .../java/org/apache/phoenix/util/NumberUtil.java   |    0
 .../org/apache/phoenix/util/ParseNodeUtil.java     |    0
 .../phoenix/util/PhoenixContextExecutor.java       |    0
 .../apache/phoenix/util/PhoenixKeyValueUtil.java   |    0
 .../org/apache/phoenix/util/PhoenixRuntime.java    | 1713 ++++++
 .../org/apache/phoenix/util/PhoenixStopWatch.java  |    0
 .../org/apache/phoenix/util/PrefixByteCodec.java   |    0
 .../org/apache/phoenix/util/PrefixByteDecoder.java |    0
 .../org/apache/phoenix/util/PrefixByteEncoder.java |    0
 .../org/apache/phoenix/util/PropertiesUtil.java    |    0
 .../java/org/apache/phoenix/util/QueryBuilder.java |    0
 .../java/org/apache/phoenix/util/QueryUtil.java    |    0
 .../org/apache/phoenix/util/ReadOnlyProps.java     |    0
 .../java/org/apache/phoenix/util/ResultUtil.java   |    0
 .../java/org/apache/phoenix/util/SQLCloseable.java |    0
 .../org/apache/phoenix/util/SQLCloseables.java     |    0
 .../java/org/apache/phoenix/util/ScanUtil.java     | 1618 +++++
 .../java/org/apache/phoenix/util/SchemaUtil.java   |    0
 .../java/org/apache/phoenix/util/SequenceUtil.java |    0
 .../java/org/apache/phoenix/util/SizedUtil.java    |    0
 .../java/org/apache/phoenix/util/StringUtil.java   |    0
 .../apache/phoenix/util/TableViewFinderResult.java |   49 +
 .../phoenix/util/TaskMetaDataServiceCallBack.java  |    0
 .../java/org/apache/phoenix/util/TimeKeeper.java   |    0
 .../org/apache/phoenix/util/TransactionUtil.java   |  171 +
 .../phoenix/util/TrustedByteArrayOutputStream.java |    0
 .../java/org/apache/phoenix/util/TupleUtil.java    |    0
 .../java/org/apache/phoenix/util/UpgradeUtil.java  | 2923 +++++++++
 .../org/apache/phoenix/util/UpsertExecutor.java    |    0
 .../phoenix/util/ValidateLastDDLTimestampUtil.java |  209 +
 .../apache/phoenix/util/VarBinaryFormatter.java    |    0
 .../phoenix/util/ViewIndexIdRetrieveUtil.java      |    0
 .../java/org/apache/phoenix/util/ViewUtil.java     |  889 +++
 .../org/apache/phoenix/util/WALAnnotationUtil.java |   58 +
 .../apache/phoenix/util/csv/CsvUpsertExecutor.java |    0
 .../phoenix/util/csv/StringToArrayConverter.java   |    0
 .../apache/phoenix/util/i18n/LinguisticSort.java   |    0
 .../org/apache/phoenix/util/i18n/LocaleUtils.java  |    0
 .../org/apache/phoenix/util/i18n/OracleUpper.java  |    0
 .../apache/phoenix/util/i18n/OracleUpperTable.java |    0
 .../org/apache/phoenix/util/i18n/package-info.java |    0
 .../phoenix/util/json/JsonUpsertExecutor.java      |    0
 .../phoenix/util/json/ObjectToArrayConverter.java  |    0
 .../phoenix/util/regex/RegexUpsertExecutor.java    |    0
 .../src/main/java/overview.html                    |    0
 .../main/protobuf/ChildLinkMetaDataService.proto   |    0
 .../src/main/protobuf/DynamicColumnMetaData.proto  |    0
 .../src/main/protobuf/MetaDataService.proto        |    0
 .../src/main/protobuf/PFunction.proto              |    0
 .../src/main/protobuf/PGuidePosts.proto            |    0
 .../src/main/protobuf/PSchema.proto                |    0
 .../src/main/protobuf/PTable.proto                 |    0
 .../protobuf/RegionServerEndpointService.proto     |    0
 .../src/main/protobuf/ServerCacheFactory.proto     |    0
 .../src/main/protobuf/ServerCachingService.proto   |    0
 .../src/main/protobuf/TaskMetaDataService.proto    |    0
 .../resources/META-INF/services/java.sql.Driver    |    0
 ...oenix.monitoring.MetricPublisherSupplierFactory |    0
 ...org.apache.phoenix.query.GuidePostsCacheFactory |    0
 .../resources/phoenix-canary-file-sink.properties  |    0
 phoenix-core-server/pom.xml                        |  195 +
 .../hadoop/hbase/ipc/PhoenixRpcScheduler.java      |    0
 .../hbase/ipc/PhoenixRpcSchedulerFactory.java      |   90 +
 .../java/org/apache/hadoop/hbase/ipc/RpcUtil.java  |    0
 ...erRegionServerMetadataRpcControllerFactory.java |    0
 .../ipc/controller/ServerRpcControllerFactory.java |    0
 .../DataTableLocalIndexRegionScanner.java          |    0
 .../regionserver/IndexHalfStoreFileReader.java     |  174 +
 .../IndexHalfStoreFileReaderGenerator.java         |  310 +
 .../regionserver/IndexKeyValueSkipListSet.java     |    0
 .../hbase/regionserver/KeyValueSkipListSet.java    |    0
 .../hbase/regionserver/LocalIndexSplitter.java     |    0
 .../regionserver/LocalIndexStoreFileScanner.java   |    0
 .../hbase/regionserver/ScannerContextUtil.java     |    0
 .../wal/BinaryCompatibleBaseDecoder.java           |    0
 .../hbase/regionserver/wal/IndexedHLogReader.java  |    0
 .../regionserver/wal/IndexedWALEditCodec.java      |    0
 .../java/org/apache/phoenix/cache/GlobalCache.java |    0
 .../apache/phoenix/cache/aggcache/SpillFile.java   |    0
 .../phoenix/cache/aggcache/SpillManager.java       |    0
 .../apache/phoenix/cache/aggcache/SpillMap.java    |    0
 .../cache/aggcache/SpillableGroupByCache.java      |    0
 .../phoenix/coprocessor/AddColumnMutator.java      |  457 ++
 .../coprocessor/BaseMetaDataEndpointObserver.java  |    0
 .../phoenix/coprocessor/BaseRegionScanner.java     |    0
 .../coprocessor/BaseScannerRegionObserver.java     |  500 ++
 .../coprocessor/ChildLinkMetaDataEndpoint.java     |    0
 .../apache/phoenix/coprocessor/ColumnMutator.java  |   67 +
 .../phoenix/coprocessor/CompactionScanner.java     |    0
 .../DelegateRegionCoprocessorEnvironment.java      |    0
 .../coprocessor/DelegateRegionObserver.java        |    0
 .../phoenix/coprocessor/DelegateRegionScanner.java |    0
 .../phoenix/coprocessor/DropColumnMutator.java     |  306 +
 .../coprocessor/GlobalIndexRegionScanner.java      | 1518 +++++
 .../apache/phoenix/coprocessor/GroupByCache.java   |    0
 .../GroupedAggregateRegionObserver.java            |  613 ++
 .../phoenix/coprocessor/HashJoinRegionScanner.java |  414 ++
 .../coprocessor/IndexRebuildRegionScanner.java     |  388 ++
 .../coprocessor/IndexRepairRegionScanner.java      |  459 ++
 .../coprocessor/IndexToolVerificationResult.java   |    0
 .../phoenix/coprocessor/IndexerRegionScanner.java  |  457 ++
 .../phoenix/coprocessor/MetaDataEndpointImpl.java  | 4805 +++++++++++++++
 .../coprocessor/MetaDataEndpointObserver.java      |    0
 .../coprocessor/MetaDataRegionObserver.java        |  706 +++
 .../phoenix/coprocessor/OmidGCProcessor.java       |    0
 .../coprocessor/OmidTransactionalProcessor.java    |    0
 .../phoenix/coprocessor/PagingRegionScanner.java   |    0
 .../coprocessor/PhoenixAccessController.java       |    0
 .../phoenix/coprocessor/PhoenixCoprocessor.java    |    0
 .../PhoenixMetaDataCoprocessorHost.java            |    0
 .../coprocessor/PhoenixRegionServerEndpoint.java   |  113 +
 .../coprocessor/PhoenixTTLRegionObserver.java      |  341 ++
 .../coprocessor/ReplicationSinkEndpoint.java       |    0
 .../phoenix/coprocessor/ScanRegionObserver.java    |  188 +
 .../coprocessor/SequenceRegionObserver.java        |  474 ++
 .../coprocessor/ServerCachingEndpointImpl.java     |  123 +
 .../apache/phoenix/coprocessor/SuffixFilter.java   |    0
 .../coprocessor/SystemCatalogRegionObserver.java   |    0
 .../phoenix/coprocessor/TTLRegionScanner.java      |  228 +
 .../phoenix/coprocessor/TaskMetaDataEndpoint.java  |    0
 .../phoenix/coprocessor/TaskRegionObserver.java    |  289 +
 .../coprocessor/TephraTransactionalProcessor.java  |    0
 .../UncoveredGlobalIndexRegionScanner.java         |  234 +
 .../coprocessor/UncoveredIndexRegionScanner.java   |  407 ++
 .../UncoveredLocalIndexRegionScanner.java          |  132 +
 .../UngroupedAggregateRegionObserver.java          |  948 +++
 .../UngroupedAggregateRegionScanner.java           |  721 +++
 .../coprocessor/VerifyLastDDLTimestamp.java        |    0
 .../apache/phoenix/coprocessor/tasks/BaseTask.java |    0
 .../coprocessor/tasks/DropChildViewsTask.java      |  107 +
 .../coprocessor/tasks/IndexRebuildTask.java        |  191 +
 .../coprocessor/tasks/TransformMonitorTask.java    |  193 +
 .../phoenix/hbase/index/CapturingAbortable.java    |    0
 .../phoenix/hbase/index/IndexRegionObserver.java   | 1637 +++++
 .../hbase/index/IndexRegionSplitPolicy.java        |    0
 .../org/apache/phoenix/hbase/index/Indexer.java    |  755 +++
 .../apache/phoenix/hbase/index/LockManager.java    |    0
 .../hbase/index/balancer/IndexLoadBalancer.java    |    0
 .../hbase/index/builder/BaseIndexBuilder.java      |  138 +
 .../hbase/index/builder/IndexBuildManager.java     |  183 +
 .../phoenix/hbase/index/builder/IndexBuilder.java  |  153 +
 .../hbase/index/covered/CoveredColumns.java        |    0
 .../hbase/index/covered/LocalTableState.java       |    0
 .../hbase/index/covered/NonTxIndexBuilder.java     |    0
 .../hbase/index/covered/data/CachedLocalTable.java |    0
 .../hbase/index/covered/data/IndexMemStore.java    |    0
 .../hbase/index/parallel/ThreadPoolManager.java    |    0
 .../phoenix/hbase/index/wal/IndexedKeyValue.java   |    0
 .../phoenix/hbase/index/wal/KeyValueCodec.java     |    0
 .../AbstractParallelWriterIndexCommitter.java      |  241 +
 .../index/write/DelegateIndexFailurePolicy.java    |    0
 .../phoenix/hbase/index/write/IndexCommitter.java  |    0
 .../hbase/index/write/IndexFailurePolicy.java      |    0
 .../phoenix/hbase/index/write/IndexWriter.java     |    0
 .../hbase/index/write/IndexWriterUtils.java        |    0
 .../index/write/KillServerOnFailurePolicy.java     |    0
 .../write/LazyParallelWriterIndexCommitter.java    |    0
 .../index/write/LeaveIndexActiveFailurePolicy.java |    0
 .../index/write/ParallelWriterIndexCommitter.java  |    0
 .../hbase/index/write/RecoveryIndexWriter.java     |    0
 .../TrackingParallelWriterIndexCommitter.java      |  302 +
 .../write/recovery/PerRegionIndexWriteCache.java   |    0
 .../write/recovery/StoreFailuresInCachePolicy.java |    0
 .../apache/phoenix/index/GlobalIndexChecker.java   |  666 ++
 .../apache/phoenix/index/PhoenixIndexBuilder.java  |  278 +
 .../phoenix/index/PhoenixIndexFailurePolicy.java   |  392 ++
 .../phoenix/index/PhoenixIndexMetaDataBuilder.java |  107 +
 .../phoenix/index/PhoenixTransactionalIndexer.java |  241 +
 .../iterate/MapReduceParallelScanGrouper.java      |    0
 .../iterate/NonAggregateRegionScannerFactory.java  |  410 ++
 .../phoenix/iterate/RegionScannerFactory.java      |  467 ++
 .../iterate/RegionScannerResultIterator.java       |   88 +
 .../apache/phoenix/iterate/SnapshotScanner.java    |  279 +
 .../iterate/TableSnapshotResultIterator.java       |  220 +
 .../phoenix/mapreduce/AbstractBulkLoadTool.java    |    0
 .../phoenix/mapreduce/CsvBulkImportUtil.java       |    0
 .../apache/phoenix/mapreduce/CsvBulkLoadTool.java  |    0
 .../phoenix/mapreduce/CsvToKeyValueMapper.java     |    0
 .../mapreduce/FormatToBytesWritableMapper.java     |    0
 .../phoenix/mapreduce/FormatToKeyValueReducer.java |    0
 .../ImportPreUpsertKeyValueProcessor.java          |    0
 .../apache/phoenix/mapreduce/JsonBulkLoadTool.java |    0
 .../phoenix/mapreduce/JsonToKeyValueMapper.java    |    0
 .../phoenix/mapreduce/MultiHfileOutputFormat.java  |  738 +++
 .../apache/phoenix/mapreduce/OrphanViewTool.java   |    0
 .../phoenix/mapreduce/PhoenixInputFormat.java      |  293 +
 .../phoenix/mapreduce/PhoenixInputSplit.java       |    0
 .../phoenix/mapreduce/PhoenixJobCounters.java      |    0
 .../mapreduce/PhoenixMultiViewInputFormat.java     |    0
 .../mapreduce/PhoenixMultiViewInputSplit.java      |    0
 .../phoenix/mapreduce/PhoenixMultiViewReader.java  |    0
 .../phoenix/mapreduce/PhoenixOutputCommitter.java  |    0
 .../phoenix/mapreduce/PhoenixOutputFormat.java     |    0
 .../phoenix/mapreduce/PhoenixRecordReader.java     |  197 +
 .../phoenix/mapreduce/PhoenixRecordWritable.java   |    0
 .../phoenix/mapreduce/PhoenixRecordWriter.java     |    0
 .../PhoenixServerBuildIndexInputFormat.java        |  218 +
 .../mapreduce/PhoenixTTLDeleteJobMapper.java       |  241 +
 .../apache/phoenix/mapreduce/PhoenixTTLTool.java   |    0
 .../phoenix/mapreduce/PhoenixTextInputFormat.java  |    0
 .../phoenix/mapreduce/RegexBulkLoadTool.java       |    0
 .../phoenix/mapreduce/RegexToKeyValueMapper.java   |    0
 .../mapreduce/bulkload/TableRowkeyPair.java        |    0
 .../phoenix/mapreduce/bulkload/TargetTableRef.java |    0
 .../bulkload/TargetTableRefFunctions.java          |    0
 .../mapreduce/index/DirectHTableWriter.java        |    0
 .../mapreduce/index/IndexScrutinyMapper.java       |  530 ++
 .../index/IndexScrutinyMapperForTest.java          |    0
 .../mapreduce/index/IndexScrutinyTableOutput.java  |    0
 .../phoenix/mapreduce/index/IndexScrutinyTool.java |  542 ++
 .../apache/phoenix/mapreduce/index/IndexTool.java  | 1247 ++++
 .../phoenix/mapreduce/index/IndexToolUtil.java     |    0
 .../phoenix/mapreduce/index/IndexUpgradeTool.java  |  930 +++
 .../index/IndexVerificationOutputRepository.java   |  406 ++
 .../index/IndexVerificationOutputRow.java          |    0
 .../index/IndexVerificationResultRepository.java   |  415 ++
 .../mapreduce/index/PhoenixIndexDBWritable.java    |    0
 .../index/PhoenixIndexImportDirectMapper.java      |    0
 .../index/PhoenixIndexImportDirectReducer.java     |    0
 .../index/PhoenixIndexPartialBuildMapper.java      |  193 +
 .../index/PhoenixIndexToolJobCounters.java         |    0
 .../index/PhoenixScrutinyJobCounters.java          |    0
 .../index/PhoenixServerBuildIndexDBWritable.java   |    0
 .../index/PhoenixServerBuildIndexMapper.java       |    0
 .../mapreduce/index/SourceTargetColumnNames.java   |    0
 .../index/automation/PhoenixAsyncIndex.java        |    0
 .../index/automation/PhoenixMRJobCallable.java     |    0
 .../index/automation/PhoenixMRJobSubmitter.java    |    0
 .../index/automation/YarnApplication.java          |    0
 .../transform/PhoenixTransformReducer.java         |    0
 .../transform/PhoenixTransformRepairMapper.java    |  205 +
 .../PhoenixTransformWithViewsInputFormat.java      |  129 +
 .../phoenix/mapreduce/transform/TransformTool.java | 1006 +++
 .../util/ColumnInfoToStringEncoderDecoder.java     |    0
 .../util/DefaultMultiViewJobStatusTracker.java     |    0
 .../util/DefaultMultiViewSplitStrategy.java        |    0
 .../util/DefaultPhoenixMultiViewListProvider.java  |    0
 .../phoenix/mapreduce/util/IndexColumnNames.java   |    0
 .../mapreduce/util/MultiViewJobStatusTracker.java  |    0
 .../mapreduce/util/MultiViewSplitStrategy.java     |    0
 .../mapreduce/util/PhoenixConfigurationUtil.java   |  897 +++
 .../mapreduce/util/PhoenixMapReduceUtil.java       |    0
 .../mapreduce/util/PhoenixMultiInputUtil.java      |    0
 .../util/PhoenixMultiViewListProvider.java         |    0
 .../phoenix/mapreduce/util/ViewInfoTracker.java    |    0
 .../phoenix/mapreduce/util/ViewInfoWritable.java   |    0
 .../replication/SystemCatalogWALEntryFilter.java   |    0
 .../apache/phoenix/schema/MetaDataSplitPolicy.java |    0
 .../schema/SplitOnLeadingVarCharColumnsPolicy.java |    0
 .../phoenix/schema/SystemFunctionSplitPolicy.java  |    0
 .../phoenix/schema/SystemStatsSplitPolicy.java     |    0
 .../phoenix/schema/SystemTaskSplitPolicy.java      |    0
 .../schema/stats/DefaultStatisticsCollector.java   |  394 ++
 .../schema/stats/NoOpStatisticsCollector.java      |    0
 .../phoenix/schema/stats/StatisticsCollector.java  |    0
 .../schema/stats/StatisticsCollectorFactory.java   |    0
 .../phoenix/schema/stats/StatisticsScanner.java    |    0
 .../phoenix/schema/stats/StatisticsWriter.java     |  312 +
 .../phoenix/schema/stats/UpdateStatisticsTool.java |    0
 .../org/apache/phoenix/schema/task/ServerTask.java |  116 +
 .../apache/phoenix/schema/transform/Transform.java |  456 ++
 .../util/MergeViewIndexIdSequencesTool.java        |    0
 .../org/apache/phoenix/util/PhoenixMRJobUtil.java  |    0
 .../java/org/apache/phoenix/util/RepairUtil.java   |    0
 .../org/apache/phoenix/util/ServerIndexUtil.java   |  108 +
 .../java/org/apache/phoenix/util/ServerUtil.java   |  283 +
 .../org/apache/phoenix/util/ServerViewUtil.java    |  143 +
 .../phoenix/util/ZKBasedMasterElectionUtil.java    |    0
 phoenix-core/pom.xml                               |  999 ++-
 ...WALReplayWithIndexWritesAndCompressedWALIT.java |    1 -
 .../phoenix/end2end/BackwardCompatibilityIT.java   |    4 -
 .../end2end/BackwardCompatibilityTestUtil.java     |    6 +-
 .../apache/phoenix/end2end/BasePermissionsIT.java  |    2 +-
 .../end2end/ConcurrentMutationsExtendedIT.java     |    4 +-
 .../ConcurrentUpsertsWithoutIndexedColsIT.java     |    4 +-
 .../org/apache/phoenix/end2end/CreateSchemaIT.java |   10 +-
 .../org/apache/phoenix/end2end/CreateTableIT.java  |    6 +-
 .../org/apache/phoenix/end2end/DropSchemaIT.java   |    8 +-
 .../end2end/ExplainPlanWithStatsEnabledIT.java     |    4 +-
 .../apache/phoenix/end2end/IndexExtendedIT.java    |    3 +-
 .../apache/phoenix/end2end/IndexRebuildTaskIT.java |    4 +-
 .../end2end/IndexRepairRegionScannerIT.java        |    4 +-
 .../end2end/IndexScrutinyWithMaxLookbackIT.java    |    4 +-
 .../end2end/IndexToolForNonTxGlobalIndexIT.java    |    3 +-
 .../end2end/IndexVerificationOldDesignIT.java      |    3 +-
 .../phoenix/end2end/LogicalTableNameBaseIT.java    |    4 +-
 .../phoenix/end2end/MaxLookbackExtendedIT.java     |    4 +-
 .../org/apache/phoenix/end2end/MaxLookbackIT.java  |    4 +-
 .../apache/phoenix/end2end/MetaDataEndPointIT.java |    2 +-
 .../MigrateSystemTablesToSystemNamespaceIT.java    |    2 +-
 .../phoenix/end2end/ParallelIteratorsIT.java       |    4 +-
 .../phoenix/end2end/ParallelStatsDisabledIT.java   |    5 +-
 .../end2end/PhoenixRegionServerEndpointIT.java     |    3 +-
 .../apache/phoenix/end2end/PhoenixTTLToolIT.java   |    4 +-
 .../end2end/PreMatureTimelyAbortScanIt.java        |    4 +-
 .../phoenix/end2end/SchemaRegistryFailureIT.java   |    2 +-
 .../org/apache/phoenix/end2end/StoreNullsIT.java   |    4 +-
 .../SystemTablesCreationOnConnectionIT.java        |    3 +-
 .../phoenix/end2end/SystemTablesUpgradeIT.java     |    2 +-
 .../org/apache/phoenix/end2end/TableTTLIT.java     |    4 +-
 .../java/org/apache/phoenix/end2end/UpgradeIT.java |    6 +-
 .../org/apache/phoenix/end2end/UpsertSelectIT.java |    4 +-
 .../org/apache/phoenix/end2end/ViewMetadataIT.java |    2 +-
 .../java/org/apache/phoenix/end2end/ViewTTLIT.java |   26 +-
 .../org/apache/phoenix/end2end/ViewUtilIT.java     |    6 +-
 .../index/IndexRebuildIncrementDisableCountIT.java |    2 +-
 .../phoenix/end2end/index/IndexTestUtil.java       |    5 +-
 .../end2end/index/IndexTwoPhaseCreateIT.java       |    5 +-
 .../index/IndexVerificationOutputRepositoryIT.java |    2 +-
 .../index/IndexVerificationResultRepositoryIT.java |    4 +-
 .../index/InvalidIndexStateClientSideIT.java       |    6 +-
 .../apache/phoenix/end2end/index/LocalIndexIT.java |    5 +-
 .../end2end/index/PartialIndexRebuilderIT.java     |    7 +-
 .../phoenix/end2end/join/HashJoinCacheIT.java      |    2 +-
 .../phoenix/end2end/transform/TransformIT.java     |    4 +-
 .../transform/TransformMonitorExtendedIT.java      |    4 +-
 .../end2end/transform/TransformMonitorIT.java      |    3 +-
 .../phoenix/end2end/transform/TransformToolIT.java |    6 +-
 .../monitoring/PhoenixTableLevelMetricsIT.java     |   71 +-
 .../phoenix/trace/PhoenixTracingEndToEndIT.java    |    4 +-
 .../hbase/ipc/PhoenixRpcSchedulerFactory.java      |  108 -
 .../hbase/ipc/controller/IndexRpcController.java   |   57 -
 .../InvalidateMetadataCacheController.java         |   51 -
 .../ipc/controller/MetadataRpcController.java      |   74 -
 .../ServerToServerRpcControllerImpl.java           |   75 -
 .../regionserver/IndexHalfStoreFileReader.java     |  174 -
 .../IndexHalfStoreFileReaderGenerator.java         |  305 -
 .../apache/phoenix/cache/ServerCacheClient.java    |  554 --
 .../apache/phoenix/cache/ServerMetadataCache.java  |  193 -
 .../java/org/apache/phoenix/cache/TenantCache.java |   42 -
 .../org/apache/phoenix/cache/TenantCacheImpl.java  |  287 -
 .../apache/phoenix/compile/AggregationManager.java |  115 -
 .../org/apache/phoenix/compile/DeleteCompiler.java | 1030 ----
 .../org/apache/phoenix/compile/FromCompiler.java   | 1234 ----
 .../apache/phoenix/compile/GroupByCompiler.java    |  476 --
 .../org/apache/phoenix/compile/JoinCompiler.java   | 1590 -----
 .../apache/phoenix/compile/PostDDLCompiler.java    |  372 --
 .../phoenix/compile/PostLocalIndexDDLCompiler.java |  133 -
 .../apache/phoenix/compile/ProjectionCompiler.java |  796 ---
 .../org/apache/phoenix/compile/QueryCompiler.java  |  815 ---
 .../org/apache/phoenix/compile/ScanRanges.java     |  785 ---
 .../phoenix/compile/ServerBuildIndexCompiler.java  |  161 -
 .../ServerBuildTransformingTableCompiler.java      |   99 -
 .../org/apache/phoenix/compile/UpsertCompiler.java | 1455 -----
 .../org/apache/phoenix/compile/WhereCompiler.java  |  958 ---
 .../phoenix/coprocessor/AddColumnMutator.java      |  467 --
 .../coprocessor/BaseScannerRegionObserver.java     |  634 --
 .../apache/phoenix/coprocessor/ColumnMutator.java  |   66 -
 .../phoenix/coprocessor/DropColumnMutator.java     |  305 -
 .../coprocessor/GlobalIndexRegionScanner.java      | 1517 -----
 .../GroupedAggregateRegionObserver.java            |  642 --
 .../HashJoinCacheNotFoundException.java            |   45 -
 .../phoenix/coprocessor/HashJoinRegionScanner.java |  413 --
 .../coprocessor/IndexRebuildRegionScanner.java     |  389 --
 .../coprocessor/IndexRepairRegionScanner.java      |  460 --
 .../phoenix/coprocessor/IndexerRegionScanner.java  |  455 --
 .../InvalidateServerMetadataCacheRequest.java      |   53 -
 .../phoenix/coprocessor/MetaDataEndpointImpl.java  | 4805 ---------------
 .../phoenix/coprocessor/MetaDataProtocol.java      |  521 --
 .../coprocessor/MetaDataRegionObserver.java        |  672 --
 .../coprocessor/PhoenixRegionServerEndpoint.java   |  113 -
 .../coprocessor/PhoenixTTLRegionObserver.java      |  340 --
 .../phoenix/coprocessor/ScanRegionObserver.java    |  220 -
 .../coprocessor/SequenceRegionObserver.java        |  471 --
 .../coprocessor/ServerCachingEndpointImpl.java     |  123 -
 .../phoenix/coprocessor/ServerCachingProtocol.java |   61 -
 .../phoenix/coprocessor/TTLRegionScanner.java      |  228 -
 .../org/apache/phoenix/coprocessor/TableInfo.java  |   79 -
 .../phoenix/coprocessor/TaskRegionObserver.java    |  288 -
 .../UncoveredGlobalIndexRegionScanner.java         |  233 -
 .../coprocessor/UncoveredIndexRegionScanner.java   |  402 --
 .../UncoveredLocalIndexRegionScanner.java          |  132 -
 .../UngroupedAggregateRegionObserver.java          |  979 ---
 .../UngroupedAggregateRegionScanner.java           |  719 ---
 .../phoenix/coprocessor/WhereConstantParser.java   |  110 -
 .../metrics/MetricsMetadataCachingSource.java      |  230 -
 .../metrics/MetricsMetadataCachingSourceImpl.java  |  122 -
 .../MetricsPhoenixCoprocessorSourceFactory.java    |   57 -
 .../metrics/MetricsPhoenixTTLSource.java           |   61 -
 .../metrics/MetricsPhoenixTTLSourceImpl.java       |   58 -
 .../coprocessor/tasks/DropChildViewsTask.java      |  107 -
 .../coprocessor/tasks/IndexRebuildTask.java        |  194 -
 .../coprocessor/tasks/TransformMonitorTask.java    |  216 -
 .../apache/phoenix/exception/SQLExceptionCode.java |  697 ---
 .../exception/UpgradeInProgressException.java      |   31 -
 .../org/apache/phoenix/execute/AggregatePlan.java  |  371 --
 .../org/apache/phoenix/execute/BaseQueryPlan.java  |  582 --
 .../phoenix/execute/ClientAggregatePlan.java       |  384 --
 .../org/apache/phoenix/execute/HashJoinPlan.java   |  700 ---
 .../org/apache/phoenix/execute/MutationState.java  | 2310 -------
 .../execute/PhoenixTxIndexMutationGenerator.java   |  523 --
 .../java/org/apache/phoenix/execute/ScanPlan.java  |  378 --
 .../org/apache/phoenix/execute/TupleProjector.java |  495 --
 .../expression/RowValueConstructorExpression.java  |  277 -
 .../phoenix/filter/BooleanExpressionFilter.java    |  135 -
 .../MultiEncodedCQKeyValueComparisonFilter.java    |  415 --
 .../filter/MultiKeyValueComparisonFilter.java      |  291 -
 .../filter/SystemCatalogViewIndexIdFilter.java     |  161 -
 .../phoenix/hbase/index/IndexRegionObserver.java   | 1676 -----
 .../org/apache/phoenix/hbase/index/Indexer.java    |  780 ---
 .../hbase/index/builder/BaseIndexBuilder.java      |  138 -
 .../hbase/index/builder/BaseIndexCodec.java        |   36 -
 .../hbase/index/builder/IndexBuildManager.java     |  182 -
 .../phoenix/hbase/index/builder/IndexBuilder.java  |  153 -
 .../phoenix/hbase/index/covered/IndexCodec.java    |   88 -
 .../phoenix/hbase/index/covered/IndexMetaData.java |   55 -
 .../phoenix/hbase/index/covered/TableState.java    |   76 -
 .../hbase/index/metrics/MetricsIndexerSource.java  |  213 -
 .../hbase/index/util/IndexManagementUtil.java      |  293 -
 .../AbstractParallelWriterIndexCommitter.java      |  241 -
 .../TrackingParallelWriterIndexCommitter.java      |  302 -
 .../apache/phoenix/index/GlobalIndexChecker.java   |  658 --
 .../org/apache/phoenix/index/IndexMaintainer.java  | 2300 -------
 .../phoenix/index/IndexMetaDataCacheClient.java    |  158 -
 .../phoenix/index/IndexMetaDataCacheFactory.java   |   82 -
 .../apache/phoenix/index/PhoenixIndexBuilder.java  |  394 --
 .../apache/phoenix/index/PhoenixIndexCodec.java    |  139 -
 .../phoenix/index/PhoenixIndexFailurePolicy.java   |  596 --
 .../apache/phoenix/index/PhoenixIndexMetaData.java |  101 -
 .../phoenix/index/PhoenixIndexMetaDataBuilder.java |  107 -
 .../phoenix/index/PhoenixTransactionalIndexer.java |  246 -
 .../phoenix/iterate/BaseResultIterators.java       | 1771 ------
 .../phoenix/iterate/ChunkedResultIterator.java     |  249 -
 .../phoenix/iterate/ConcatResultIterator.java      |  150 -
 .../org/apache/phoenix/iterate/ExplainTable.java   |  550 --
 .../iterate/NonAggregateRegionScannerFactory.java  |  410 --
 .../phoenix/iterate/OrderedResultIterator.java     |  426 --
 .../phoenix/iterate/RegionScannerFactory.java      |  464 --
 .../iterate/RegionScannerResultIterator.java       |   88 -
 .../phoenix/iterate/RoundRobinResultIterator.java  |  354 --
 .../RowKeyOrderedAggregateResultIterator.java      |  200 -
 .../phoenix/iterate/ScanningResultIterator.java    |  236 -
 .../apache/phoenix/iterate/SerialIterators.java    |  231 -
 .../apache/phoenix/iterate/SnapshotScanner.java    |  279 -
 .../phoenix/iterate/SpoolingResultIterator.java    |  381 --
 .../phoenix/iterate/TableResultIterator.java       |  344 --
 .../iterate/TableSnapshotResultIterator.java       |  220 -
 .../phoenix/iterate/UnionResultIterators.java      |  166 -
 .../ParallelPhoenixNullComparingResultSet.java     |  333 -
 .../phoenix/jdbc/PhoenixDatabaseMetaData.java      | 1951 ------
 .../apache/phoenix/jdbc/PhoenixEmbeddedDriver.java |  198 -
 .../org/apache/phoenix/jdbc/PhoenixResultSet.java  | 1649 -----
 .../org/apache/phoenix/jdbc/PhoenixStatement.java  | 2650 --------
 .../org/apache/phoenix/join/HashCacheClient.java   |  228 -
 .../org/apache/phoenix/join/HashCacheFactory.java  |  174 -
 .../phoenix/mapreduce/MultiHfileOutputFormat.java  |  737 ---
 .../phoenix/mapreduce/PhoenixInputFormat.java      |  293 -
 .../phoenix/mapreduce/PhoenixRecordReader.java     |  197 -
 .../PhoenixServerBuildIndexInputFormat.java        |  218 -
 .../mapreduce/PhoenixTTLDeleteJobMapper.java       |  241 -
 .../mapreduce/index/IndexScrutinyMapper.java       |  530 --
 .../phoenix/mapreduce/index/IndexScrutinyTool.java |  542 --
 .../apache/phoenix/mapreduce/index/IndexTool.java  | 1247 ----
 .../phoenix/mapreduce/index/IndexUpgradeTool.java  |  930 ---
 .../index/IndexVerificationOutputRepository.java   |  406 --
 .../index/IndexVerificationResultRepository.java   |  415 --
 .../index/PhoenixIndexPartialBuildMapper.java      |  194 -
 .../transform/PhoenixTransformRepairMapper.java    |  205 -
 .../PhoenixTransformWithViewsInputFormat.java      |  129 -
 .../phoenix/mapreduce/transform/TransformTool.java | 1006 ---
 .../phoenix/mapreduce/util/ConnectionUtil.java     |  141 -
 .../mapreduce/util/PhoenixConfigurationUtil.java   | 1071 ----
 .../phoenix/monitoring/LatencyHistogram.java       |   46 -
 .../apache/phoenix/monitoring/SizeHistogram.java   |   47 -
 .../ConnectionQueryServicesHistogram.java          |   43 -
 .../parse/PhoenixRowTimestampParseNode.java        |   98 -
 .../phoenix/query/ConnectionQueryServices.java     |  237 -
 .../phoenix/query/ConnectionQueryServicesImpl.java | 6441 --------------------
 .../query/ConnectionlessQueryServicesImpl.java     |  834 ---
 .../query/DelegateConnectionQueryServices.java     |  442 --
 .../org/apache/phoenix/query/QueryConstants.java   |  590 --
 .../org/apache/phoenix/query/QueryServices.java    |  480 --
 .../apache/phoenix/query/QueryServicesOptions.java |  977 ---
 .../org/apache/phoenix/schema/MetaDataClient.java  | 6028 ------------------
 .../main/java/org/apache/phoenix/schema/PRow.java  |   89 -
 .../java/org/apache/phoenix/schema/PTableImpl.java | 2469 --------
 .../java/org/apache/phoenix/schema/Sequence.java   |  639 --
 .../schema/stats/DefaultStatisticsCollector.java   |  394 --
 .../phoenix/schema/stats/StatisticsUtil.java       |  252 -
 .../phoenix/schema/stats/StatisticsWriter.java     |  312 -
 .../java/org/apache/phoenix/schema/task/Task.java  |  529 --
 .../apache/phoenix/schema/transform/Transform.java |  795 ---
 .../transaction/OmidTransactionProvider.java       |  136 -
 .../phoenix/transaction/TransactionFactory.java    |   86 -
 .../apache/phoenix/util/EncodedColumnsUtil.java    |  207 -
 .../java/org/apache/phoenix/util/IndexUtil.java    | 1019 ----
 .../java/org/apache/phoenix/util/MetaDataUtil.java | 1243 ----
 .../org/apache/phoenix/util/PhoenixRuntime.java    | 1713 ------
 .../java/org/apache/phoenix/util/ScanUtil.java     | 1589 -----
 .../java/org/apache/phoenix/util/ServerUtil.java   |  450 --
 .../apache/phoenix/util/TableViewFinderResult.java |   49 -
 .../org/apache/phoenix/util/TransactionUtil.java   |  171 -
 .../java/org/apache/phoenix/util/UpgradeUtil.java  | 2925 ---------
 .../phoenix/util/ValidateLastDDLTimestampUtil.java |  211 -
 .../java/org/apache/phoenix/util/ViewUtil.java     |  994 ---
 .../org/apache/phoenix/util/WALAnnotationUtil.java |   78 -
 .../phoenix/cache/ServerMetadataCacheTest.java     |    4 +-
 .../org/apache/phoenix/cache/TenantCacheTest.java  |    4 +-
 .../apache/phoenix/compile/QueryCompilerTest.java  |   10 +-
 .../apache/phoenix/compile/QueryOptimizerTest.java |    4 +-
 .../execute/LiteralResultIteratorPlanTest.java     |    2 +-
 .../index/covered/CoveredColumnIndexCodec.java     |    2 +-
 .../CoveredColumnIndexSpecifierBuilder.java        |   11 +-
 .../index/covered/CoveredIndexCodecForTesting.java |    2 +-
 .../hbase/index/covered/LocalTableStateTest.java   |    2 +-
 .../hbase/index/covered/NonTxIndexBuilderTest.java |    2 +-
 .../org/apache/phoenix/index/ShouldVerifyTest.java |    8 +-
 .../phoenix/iterate/OrderedResultIteratorTest.java |    4 +-
 .../util/PhoenixConfigurationUtilTest.java         |   20 +-
 .../java/org/apache/phoenix/query/BaseTest.java    |    5 -
 .../apache/phoenix/schema/MetaDataClientTest.java  |    2 +-
 .../org/apache/phoenix/util/ClientUtilTest.java    |   93 +
 .../org/apache/phoenix/util/MetaDataUtilTest.java  |    5 +-
 .../apache/phoenix/util/PropertiesUtilTest.java    |    7 +-
 .../java/org/apache/phoenix/util/ScanUtilTest.java |    4 +-
 .../org/apache/phoenix/util/ServerUtilTest.java    |   93 -
 phoenix-pherf/pom.xml                              |   15 +-
 .../src/main/config/checkstyle/checker.xml         |   21 +-
 pom.xml                                            |   78 +-
 src/main/config/checkstyle/checker.xml             |   21 +-
 1596 files changed, 102397 insertions(+), 101545 deletions(-)
 create mode 100644 phoenix-core-client/pom.xml
 rename {phoenix-core => phoenix-core-client}/src/build/phoenix-core.xml (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/antlr3/PhoenixSQL.g (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/hadoop/hbase/PhoenixTagType.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/hadoop/hbase/client/RegionInfoUtil.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/hadoop/hbase/ipc/controller/ClientRpcControllerFactory.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/hadoop/hbase/ipc/controller/IndexRpcController.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/hadoop/hbase/ipc/controller/InterRegionServerIndexRpcControllerFactory.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/hadoop/hbase/ipc/controller/InvalidateMetadataCacheController.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/hadoop/hbase/ipc/controller/InvalidateMetadataCacheControllerFactory.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/hadoop/hbase/ipc/controller/MetadataRpcController.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/hadoop/hbase/ipc/controller/ServerSideRPCControllerFactory.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/hadoop/hbase/ipc/controller/ServerToServerRpcController.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/hadoop/hbase/ipc/controller/ServerToServerRpcControllerImpl.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/cache/HashCache.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/cache/IndexMetaDataCache.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/cache/JodaTimezoneCache.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/cache/ServerCacheClient.java
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/cache/ServerMetadataCache.java
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/cache/TenantCache.java
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/cache/TenantCacheImpl.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/call/CallRunner.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/call/CallWrapper.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/compile/AggregationManager.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/compile/BaseMutationPlan.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/compile/BindManager.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/compile/CloseStatementCompiler.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/compile/ColumnNameTrackingExpressionCompiler.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/compile/ColumnProjector.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/compile/ColumnResolver.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/compile/CompiledOffset.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/compile/CreateFunctionCompiler.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/compile/CreateIndexCompiler.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/compile/CreateSchemaCompiler.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/compile/CreateSequenceCompiler.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/compile/CreateTableCompiler.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/compile/DeclareCursorCompiler.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/compile/DelegateMutationPlan.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/compile/DeleteCompiler.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/compile/DropSequenceCompiler.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/compile/ExplainPlan.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/compile/ExplainPlanAttributes.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/compile/ExpressionCompiler.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/compile/ExpressionManager.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/compile/ExpressionProjector.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/compile/FromCompiler.java
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/compile/GroupByCompiler.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/compile/HavingCompiler.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/compile/IndexExpressionCompiler.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/compile/IndexStatementRewriter.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/compile/JoinCompiler.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/compile/KeyPart.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/compile/LimitCompiler.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/compile/ListJarsQueryPlan.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/compile/MutatingParallelIteratorFactory.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/compile/MutationPlan.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/compile/OffsetCompiler.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/compile/OpenStatementCompiler.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/compile/OrderByCompiler.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/compile/OrderPreservingTracker.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/compile/PostDDLCompiler.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/compile/PostIndexDDLCompiler.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/compile/PostLocalIndexDDLCompiler.java
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/compile/ProjectionCompiler.java
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/compile/QueryCompiler.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/compile/QueryPlan.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/compile/RVCOffsetCompiler.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/compile/RowProjector.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/compile/ScanRanges.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/compile/SequenceManager.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/compile/SequenceValueExpression.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/compile/ServerBuildIndexCompiler.java
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/compile/ServerBuildTransformingTableCompiler.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/compile/StatelessExpressionCompiler.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/compile/StatementContext.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/compile/StatementNormalizer.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/compile/StatementPlan.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/compile/SubqueryRewriter.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/compile/SubselectRewriter.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/compile/TraceQueryPlan.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/compile/TupleProjectionCompiler.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/compile/UnionCompiler.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/compile/UpsertCompiler.java
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/compile/WhereCompiler.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/compile/WhereOptimizer.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/coprocessorclient/BaseScannerRegionObserverConstants.java
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/coprocessorclient/HashJoinCacheNotFoundException.java
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/coprocessorclient/InvalidateServerMetadataCacheRequest.java
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/coprocessorclient/MetaDataEndpointImplConstants.java
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/coprocessorclient/MetaDataProtocol.java
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/coprocessorclient/ScanRegionObserverConstants.java
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/coprocessorclient/SequenceRegionObserverConstants.java
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/coprocessorclient/ServerCachingProtocol.java
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/coprocessorclient/TableInfo.java
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/coprocessorclient/UngroupedAggregateRegionObserverHelper.java
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/coprocessorclient/WhereConstantParser.java
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/coprocessorclient/metrics/MetricsMetadataCachingSource.java
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/coprocessorclient/metrics/MetricsMetadataCachingSourceImpl.java
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/coprocessorclient/metrics/MetricsPhoenixCoprocessorSourceFactory.java
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/coprocessorclient/metrics/MetricsPhoenixTTLSource.java
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/coprocessorclient/metrics/MetricsPhoenixTTLSourceImpl.java
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/coprocessorclient/tasks/IndexRebuildTaskConstants.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/exception/DataExceedsCapacityException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/exception/FailoverSQLException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/exception/InvalidRegionSplitPolicyException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/exception/PhoenixIOException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/exception/PhoenixNonRetryableRuntimeException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/exception/PhoenixParserException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/exception/RetriableUpgradeException.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/exception/SQLExceptionCode.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/exception/SQLExceptionInfo.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/exception/StaleMetadataCacheException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/exception/UndecodableByteException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/exception/UnknownFunctionException.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/exception/UpgradeInProgressException.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/exception/UpgradeNotRequiredException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/exception/UpgradeRequiredException.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/execute/AggregatePlan.java
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/execute/BaseQueryPlan.java
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/execute/ClientAggregatePlan.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/execute/ClientProcessingPlan.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/execute/ClientScanPlan.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/execute/CommitException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/execute/CursorFetchPlan.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/execute/DelegateHTable.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/execute/DelegateQueryPlan.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/execute/DescVarLengthFastByteComparisons.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/execute/HashJoinPlan.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/execute/LiteralResultIterationPlan.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/execute/MutationState.java
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/execute/PhoenixTxIndexMutationGenerator.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/execute/RuntimeContext.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/execute/RuntimeContextImpl.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/execute/ScanPlan.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/execute/SortMergeJoinPlan.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/execute/TupleProjectionPlan.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/execute/TupleProjector.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/execute/UnionPlan.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/execute/UnnestArrayPlan.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/execute/visitor/AvgRowWidthVisitor.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/execute/visitor/ByteCountVisitor.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/execute/visitor/QueryPlanVisitor.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/execute/visitor/RowCountVisitor.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/AddExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/AndExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/AndOrExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/ArithmeticExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/ArrayConstructorExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/BaseAddSubtractExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/BaseCompoundExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/BaseDecimalAddSubtractExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/BaseExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/BaseSingleExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/BaseTerminalExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/ByteBasedLikeExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/CaseExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/CoerceExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/ColumnExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/ComparisonExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/CorrelateVariableFieldAccessExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/CurrentDateTimeFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/DateAddExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/DateSubtractExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/DecimalAddExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/DecimalDivideExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/DecimalMultiplyExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/DecimalSubtractExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/DelegateExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/Determinism.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/DivideExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/DoubleAddExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/DoubleDivideExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/DoubleMultiplyExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/DoubleSubtractExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/Expression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/ExpressionType.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/InListExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/IsNullExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/KeyValueColumnExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/LikeExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/LiteralExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/LongAddExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/LongDivideExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/LongMultiplyExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/LongSubtractExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/ModulusExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/MultiplyExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/NotExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/OrExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/OrderByExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/ProjectedColumnExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/RowKeyColumnExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/RowKeyExpression.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/expression/RowValueConstructorExpression.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/SingleCellColumnExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/SingleCellConstructorExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/StringBasedLikeExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/StringConcatExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/SubtractExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/TimestampAddExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/TimestampSubtractExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/aggregator/Aggregator.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/aggregator/Aggregators.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/aggregator/BaseAggregator.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/aggregator/BaseDecimalStddevAggregator.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/aggregator/BaseStddevAggregator.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/aggregator/ClientAggregators.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/aggregator/CountAggregator.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/aggregator/DecimalStddevPopAggregator.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/aggregator/DecimalStddevSampAggregator.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/aggregator/DecimalSumAggregator.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/aggregator/DistinctCountClientAggregator.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/aggregator/DistinctValueClientAggregator.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/aggregator/DistinctValueWithCountClientAggregator.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/aggregator/DistinctValueWithCountServerAggregator.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/aggregator/DoubleSumAggregator.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/aggregator/FirstLastValueBaseClientAggregator.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/aggregator/FirstLastValueServerAggregator.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/aggregator/IntSumAggregator.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/aggregator/LongSumAggregator.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/aggregator/MaxAggregator.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/aggregator/MinAggregator.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/aggregator/NonSizeTrackingServerAggregators.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/aggregator/NumberSumAggregator.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/aggregator/PercentRankClientAggregator.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/aggregator/PercentileClientAggregator.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/aggregator/PercentileDiscClientAggregator.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/aggregator/ServerAggregators.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/aggregator/SizeTrackingServerAggregators.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/aggregator/StddevPopAggregator.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/aggregator/StddevSampAggregator.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/aggregator/UnsignedIntSumAggregator.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/aggregator/UnsignedLongSumAggregator.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/AbsFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/AggregateFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/ArrayAllComparisonExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/ArrayAnyComparisonExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/ArrayAppendFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/ArrayConcatFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/ArrayElemRefExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/ArrayFillFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/ArrayIndexFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/ArrayLengthFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/ArrayModifierFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/ArrayPrependFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/ArrayRemoveFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/ArrayToStringFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/AvgAggregateFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/ByteBasedRegexpReplaceFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/ByteBasedRegexpSplitFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/ByteBasedRegexpSubstrFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/CbrtFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/CeilDateExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/CeilDecimalExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/CeilFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/CeilMonthExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/CeilTimestampExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/CeilWeekExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/CeilYearExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/CoalesceFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/CollationKeyFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/CompositeAggregateFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/ConvertTimezoneFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/CosFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/CountAggregateFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/CurrentDateFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/CurrentTimeFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/DateScalarFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/DayOfMonthFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/DayOfWeekFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/DayOfYearFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/DecodeFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/DefaultValueExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/DelegateConstantToCountAggregateFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/DistinctCountAggregateFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/DistinctCountHyperLogLogAggregateFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/DistinctValueAggregateFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/DistinctValueWithCountAggregateFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/EncodeFormat.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/EncodeFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/ExpFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/ExternalSqlTypeIdFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/FirstLastValueBaseFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/FirstValueFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/FirstValuesFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/FloorDateExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/FloorDecimalExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/FloorFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/FloorMonthExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/FloorWeekExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/FloorYearExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/FunctionArgumentType.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/FunctionExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/GetBitFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/GetByteFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/HourFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/IndexStateNameFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/InstrFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/InvertFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/JavaMathOneArgumentFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/JavaMathTwoArgumentFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/LTrimFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/LastValueFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/LastValuesFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/LengthFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/LnFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/LogFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/LowerFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/LpadFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/MD5Function.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/MathPIFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/MaxAggregateFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/MinAggregateFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/MinuteFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/MonthFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/NowFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/NthValueFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/OctetLengthFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/PercentRankAggregateFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/PercentileContAggregateFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/PercentileDiscAggregateFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/PhoenixRowTimestampFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/PowerFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/PrefixFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/RTrimFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/RandomFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/RegexpReplaceFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/RegexpSplitFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/RegexpSubstrFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/ReverseFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/RoundDateExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/RoundDecimalExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/RoundFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/RoundJodaDateExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/RoundMonthExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/RoundTimestampExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/RoundWeekExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/RoundYearExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/RowKeyBytesStringFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/SQLIndexTypeFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/SQLTableTypeFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/SQLViewTypeFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/ScalarFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/SecondFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/SetBitFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/SetByteFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/SignFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/SinFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/SingleAggregateFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/SqlTypeNameFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/SqrtFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/StddevPopFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/StddevSampFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/StringBasedRegexpReplaceFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/StringBasedRegexpSplitFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/StringBasedRegexpSubstrFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/StringToArrayFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/SubstrFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/SumAggregateFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/TanFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/TimeUnit.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/TimezoneOffsetFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/ToCharFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/ToDateFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/ToNumberFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/ToTimeFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/ToTimestampFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/TransactionProviderNameFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/TrimFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/TruncFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/UDFExpression.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/UpperFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/WeekFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/function/YearFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/rewrite/RowValueConstructorExpressionRewriter.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/util/regex/AbstractBasePattern.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/util/regex/AbstractBaseSplitter.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/util/regex/GuavaSplitter.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/util/regex/JONIPattern.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/util/regex/JavaPattern.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/visitor/BaseExpressionVisitor.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/visitor/CloneExpressionVisitor.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/visitor/ExpressionVisitor.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/visitor/KeyValueExpressionVisitor.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/visitor/ProjectedColumnExpressionVisitor.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/visitor/ReplaceArrayFunctionExpressionVisitor.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/visitor/RowKeyExpressionVisitor.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/visitor/SingleAggregateFunctionVisitor.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/visitor/StatelessTraverseAllExpressionVisitor.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/visitor/StatelessTraverseNoExpressionVisitor.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/visitor/TraverseAllExpressionVisitor.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/expression/visitor/TraverseNoExpressionVisitor.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/filter/AllVersionsIndexRebuildFilter.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/filter/BooleanExpressionFilter.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/filter/ColumnProjectionFilter.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/filter/DelegateFilter.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/filter/DistinctPrefixFilter.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/filter/EmptyColumnOnlyFilter.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/filter/EncodedQualifiersColumnProjectionFilter.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/filter/MultiCFCQKeyValueComparisonFilter.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/filter/MultiCQKeyValueComparisonFilter.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/filter/MultiEncodedCQKeyValueComparisonFilter.java
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/filter/MultiKeyValueComparisonFilter.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/filter/PagingFilter.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/filter/RowKeyComparisonFilter.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/filter/SingleCFCQKeyValueComparisonFilter.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/filter/SingleCQKeyValueComparisonFilter.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/filter/SingleKeyValueComparisonFilter.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/filter/SkipScanFilter.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/filter/SystemCatalogViewIndexIdFilter.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/filter/UnverifiedRowFilter.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/hbase/index/AbstractValueGetter.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/hbase/index/BaseIndexCodec.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/hbase/index/MultiMutation.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/hbase/index/OffsetCell.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/hbase/index/ValueGetter.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/hbase/index/builder/FatalIndexBuildingFailureException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/hbase/index/builder/IndexBuildingFailureException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/hbase/index/covered/Batch.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/hbase/index/covered/IndexCodec.java
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/hbase/index/covered/IndexMetaData.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/hbase/index/covered/IndexUpdate.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/hbase/index/covered/KeyValueStore.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/hbase/index/covered/TableState.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/hbase/index/covered/data/DelegateComparator.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/hbase/index/covered/data/LazyValueGetter.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/hbase/index/covered/data/LocalHBaseState.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/hbase/index/covered/filter/ApplyAndFilterDeletesFilter.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/hbase/index/covered/filter/ColumnTrackingNextLargestTimestampFilter.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/hbase/index/covered/filter/MaxTimestampFilter.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/hbase/index/covered/filter/NewerTimestampFilter.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/hbase/index/covered/update/ColumnReference.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/hbase/index/covered/update/ColumnTracker.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/hbase/index/covered/update/IndexUpdateManager.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/hbase/index/covered/update/IndexedColumnGroup.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/hbase/index/exception/IndexWriteException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/hbase/index/exception/MultiIndexWriteFailureException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/hbase/index/exception/SingleIndexWriteFailureException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/hbase/index/metrics/GlobalIndexCheckerSource.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/hbase/index/metrics/GlobalIndexCheckerSourceImpl.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/hbase/index/metrics/MetricsIndexerSource.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/hbase/index/metrics/MetricsIndexerSourceFactory.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/hbase/index/metrics/MetricsIndexerSourceImpl.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/hbase/index/parallel/BaseTaskRunner.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/hbase/index/parallel/EarlyExitFailure.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/hbase/index/parallel/QuickFailingTaskRunner.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/hbase/index/parallel/Task.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/hbase/index/parallel/TaskBatch.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/hbase/index/parallel/TaskRunner.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/hbase/index/parallel/ThreadPoolBuilder.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/hbase/index/parallel/WaitForCompletionTaskRunner.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/hbase/index/scanner/EmptyScanner.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/hbase/index/scanner/FilteredKeyValueScanner.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/hbase/index/scanner/ReseekableScanner.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/hbase/index/scanner/Scanner.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/hbase/index/scanner/ScannerBuilder.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/hbase/index/table/HTableFactory.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/hbase/index/table/HTableInterfaceReference.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/hbase/index/util/GenericKeyValueBuilder.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/hbase/index/util/ImmutableBytesPtr.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/hbase/index/util/IndexManagementUtil.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/hbase/index/util/KeyValueBuilder.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/hbase/index/util/VersionUtil.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/index/IndexMaintainer.java
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/index/IndexMetaDataCacheClient.java
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/index/IndexMetaDataCacheFactory.java
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/index/PhoenixIndexBuilderHelper.java
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/index/PhoenixIndexCodec.java
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/index/PhoenixIndexFailurePolicyHelper.java
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/index/PhoenixIndexMetaData.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/iterate/AggregatingResultIterator.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/iterate/BaseGroupedAggregatingResultIterator.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/iterate/BaseResultIterator.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/iterate/BaseResultIterators.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/iterate/BufferedQueue.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/iterate/BufferedSortedQueue.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/iterate/BufferedTupleQueue.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/iterate/ChunkedResultIterator.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/iterate/ClientHashAggregatingResultIterator.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/iterate/ConcatResultIterator.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/iterate/CursorResultIterator.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/iterate/DefaultParallelScanGrouper.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/iterate/DefaultTableResultIteratorFactory.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/iterate/DelegateResultIterator.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/iterate/DistinctAggregatingResultIterator.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/iterate/ExplainTable.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/iterate/FilterAggregatingResultIterator.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/iterate/FilterResultIterator.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/iterate/GroupedAggregatingResultIterator.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/iterate/LimitingPeekingResultIterator.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/iterate/LimitingResultIterator.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/iterate/LookAheadResultIterator.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/iterate/MaterializedComparableResultIterator.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/iterate/MaterializedResultIterator.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/iterate/MergeSortResultIterator.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/iterate/MergeSortRowKeyResultIterator.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/iterate/MergeSortTopNResultIterator.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/iterate/OffsetResultIterator.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/iterate/OrderedAggregatingResultIterator.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/iterate/OrderedResultIterator.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/iterate/ParallelIteratorFactory.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/iterate/ParallelIteratorRegionSplitter.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/iterate/ParallelIterators.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/iterate/ParallelScanGrouper.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/iterate/ParallelScansCollector.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/iterate/PeekingResultIterator.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/iterate/PhoenixQueues.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/iterate/ResultIterator.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/iterate/ResultIterators.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/iterate/RoundRobinResultIterator.java
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/iterate/RowKeyOrderedAggregateResultIterator.java
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/iterate/ScanningResultIterator.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/iterate/ScansWithRegionLocations.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/iterate/SequenceResultIterator.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/iterate/SerialIterators.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/iterate/SizeAwareQueue.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/iterate/SizeBoundQueue.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/iterate/SpoolTooBigToDiskException.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/iterate/SpoolingResultIterator.java
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/iterate/TableResultIterator.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/iterate/TableResultIteratorFactory.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/iterate/TableSamplerPredicate.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/iterate/UngroupedAggregatingResultIterator.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/iterate/UnionResultIterators.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/jdbc/AbstractRPCConnectionInfo.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/jdbc/ClusterRoleRecord.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/jdbc/ClusterRoleRecordGeneratorTool.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/jdbc/ConnectionInfo.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/jdbc/DelegateConnection.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/jdbc/DelegatePreparedStatement.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/jdbc/DelegateResultSet.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/jdbc/DelegateStatement.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/jdbc/FailoverPhoenixConnection.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/jdbc/FailoverPolicy.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/jdbc/HighAvailabilityGroup.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/jdbc/HighAvailabilityPolicy.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/jdbc/LoggingPhoenixConnection.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/jdbc/LoggingPhoenixPreparedStatement.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/jdbc/LoggingPhoenixResultSet.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/jdbc/LoggingPhoenixStatement.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/jdbc/MasterConnectionInfo.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/jdbc/ParallelPhoenixConnection.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/jdbc/ParallelPhoenixContext.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/jdbc/ParallelPhoenixMetrics.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/jdbc/ParallelPhoenixNullComparingResultSet.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/jdbc/ParallelPhoenixPreparedStatement.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/jdbc/ParallelPhoenixResultSet.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/jdbc/ParallelPhoenixResultSetFactory.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/jdbc/ParallelPhoenixStatement.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/jdbc/ParallelPhoenixUtil.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/jdbc/PhoenixConnection.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/jdbc/PhoenixDriver.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/jdbc/PhoenixEmbeddedDriver.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/jdbc/PhoenixHAAdminTool.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/jdbc/PhoenixHAExecutorServiceProvider.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/jdbc/PhoenixHAGroupMetrics.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/jdbc/PhoenixMetricsHolder.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/jdbc/PhoenixMetricsLog.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/jdbc/PhoenixMonitoredConnection.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/jdbc/PhoenixMonitoredPreparedStatement.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/jdbc/PhoenixMonitoredResultSet.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/jdbc/PhoenixMonitoredStatement.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/jdbc/PhoenixParameterMetaData.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/jdbc/PhoenixPreparedStatement.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/jdbc/PhoenixResultSet.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/jdbc/PhoenixResultSetMetaData.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/jdbc/PhoenixStatement.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/jdbc/PhoenixStatementFactory.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/jdbc/RPCConnectionInfo.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/jdbc/ZKConnectionInfo.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/job/AbstractRoundRobinQueue.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/job/JobManager.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/join/HashCacheClient.java
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/join/HashCacheFactory.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/join/HashJoinInfo.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/join/MaxServerCacheSizeExceededException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/log/ActivityLogInfo.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/log/AuditQueryLogger.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/log/BaseConnectionLimiter.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/log/ConnectionActivityLogger.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/log/ConnectionLimiter.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/log/DefaultConnectionLimiter.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/log/LogLevel.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/log/LogWriter.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/log/LoggingConnectionLimiter.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/log/QueryLogDetailsWorkHandler.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/log/QueryLogInfo.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/log/QueryLogger.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/log/QueryLoggerDefaultExceptionHandler.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/log/QueryLoggerDisruptor.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/log/QueryLoggerUtil.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/log/QueryStatus.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/log/RingBufferEvent.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/log/RingBufferEventTranslator.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/log/TableLogWriter.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/mapreduce/util/ConnectionUtil.java
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/mapreduce/util/PhoenixConfigurationUtilHelper.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/memory/ChildMemoryManager.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/memory/DelegatingMemoryManager.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/memory/GlobalMemoryManager.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/memory/InsufficientMemoryException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/memory/MemoryManager.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/metrics/MetricInfo.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/metrics/Metrics.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/monitoring/AtomicMetric.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/monitoring/CombinableMetric.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/monitoring/CombinableMetricImpl.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/monitoring/ConnectionQueryServicesMetric.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/monitoring/ConnectionQueryServicesMetricImpl.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/monitoring/GlobalClientMetrics.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/monitoring/GlobalMetric.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/monitoring/GlobalMetricImpl.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/monitoring/GlobalMetricRegistriesAdapter.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/monitoring/HistogramDistribution.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/monitoring/HistogramDistributionImpl.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/monitoring/JmxMetricProvider.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/monitoring/LatencyHistogram.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/monitoring/MemoryMetricsHolder.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/monitoring/Metric.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/monitoring/MetricPublisherSupplierFactory.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/monitoring/MetricServiceResolver.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/monitoring/MetricType.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/monitoring/MetricUtil.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/monitoring/MetricsRegistry.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/monitoring/MetricsStopWatch.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/monitoring/MutationMetricQueue.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/monitoring/NoOpGlobalMetricImpl.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/monitoring/NoOpTableMetricsManager.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/monitoring/NonAtomicMetric.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/monitoring/OverAllQueryMetrics.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/monitoring/PhoenixTableMetric.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/monitoring/PhoenixTableMetricImpl.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/monitoring/RangeHistogram.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/monitoring/ReadMetricQueue.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/monitoring/ScanMetricsHolder.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/monitoring/SizeHistogram.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/monitoring/SpoolingMetricsHolder.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/monitoring/TableClientMetrics.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/monitoring/TableHistograms.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/monitoring/TableMetricsManager.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/monitoring/TaskExecutionMetricsHolder.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/monitoring/connectionqueryservice/ConnectionQueryServicesHistogram.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/monitoring/connectionqueryservice/ConnectionQueryServicesMetrics.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/monitoring/connectionqueryservice/ConnectionQueryServicesMetricsHistograms.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/monitoring/connectionqueryservice/ConnectionQueryServicesMetricsManager.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/monitoring/connectionqueryservice/NoOpConnectionQueryServicesMetricsManager.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/optimize/Cost.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/optimize/GenSubqueryParamValuesRewriter.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/optimize/QueryOptimizer.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/AddColumnStatement.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/AddJarsStatement.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/AddParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/AggregateFunctionParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/AggregateFunctionWithinGroupParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/AliasedNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/AlterIndexStatement.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/AlterSessionStatement.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/AlterTableStatement.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/AndBooleanParseNodeVisitor.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/AndParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/AndRewriterBooleanParseNodeVisitor.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/ArithmeticParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/ArrayAllAnyComparisonNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/ArrayAllComparisonNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/ArrayAnyComparisonNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/ArrayConstructorNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/ArrayElemRefNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/ArrayModifierParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/AvgAggregateParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/BaseParseNodeVisitor.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/BetweenParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/BinaryParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/BindParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/BindTableNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/BindableStatement.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/BooleanParseNodeVisitor.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/CaseParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/CastParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/CeilParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/ChangePermsStatement.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/CloseStatement.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/ColumnDef.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/ColumnDefInPkConstraint.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/ColumnFamilyDef.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/ColumnName.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/ColumnParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/ComparisonParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/CompoundParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/ConcreteTableNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/CreateFunctionStatement.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/CreateIndexStatement.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/CreateSchemaStatement.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/CreateSequenceStatement.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/CreateTableStatement.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/CurrentDateParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/CurrentTimeParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/CursorName.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/DMLStatement.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/DeclareCursorStatement.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/DelegateConstantToCountParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/DeleteJarStatement.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/DeleteStatement.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/DerivedTableNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/DistinctCountHyperLogLogAggregateParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/DistinctCountParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/DivideParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/DropColumnStatement.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/DropFunctionStatement.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/DropIndexStatement.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/DropSchemaStatement.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/DropSequenceStatement.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/DropTableStatement.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/EqualParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/ExecuteUpgradeStatement.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/ExistsParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/ExplainStatement.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/ExplainType.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/FamilyWildcardParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/FetchStatement.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/FilterableStatement.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/FirstValueAggregateParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/FirstValuesAggregateParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/FloorParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/FunctionParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/GreaterThanOrEqualParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/GreaterThanParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/HintNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/InListParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/InParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/IndexExpressionParseNodeRewriter.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/IndexKeyConstraint.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/IsNullParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/JoinTableNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/LastValueAggregateParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/LastValuesAggregateParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/LessThanOrEqualParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/LessThanParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/LikeParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/LimitNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/ListJarsStatement.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/LiteralParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/MaxAggregateParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/MinAggregateParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/ModulusParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/MultiplyParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/MutableStatement.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/NamedNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/NamedParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/NamedTableNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/NotEqualParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/NotParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/NthValueAggregateParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/OffsetNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/OpenStatement.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/OrParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/OrderByNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/PFunction.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/PSchema.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/ParseContext.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/ParseException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/ParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/ParseNodeFactory.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/ParseNodeRewriter.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/ParseNodeVisitor.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/parse/PhoenixRowTimestampParseNode.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/PrimaryKeyConstraint.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/PropertyName.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/RegexpReplaceParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/RegexpSplitParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/RegexpSubstrParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/RoundParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/RowValueConstructorParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/SQLParser.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/SelectStatement.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/SelectStatementRewriter.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/SequenceValueParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/ShowCreateTable.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/ShowCreateTableStatement.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/ShowSchemasStatement.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/ShowStatement.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/ShowTablesStatement.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/SingleTableStatement.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/StatelessTraverseAllParseNodeVisitor.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/StringConcatParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/SubqueryParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/SubtractParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/SumAggregateParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/TableName.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/TableNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/TableNodeVisitor.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/TableWildcardParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/TerminalParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/ToCharParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/ToDateParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/ToNumberParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/ToTimeParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/ToTimestampParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/TraceStatement.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/TraverseAllParseNodeVisitor.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/TraverseNoParseNodeVisitor.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/UDFParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/UnaryParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/UnsupportedAllParseNodeVisitor.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/UpdateStatisticsStatement.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/UpsertStatement.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/UseSchemaStatement.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/parse/WildcardParseNode.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/protobuf/ProtobufUtil.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/query/AdminUtilWithFallback.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/query/BaseQueryServicesImpl.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/query/ChildLinkMetaDataServiceCallBack.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/query/ChildQueryServices.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/query/ConfigurationFactory.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/query/ConnectionQueryServices.java
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/query/ConnectionlessQueryServicesImpl.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/query/DefaultGuidePostsCacheFactory.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/query/DelegateConnectionQueryServices.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/query/DelegateQueryServices.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/query/EmptyStatsLoader.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/query/GuidePostsCache.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/query/GuidePostsCacheFactory.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/query/GuidePostsCacheImpl.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/query/GuidePostsCacheProvider.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/query/GuidePostsCacheWrapper.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/query/HBaseFactoryProvider.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/query/HConnectionFactory.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/query/HTableFactory.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/query/ITGuidePostsCacheFactory.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/query/KeyRange.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/query/MetaDataMutated.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/query/PhoenixStatsCacheLoader.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/query/PhoenixStatsLoader.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/query/PropertyNotAllowedException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/query/PropertyPolicy.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/query/PropertyPolicyProvider.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/query/QueryConstants.java
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/query/QueryServices.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/query/QueryServicesImpl.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/query/QueryServicesOptions.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/query/StatsLoaderImpl.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/AmbiguousColumnException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/AmbiguousTableException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/ArgumentTypeMismatchException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/ColumnAlreadyExistsException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/ColumnFamilyNotFoundException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/ColumnMetaDataOps.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/ColumnModifier.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/ColumnNotFoundException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/ColumnRef.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/ColumnValueDecoder.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/ColumnValueEncoder.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/ConcurrentTableMutationException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/ConnectionProperty.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/ConstraintViolationException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/DelegateColumn.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/DelegateDatum.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/DelegateSQLException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/DelegateTable.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/EmptySequenceCacheException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/ExecuteQueryNotApplicableException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/ExecuteUpdateNotApplicableException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/FunctionAlreadyExistsException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/FunctionNotFoundException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/IllegalDataException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/IndexNotFoundException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/IndexUncoveredDataColumnRef.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/KeyValueSchema.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/MaxMutationSizeBytesExceededException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/MaxMutationSizeExceededException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/MaxPhoenixColumnSizeExceededException.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/MetaDataEntityNotFoundException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/NewerFunctionAlreadyExistsException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/NewerSchemaAlreadyExistsException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/NewerTableAlreadyExistsException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/PColumn.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/PColumnFamily.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/PColumnFamilyImpl.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/PColumnImpl.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/PDatum.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/PIndexState.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/PMetaData.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/PMetaDataCache.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/PMetaDataEntity.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/PMetaDataImpl.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/PName.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/PNameFactory.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/PNameImpl.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/schema/PRow.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/PSynchronizedMetaData.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/PTable.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/schema/PTableImpl.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/PTableKey.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/PTableRef.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/PTableRefFactory.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/PTableRefImpl.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/PTableType.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/ProjectedColumn.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/ReadOnlyTableException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/RowKeySchema.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/RowKeyValueAccessor.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/RowValueConstructorOffsetInternalErrorException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/RowValueConstructorOffsetNotAllowedInQueryException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/RowValueConstructorOffsetNotCoercibleException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/SaltingUtil.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/SchemaAlreadyExistsException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/SchemaNotFoundException.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/schema/Sequence.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/SequenceAllocation.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/SequenceAlreadyExistsException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/SequenceInfo.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/SequenceKey.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/SequenceNotFoundException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/SerializedPTableRef.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/SerializedPTableRefFactory.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/SortOrder.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/StaleRegionBoundaryCacheException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/TableAlreadyExistsException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/TableNotFoundException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/TableProperty.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/TableRef.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/TablesNotInSyncException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/TypeMismatchException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/UpsertColumnsValuesMismatchException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/ValueBitSet.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/ValueRangeExcpetion.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/ValueSchema.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/export/DefaultSchemaRegistryRepository.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/export/DefaultSchemaWriter.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/export/SchemaImporter.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/export/SchemaRegistryRepository.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/export/SchemaRegistryRepositoryFactory.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/export/SchemaWriter.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/export/SchemaWriterFactory.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/metrics/MetricsMetadataSource.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/metrics/MetricsMetadataSourceFactory.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/metrics/MetricsMetadataSourceImpl.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/stats/GuidePostsInfo.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/stats/GuidePostsInfoBuilder.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/stats/GuidePostsKey.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/stats/StatisticsCollectionRunTracker.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/stats/StatisticsCollectionScope.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/schema/stats/StatisticsUtil.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/stats/StatsCollectionDisabledOnServerException.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/task/SystemTaskParams.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/schema/task/Task.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/tool/SchemaExtractionProcessor.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/tool/SchemaProcessor.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/tool/SchemaSQLUtil.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/tool/SchemaSynthesisProcessor.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/tool/SchemaTool.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/transform/SystemTransformRecord.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/schema/transform/TransformClient.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/transform/TransformMaintainer.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/tuple/BaseTuple.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/tuple/DelegateTuple.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/tuple/EncodedColumnQualiferCellsList.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/tuple/MultiKeyValueTuple.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/tuple/PositionBasedMultiKeyValueTuple.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/tuple/PositionBasedResultTuple.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/tuple/ResultTuple.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/tuple/SingleKeyValueTuple.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/tuple/Tuple.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/tuple/ValueGetterTuple.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PArrayDataType.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PArrayDataTypeDecoder.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PArrayDataTypeEncoder.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PBinary.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PBinaryArray.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PBinaryBase.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PBoolean.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PBooleanArray.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PChar.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PCharArray.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PDataType.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PDataTypeFactory.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PDate.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PDateArray.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PDecimal.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PDecimalArray.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PDouble.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PDoubleArray.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PFloat.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PFloatArray.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PInteger.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PIntegerArray.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PLong.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PLongArray.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PNumericType.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PRealNumber.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PSmallint.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PSmallintArray.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PTime.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PTimeArray.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PTimestamp.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PTimestampArray.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PTinyint.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PTinyintArray.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PUnsignedDate.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PUnsignedDateArray.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PUnsignedDouble.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PUnsignedDoubleArray.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PUnsignedFloat.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PUnsignedFloatArray.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PUnsignedInt.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PUnsignedIntArray.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PUnsignedLong.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PUnsignedLongArray.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PUnsignedSmallint.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PUnsignedSmallintArray.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PUnsignedTime.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PUnsignedTimeArray.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PUnsignedTimestamp.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PUnsignedTimestampArray.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PUnsignedTinyint.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PUnsignedTinyintArray.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PVarbinary.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PVarbinaryArray.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PVarchar.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PVarcharArray.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PWholeNumber.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/schema/types/PhoenixArray.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/trace/MetricsInfoImpl.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/trace/PhoenixMetricsSink.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/trace/TraceReader.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/trace/TraceSpanReceiver.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/trace/TraceWriter.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/trace/TracingIterator.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/trace/TracingUtils.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/trace/util/ConfigurationAdapter.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/trace/util/NullSpan.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/trace/util/Tracing.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/transaction/NotAvailableTransactionProvider.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/transaction/OmidTransactionContext.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/transaction/OmidTransactionProvider.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/transaction/OmidTransactionTable.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/transaction/PhoenixTransactionClient.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/transaction/PhoenixTransactionContext.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/transaction/PhoenixTransactionProvider.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/transaction/TransactionFactory.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/Base62Encoder.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/BigDecimalUtil.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/BitSet.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/ByteUtil.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/CSVCommonsLoader.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/util/ClientUtil.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/Closeables.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/ColumnInfo.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/ConfigUtil.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/CostUtil.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/CursorUtil.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/DateUtil.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/DefaultEnvironmentEdge.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/DeferredStringBuilder.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/util/EncodedColumnsUtil.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/EnvironmentEdge.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/EnvironmentEdgeManager.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/EquiDepthStreamHistogram.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/ExpressionUtil.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/FirstLastNthValueDataContainer.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/util/IndexUtil.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/InstanceResolver.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/JDBCUtil.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/JacksonUtil.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/LogUtil.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/MajorMinorVersion.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/ManualEnvironmentEdge.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/util/MetaDataUtil.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/NumberUtil.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/ParseNodeUtil.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/PhoenixContextExecutor.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/PhoenixKeyValueUtil.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/util/PhoenixRuntime.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/PhoenixStopWatch.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/PrefixByteCodec.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/PrefixByteDecoder.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/PrefixByteEncoder.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/PropertiesUtil.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/QueryBuilder.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/QueryUtil.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/ReadOnlyProps.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/ResultUtil.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/SQLCloseable.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/SQLCloseables.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/util/ScanUtil.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/SchemaUtil.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/SequenceUtil.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/SizedUtil.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/StringUtil.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/util/TableViewFinderResult.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/TaskMetaDataServiceCallBack.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/TimeKeeper.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/util/TransactionUtil.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/TrustedByteArrayOutputStream.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/TupleUtil.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/util/UpgradeUtil.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/UpsertExecutor.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/util/ValidateLastDDLTimestampUtil.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/VarBinaryFormatter.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/ViewIndexIdRetrieveUtil.java (100%)
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/util/ViewUtil.java
 create mode 100644 phoenix-core-client/src/main/java/org/apache/phoenix/util/WALAnnotationUtil.java
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/csv/CsvUpsertExecutor.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/csv/StringToArrayConverter.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/i18n/LinguisticSort.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/i18n/LocaleUtils.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/i18n/OracleUpper.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/i18n/OracleUpperTable.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/i18n/package-info.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/json/JsonUpsertExecutor.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/json/ObjectToArrayConverter.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/org/apache/phoenix/util/regex/RegexUpsertExecutor.java (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/java/overview.html (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/protobuf/ChildLinkMetaDataService.proto (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/protobuf/DynamicColumnMetaData.proto (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/protobuf/MetaDataService.proto (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/protobuf/PFunction.proto (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/protobuf/PGuidePosts.proto (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/protobuf/PSchema.proto (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/protobuf/PTable.proto (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/protobuf/RegionServerEndpointService.proto (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/protobuf/ServerCacheFactory.proto (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/protobuf/ServerCachingService.proto (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/protobuf/TaskMetaDataService.proto (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/resources/META-INF/services/java.sql.Driver (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/resources/META-INF/services/org.apache.phoenix.monitoring.MetricPublisherSupplierFactory (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/resources/META-INF/services/org.apache.phoenix.query.GuidePostsCacheFactory (100%)
 rename {phoenix-core => phoenix-core-client}/src/main/resources/phoenix-canary-file-sink.properties (100%)
 create mode 100644 phoenix-core-server/pom.xml
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/hadoop/hbase/ipc/PhoenixRpcScheduler.java (100%)
 create mode 100644 phoenix-core-server/src/main/java/org/apache/hadoop/hbase/ipc/PhoenixRpcSchedulerFactory.java
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/hadoop/hbase/ipc/RpcUtil.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/hadoop/hbase/ipc/controller/InterRegionServerMetadataRpcControllerFactory.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/hadoop/hbase/ipc/controller/ServerRpcControllerFactory.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/hadoop/hbase/regionserver/DataTableLocalIndexRegionScanner.java (100%)
 create mode 100644 phoenix-core-server/src/main/java/org/apache/hadoop/hbase/regionserver/IndexHalfStoreFileReader.java
 create mode 100644 phoenix-core-server/src/main/java/org/apache/hadoop/hbase/regionserver/IndexHalfStoreFileReaderGenerator.java
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/hadoop/hbase/regionserver/IndexKeyValueSkipListSet.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/hadoop/hbase/regionserver/KeyValueSkipListSet.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/hadoop/hbase/regionserver/LocalIndexSplitter.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/hadoop/hbase/regionserver/LocalIndexStoreFileScanner.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/hadoop/hbase/regionserver/ScannerContextUtil.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/hadoop/hbase/regionserver/wal/BinaryCompatibleBaseDecoder.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/hadoop/hbase/regionserver/wal/IndexedHLogReader.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/hadoop/hbase/regionserver/wal/IndexedWALEditCodec.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/cache/GlobalCache.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/cache/aggcache/SpillFile.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/cache/aggcache/SpillManager.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/cache/aggcache/SpillMap.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/cache/aggcache/SpillableGroupByCache.java (100%)
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/coprocessor/AddColumnMutator.java
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/coprocessor/BaseMetaDataEndpointObserver.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/coprocessor/BaseRegionScanner.java (100%)
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/coprocessor/BaseScannerRegionObserver.java
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/coprocessor/ChildLinkMetaDataEndpoint.java (100%)
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/coprocessor/ColumnMutator.java
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/coprocessor/CompactionScanner.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/coprocessor/DelegateRegionCoprocessorEnvironment.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/coprocessor/DelegateRegionObserver.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/coprocessor/DelegateRegionScanner.java (100%)
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/coprocessor/DropColumnMutator.java
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/coprocessor/GlobalIndexRegionScanner.java
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/coprocessor/GroupByCache.java (100%)
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/coprocessor/GroupedAggregateRegionObserver.java
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/coprocessor/HashJoinRegionScanner.java
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/coprocessor/IndexRebuildRegionScanner.java
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/coprocessor/IndexRepairRegionScanner.java
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/coprocessor/IndexToolVerificationResult.java (100%)
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/coprocessor/IndexerRegionScanner.java
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointObserver.java (100%)
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/coprocessor/MetaDataRegionObserver.java
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/coprocessor/OmidGCProcessor.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/coprocessor/OmidTransactionalProcessor.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/coprocessor/PagingRegionScanner.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/coprocessor/PhoenixAccessController.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/coprocessor/PhoenixCoprocessor.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/coprocessor/PhoenixMetaDataCoprocessorHost.java (100%)
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/coprocessor/PhoenixRegionServerEndpoint.java
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/coprocessor/PhoenixTTLRegionObserver.java
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/coprocessor/ReplicationSinkEndpoint.java (100%)
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/coprocessor/ScanRegionObserver.java
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/coprocessor/SequenceRegionObserver.java
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/coprocessor/ServerCachingEndpointImpl.java
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/coprocessor/SuffixFilter.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/coprocessor/SystemCatalogRegionObserver.java (100%)
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/coprocessor/TTLRegionScanner.java
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/coprocessor/TaskMetaDataEndpoint.java (100%)
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/coprocessor/TaskRegionObserver.java
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/coprocessor/TephraTransactionalProcessor.java (100%)
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/coprocessor/UncoveredGlobalIndexRegionScanner.java
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/coprocessor/UncoveredIndexRegionScanner.java
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/coprocessor/UncoveredLocalIndexRegionScanner.java
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/coprocessor/UngroupedAggregateRegionObserver.java
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/coprocessor/UngroupedAggregateRegionScanner.java
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/coprocessor/VerifyLastDDLTimestamp.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/coprocessor/tasks/BaseTask.java (100%)
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/coprocessor/tasks/DropChildViewsTask.java
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/coprocessor/tasks/IndexRebuildTask.java
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/coprocessor/tasks/TransformMonitorTask.java
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/hbase/index/CapturingAbortable.java (100%)
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/hbase/index/IndexRegionObserver.java
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/hbase/index/IndexRegionSplitPolicy.java (100%)
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/hbase/index/Indexer.java
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/hbase/index/LockManager.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/hbase/index/balancer/IndexLoadBalancer.java (100%)
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/hbase/index/builder/BaseIndexBuilder.java
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/hbase/index/builder/IndexBuildManager.java
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/hbase/index/builder/IndexBuilder.java
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/hbase/index/covered/CoveredColumns.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/hbase/index/covered/LocalTableState.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/hbase/index/covered/NonTxIndexBuilder.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/hbase/index/covered/data/CachedLocalTable.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/hbase/index/covered/data/IndexMemStore.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/hbase/index/parallel/ThreadPoolManager.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/hbase/index/wal/IndexedKeyValue.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/hbase/index/wal/KeyValueCodec.java (100%)
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/hbase/index/write/AbstractParallelWriterIndexCommitter.java
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/hbase/index/write/DelegateIndexFailurePolicy.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/hbase/index/write/IndexCommitter.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/hbase/index/write/IndexFailurePolicy.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/hbase/index/write/IndexWriter.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/hbase/index/write/IndexWriterUtils.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/hbase/index/write/KillServerOnFailurePolicy.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/hbase/index/write/LazyParallelWriterIndexCommitter.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/hbase/index/write/LeaveIndexActiveFailurePolicy.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/hbase/index/write/ParallelWriterIndexCommitter.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/hbase/index/write/RecoveryIndexWriter.java (100%)
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/hbase/index/write/TrackingParallelWriterIndexCommitter.java
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/hbase/index/write/recovery/PerRegionIndexWriteCache.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/hbase/index/write/recovery/StoreFailuresInCachePolicy.java (100%)
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/index/GlobalIndexChecker.java
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/index/PhoenixIndexBuilder.java
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/index/PhoenixIndexFailurePolicy.java
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/index/PhoenixIndexMetaDataBuilder.java
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/index/PhoenixTransactionalIndexer.java
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/iterate/MapReduceParallelScanGrouper.java (100%)
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/iterate/NonAggregateRegionScannerFactory.java
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/iterate/RegionScannerFactory.java
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/iterate/RegionScannerResultIterator.java
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/iterate/SnapshotScanner.java
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/iterate/TableSnapshotResultIterator.java
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/AbstractBulkLoadTool.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/CsvBulkImportUtil.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/CsvBulkLoadTool.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/CsvToKeyValueMapper.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/FormatToBytesWritableMapper.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/FormatToKeyValueReducer.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/ImportPreUpsertKeyValueProcessor.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/JsonBulkLoadTool.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/JsonToKeyValueMapper.java (100%)
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/mapreduce/MultiHfileOutputFormat.java
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/OrphanViewTool.java (100%)
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/mapreduce/PhoenixInputFormat.java
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/PhoenixInputSplit.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/PhoenixJobCounters.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/PhoenixMultiViewInputFormat.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/PhoenixMultiViewInputSplit.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/PhoenixMultiViewReader.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/PhoenixOutputCommitter.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/PhoenixOutputFormat.java (100%)
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/mapreduce/PhoenixRecordReader.java
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/PhoenixRecordWritable.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/PhoenixRecordWriter.java (100%)
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/mapreduce/PhoenixServerBuildIndexInputFormat.java
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/mapreduce/PhoenixTTLDeleteJobMapper.java
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/PhoenixTTLTool.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/PhoenixTextInputFormat.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/RegexBulkLoadTool.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/RegexToKeyValueMapper.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/bulkload/TableRowkeyPair.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/bulkload/TargetTableRef.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/bulkload/TargetTableRefFunctions.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/index/DirectHTableWriter.java (100%)
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/mapreduce/index/IndexScrutinyMapper.java
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/index/IndexScrutinyMapperForTest.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/index/IndexScrutinyTableOutput.java (100%)
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/mapreduce/index/IndexScrutinyTool.java
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/mapreduce/index/IndexTool.java
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/index/IndexToolUtil.java (100%)
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/mapreduce/index/IndexUpgradeTool.java
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/mapreduce/index/IndexVerificationOutputRepository.java
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/index/IndexVerificationOutputRow.java (100%)
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/mapreduce/index/IndexVerificationResultRepository.java
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/index/PhoenixIndexDBWritable.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/index/PhoenixIndexImportDirectMapper.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/index/PhoenixIndexImportDirectReducer.java (100%)
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/mapreduce/index/PhoenixIndexPartialBuildMapper.java
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/index/PhoenixIndexToolJobCounters.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/index/PhoenixScrutinyJobCounters.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/index/PhoenixServerBuildIndexDBWritable.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/index/PhoenixServerBuildIndexMapper.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/index/SourceTargetColumnNames.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/index/automation/PhoenixAsyncIndex.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/index/automation/PhoenixMRJobCallable.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/index/automation/PhoenixMRJobSubmitter.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/index/automation/YarnApplication.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/transform/PhoenixTransformReducer.java (100%)
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/mapreduce/transform/PhoenixTransformRepairMapper.java
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/mapreduce/transform/PhoenixTransformWithViewsInputFormat.java
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/mapreduce/transform/TransformTool.java
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/util/ColumnInfoToStringEncoderDecoder.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/util/DefaultMultiViewJobStatusTracker.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/util/DefaultMultiViewSplitStrategy.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/util/DefaultPhoenixMultiViewListProvider.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/util/IndexColumnNames.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/util/MultiViewJobStatusTracker.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/util/MultiViewSplitStrategy.java (100%)
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/mapreduce/util/PhoenixConfigurationUtil.java
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/util/PhoenixMapReduceUtil.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/util/PhoenixMultiInputUtil.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/util/PhoenixMultiViewListProvider.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/util/ViewInfoTracker.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/mapreduce/util/ViewInfoWritable.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/replication/SystemCatalogWALEntryFilter.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/schema/MetaDataSplitPolicy.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/schema/SplitOnLeadingVarCharColumnsPolicy.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/schema/SystemFunctionSplitPolicy.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/schema/SystemStatsSplitPolicy.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/schema/SystemTaskSplitPolicy.java (100%)
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/schema/stats/DefaultStatisticsCollector.java
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/schema/stats/NoOpStatisticsCollector.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/schema/stats/StatisticsCollector.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/schema/stats/StatisticsCollectorFactory.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/schema/stats/StatisticsScanner.java (100%)
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/schema/stats/StatisticsWriter.java
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/schema/stats/UpdateStatisticsTool.java (100%)
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/schema/task/ServerTask.java
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/schema/transform/Transform.java
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/util/MergeViewIndexIdSequencesTool.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/util/PhoenixMRJobUtil.java (100%)
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/util/RepairUtil.java (100%)
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/util/ServerIndexUtil.java
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/util/ServerUtil.java
 create mode 100644 phoenix-core-server/src/main/java/org/apache/phoenix/util/ServerViewUtil.java
 rename {phoenix-core => phoenix-core-server}/src/main/java/org/apache/phoenix/util/ZKBasedMasterElectionUtil.java (100%)
 delete mode 100644 phoenix-core/src/main/java/org/apache/hadoop/hbase/ipc/PhoenixRpcSchedulerFactory.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/hadoop/hbase/ipc/controller/IndexRpcController.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/hadoop/hbase/ipc/controller/InvalidateMetadataCacheController.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/hadoop/hbase/ipc/controller/MetadataRpcController.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/hadoop/hbase/ipc/controller/ServerToServerRpcControllerImpl.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/hadoop/hbase/regionserver/IndexHalfStoreFileReader.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/hadoop/hbase/regionserver/IndexHalfStoreFileReaderGenerator.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/cache/ServerCacheClient.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/cache/ServerMetadataCache.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/cache/TenantCache.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/cache/TenantCacheImpl.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/compile/AggregationManager.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/compile/DeleteCompiler.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/compile/FromCompiler.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/compile/GroupByCompiler.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/compile/JoinCompiler.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/compile/PostDDLCompiler.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/compile/PostLocalIndexDDLCompiler.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/compile/ProjectionCompiler.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/compile/QueryCompiler.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/compile/ScanRanges.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/compile/ServerBuildIndexCompiler.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/compile/ServerBuildTransformingTableCompiler.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/compile/UpsertCompiler.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/compile/WhereCompiler.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/coprocessor/AddColumnMutator.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/coprocessor/BaseScannerRegionObserver.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/coprocessor/ColumnMutator.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/coprocessor/DropColumnMutator.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/coprocessor/GlobalIndexRegionScanner.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/coprocessor/GroupedAggregateRegionObserver.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/coprocessor/HashJoinCacheNotFoundException.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/coprocessor/HashJoinRegionScanner.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/coprocessor/IndexRebuildRegionScanner.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/coprocessor/IndexRepairRegionScanner.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/coprocessor/IndexerRegionScanner.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/coprocessor/InvalidateServerMetadataCacheRequest.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataProtocol.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataRegionObserver.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/coprocessor/PhoenixRegionServerEndpoint.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/coprocessor/PhoenixTTLRegionObserver.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/coprocessor/ScanRegionObserver.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/coprocessor/SequenceRegionObserver.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/coprocessor/ServerCachingEndpointImpl.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/coprocessor/ServerCachingProtocol.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/coprocessor/TTLRegionScanner.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/coprocessor/TableInfo.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/coprocessor/TaskRegionObserver.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/coprocessor/UncoveredGlobalIndexRegionScanner.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/coprocessor/UncoveredIndexRegionScanner.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/coprocessor/UncoveredLocalIndexRegionScanner.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/coprocessor/UngroupedAggregateRegionObserver.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/coprocessor/UngroupedAggregateRegionScanner.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/coprocessor/WhereConstantParser.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/coprocessor/metrics/MetricsMetadataCachingSource.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/coprocessor/metrics/MetricsMetadataCachingSourceImpl.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/coprocessor/metrics/MetricsPhoenixCoprocessorSourceFactory.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/coprocessor/metrics/MetricsPhoenixTTLSource.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/coprocessor/metrics/MetricsPhoenixTTLSourceImpl.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/coprocessor/tasks/DropChildViewsTask.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/coprocessor/tasks/IndexRebuildTask.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/coprocessor/tasks/TransformMonitorTask.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/exception/SQLExceptionCode.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/exception/UpgradeInProgressException.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/execute/AggregatePlan.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/execute/BaseQueryPlan.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/execute/ClientAggregatePlan.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/execute/HashJoinPlan.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/execute/MutationState.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/execute/PhoenixTxIndexMutationGenerator.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/execute/ScanPlan.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/execute/TupleProjector.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/expression/RowValueConstructorExpression.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/filter/BooleanExpressionFilter.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/filter/MultiEncodedCQKeyValueComparisonFilter.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/filter/MultiKeyValueComparisonFilter.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/filter/SystemCatalogViewIndexIdFilter.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/hbase/index/IndexRegionObserver.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/hbase/index/Indexer.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/hbase/index/builder/BaseIndexBuilder.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/hbase/index/builder/BaseIndexCodec.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/hbase/index/builder/IndexBuildManager.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/hbase/index/builder/IndexBuilder.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/hbase/index/covered/IndexCodec.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/hbase/index/covered/IndexMetaData.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/hbase/index/covered/TableState.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/hbase/index/metrics/MetricsIndexerSource.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/hbase/index/util/IndexManagementUtil.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/hbase/index/write/AbstractParallelWriterIndexCommitter.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/hbase/index/write/TrackingParallelWriterIndexCommitter.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/index/GlobalIndexChecker.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/index/IndexMaintainer.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/index/IndexMetaDataCacheClient.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/index/IndexMetaDataCacheFactory.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/index/PhoenixIndexBuilder.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/index/PhoenixIndexCodec.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/index/PhoenixIndexFailurePolicy.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/index/PhoenixIndexMetaData.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/index/PhoenixIndexMetaDataBuilder.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/index/PhoenixTransactionalIndexer.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/iterate/BaseResultIterators.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/iterate/ChunkedResultIterator.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/iterate/ConcatResultIterator.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/iterate/ExplainTable.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/iterate/NonAggregateRegionScannerFactory.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/iterate/OrderedResultIterator.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/iterate/RegionScannerFactory.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/iterate/RegionScannerResultIterator.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/iterate/RoundRobinResultIterator.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/iterate/RowKeyOrderedAggregateResultIterator.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/iterate/ScanningResultIterator.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/iterate/SerialIterators.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/iterate/SnapshotScanner.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/iterate/SpoolingResultIterator.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/iterate/TableResultIterator.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/iterate/TableSnapshotResultIterator.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/iterate/UnionResultIterators.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/jdbc/ParallelPhoenixNullComparingResultSet.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDatabaseMetaData.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixEmbeddedDriver.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixResultSet.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixStatement.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/join/HashCacheClient.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/join/HashCacheFactory.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/mapreduce/MultiHfileOutputFormat.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/mapreduce/PhoenixInputFormat.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/mapreduce/PhoenixRecordReader.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/mapreduce/PhoenixServerBuildIndexInputFormat.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/mapreduce/PhoenixTTLDeleteJobMapper.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/mapreduce/index/IndexScrutinyMapper.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/mapreduce/index/IndexScrutinyTool.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/mapreduce/index/IndexTool.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/mapreduce/index/IndexUpgradeTool.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/mapreduce/index/IndexVerificationOutputRepository.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/mapreduce/index/IndexVerificationResultRepository.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/mapreduce/index/PhoenixIndexPartialBuildMapper.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/mapreduce/transform/PhoenixTransformRepairMapper.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/mapreduce/transform/PhoenixTransformWithViewsInputFormat.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/mapreduce/transform/TransformTool.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/mapreduce/util/ConnectionUtil.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/mapreduce/util/PhoenixConfigurationUtil.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/monitoring/LatencyHistogram.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/monitoring/SizeHistogram.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/monitoring/connectionqueryservice/ConnectionQueryServicesHistogram.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/parse/PhoenixRowTimestampParseNode.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServices.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionlessQueryServicesImpl.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/query/DelegateConnectionQueryServices.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/query/QueryServices.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/query/QueryServicesOptions.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/schema/PRow.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/schema/Sequence.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/schema/stats/DefaultStatisticsCollector.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/schema/stats/StatisticsUtil.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/schema/stats/StatisticsWriter.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/schema/task/Task.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/schema/transform/Transform.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/transaction/OmidTransactionProvider.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/transaction/TransactionFactory.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/util/EncodedColumnsUtil.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/util/IndexUtil.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/util/MetaDataUtil.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/util/PhoenixRuntime.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/util/ScanUtil.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/util/ServerUtil.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/util/TableViewFinderResult.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/util/TransactionUtil.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/util/UpgradeUtil.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/util/ValidateLastDDLTimestampUtil.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/util/ViewUtil.java
 delete mode 100644 phoenix-core/src/main/java/org/apache/phoenix/util/WALAnnotationUtil.java
 create mode 100644 phoenix-core/src/test/java/org/apache/phoenix/util/ClientUtilTest.java
 delete mode 100644 phoenix-core/src/test/java/org/apache/phoenix/util/ServerUtilTest.java


(phoenix) 01/01: Merge branch 'master' into PHOENIX-6883-feature

Posted by sh...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

shahrs87 pushed a commit to branch PHOENIX-6883-feature
in repository https://gitbox.apache.org/repos/asf/phoenix.git

commit 813e7640471a0a0d4d8489a157b920a770ed20fd
Merge: 83134d9731 2426212be2
Author: Rushabh Shah <ru...@rushabh-ltmflld.internal.salesforce.com>
AuthorDate: Thu Dec 28 14:17:14 2023 -0800

    Merge branch 'master' into PHOENIX-6883-feature

 bin/performance.py                                 |   41 +-
 bin/pherf-standalone.py                            |   37 +-
 bin/phoenix_utils.py                               |   78 +
 bin/psql.py                                        |   38 +-
 bin/sqlline.py                                     |   35 +-
 .../phoenix-client-embedded/pom.xml                |    2 +-
 phoenix-core-client/pom.xml                        |  434 ++
 .../src/build/phoenix-core.xml                     |    0
 .../src/main/antlr3/PhoenixSQL.g                   |    0
 .../org/apache/hadoop/hbase/PhoenixTagType.java    |    0
 .../apache/hadoop/hbase/client/RegionInfoUtil.java |    0
 .../ipc/controller/ClientRpcControllerFactory.java |    0
 .../hbase/ipc/controller/IndexRpcController.java   |   57 +
 ...InterRegionServerIndexRpcControllerFactory.java |    0
 .../InvalidateMetadataCacheController.java         |   51 +
 .../InvalidateMetadataCacheControllerFactory.java  |    0
 .../ipc/controller/MetadataRpcController.java      |   74 +
 .../controller/ServerSideRPCControllerFactory.java |    0
 .../controller/ServerToServerRpcController.java    |    0
 .../ServerToServerRpcControllerImpl.java           |   75 +
 .../java/org/apache/phoenix/cache/HashCache.java   |    0
 .../apache/phoenix/cache/IndexMetaDataCache.java   |    0
 .../apache/phoenix/cache/JodaTimezoneCache.java    |    0
 .../apache/phoenix/cache/ServerCacheClient.java    |  553 ++
 .../apache/phoenix/cache/ServerMetadataCache.java  |  193 +
 .../java/org/apache/phoenix/cache/TenantCache.java |   42 +
 .../org/apache/phoenix/cache/TenantCacheImpl.java  |  287 +
 .../java/org/apache/phoenix/call/CallRunner.java   |    0
 .../java/org/apache/phoenix/call/CallWrapper.java  |    0
 .../apache/phoenix/compile/AggregationManager.java |  115 +
 .../apache/phoenix/compile/BaseMutationPlan.java   |    0
 .../org/apache/phoenix/compile/BindManager.java    |    0
 .../phoenix/compile/CloseStatementCompiler.java    |    0
 .../ColumnNameTrackingExpressionCompiler.java      |    0
 .../apache/phoenix/compile/ColumnProjector.java    |    0
 .../org/apache/phoenix/compile/ColumnResolver.java |    0
 .../org/apache/phoenix/compile/CompiledOffset.java |    0
 .../phoenix/compile/CreateFunctionCompiler.java    |    0
 .../phoenix/compile/CreateIndexCompiler.java       |    0
 .../phoenix/compile/CreateSchemaCompiler.java      |    0
 .../phoenix/compile/CreateSequenceCompiler.java    |    0
 .../phoenix/compile/CreateTableCompiler.java       |    0
 .../phoenix/compile/DeclareCursorCompiler.java     |    0
 .../phoenix/compile/DelegateMutationPlan.java      |    0
 .../org/apache/phoenix/compile/DeleteCompiler.java | 1030 ++++
 .../phoenix/compile/DropSequenceCompiler.java      |    0
 .../org/apache/phoenix/compile/ExplainPlan.java    |    0
 .../phoenix/compile/ExplainPlanAttributes.java     |    0
 .../apache/phoenix/compile/ExpressionCompiler.java |    0
 .../apache/phoenix/compile/ExpressionManager.java  |    0
 .../phoenix/compile/ExpressionProjector.java       |    0
 .../org/apache/phoenix/compile/FromCompiler.java   | 1233 ++++
 .../apache/phoenix/compile/GroupByCompiler.java    |  476 ++
 .../org/apache/phoenix/compile/HavingCompiler.java |    0
 .../phoenix/compile/IndexExpressionCompiler.java   |    0
 .../phoenix/compile/IndexStatementRewriter.java    |    0
 .../org/apache/phoenix/compile/JoinCompiler.java   | 1589 +++++
 .../java/org/apache/phoenix/compile/KeyPart.java   |    0
 .../org/apache/phoenix/compile/LimitCompiler.java  |    0
 .../apache/phoenix/compile/ListJarsQueryPlan.java  |    0
 .../compile/MutatingParallelIteratorFactory.java   |    0
 .../org/apache/phoenix/compile/MutationPlan.java   |    0
 .../org/apache/phoenix/compile/OffsetCompiler.java |    0
 .../phoenix/compile/OpenStatementCompiler.java     |    0
 .../apache/phoenix/compile/OrderByCompiler.java    |    0
 .../phoenix/compile/OrderPreservingTracker.java    |    0
 .../apache/phoenix/compile/PostDDLCompiler.java    |  372 ++
 .../phoenix/compile/PostIndexDDLCompiler.java      |    0
 .../phoenix/compile/PostLocalIndexDDLCompiler.java |  133 +
 .../apache/phoenix/compile/ProjectionCompiler.java |  796 +++
 .../org/apache/phoenix/compile/QueryCompiler.java  |  814 +++
 .../java/org/apache/phoenix/compile/QueryPlan.java |    0
 .../apache/phoenix/compile/RVCOffsetCompiler.java  |    0
 .../org/apache/phoenix/compile/RowProjector.java   |    0
 .../org/apache/phoenix/compile/ScanRanges.java     |  785 +++
 .../apache/phoenix/compile/SequenceManager.java    |    0
 .../phoenix/compile/SequenceValueExpression.java   |    0
 .../phoenix/compile/ServerBuildIndexCompiler.java  |  161 +
 .../ServerBuildTransformingTableCompiler.java      |   99 +
 .../compile/StatelessExpressionCompiler.java       |    0
 .../apache/phoenix/compile/StatementContext.java   |    0
 .../phoenix/compile/StatementNormalizer.java       |    0
 .../org/apache/phoenix/compile/StatementPlan.java  |    0
 .../apache/phoenix/compile/SubqueryRewriter.java   |    0
 .../apache/phoenix/compile/SubselectRewriter.java  |    0
 .../org/apache/phoenix/compile/TraceQueryPlan.java |    0
 .../phoenix/compile/TupleProjectionCompiler.java   |    0
 .../org/apache/phoenix/compile/UnionCompiler.java  |    0
 .../org/apache/phoenix/compile/UpsertCompiler.java | 1455 +++++
 .../org/apache/phoenix/compile/WhereCompiler.java  |  958 +++
 .../org/apache/phoenix/compile/WhereOptimizer.java |    0
 .../BaseScannerRegionObserverConstants.java        |  157 +
 .../HashJoinCacheNotFoundException.java            |   45 +
 .../InvalidateServerMetadataCacheRequest.java      |   53 +
 .../MetaDataEndpointImplConstants.java             |   35 +
 .../coprocessorclient/MetaDataProtocol.java        |  521 ++
 .../ScanRegionObserverConstants.java               |   29 +
 .../SequenceRegionObserverConstants.java           |   25 +
 .../coprocessorclient/ServerCachingProtocol.java   |   61 +
 .../phoenix/coprocessorclient/TableInfo.java       |   79 +
 .../UngroupedAggregateRegionObserverHelper.java    |   59 +
 .../coprocessorclient/WhereConstantParser.java     |  110 +
 .../metrics/MetricsMetadataCachingSource.java      |  230 +
 .../metrics/MetricsMetadataCachingSourceImpl.java  |  122 +
 .../MetricsPhoenixCoprocessorSourceFactory.java    |   57 +
 .../metrics/MetricsPhoenixTTLSource.java           |   59 +
 .../metrics/MetricsPhoenixTTLSourceImpl.java       |   58 +
 .../tasks/IndexRebuildTaskConstants.java           |   25 +
 .../exception/DataExceedsCapacityException.java    |    0
 .../phoenix/exception/FailoverSQLException.java    |    0
 .../InvalidRegionSplitPolicyException.java         |    0
 .../phoenix/exception/PhoenixIOException.java      |    0
 .../PhoenixNonRetryableRuntimeException.java       |    0
 .../phoenix/exception/PhoenixParserException.java  |    0
 .../exception/RetriableUpgradeException.java       |    0
 .../apache/phoenix/exception/SQLExceptionCode.java |  697 +++
 .../apache/phoenix/exception/SQLExceptionInfo.java |    0
 .../exception/StaleMetadataCacheException.java     |    0
 .../exception/UndecodableByteException.java        |    0
 .../exception/UnknownFunctionException.java        |    0
 .../exception/UpgradeInProgressException.java      |   31 +
 .../exception/UpgradeNotRequiredException.java     |    0
 .../exception/UpgradeRequiredException.java        |    0
 .../org/apache/phoenix/execute/AggregatePlan.java  |  405 ++
 .../org/apache/phoenix/execute/BaseQueryPlan.java  |  579 ++
 .../phoenix/execute/ClientAggregatePlan.java       |  384 ++
 .../phoenix/execute/ClientProcessingPlan.java      |    0
 .../org/apache/phoenix/execute/ClientScanPlan.java |    0
 .../apache/phoenix/execute/CommitException.java    |    0
 .../apache/phoenix/execute/CursorFetchPlan.java    |    0
 .../org/apache/phoenix/execute/DelegateHTable.java |    0
 .../apache/phoenix/execute/DelegateQueryPlan.java  |    0
 .../execute/DescVarLengthFastByteComparisons.java  |    0
 .../org/apache/phoenix/execute/HashJoinPlan.java   |  700 +++
 .../execute/LiteralResultIterationPlan.java        |    0
 .../org/apache/phoenix/execute/MutationState.java  | 2309 +++++++
 .../execute/PhoenixTxIndexMutationGenerator.java   |  522 ++
 .../org/apache/phoenix/execute/RuntimeContext.java |    0
 .../apache/phoenix/execute/RuntimeContextImpl.java |    0
 .../java/org/apache/phoenix/execute/ScanPlan.java  |  405 ++
 .../apache/phoenix/execute/SortMergeJoinPlan.java  |    0
 .../phoenix/execute/TupleProjectionPlan.java       |    0
 .../org/apache/phoenix/execute/TupleProjector.java |  495 ++
 .../java/org/apache/phoenix/execute/UnionPlan.java |    0
 .../apache/phoenix/execute/UnnestArrayPlan.java    |    0
 .../execute/visitor/AvgRowWidthVisitor.java        |    0
 .../phoenix/execute/visitor/ByteCountVisitor.java  |    0
 .../phoenix/execute/visitor/QueryPlanVisitor.java  |    0
 .../phoenix/execute/visitor/RowCountVisitor.java   |    0
 .../apache/phoenix/expression/AddExpression.java   |    0
 .../apache/phoenix/expression/AndExpression.java   |    0
 .../apache/phoenix/expression/AndOrExpression.java |    0
 .../phoenix/expression/ArithmeticExpression.java   |    0
 .../expression/ArrayConstructorExpression.java     |    0
 .../expression/BaseAddSubtractExpression.java      |    0
 .../phoenix/expression/BaseCompoundExpression.java |    0
 .../BaseDecimalAddSubtractExpression.java          |    0
 .../apache/phoenix/expression/BaseExpression.java  |    0
 .../phoenix/expression/BaseSingleExpression.java   |    0
 .../phoenix/expression/BaseTerminalExpression.java |    0
 .../expression/ByteBasedLikeExpression.java        |    0
 .../apache/phoenix/expression/CaseExpression.java  |    0
 .../phoenix/expression/CoerceExpression.java       |    0
 .../phoenix/expression/ColumnExpression.java       |    0
 .../phoenix/expression/ComparisonExpression.java   |    0
 .../CorrelateVariableFieldAccessExpression.java    |    0
 .../expression/CurrentDateTimeFunction.java        |    0
 .../phoenix/expression/DateAddExpression.java      |    0
 .../phoenix/expression/DateSubtractExpression.java |    0
 .../phoenix/expression/DecimalAddExpression.java   |    0
 .../expression/DecimalDivideExpression.java        |    0
 .../expression/DecimalMultiplyExpression.java      |    0
 .../expression/DecimalSubtractExpression.java      |    0
 .../phoenix/expression/DelegateExpression.java     |    0
 .../org/apache/phoenix/expression/Determinism.java |    0
 .../phoenix/expression/DivideExpression.java       |    0
 .../phoenix/expression/DoubleAddExpression.java    |    0
 .../phoenix/expression/DoubleDivideExpression.java |    0
 .../expression/DoubleMultiplyExpression.java       |    0
 .../expression/DoubleSubtractExpression.java       |    0
 .../org/apache/phoenix/expression/Expression.java  |    0
 .../apache/phoenix/expression/ExpressionType.java  |    0
 .../phoenix/expression/InListExpression.java       |    0
 .../phoenix/expression/IsNullExpression.java       |    0
 .../expression/KeyValueColumnExpression.java       |    0
 .../apache/phoenix/expression/LikeExpression.java  |    0
 .../phoenix/expression/LiteralExpression.java      |    0
 .../phoenix/expression/LongAddExpression.java      |    0
 .../phoenix/expression/LongDivideExpression.java   |    0
 .../phoenix/expression/LongMultiplyExpression.java |    0
 .../phoenix/expression/LongSubtractExpression.java |    0
 .../phoenix/expression/ModulusExpression.java      |    0
 .../phoenix/expression/MultiplyExpression.java     |    0
 .../apache/phoenix/expression/NotExpression.java   |    0
 .../apache/phoenix/expression/OrExpression.java    |    0
 .../phoenix/expression/OrderByExpression.java      |    0
 .../expression/ProjectedColumnExpression.java      |    0
 .../phoenix/expression/RowKeyColumnExpression.java |    0
 .../phoenix/expression/RowKeyExpression.java       |    0
 .../expression/RowValueConstructorExpression.java  |  277 +
 .../expression/SingleCellColumnExpression.java     |    0
 .../SingleCellConstructorExpression.java           |    0
 .../expression/StringBasedLikeExpression.java      |    0
 .../phoenix/expression/StringConcatExpression.java |    0
 .../phoenix/expression/SubtractExpression.java     |    0
 .../phoenix/expression/TimestampAddExpression.java |    0
 .../expression/TimestampSubtractExpression.java    |    0
 .../phoenix/expression/aggregator/Aggregator.java  |    0
 .../phoenix/expression/aggregator/Aggregators.java |    0
 .../expression/aggregator/BaseAggregator.java      |    0
 .../aggregator/BaseDecimalStddevAggregator.java    |    0
 .../aggregator/BaseStddevAggregator.java           |    0
 .../expression/aggregator/ClientAggregators.java   |    0
 .../expression/aggregator/CountAggregator.java     |    0
 .../aggregator/DecimalStddevPopAggregator.java     |    0
 .../aggregator/DecimalStddevSampAggregator.java    |    0
 .../aggregator/DecimalSumAggregator.java           |    0
 .../aggregator/DistinctCountClientAggregator.java  |    0
 .../aggregator/DistinctValueClientAggregator.java  |    0
 .../DistinctValueWithCountClientAggregator.java    |    0
 .../DistinctValueWithCountServerAggregator.java    |    0
 .../expression/aggregator/DoubleSumAggregator.java |    0
 .../FirstLastValueBaseClientAggregator.java        |    0
 .../aggregator/FirstLastValueServerAggregator.java |    0
 .../expression/aggregator/IntSumAggregator.java    |    0
 .../expression/aggregator/LongSumAggregator.java   |    0
 .../expression/aggregator/MaxAggregator.java       |    0
 .../expression/aggregator/MinAggregator.java       |    0
 .../NonSizeTrackingServerAggregators.java          |    0
 .../expression/aggregator/NumberSumAggregator.java |    0
 .../aggregator/PercentRankClientAggregator.java    |    0
 .../aggregator/PercentileClientAggregator.java     |    0
 .../aggregator/PercentileDiscClientAggregator.java |    0
 .../expression/aggregator/ServerAggregators.java   |    0
 .../aggregator/SizeTrackingServerAggregators.java  |    0
 .../expression/aggregator/StddevPopAggregator.java |    0
 .../aggregator/StddevSampAggregator.java           |    0
 .../aggregator/UnsignedIntSumAggregator.java       |    0
 .../aggregator/UnsignedLongSumAggregator.java      |    0
 .../phoenix/expression/function/AbsFunction.java   |    0
 .../expression/function/AggregateFunction.java     |    0
 .../function/ArrayAllComparisonExpression.java     |    0
 .../function/ArrayAnyComparisonExpression.java     |    0
 .../expression/function/ArrayAppendFunction.java   |    0
 .../expression/function/ArrayConcatFunction.java   |    0
 .../function/ArrayElemRefExpression.java           |    0
 .../expression/function/ArrayFillFunction.java     |    0
 .../expression/function/ArrayIndexFunction.java    |    0
 .../expression/function/ArrayLengthFunction.java   |    0
 .../expression/function/ArrayModifierFunction.java |    0
 .../expression/function/ArrayPrependFunction.java  |    0
 .../expression/function/ArrayRemoveFunction.java   |    0
 .../expression/function/ArrayToStringFunction.java |    0
 .../expression/function/AvgAggregateFunction.java  |    0
 .../function/ByteBasedRegexpReplaceFunction.java   |    0
 .../function/ByteBasedRegexpSplitFunction.java     |    0
 .../function/ByteBasedRegexpSubstrFunction.java    |    0
 .../phoenix/expression/function/CbrtFunction.java  |    0
 .../expression/function/CeilDateExpression.java    |    0
 .../expression/function/CeilDecimalExpression.java |    0
 .../phoenix/expression/function/CeilFunction.java  |    0
 .../expression/function/CeilMonthExpression.java   |    0
 .../function/CeilTimestampExpression.java          |    0
 .../expression/function/CeilWeekExpression.java    |    0
 .../expression/function/CeilYearExpression.java    |    0
 .../expression/function/CoalesceFunction.java      |    0
 .../expression/function/CollationKeyFunction.java  |    0
 .../function/CompositeAggregateFunction.java       |    0
 .../function/ConvertTimezoneFunction.java          |    0
 .../phoenix/expression/function/CosFunction.java   |    0
 .../function/CountAggregateFunction.java           |    0
 .../expression/function/CurrentDateFunction.java   |    0
 .../expression/function/CurrentTimeFunction.java   |    0
 .../expression/function/DateScalarFunction.java    |    0
 .../expression/function/DayOfMonthFunction.java    |    0
 .../expression/function/DayOfWeekFunction.java     |    0
 .../expression/function/DayOfYearFunction.java     |    0
 .../expression/function/DecodeFunction.java        |    0
 .../function/DefaultValueExpression.java           |    0
 .../DelegateConstantToCountAggregateFunction.java  |    0
 .../function/DistinctCountAggregateFunction.java   |    0
 .../DistinctCountHyperLogLogAggregateFunction.java |    0
 .../function/DistinctValueAggregateFunction.java   |    0
 .../DistinctValueWithCountAggregateFunction.java   |    0
 .../phoenix/expression/function/EncodeFormat.java  |    0
 .../expression/function/EncodeFunction.java        |    0
 .../phoenix/expression/function/ExpFunction.java   |    0
 .../function/ExternalSqlTypeIdFunction.java        |    0
 .../function/FirstLastValueBaseFunction.java       |    0
 .../expression/function/FirstValueFunction.java    |    0
 .../expression/function/FirstValuesFunction.java   |    0
 .../expression/function/FloorDateExpression.java   |    0
 .../function/FloorDecimalExpression.java           |    0
 .../phoenix/expression/function/FloorFunction.java |    0
 .../expression/function/FloorMonthExpression.java  |    0
 .../expression/function/FloorWeekExpression.java   |    0
 .../expression/function/FloorYearExpression.java   |    0
 .../expression/function/FunctionArgumentType.java  |    0
 .../expression/function/FunctionExpression.java    |    0
 .../expression/function/GetBitFunction.java        |    0
 .../expression/function/GetByteFunction.java       |    0
 .../phoenix/expression/function/HourFunction.java  |    0
 .../function/IndexStateNameFunction.java           |    0
 .../phoenix/expression/function/InstrFunction.java |    0
 .../expression/function/InvertFunction.java        |    0
 .../function/JavaMathOneArgumentFunction.java      |    0
 .../function/JavaMathTwoArgumentFunction.java      |    0
 .../phoenix/expression/function/LTrimFunction.java |    0
 .../expression/function/LastValueFunction.java     |    0
 .../expression/function/LastValuesFunction.java    |    0
 .../expression/function/LengthFunction.java        |    0
 .../phoenix/expression/function/LnFunction.java    |    0
 .../phoenix/expression/function/LogFunction.java   |    0
 .../phoenix/expression/function/LowerFunction.java |    0
 .../phoenix/expression/function/LpadFunction.java  |    0
 .../phoenix/expression/function/MD5Function.java   |    0
 .../expression/function/MathPIFunction.java        |    0
 .../expression/function/MaxAggregateFunction.java  |    0
 .../expression/function/MinAggregateFunction.java  |    0
 .../expression/function/MinuteFunction.java        |    0
 .../phoenix/expression/function/MonthFunction.java |    0
 .../phoenix/expression/function/NowFunction.java   |    0
 .../expression/function/NthValueFunction.java      |    0
 .../expression/function/OctetLengthFunction.java   |    0
 .../function/PercentRankAggregateFunction.java     |    0
 .../function/PercentileContAggregateFunction.java  |    0
 .../function/PercentileDiscAggregateFunction.java  |    0
 .../function/PhoenixRowTimestampFunction.java      |    0
 .../phoenix/expression/function/PowerFunction.java |    0
 .../expression/function/PrefixFunction.java        |    0
 .../phoenix/expression/function/RTrimFunction.java |    0
 .../expression/function/RandomFunction.java        |    0
 .../expression/function/RegexpReplaceFunction.java |    0
 .../expression/function/RegexpSplitFunction.java   |    0
 .../expression/function/RegexpSubstrFunction.java  |    0
 .../expression/function/ReverseFunction.java       |    0
 .../expression/function/RoundDateExpression.java   |    0
 .../function/RoundDecimalExpression.java           |    0
 .../phoenix/expression/function/RoundFunction.java |    0
 .../function/RoundJodaDateExpression.java          |    0
 .../expression/function/RoundMonthExpression.java  |    0
 .../function/RoundTimestampExpression.java         |    0
 .../expression/function/RoundWeekExpression.java   |    0
 .../expression/function/RoundYearExpression.java   |    0
 .../function/RowKeyBytesStringFunction.java        |    0
 .../expression/function/SQLIndexTypeFunction.java  |    0
 .../expression/function/SQLTableTypeFunction.java  |    0
 .../expression/function/SQLViewTypeFunction.java   |    0
 .../expression/function/ScalarFunction.java        |    0
 .../expression/function/SecondFunction.java        |    0
 .../expression/function/SetBitFunction.java        |    0
 .../expression/function/SetByteFunction.java       |    0
 .../phoenix/expression/function/SignFunction.java  |    0
 .../phoenix/expression/function/SinFunction.java   |    0
 .../function/SingleAggregateFunction.java          |    0
 .../expression/function/SqlTypeNameFunction.java   |    0
 .../phoenix/expression/function/SqrtFunction.java  |    0
 .../expression/function/StddevPopFunction.java     |    0
 .../expression/function/StddevSampFunction.java    |    0
 .../function/StringBasedRegexpReplaceFunction.java |    0
 .../function/StringBasedRegexpSplitFunction.java   |    0
 .../function/StringBasedRegexpSubstrFunction.java  |    0
 .../expression/function/StringToArrayFunction.java |    0
 .../expression/function/SubstrFunction.java        |    0
 .../expression/function/SumAggregateFunction.java  |    0
 .../phoenix/expression/function/TanFunction.java   |    0
 .../phoenix/expression/function/TimeUnit.java      |    0
 .../function/TimezoneOffsetFunction.java           |    0
 .../expression/function/ToCharFunction.java        |    0
 .../expression/function/ToDateFunction.java        |    0
 .../expression/function/ToNumberFunction.java      |    0
 .../expression/function/ToTimeFunction.java        |    0
 .../expression/function/ToTimestampFunction.java   |    0
 .../function/TransactionProviderNameFunction.java  |    0
 .../phoenix/expression/function/TrimFunction.java  |    0
 .../phoenix/expression/function/TruncFunction.java |    0
 .../phoenix/expression/function/UDFExpression.java |    0
 .../phoenix/expression/function/UpperFunction.java |    0
 .../phoenix/expression/function/WeekFunction.java  |    0
 .../phoenix/expression/function/YearFunction.java  |    0
 .../RowValueConstructorExpressionRewriter.java     |    0
 .../expression/util/regex/AbstractBasePattern.java |    0
 .../util/regex/AbstractBaseSplitter.java           |    0
 .../expression/util/regex/GuavaSplitter.java       |    0
 .../phoenix/expression/util/regex/JONIPattern.java |    0
 .../phoenix/expression/util/regex/JavaPattern.java |    0
 .../expression/visitor/BaseExpressionVisitor.java  |    0
 .../expression/visitor/CloneExpressionVisitor.java |    0
 .../expression/visitor/ExpressionVisitor.java      |    0
 .../visitor/KeyValueExpressionVisitor.java         |    0
 .../visitor/ProjectedColumnExpressionVisitor.java  |    0
 .../ReplaceArrayFunctionExpressionVisitor.java     |    0
 .../visitor/RowKeyExpressionVisitor.java           |    0
 .../visitor/SingleAggregateFunctionVisitor.java    |    0
 .../StatelessTraverseAllExpressionVisitor.java     |    0
 .../StatelessTraverseNoExpressionVisitor.java      |    0
 .../visitor/TraverseAllExpressionVisitor.java      |    0
 .../visitor/TraverseNoExpressionVisitor.java       |    0
 .../filter/AllVersionsIndexRebuildFilter.java      |    0
 .../phoenix/filter/BooleanExpressionFilter.java    |  135 +
 .../phoenix/filter/ColumnProjectionFilter.java     |    0
 .../org/apache/phoenix/filter/DelegateFilter.java  |    0
 .../phoenix/filter/DistinctPrefixFilter.java       |    0
 .../phoenix/filter/EmptyColumnOnlyFilter.java      |    0
 .../EncodedQualifiersColumnProjectionFilter.java   |    0
 .../filter/MultiCFCQKeyValueComparisonFilter.java  |    0
 .../filter/MultiCQKeyValueComparisonFilter.java    |    0
 .../MultiEncodedCQKeyValueComparisonFilter.java    |  415 ++
 .../filter/MultiKeyValueComparisonFilter.java      |  291 +
 .../org/apache/phoenix/filter/PagingFilter.java    |    0
 .../phoenix/filter/RowKeyComparisonFilter.java     |    0
 .../filter/SingleCFCQKeyValueComparisonFilter.java |    0
 .../filter/SingleCQKeyValueComparisonFilter.java   |    0
 .../filter/SingleKeyValueComparisonFilter.java     |    0
 .../org/apache/phoenix/filter/SkipScanFilter.java  |    0
 .../filter/SystemCatalogViewIndexIdFilter.java     |  161 +
 .../apache/phoenix/filter/UnverifiedRowFilter.java |    0
 .../phoenix/hbase/index/AbstractValueGetter.java   |    0
 .../apache/phoenix/hbase/index/BaseIndexCodec.java |   34 +
 .../apache/phoenix/hbase/index/MultiMutation.java  |    0
 .../org/apache/phoenix/hbase/index/OffsetCell.java |    0
 .../apache/phoenix/hbase/index/ValueGetter.java    |    0
 .../FatalIndexBuildingFailureException.java        |    0
 .../builder/IndexBuildingFailureException.java     |    0
 .../apache/phoenix/hbase/index/covered/Batch.java  |    0
 .../phoenix/hbase/index/covered/IndexCodec.java    |   88 +
 .../phoenix/hbase/index/covered/IndexMetaData.java |   55 +
 .../phoenix/hbase/index/covered/IndexUpdate.java   |    0
 .../phoenix/hbase/index/covered/KeyValueStore.java |    0
 .../phoenix/hbase/index/covered/TableState.java    |   73 +
 .../index/covered/data/DelegateComparator.java     |    0
 .../hbase/index/covered/data/LazyValueGetter.java  |    0
 .../hbase/index/covered/data/LocalHBaseState.java  |    0
 .../filter/ApplyAndFilterDeletesFilter.java        |    0
 .../ColumnTrackingNextLargestTimestampFilter.java  |    0
 .../index/covered/filter/MaxTimestampFilter.java   |    0
 .../index/covered/filter/NewerTimestampFilter.java |    0
 .../index/covered/update/ColumnReference.java      |    0
 .../hbase/index/covered/update/ColumnTracker.java  |    0
 .../index/covered/update/IndexUpdateManager.java   |    0
 .../index/covered/update/IndexedColumnGroup.java   |    0
 .../hbase/index/exception/IndexWriteException.java |    0
 .../exception/MultiIndexWriteFailureException.java |    0
 .../SingleIndexWriteFailureException.java          |    0
 .../index/metrics/GlobalIndexCheckerSource.java    |    0
 .../metrics/GlobalIndexCheckerSourceImpl.java      |    0
 .../hbase/index/metrics/MetricsIndexerSource.java  |  212 +
 .../index/metrics/MetricsIndexerSourceFactory.java |    0
 .../index/metrics/MetricsIndexerSourceImpl.java    |    0
 .../hbase/index/parallel/BaseTaskRunner.java       |    0
 .../hbase/index/parallel/EarlyExitFailure.java     |    0
 .../index/parallel/QuickFailingTaskRunner.java     |    0
 .../apache/phoenix/hbase/index/parallel/Task.java  |    0
 .../phoenix/hbase/index/parallel/TaskBatch.java    |    0
 .../phoenix/hbase/index/parallel/TaskRunner.java   |    0
 .../hbase/index/parallel/ThreadPoolBuilder.java    |    0
 .../parallel/WaitForCompletionTaskRunner.java      |    0
 .../phoenix/hbase/index/scanner/EmptyScanner.java  |    0
 .../index/scanner/FilteredKeyValueScanner.java     |    0
 .../hbase/index/scanner/ReseekableScanner.java     |    0
 .../phoenix/hbase/index/scanner/Scanner.java       |    0
 .../hbase/index/scanner/ScannerBuilder.java        |    0
 .../phoenix/hbase/index/table/HTableFactory.java   |    0
 .../index/table/HTableInterfaceReference.java      |    0
 .../hbase/index/util/GenericKeyValueBuilder.java   |    0
 .../hbase/index/util/ImmutableBytesPtr.java        |    0
 .../hbase/index/util/IndexManagementUtil.java      |  294 +
 .../phoenix/hbase/index/util/KeyValueBuilder.java  |    0
 .../phoenix/hbase/index/util/VersionUtil.java      |    0
 .../org/apache/phoenix/index/IndexMaintainer.java  | 2299 +++++++
 .../phoenix/index/IndexMetaDataCacheClient.java    |  158 +
 .../phoenix/index/IndexMetaDataCacheFactory.java   |   82 +
 .../phoenix/index/PhoenixIndexBuilderHelper.java   |  146 +
 .../apache/phoenix/index/PhoenixIndexCodec.java    |  139 +
 .../index/PhoenixIndexFailurePolicyHelper.java     |  245 +
 .../apache/phoenix/index/PhoenixIndexMetaData.java |  101 +
 .../phoenix/iterate/AggregatingResultIterator.java |    0
 .../BaseGroupedAggregatingResultIterator.java      |    0
 .../apache/phoenix/iterate/BaseResultIterator.java |    0
 .../phoenix/iterate/BaseResultIterators.java       | 1770 ++++++
 .../org/apache/phoenix/iterate/BufferedQueue.java  |    0
 .../phoenix/iterate/BufferedSortedQueue.java       |    0
 .../apache/phoenix/iterate/BufferedTupleQueue.java |    0
 .../phoenix/iterate/ChunkedResultIterator.java     |  249 +
 .../ClientHashAggregatingResultIterator.java       |    0
 .../phoenix/iterate/ConcatResultIterator.java      |  150 +
 .../phoenix/iterate/CursorResultIterator.java      |    0
 .../iterate/DefaultParallelScanGrouper.java        |    0
 .../iterate/DefaultTableResultIteratorFactory.java |    0
 .../phoenix/iterate/DelegateResultIterator.java    |    0
 .../iterate/DistinctAggregatingResultIterator.java |    0
 .../org/apache/phoenix/iterate/ExplainTable.java   |  550 ++
 .../iterate/FilterAggregatingResultIterator.java   |    0
 .../phoenix/iterate/FilterResultIterator.java      |    0
 .../iterate/GroupedAggregatingResultIterator.java  |    0
 .../iterate/LimitingPeekingResultIterator.java     |    0
 .../phoenix/iterate/LimitingResultIterator.java    |    0
 .../phoenix/iterate/LookAheadResultIterator.java   |    0
 .../MaterializedComparableResultIterator.java      |    0
 .../iterate/MaterializedResultIterator.java        |    0
 .../phoenix/iterate/MergeSortResultIterator.java   |    0
 .../iterate/MergeSortRowKeyResultIterator.java     |    0
 .../iterate/MergeSortTopNResultIterator.java       |    0
 .../phoenix/iterate/OffsetResultIterator.java      |    0
 .../iterate/OrderedAggregatingResultIterator.java  |    0
 .../phoenix/iterate/OrderedResultIterator.java     |  426 ++
 .../phoenix/iterate/ParallelIteratorFactory.java   |    0
 .../iterate/ParallelIteratorRegionSplitter.java    |    0
 .../apache/phoenix/iterate/ParallelIterators.java  |    0
 .../phoenix/iterate/ParallelScanGrouper.java       |    0
 .../phoenix/iterate/ParallelScansCollector.java    |    0
 .../phoenix/iterate/PeekingResultIterator.java     |    0
 .../org/apache/phoenix/iterate/PhoenixQueues.java  |    0
 .../org/apache/phoenix/iterate/ResultIterator.java |    0
 .../apache/phoenix/iterate/ResultIterators.java    |    0
 .../phoenix/iterate/RoundRobinResultIterator.java  |  354 ++
 .../RowKeyOrderedAggregateResultIterator.java      |  200 +
 .../phoenix/iterate/ScanningResultIterator.java    |  236 +
 .../phoenix/iterate/ScansWithRegionLocations.java  |    0
 .../phoenix/iterate/SequenceResultIterator.java    |    0
 .../apache/phoenix/iterate/SerialIterators.java    |  231 +
 .../org/apache/phoenix/iterate/SizeAwareQueue.java |    0
 .../org/apache/phoenix/iterate/SizeBoundQueue.java |    0
 .../iterate/SpoolTooBigToDiskException.java        |    0
 .../phoenix/iterate/SpoolingResultIterator.java    |  381 ++
 .../phoenix/iterate/TableResultIterator.java       |  344 ++
 .../iterate/TableResultIteratorFactory.java        |    0
 .../phoenix/iterate/TableSamplerPredicate.java     |    0
 .../UngroupedAggregatingResultIterator.java        |    0
 .../phoenix/iterate/UnionResultIterators.java      |  166 +
 .../phoenix/jdbc/AbstractRPCConnectionInfo.java    |    0
 .../org/apache/phoenix/jdbc/ClusterRoleRecord.java |    0
 .../jdbc/ClusterRoleRecordGeneratorTool.java       |    0
 .../org/apache/phoenix/jdbc/ConnectionInfo.java    |    0
 .../apache/phoenix/jdbc/DelegateConnection.java    |    0
 .../phoenix/jdbc/DelegatePreparedStatement.java    |    0
 .../org/apache/phoenix/jdbc/DelegateResultSet.java |    0
 .../org/apache/phoenix/jdbc/DelegateStatement.java |    0
 .../phoenix/jdbc/FailoverPhoenixConnection.java    |    0
 .../org/apache/phoenix/jdbc/FailoverPolicy.java    |    0
 .../apache/phoenix/jdbc/HighAvailabilityGroup.java |    0
 .../phoenix/jdbc/HighAvailabilityPolicy.java       |    0
 .../phoenix/jdbc/LoggingPhoenixConnection.java     |    0
 .../jdbc/LoggingPhoenixPreparedStatement.java      |    0
 .../phoenix/jdbc/LoggingPhoenixResultSet.java      |    0
 .../phoenix/jdbc/LoggingPhoenixStatement.java      |    0
 .../apache/phoenix/jdbc/MasterConnectionInfo.java  |    0
 .../phoenix/jdbc/ParallelPhoenixConnection.java    |    0
 .../phoenix/jdbc/ParallelPhoenixContext.java       |    0
 .../phoenix/jdbc/ParallelPhoenixMetrics.java       |    0
 .../ParallelPhoenixNullComparingResultSet.java     |  333 +
 .../jdbc/ParallelPhoenixPreparedStatement.java     |    0
 .../phoenix/jdbc/ParallelPhoenixResultSet.java     |    0
 .../jdbc/ParallelPhoenixResultSetFactory.java      |    0
 .../phoenix/jdbc/ParallelPhoenixStatement.java     |    0
 .../apache/phoenix/jdbc/ParallelPhoenixUtil.java   |    0
 .../org/apache/phoenix/jdbc/PhoenixConnection.java |    0
 .../phoenix/jdbc/PhoenixDatabaseMetaData.java      | 1951 ++++++
 .../org/apache/phoenix/jdbc/PhoenixDriver.java     |    0
 .../apache/phoenix/jdbc/PhoenixEmbeddedDriver.java |  198 +
 .../apache/phoenix/jdbc/PhoenixHAAdminTool.java    |    0
 .../jdbc/PhoenixHAExecutorServiceProvider.java     |    0
 .../apache/phoenix/jdbc/PhoenixHAGroupMetrics.java |    0
 .../apache/phoenix/jdbc/PhoenixMetricsHolder.java  |    0
 .../org/apache/phoenix/jdbc/PhoenixMetricsLog.java |    0
 .../phoenix/jdbc/PhoenixMonitoredConnection.java   |    0
 .../jdbc/PhoenixMonitoredPreparedStatement.java    |    0
 .../phoenix/jdbc/PhoenixMonitoredResultSet.java    |    0
 .../phoenix/jdbc/PhoenixMonitoredStatement.java    |    0
 .../phoenix/jdbc/PhoenixParameterMetaData.java     |    0
 .../phoenix/jdbc/PhoenixPreparedStatement.java     |    0
 .../org/apache/phoenix/jdbc/PhoenixResultSet.java  | 1649 +++++
 .../phoenix/jdbc/PhoenixResultSetMetaData.java     |    0
 .../org/apache/phoenix/jdbc/PhoenixStatement.java  | 2650 ++++++++
 .../phoenix/jdbc/PhoenixStatementFactory.java      |    0
 .../org/apache/phoenix/jdbc/RPCConnectionInfo.java |    0
 .../org/apache/phoenix/jdbc/ZKConnectionInfo.java  |    0
 .../phoenix/job/AbstractRoundRobinQueue.java       |    0
 .../java/org/apache/phoenix/job/JobManager.java    |    0
 .../org/apache/phoenix/join/HashCacheClient.java   |  228 +
 .../org/apache/phoenix/join/HashCacheFactory.java  |  174 +
 .../java/org/apache/phoenix/join/HashJoinInfo.java |    0
 .../join/MaxServerCacheSizeExceededException.java  |    0
 .../org/apache/phoenix/log/ActivityLogInfo.java    |    0
 .../org/apache/phoenix/log/AuditQueryLogger.java   |    0
 .../apache/phoenix/log/BaseConnectionLimiter.java  |    0
 .../phoenix/log/ConnectionActivityLogger.java      |    0
 .../org/apache/phoenix/log/ConnectionLimiter.java  |    0
 .../phoenix/log/DefaultConnectionLimiter.java      |    0
 .../main/java/org/apache/phoenix/log/LogLevel.java |    0
 .../java/org/apache/phoenix/log/LogWriter.java     |    0
 .../phoenix/log/LoggingConnectionLimiter.java      |    0
 .../phoenix/log/QueryLogDetailsWorkHandler.java    |    0
 .../java/org/apache/phoenix/log/QueryLogInfo.java  |    0
 .../java/org/apache/phoenix/log/QueryLogger.java   |    0
 .../log/QueryLoggerDefaultExceptionHandler.java    |    0
 .../apache/phoenix/log/QueryLoggerDisruptor.java   |    0
 .../org/apache/phoenix/log/QueryLoggerUtil.java    |    0
 .../java/org/apache/phoenix/log/QueryStatus.java   |    0
 .../org/apache/phoenix/log/RingBufferEvent.java    |    0
 .../phoenix/log/RingBufferEventTranslator.java     |    0
 .../org/apache/phoenix/log/TableLogWriter.java     |    0
 .../phoenix/mapreduce/util/ConnectionUtil.java     |  141 +
 .../util/PhoenixConfigurationUtilHelper.java       |  148 +
 .../apache/phoenix/memory/ChildMemoryManager.java  |    0
 .../phoenix/memory/DelegatingMemoryManager.java    |    0
 .../apache/phoenix/memory/GlobalMemoryManager.java |    0
 .../memory/InsufficientMemoryException.java        |    0
 .../org/apache/phoenix/memory/MemoryManager.java   |    0
 .../org/apache/phoenix/metrics/MetricInfo.java     |    0
 .../java/org/apache/phoenix/metrics/Metrics.java   |    0
 .../apache/phoenix/monitoring/AtomicMetric.java    |    0
 .../phoenix/monitoring/CombinableMetric.java       |    0
 .../phoenix/monitoring/CombinableMetricImpl.java   |    0
 .../monitoring/ConnectionQueryServicesMetric.java  |    0
 .../ConnectionQueryServicesMetricImpl.java         |    0
 .../phoenix/monitoring/GlobalClientMetrics.java    |    0
 .../apache/phoenix/monitoring/GlobalMetric.java    |    0
 .../phoenix/monitoring/GlobalMetricImpl.java       |    0
 .../monitoring/GlobalMetricRegistriesAdapter.java  |    0
 .../phoenix/monitoring/HistogramDistribution.java  |    0
 .../monitoring/HistogramDistributionImpl.java      |    0
 .../phoenix/monitoring/JmxMetricProvider.java      |    0
 .../phoenix/monitoring/LatencyHistogram.java       |   46 +
 .../phoenix/monitoring/MemoryMetricsHolder.java    |    0
 .../java/org/apache/phoenix/monitoring/Metric.java |    0
 .../monitoring/MetricPublisherSupplierFactory.java |    0
 .../phoenix/monitoring/MetricServiceResolver.java  |    0
 .../org/apache/phoenix/monitoring/MetricType.java  |    0
 .../org/apache/phoenix/monitoring/MetricUtil.java  |    0
 .../apache/phoenix/monitoring/MetricsRegistry.java |    0
 .../phoenix/monitoring/MetricsStopWatch.java       |    0
 .../phoenix/monitoring/MutationMetricQueue.java    |    0
 .../phoenix/monitoring/NoOpGlobalMetricImpl.java   |    0
 .../monitoring/NoOpTableMetricsManager.java        |    0
 .../apache/phoenix/monitoring/NonAtomicMetric.java |    0
 .../phoenix/monitoring/OverAllQueryMetrics.java    |    0
 .../phoenix/monitoring/PhoenixTableMetric.java     |    0
 .../phoenix/monitoring/PhoenixTableMetricImpl.java |    0
 .../apache/phoenix/monitoring/RangeHistogram.java  |    0
 .../apache/phoenix/monitoring/ReadMetricQueue.java |    0
 .../phoenix/monitoring/ScanMetricsHolder.java      |    0
 .../apache/phoenix/monitoring/SizeHistogram.java   |   47 +
 .../phoenix/monitoring/SpoolingMetricsHolder.java  |    0
 .../phoenix/monitoring/TableClientMetrics.java     |    0
 .../apache/phoenix/monitoring/TableHistograms.java |    0
 .../phoenix/monitoring/TableMetricsManager.java    |    0
 .../monitoring/TaskExecutionMetricsHolder.java     |    0
 .../ConnectionQueryServicesHistogram.java          |   43 +
 .../ConnectionQueryServicesMetrics.java            |    0
 .../ConnectionQueryServicesMetricsHistograms.java  |    0
 .../ConnectionQueryServicesMetricsManager.java     |    0
 .../NoOpConnectionQueryServicesMetricsManager.java |    0
 .../java/org/apache/phoenix/optimize/Cost.java     |    0
 .../optimize/GenSubqueryParamValuesRewriter.java   |    0
 .../apache/phoenix/optimize/QueryOptimizer.java    |    0
 .../apache/phoenix/parse/AddColumnStatement.java   |    0
 .../org/apache/phoenix/parse/AddJarsStatement.java |    0
 .../org/apache/phoenix/parse/AddParseNode.java     |    0
 .../phoenix/parse/AggregateFunctionParseNode.java  |    0
 .../AggregateFunctionWithinGroupParseNode.java     |    0
 .../java/org/apache/phoenix/parse/AliasedNode.java |    0
 .../apache/phoenix/parse/AlterIndexStatement.java  |    0
 .../phoenix/parse/AlterSessionStatement.java       |    0
 .../apache/phoenix/parse/AlterTableStatement.java  |    0
 .../phoenix/parse/AndBooleanParseNodeVisitor.java  |    0
 .../org/apache/phoenix/parse/AndParseNode.java     |    0
 .../parse/AndRewriterBooleanParseNodeVisitor.java  |    0
 .../apache/phoenix/parse/ArithmeticParseNode.java  |    0
 .../phoenix/parse/ArrayAllAnyComparisonNode.java   |    0
 .../phoenix/parse/ArrayAllComparisonNode.java      |    0
 .../phoenix/parse/ArrayAnyComparisonNode.java      |    0
 .../apache/phoenix/parse/ArrayConstructorNode.java |    0
 .../org/apache/phoenix/parse/ArrayElemRefNode.java |    0
 .../phoenix/parse/ArrayModifierParseNode.java      |    0
 .../phoenix/parse/AvgAggregateParseNode.java       |    0
 .../apache/phoenix/parse/BaseParseNodeVisitor.java |    0
 .../org/apache/phoenix/parse/BetweenParseNode.java |    0
 .../org/apache/phoenix/parse/BinaryParseNode.java  |    0
 .../org/apache/phoenix/parse/BindParseNode.java    |    0
 .../org/apache/phoenix/parse/BindTableNode.java    |    0
 .../apache/phoenix/parse/BindableStatement.java    |    0
 .../phoenix/parse/BooleanParseNodeVisitor.java     |    0
 .../org/apache/phoenix/parse/CaseParseNode.java    |    0
 .../org/apache/phoenix/parse/CastParseNode.java    |    0
 .../org/apache/phoenix/parse/CeilParseNode.java    |    0
 .../apache/phoenix/parse/ChangePermsStatement.java |    0
 .../org/apache/phoenix/parse/CloseStatement.java   |    0
 .../java/org/apache/phoenix/parse/ColumnDef.java   |    0
 .../phoenix/parse/ColumnDefInPkConstraint.java     |    0
 .../org/apache/phoenix/parse/ColumnFamilyDef.java  |    0
 .../java/org/apache/phoenix/parse/ColumnName.java  |    0
 .../org/apache/phoenix/parse/ColumnParseNode.java  |    0
 .../apache/phoenix/parse/ComparisonParseNode.java  |    0
 .../apache/phoenix/parse/CompoundParseNode.java    |    0
 .../apache/phoenix/parse/ConcreteTableNode.java    |    0
 .../phoenix/parse/CreateFunctionStatement.java     |    0
 .../apache/phoenix/parse/CreateIndexStatement.java |    0
 .../phoenix/parse/CreateSchemaStatement.java       |    0
 .../phoenix/parse/CreateSequenceStatement.java     |    0
 .../apache/phoenix/parse/CreateTableStatement.java |    0
 .../apache/phoenix/parse/CurrentDateParseNode.java |    0
 .../apache/phoenix/parse/CurrentTimeParseNode.java |    0
 .../java/org/apache/phoenix/parse/CursorName.java  |    0
 .../org/apache/phoenix/parse/DMLStatement.java     |    0
 .../phoenix/parse/DeclareCursorStatement.java      |    0
 .../parse/DelegateConstantToCountParseNode.java    |    0
 .../apache/phoenix/parse/DeleteJarStatement.java   |    0
 .../org/apache/phoenix/parse/DeleteStatement.java  |    0
 .../org/apache/phoenix/parse/DerivedTableNode.java |    0
 ...DistinctCountHyperLogLogAggregateParseNode.java |    0
 .../phoenix/parse/DistinctCountParseNode.java      |    0
 .../org/apache/phoenix/parse/DivideParseNode.java  |    0
 .../apache/phoenix/parse/DropColumnStatement.java  |    0
 .../phoenix/parse/DropFunctionStatement.java       |    0
 .../apache/phoenix/parse/DropIndexStatement.java   |    0
 .../apache/phoenix/parse/DropSchemaStatement.java  |    0
 .../phoenix/parse/DropSequenceStatement.java       |    0
 .../apache/phoenix/parse/DropTableStatement.java   |    0
 .../org/apache/phoenix/parse/EqualParseNode.java   |    0
 .../phoenix/parse/ExecuteUpgradeStatement.java     |    0
 .../org/apache/phoenix/parse/ExistsParseNode.java  |    0
 .../org/apache/phoenix/parse/ExplainStatement.java |    0
 .../java/org/apache/phoenix/parse/ExplainType.java |    0
 .../phoenix/parse/FamilyWildcardParseNode.java     |    0
 .../org/apache/phoenix/parse/FetchStatement.java   |    0
 .../apache/phoenix/parse/FilterableStatement.java  |    0
 .../parse/FirstValueAggregateParseNode.java        |    0
 .../parse/FirstValuesAggregateParseNode.java       |    0
 .../org/apache/phoenix/parse/FloorParseNode.java   |    0
 .../apache/phoenix/parse/FunctionParseNode.java    |    0
 .../phoenix/parse/GreaterThanOrEqualParseNode.java |    0
 .../apache/phoenix/parse/GreaterThanParseNode.java |    0
 .../java/org/apache/phoenix/parse/HintNode.java    |    0
 .../org/apache/phoenix/parse/InListParseNode.java  |    0
 .../java/org/apache/phoenix/parse/InParseNode.java |    0
 .../parse/IndexExpressionParseNodeRewriter.java    |    0
 .../apache/phoenix/parse/IndexKeyConstraint.java   |    0
 .../org/apache/phoenix/parse/IsNullParseNode.java  |    0
 .../org/apache/phoenix/parse/JoinTableNode.java    |    0
 .../phoenix/parse/LastValueAggregateParseNode.java |    0
 .../parse/LastValuesAggregateParseNode.java        |    0
 .../phoenix/parse/LessThanOrEqualParseNode.java    |    0
 .../apache/phoenix/parse/LessThanParseNode.java    |    0
 .../org/apache/phoenix/parse/LikeParseNode.java    |    0
 .../java/org/apache/phoenix/parse/LimitNode.java   |    0
 .../apache/phoenix/parse/ListJarsStatement.java    |    0
 .../org/apache/phoenix/parse/LiteralParseNode.java |    0
 .../phoenix/parse/MaxAggregateParseNode.java       |    0
 .../phoenix/parse/MinAggregateParseNode.java       |    0
 .../org/apache/phoenix/parse/ModulusParseNode.java |    0
 .../apache/phoenix/parse/MultiplyParseNode.java    |    0
 .../org/apache/phoenix/parse/MutableStatement.java |    0
 .../java/org/apache/phoenix/parse/NamedNode.java   |    0
 .../org/apache/phoenix/parse/NamedParseNode.java   |    0
 .../org/apache/phoenix/parse/NamedTableNode.java   |    0
 .../apache/phoenix/parse/NotEqualParseNode.java    |    0
 .../org/apache/phoenix/parse/NotParseNode.java     |    0
 .../phoenix/parse/NthValueAggregateParseNode.java  |    0
 .../java/org/apache/phoenix/parse/OffsetNode.java  |    0
 .../org/apache/phoenix/parse/OpenStatement.java    |    0
 .../java/org/apache/phoenix/parse/OrParseNode.java |    0
 .../java/org/apache/phoenix/parse/OrderByNode.java |    0
 .../java/org/apache/phoenix/parse/PFunction.java   |    0
 .../java/org/apache/phoenix/parse/PSchema.java     |    0
 .../org/apache/phoenix/parse/ParseContext.java     |    0
 .../org/apache/phoenix/parse/ParseException.java   |    0
 .../java/org/apache/phoenix/parse/ParseNode.java   |    0
 .../org/apache/phoenix/parse/ParseNodeFactory.java |    0
 .../apache/phoenix/parse/ParseNodeRewriter.java    |    0
 .../org/apache/phoenix/parse/ParseNodeVisitor.java |    0
 .../parse/PhoenixRowTimestampParseNode.java        |   98 +
 .../apache/phoenix/parse/PrimaryKeyConstraint.java |    0
 .../org/apache/phoenix/parse/PropertyName.java     |    0
 .../phoenix/parse/RegexpReplaceParseNode.java      |    0
 .../apache/phoenix/parse/RegexpSplitParseNode.java |    0
 .../phoenix/parse/RegexpSubstrParseNode.java       |    0
 .../org/apache/phoenix/parse/RoundParseNode.java   |    0
 .../parse/RowValueConstructorParseNode.java        |    0
 .../java/org/apache/phoenix/parse/SQLParser.java   |    0
 .../org/apache/phoenix/parse/SelectStatement.java  |    0
 .../phoenix/parse/SelectStatementRewriter.java     |    0
 .../phoenix/parse/SequenceValueParseNode.java      |    0
 .../org/apache/phoenix/parse/ShowCreateTable.java  |    0
 .../phoenix/parse/ShowCreateTableStatement.java    |    0
 .../apache/phoenix/parse/ShowSchemasStatement.java |    0
 .../org/apache/phoenix/parse/ShowStatement.java    |    0
 .../apache/phoenix/parse/ShowTablesStatement.java  |    0
 .../apache/phoenix/parse/SingleTableStatement.java |    0
 .../StatelessTraverseAllParseNodeVisitor.java      |    0
 .../phoenix/parse/StringConcatParseNode.java       |    0
 .../apache/phoenix/parse/SubqueryParseNode.java    |    0
 .../apache/phoenix/parse/SubtractParseNode.java    |    0
 .../phoenix/parse/SumAggregateParseNode.java       |    0
 .../java/org/apache/phoenix/parse/TableName.java   |    0
 .../java/org/apache/phoenix/parse/TableNode.java   |    0
 .../org/apache/phoenix/parse/TableNodeVisitor.java |    0
 .../phoenix/parse/TableWildcardParseNode.java      |    0
 .../apache/phoenix/parse/TerminalParseNode.java    |    0
 .../org/apache/phoenix/parse/ToCharParseNode.java  |    0
 .../org/apache/phoenix/parse/ToDateParseNode.java  |    0
 .../apache/phoenix/parse/ToNumberParseNode.java    |    0
 .../org/apache/phoenix/parse/ToTimeParseNode.java  |    0
 .../apache/phoenix/parse/ToTimestampParseNode.java |    0
 .../org/apache/phoenix/parse/TraceStatement.java   |    0
 .../phoenix/parse/TraverseAllParseNodeVisitor.java |    0
 .../phoenix/parse/TraverseNoParseNodeVisitor.java  |    0
 .../org/apache/phoenix/parse/UDFParseNode.java     |    0
 .../org/apache/phoenix/parse/UnaryParseNode.java   |    0
 .../parse/UnsupportedAllParseNodeVisitor.java      |    0
 .../phoenix/parse/UpdateStatisticsStatement.java   |    0
 .../org/apache/phoenix/parse/UpsertStatement.java  |    0
 .../apache/phoenix/parse/UseSchemaStatement.java   |    0
 .../apache/phoenix/parse/WildcardParseNode.java    |    0
 .../org/apache/phoenix/protobuf/ProtobufUtil.java  |    0
 .../phoenix/query/AdminUtilWithFallback.java       |    0
 .../phoenix/query/BaseQueryServicesImpl.java       |    0
 .../query/ChildLinkMetaDataServiceCallBack.java    |    0
 .../apache/phoenix/query/ChildQueryServices.java   |    0
 .../apache/phoenix/query/ConfigurationFactory.java |    0
 .../phoenix/query/ConnectionQueryServices.java     |  237 +
 .../phoenix/query/ConnectionQueryServicesImpl.java | 6418 +++++++++++++++++++
 .../query/ConnectionlessQueryServicesImpl.java     |  834 +++
 .../query/DefaultGuidePostsCacheFactory.java       |    0
 .../query/DelegateConnectionQueryServices.java     |  442 ++
 .../phoenix/query/DelegateQueryServices.java       |    0
 .../org/apache/phoenix/query/EmptyStatsLoader.java |    0
 .../org/apache/phoenix/query/GuidePostsCache.java  |    0
 .../phoenix/query/GuidePostsCacheFactory.java      |    0
 .../apache/phoenix/query/GuidePostsCacheImpl.java  |    0
 .../phoenix/query/GuidePostsCacheProvider.java     |    0
 .../phoenix/query/GuidePostsCacheWrapper.java      |    0
 .../apache/phoenix/query/HBaseFactoryProvider.java |    0
 .../apache/phoenix/query/HConnectionFactory.java   |    0
 .../org/apache/phoenix/query/HTableFactory.java    |    0
 .../phoenix/query/ITGuidePostsCacheFactory.java    |    0
 .../java/org/apache/phoenix/query/KeyRange.java    |    0
 .../org/apache/phoenix/query/MetaDataMutated.java  |    0
 .../phoenix/query/PhoenixStatsCacheLoader.java     |    0
 .../apache/phoenix/query/PhoenixStatsLoader.java   |    0
 .../phoenix/query/PropertyNotAllowedException.java |    0
 .../org/apache/phoenix/query/PropertyPolicy.java   |    0
 .../phoenix/query/PropertyPolicyProvider.java      |    0
 .../org/apache/phoenix/query/QueryConstants.java   |  617 ++
 .../org/apache/phoenix/query/QueryServices.java    |  481 ++
 .../apache/phoenix/query/QueryServicesImpl.java    |    0
 .../apache/phoenix/query/QueryServicesOptions.java |  975 +++
 .../org/apache/phoenix/query/StatsLoaderImpl.java  |    0
 .../phoenix/schema/AmbiguousColumnException.java   |    0
 .../phoenix/schema/AmbiguousTableException.java    |    0
 .../schema/ArgumentTypeMismatchException.java      |    0
 .../schema/ColumnAlreadyExistsException.java       |    0
 .../schema/ColumnFamilyNotFoundException.java      |    0
 .../apache/phoenix/schema/ColumnMetaDataOps.java   |    0
 .../org/apache/phoenix/schema/ColumnModifier.java  |    0
 .../phoenix/schema/ColumnNotFoundException.java    |    0
 .../java/org/apache/phoenix/schema/ColumnRef.java  |    0
 .../apache/phoenix/schema/ColumnValueDecoder.java  |    0
 .../apache/phoenix/schema/ColumnValueEncoder.java  |    0
 .../schema/ConcurrentTableMutationException.java   |    0
 .../apache/phoenix/schema/ConnectionProperty.java  |    0
 .../schema/ConstraintViolationException.java       |    0
 .../org/apache/phoenix/schema/DelegateColumn.java  |    0
 .../org/apache/phoenix/schema/DelegateDatum.java   |    0
 .../phoenix/schema/DelegateSQLException.java       |    0
 .../org/apache/phoenix/schema/DelegateTable.java   |    0
 .../schema/EmptySequenceCacheException.java        |    0
 .../schema/ExecuteQueryNotApplicableException.java |    0
 .../ExecuteUpdateNotApplicableException.java       |    0
 .../schema/FunctionAlreadyExistsException.java     |    0
 .../phoenix/schema/FunctionNotFoundException.java  |    0
 .../phoenix/schema/IllegalDataException.java       |    0
 .../phoenix/schema/IndexNotFoundException.java     |    0
 .../schema/IndexUncoveredDataColumnRef.java        |    0
 .../org/apache/phoenix/schema/KeyValueSchema.java  |    0
 .../MaxMutationSizeBytesExceededException.java     |    0
 .../schema/MaxMutationSizeExceededException.java   |    0
 .../MaxPhoenixColumnSizeExceededException.java     |    0
 .../org/apache/phoenix/schema/MetaDataClient.java  | 6028 ++++++++++++++++++
 .../schema/MetaDataEntityNotFoundException.java    |    0
 .../NewerFunctionAlreadyExistsException.java       |    0
 .../schema/NewerSchemaAlreadyExistsException.java  |    0
 .../schema/NewerTableAlreadyExistsException.java   |    0
 .../java/org/apache/phoenix/schema/PColumn.java    |    0
 .../org/apache/phoenix/schema/PColumnFamily.java   |    0
 .../apache/phoenix/schema/PColumnFamilyImpl.java   |    0
 .../org/apache/phoenix/schema/PColumnImpl.java     |    0
 .../java/org/apache/phoenix/schema/PDatum.java     |    0
 .../org/apache/phoenix/schema/PIndexState.java     |    0
 .../java/org/apache/phoenix/schema/PMetaData.java  |    0
 .../org/apache/phoenix/schema/PMetaDataCache.java  |    0
 .../org/apache/phoenix/schema/PMetaDataEntity.java |    0
 .../org/apache/phoenix/schema/PMetaDataImpl.java   |    0
 .../main/java/org/apache/phoenix/schema/PName.java |    0
 .../org/apache/phoenix/schema/PNameFactory.java    |    0
 .../java/org/apache/phoenix/schema/PNameImpl.java  |    0
 .../main/java/org/apache/phoenix/schema/PRow.java  |   87 +
 .../phoenix/schema/PSynchronizedMetaData.java      |    0
 .../java/org/apache/phoenix/schema/PTable.java     |    0
 .../java/org/apache/phoenix/schema/PTableImpl.java | 2467 ++++++++
 .../java/org/apache/phoenix/schema/PTableKey.java  |    0
 .../java/org/apache/phoenix/schema/PTableRef.java  |    0
 .../apache/phoenix/schema/PTableRefFactory.java    |    0
 .../org/apache/phoenix/schema/PTableRefImpl.java   |    0
 .../java/org/apache/phoenix/schema/PTableType.java |    0
 .../org/apache/phoenix/schema/ProjectedColumn.java |    0
 .../phoenix/schema/ReadOnlyTableException.java     |    0
 .../org/apache/phoenix/schema/RowKeySchema.java    |    0
 .../apache/phoenix/schema/RowKeyValueAccessor.java |    0
 ...lueConstructorOffsetInternalErrorException.java |    0
 ...onstructorOffsetNotAllowedInQueryException.java |    0
 ...alueConstructorOffsetNotCoercibleException.java |    0
 .../org/apache/phoenix/schema/SaltingUtil.java     |    0
 .../schema/SchemaAlreadyExistsException.java       |    0
 .../phoenix/schema/SchemaNotFoundException.java    |    0
 .../java/org/apache/phoenix/schema/Sequence.java   |  639 ++
 .../apache/phoenix/schema/SequenceAllocation.java  |    0
 .../schema/SequenceAlreadyExistsException.java     |    0
 .../org/apache/phoenix/schema/SequenceInfo.java    |    0
 .../org/apache/phoenix/schema/SequenceKey.java     |    0
 .../phoenix/schema/SequenceNotFoundException.java  |    0
 .../apache/phoenix/schema/SerializedPTableRef.java |    0
 .../phoenix/schema/SerializedPTableRefFactory.java |    0
 .../java/org/apache/phoenix/schema/SortOrder.java  |    0
 .../schema/StaleRegionBoundaryCacheException.java  |    0
 .../schema/TableAlreadyExistsException.java        |    0
 .../phoenix/schema/TableNotFoundException.java     |    0
 .../org/apache/phoenix/schema/TableProperty.java   |    0
 .../java/org/apache/phoenix/schema/TableRef.java   |    0
 .../phoenix/schema/TablesNotInSyncException.java   |    0
 .../phoenix/schema/TypeMismatchException.java      |    0
 .../UpsertColumnsValuesMismatchException.java      |    0
 .../org/apache/phoenix/schema/ValueBitSet.java     |    0
 .../apache/phoenix/schema/ValueRangeExcpetion.java |    0
 .../org/apache/phoenix/schema/ValueSchema.java     |    0
 .../export/DefaultSchemaRegistryRepository.java    |    0
 .../phoenix/schema/export/DefaultSchemaWriter.java |    0
 .../phoenix/schema/export/SchemaImporter.java      |    0
 .../schema/export/SchemaRegistryRepository.java    |    0
 .../export/SchemaRegistryRepositoryFactory.java    |    0
 .../apache/phoenix/schema/export/SchemaWriter.java |    0
 .../phoenix/schema/export/SchemaWriterFactory.java |    0
 .../schema/metrics/MetricsMetadataSource.java      |    0
 .../metrics/MetricsMetadataSourceFactory.java      |    0
 .../schema/metrics/MetricsMetadataSourceImpl.java  |    0
 .../phoenix/schema/stats/GuidePostsInfo.java       |    0
 .../schema/stats/GuidePostsInfoBuilder.java        |    0
 .../apache/phoenix/schema/stats/GuidePostsKey.java |    0
 .../stats/StatisticsCollectionRunTracker.java      |    0
 .../schema/stats/StatisticsCollectionScope.java    |    0
 .../phoenix/schema/stats/StatisticsUtil.java       |  253 +
 .../StatsCollectionDisabledOnServerException.java  |    0
 .../phoenix/schema/task/SystemTaskParams.java      |    0
 .../java/org/apache/phoenix/schema/task/Task.java  |  423 ++
 .../schema/tool/SchemaExtractionProcessor.java     |    0
 .../phoenix/schema/tool/SchemaProcessor.java       |    0
 .../apache/phoenix/schema/tool/SchemaSQLUtil.java  |    0
 .../schema/tool/SchemaSynthesisProcessor.java      |    0
 .../org/apache/phoenix/schema/tool/SchemaTool.java |    0
 .../schema/transform/SystemTransformRecord.java    |    0
 .../phoenix/schema/transform/TransformClient.java  |  432 ++
 .../schema/transform/TransformMaintainer.java      |    0
 .../org/apache/phoenix/schema/tuple/BaseTuple.java |    0
 .../apache/phoenix/schema/tuple/DelegateTuple.java |    0
 .../tuple/EncodedColumnQualiferCellsList.java      |    0
 .../phoenix/schema/tuple/MultiKeyValueTuple.java   |    0
 .../tuple/PositionBasedMultiKeyValueTuple.java     |    0
 .../schema/tuple/PositionBasedResultTuple.java     |    0
 .../apache/phoenix/schema/tuple/ResultTuple.java   |    0
 .../phoenix/schema/tuple/SingleKeyValueTuple.java  |    0
 .../org/apache/phoenix/schema/tuple/Tuple.java     |    0
 .../phoenix/schema/tuple/ValueGetterTuple.java     |    0
 .../phoenix/schema/types/PArrayDataType.java       |    0
 .../schema/types/PArrayDataTypeDecoder.java        |    0
 .../schema/types/PArrayDataTypeEncoder.java        |    0
 .../org/apache/phoenix/schema/types/PBinary.java   |    0
 .../apache/phoenix/schema/types/PBinaryArray.java  |    0
 .../apache/phoenix/schema/types/PBinaryBase.java   |    0
 .../org/apache/phoenix/schema/types/PBoolean.java  |    0
 .../apache/phoenix/schema/types/PBooleanArray.java |    0
 .../org/apache/phoenix/schema/types/PChar.java     |    0
 .../apache/phoenix/schema/types/PCharArray.java    |    0
 .../org/apache/phoenix/schema/types/PDataType.java |    0
 .../phoenix/schema/types/PDataTypeFactory.java     |    0
 .../org/apache/phoenix/schema/types/PDate.java     |    0
 .../apache/phoenix/schema/types/PDateArray.java    |    0
 .../org/apache/phoenix/schema/types/PDecimal.java  |    0
 .../apache/phoenix/schema/types/PDecimalArray.java |    0
 .../org/apache/phoenix/schema/types/PDouble.java   |    0
 .../apache/phoenix/schema/types/PDoubleArray.java  |    0
 .../org/apache/phoenix/schema/types/PFloat.java    |    0
 .../apache/phoenix/schema/types/PFloatArray.java   |    0
 .../org/apache/phoenix/schema/types/PInteger.java  |    0
 .../apache/phoenix/schema/types/PIntegerArray.java |    0
 .../org/apache/phoenix/schema/types/PLong.java     |    0
 .../apache/phoenix/schema/types/PLongArray.java    |    0
 .../apache/phoenix/schema/types/PNumericType.java  |    0
 .../apache/phoenix/schema/types/PRealNumber.java   |    0
 .../org/apache/phoenix/schema/types/PSmallint.java |    0
 .../phoenix/schema/types/PSmallintArray.java       |    0
 .../org/apache/phoenix/schema/types/PTime.java     |    0
 .../apache/phoenix/schema/types/PTimeArray.java    |    0
 .../apache/phoenix/schema/types/PTimestamp.java    |    0
 .../phoenix/schema/types/PTimestampArray.java      |    0
 .../org/apache/phoenix/schema/types/PTinyint.java  |    0
 .../apache/phoenix/schema/types/PTinyintArray.java |    0
 .../apache/phoenix/schema/types/PUnsignedDate.java |    0
 .../phoenix/schema/types/PUnsignedDateArray.java   |    0
 .../phoenix/schema/types/PUnsignedDouble.java      |    0
 .../phoenix/schema/types/PUnsignedDoubleArray.java |    0
 .../phoenix/schema/types/PUnsignedFloat.java       |    0
 .../phoenix/schema/types/PUnsignedFloatArray.java  |    0
 .../apache/phoenix/schema/types/PUnsignedInt.java  |    0
 .../phoenix/schema/types/PUnsignedIntArray.java    |    0
 .../apache/phoenix/schema/types/PUnsignedLong.java |    0
 .../phoenix/schema/types/PUnsignedLongArray.java   |    0
 .../phoenix/schema/types/PUnsignedSmallint.java    |    0
 .../schema/types/PUnsignedSmallintArray.java       |    0
 .../apache/phoenix/schema/types/PUnsignedTime.java |    0
 .../phoenix/schema/types/PUnsignedTimeArray.java   |    0
 .../phoenix/schema/types/PUnsignedTimestamp.java   |    0
 .../schema/types/PUnsignedTimestampArray.java      |    0
 .../phoenix/schema/types/PUnsignedTinyint.java     |    0
 .../schema/types/PUnsignedTinyintArray.java        |    0
 .../apache/phoenix/schema/types/PVarbinary.java    |    0
 .../phoenix/schema/types/PVarbinaryArray.java      |    0
 .../org/apache/phoenix/schema/types/PVarchar.java  |    0
 .../apache/phoenix/schema/types/PVarcharArray.java |    0
 .../apache/phoenix/schema/types/PWholeNumber.java  |    0
 .../apache/phoenix/schema/types/PhoenixArray.java  |    0
 .../org/apache/phoenix/trace/MetricsInfoImpl.java  |    0
 .../apache/phoenix/trace/PhoenixMetricsSink.java   |    0
 .../java/org/apache/phoenix/trace/TraceReader.java |    0
 .../apache/phoenix/trace/TraceSpanReceiver.java    |    0
 .../java/org/apache/phoenix/trace/TraceWriter.java |    0
 .../org/apache/phoenix/trace/TracingIterator.java  |    0
 .../org/apache/phoenix/trace/TracingUtils.java     |    0
 .../phoenix/trace/util/ConfigurationAdapter.java   |    0
 .../org/apache/phoenix/trace/util/NullSpan.java    |    0
 .../org/apache/phoenix/trace/util/Tracing.java     |    0
 .../NotAvailableTransactionProvider.java           |    0
 .../transaction/OmidTransactionContext.java        |    0
 .../transaction/OmidTransactionProvider.java       |  134 +
 .../phoenix/transaction/OmidTransactionTable.java  |    0
 .../transaction/PhoenixTransactionClient.java      |    0
 .../transaction/PhoenixTransactionContext.java     |    0
 .../transaction/PhoenixTransactionProvider.java    |    0
 .../phoenix/transaction/TransactionFactory.java    |   86 +
 .../org/apache/phoenix/util/Base62Encoder.java     |    0
 .../org/apache/phoenix/util/BigDecimalUtil.java    |    0
 .../main/java/org/apache/phoenix/util/BitSet.java  |    0
 .../java/org/apache/phoenix/util/ByteUtil.java     |    0
 .../org/apache/phoenix/util/CSVCommonsLoader.java  |    0
 .../java/org/apache/phoenix/util/ClientUtil.java   |  209 +
 .../java/org/apache/phoenix/util/Closeables.java   |    0
 .../java/org/apache/phoenix/util/ColumnInfo.java   |    0
 .../java/org/apache/phoenix/util/ConfigUtil.java   |    0
 .../java/org/apache/phoenix/util/CostUtil.java     |    0
 .../java/org/apache/phoenix/util/CursorUtil.java   |    0
 .../java/org/apache/phoenix/util/DateUtil.java     |    0
 .../phoenix/util/DefaultEnvironmentEdge.java       |    0
 .../apache/phoenix/util/DeferredStringBuilder.java |    0
 .../apache/phoenix/util/EncodedColumnsUtil.java    |  207 +
 .../org/apache/phoenix/util/EnvironmentEdge.java   |    0
 .../phoenix/util/EnvironmentEdgeManager.java       |    0
 .../phoenix/util/EquiDepthStreamHistogram.java     |    0
 .../org/apache/phoenix/util/ExpressionUtil.java    |    0
 .../util/FirstLastNthValueDataContainer.java       |    0
 .../java/org/apache/phoenix/util/IndexUtil.java    | 1001 +++
 .../org/apache/phoenix/util/InstanceResolver.java  |    0
 .../java/org/apache/phoenix/util/JDBCUtil.java     |    0
 .../java/org/apache/phoenix/util/JacksonUtil.java  |    0
 .../main/java/org/apache/phoenix/util/LogUtil.java |    0
 .../org/apache/phoenix/util/MajorMinorVersion.java |    0
 .../apache/phoenix/util/ManualEnvironmentEdge.java |    0
 .../java/org/apache/phoenix/util/MetaDataUtil.java | 1185 ++++
 .../java/org/apache/phoenix/util/NumberUtil.java   |    0
 .../org/apache/phoenix/util/ParseNodeUtil.java     |    0
 .../phoenix/util/PhoenixContextExecutor.java       |    0
 .../apache/phoenix/util/PhoenixKeyValueUtil.java   |    0
 .../org/apache/phoenix/util/PhoenixRuntime.java    | 1713 ++++++
 .../org/apache/phoenix/util/PhoenixStopWatch.java  |    0
 .../org/apache/phoenix/util/PrefixByteCodec.java   |    0
 .../org/apache/phoenix/util/PrefixByteDecoder.java |    0
 .../org/apache/phoenix/util/PrefixByteEncoder.java |    0
 .../org/apache/phoenix/util/PropertiesUtil.java    |    0
 .../java/org/apache/phoenix/util/QueryBuilder.java |    0
 .../java/org/apache/phoenix/util/QueryUtil.java    |    0
 .../org/apache/phoenix/util/ReadOnlyProps.java     |    0
 .../java/org/apache/phoenix/util/ResultUtil.java   |    0
 .../java/org/apache/phoenix/util/SQLCloseable.java |    0
 .../org/apache/phoenix/util/SQLCloseables.java     |    0
 .../java/org/apache/phoenix/util/ScanUtil.java     | 1618 +++++
 .../java/org/apache/phoenix/util/SchemaUtil.java   |    0
 .../java/org/apache/phoenix/util/SequenceUtil.java |    0
 .../java/org/apache/phoenix/util/SizedUtil.java    |    0
 .../java/org/apache/phoenix/util/StringUtil.java   |    0
 .../apache/phoenix/util/TableViewFinderResult.java |   49 +
 .../phoenix/util/TaskMetaDataServiceCallBack.java  |    0
 .../java/org/apache/phoenix/util/TimeKeeper.java   |    0
 .../org/apache/phoenix/util/TransactionUtil.java   |  171 +
 .../phoenix/util/TrustedByteArrayOutputStream.java |    0
 .../java/org/apache/phoenix/util/TupleUtil.java    |    0
 .../java/org/apache/phoenix/util/UpgradeUtil.java  | 2923 +++++++++
 .../org/apache/phoenix/util/UpsertExecutor.java    |    0
 .../phoenix/util/ValidateLastDDLTimestampUtil.java |  209 +
 .../apache/phoenix/util/VarBinaryFormatter.java    |    0
 .../phoenix/util/ViewIndexIdRetrieveUtil.java      |    0
 .../java/org/apache/phoenix/util/ViewUtil.java     |  889 +++
 .../org/apache/phoenix/util/WALAnnotationUtil.java |   58 +
 .../apache/phoenix/util/csv/CsvUpsertExecutor.java |    0
 .../phoenix/util/csv/StringToArrayConverter.java   |    0
 .../apache/phoenix/util/i18n/LinguisticSort.java   |    0
 .../org/apache/phoenix/util/i18n/LocaleUtils.java  |    0
 .../org/apache/phoenix/util/i18n/OracleUpper.java  |    0
 .../apache/phoenix/util/i18n/OracleUpperTable.java |    0
 .../org/apache/phoenix/util/i18n/package-info.java |    0
 .../phoenix/util/json/JsonUpsertExecutor.java      |    0
 .../phoenix/util/json/ObjectToArrayConverter.java  |    0
 .../phoenix/util/regex/RegexUpsertExecutor.java    |    0
 .../src/main/java/overview.html                    |    0
 .../main/protobuf/ChildLinkMetaDataService.proto   |    0
 .../src/main/protobuf/DynamicColumnMetaData.proto  |    0
 .../src/main/protobuf/MetaDataService.proto        |    0
 .../src/main/protobuf/PFunction.proto              |    0
 .../src/main/protobuf/PGuidePosts.proto            |    0
 .../src/main/protobuf/PSchema.proto                |    0
 .../src/main/protobuf/PTable.proto                 |    0
 .../protobuf/RegionServerEndpointService.proto     |    0
 .../src/main/protobuf/ServerCacheFactory.proto     |    0
 .../src/main/protobuf/ServerCachingService.proto   |    0
 .../src/main/protobuf/TaskMetaDataService.proto    |    0
 .../resources/META-INF/services/java.sql.Driver    |    0
 ...oenix.monitoring.MetricPublisherSupplierFactory |    0
 ...org.apache.phoenix.query.GuidePostsCacheFactory |    0
 .../resources/phoenix-canary-file-sink.properties  |    0
 phoenix-core-server/pom.xml                        |  195 +
 .../hadoop/hbase/ipc/PhoenixRpcScheduler.java      |    0
 .../hbase/ipc/PhoenixRpcSchedulerFactory.java      |   90 +
 .../java/org/apache/hadoop/hbase/ipc/RpcUtil.java  |    0
 ...erRegionServerMetadataRpcControllerFactory.java |    0
 .../ipc/controller/ServerRpcControllerFactory.java |    0
 .../DataTableLocalIndexRegionScanner.java          |    0
 .../regionserver/IndexHalfStoreFileReader.java     |  174 +
 .../IndexHalfStoreFileReaderGenerator.java         |  310 +
 .../regionserver/IndexKeyValueSkipListSet.java     |    0
 .../hbase/regionserver/KeyValueSkipListSet.java    |    0
 .../hbase/regionserver/LocalIndexSplitter.java     |    0
 .../regionserver/LocalIndexStoreFileScanner.java   |    0
 .../hbase/regionserver/ScannerContextUtil.java     |    0
 .../wal/BinaryCompatibleBaseDecoder.java           |    0
 .../hbase/regionserver/wal/IndexedHLogReader.java  |    0
 .../regionserver/wal/IndexedWALEditCodec.java      |    0
 .../java/org/apache/phoenix/cache/GlobalCache.java |    0
 .../apache/phoenix/cache/aggcache/SpillFile.java   |    0
 .../phoenix/cache/aggcache/SpillManager.java       |    0
 .../apache/phoenix/cache/aggcache/SpillMap.java    |    0
 .../cache/aggcache/SpillableGroupByCache.java      |    0
 .../phoenix/coprocessor/AddColumnMutator.java      |  457 ++
 .../coprocessor/BaseMetaDataEndpointObserver.java  |    0
 .../phoenix/coprocessor/BaseRegionScanner.java     |    0
 .../coprocessor/BaseScannerRegionObserver.java     |  500 ++
 .../coprocessor/ChildLinkMetaDataEndpoint.java     |    0
 .../apache/phoenix/coprocessor/ColumnMutator.java  |   67 +
 .../phoenix/coprocessor/CompactionScanner.java     |    0
 .../DelegateRegionCoprocessorEnvironment.java      |    0
 .../coprocessor/DelegateRegionObserver.java        |    0
 .../phoenix/coprocessor/DelegateRegionScanner.java |    0
 .../phoenix/coprocessor/DropColumnMutator.java     |  306 +
 .../coprocessor/GlobalIndexRegionScanner.java      | 1518 +++++
 .../apache/phoenix/coprocessor/GroupByCache.java   |    0
 .../GroupedAggregateRegionObserver.java            |  613 ++
 .../phoenix/coprocessor/HashJoinRegionScanner.java |  414 ++
 .../coprocessor/IndexRebuildRegionScanner.java     |  388 ++
 .../coprocessor/IndexRepairRegionScanner.java      |  459 ++
 .../coprocessor/IndexToolVerificationResult.java   |    0
 .../phoenix/coprocessor/IndexerRegionScanner.java  |  457 ++
 .../phoenix/coprocessor/MetaDataEndpointImpl.java  | 4805 +++++++++++++++
 .../coprocessor/MetaDataEndpointObserver.java      |    0
 .../coprocessor/MetaDataRegionObserver.java        |  706 +++
 .../phoenix/coprocessor/OmidGCProcessor.java       |    0
 .../coprocessor/OmidTransactionalProcessor.java    |    0
 .../phoenix/coprocessor/PagingRegionScanner.java   |    0
 .../coprocessor/PhoenixAccessController.java       |    0
 .../phoenix/coprocessor/PhoenixCoprocessor.java    |    0
 .../PhoenixMetaDataCoprocessorHost.java            |    0
 .../coprocessor/PhoenixRegionServerEndpoint.java   |  113 +
 .../coprocessor/PhoenixTTLRegionObserver.java      |  341 ++
 .../coprocessor/ReplicationSinkEndpoint.java       |    0
 .../phoenix/coprocessor/ScanRegionObserver.java    |  188 +
 .../coprocessor/SequenceRegionObserver.java        |  474 ++
 .../coprocessor/ServerCachingEndpointImpl.java     |  123 +
 .../apache/phoenix/coprocessor/SuffixFilter.java   |    0
 .../coprocessor/SystemCatalogRegionObserver.java   |    0
 .../phoenix/coprocessor/TTLRegionScanner.java      |  228 +
 .../phoenix/coprocessor/TaskMetaDataEndpoint.java  |    0
 .../phoenix/coprocessor/TaskRegionObserver.java    |  289 +
 .../coprocessor/TephraTransactionalProcessor.java  |    0
 .../UncoveredGlobalIndexRegionScanner.java         |  234 +
 .../coprocessor/UncoveredIndexRegionScanner.java   |  407 ++
 .../UncoveredLocalIndexRegionScanner.java          |  132 +
 .../UngroupedAggregateRegionObserver.java          |  948 +++
 .../UngroupedAggregateRegionScanner.java           |  721 +++
 .../coprocessor/VerifyLastDDLTimestamp.java        |    0
 .../apache/phoenix/coprocessor/tasks/BaseTask.java |    0
 .../coprocessor/tasks/DropChildViewsTask.java      |  107 +
 .../coprocessor/tasks/IndexRebuildTask.java        |  191 +
 .../coprocessor/tasks/TransformMonitorTask.java    |  193 +
 .../phoenix/hbase/index/CapturingAbortable.java    |    0
 .../phoenix/hbase/index/IndexRegionObserver.java   | 1637 +++++
 .../hbase/index/IndexRegionSplitPolicy.java        |    0
 .../org/apache/phoenix/hbase/index/Indexer.java    |  755 +++
 .../apache/phoenix/hbase/index/LockManager.java    |    0
 .../hbase/index/balancer/IndexLoadBalancer.java    |    0
 .../hbase/index/builder/BaseIndexBuilder.java      |  138 +
 .../hbase/index/builder/IndexBuildManager.java     |  183 +
 .../phoenix/hbase/index/builder/IndexBuilder.java  |  153 +
 .../hbase/index/covered/CoveredColumns.java        |    0
 .../hbase/index/covered/LocalTableState.java       |    0
 .../hbase/index/covered/NonTxIndexBuilder.java     |    0
 .../hbase/index/covered/data/CachedLocalTable.java |    0
 .../hbase/index/covered/data/IndexMemStore.java    |    0
 .../hbase/index/parallel/ThreadPoolManager.java    |    0
 .../phoenix/hbase/index/wal/IndexedKeyValue.java   |    0
 .../phoenix/hbase/index/wal/KeyValueCodec.java     |    0
 .../AbstractParallelWriterIndexCommitter.java      |  241 +
 .../index/write/DelegateIndexFailurePolicy.java    |    0
 .../phoenix/hbase/index/write/IndexCommitter.java  |    0
 .../hbase/index/write/IndexFailurePolicy.java      |    0
 .../phoenix/hbase/index/write/IndexWriter.java     |    0
 .../hbase/index/write/IndexWriterUtils.java        |    0
 .../index/write/KillServerOnFailurePolicy.java     |    0
 .../write/LazyParallelWriterIndexCommitter.java    |    0
 .../index/write/LeaveIndexActiveFailurePolicy.java |    0
 .../index/write/ParallelWriterIndexCommitter.java  |    0
 .../hbase/index/write/RecoveryIndexWriter.java     |    0
 .../TrackingParallelWriterIndexCommitter.java      |  302 +
 .../write/recovery/PerRegionIndexWriteCache.java   |    0
 .../write/recovery/StoreFailuresInCachePolicy.java |    0
 .../apache/phoenix/index/GlobalIndexChecker.java   |  666 ++
 .../apache/phoenix/index/PhoenixIndexBuilder.java  |  278 +
 .../phoenix/index/PhoenixIndexFailurePolicy.java   |  392 ++
 .../phoenix/index/PhoenixIndexMetaDataBuilder.java |  107 +
 .../phoenix/index/PhoenixTransactionalIndexer.java |  241 +
 .../iterate/MapReduceParallelScanGrouper.java      |    0
 .../iterate/NonAggregateRegionScannerFactory.java  |  410 ++
 .../phoenix/iterate/RegionScannerFactory.java      |  467 ++
 .../iterate/RegionScannerResultIterator.java       |   88 +
 .../apache/phoenix/iterate/SnapshotScanner.java    |  279 +
 .../iterate/TableSnapshotResultIterator.java       |  220 +
 .../phoenix/mapreduce/AbstractBulkLoadTool.java    |    0
 .../phoenix/mapreduce/CsvBulkImportUtil.java       |    0
 .../apache/phoenix/mapreduce/CsvBulkLoadTool.java  |    0
 .../phoenix/mapreduce/CsvToKeyValueMapper.java     |    0
 .../mapreduce/FormatToBytesWritableMapper.java     |    0
 .../phoenix/mapreduce/FormatToKeyValueReducer.java |    0
 .../ImportPreUpsertKeyValueProcessor.java          |    0
 .../apache/phoenix/mapreduce/JsonBulkLoadTool.java |    0
 .../phoenix/mapreduce/JsonToKeyValueMapper.java    |    0
 .../phoenix/mapreduce/MultiHfileOutputFormat.java  |  738 +++
 .../apache/phoenix/mapreduce/OrphanViewTool.java   |    0
 .../phoenix/mapreduce/PhoenixInputFormat.java      |  293 +
 .../phoenix/mapreduce/PhoenixInputSplit.java       |    0
 .../phoenix/mapreduce/PhoenixJobCounters.java      |    0
 .../mapreduce/PhoenixMultiViewInputFormat.java     |    0
 .../mapreduce/PhoenixMultiViewInputSplit.java      |    0
 .../phoenix/mapreduce/PhoenixMultiViewReader.java  |    0
 .../phoenix/mapreduce/PhoenixOutputCommitter.java  |    0
 .../phoenix/mapreduce/PhoenixOutputFormat.java     |    0
 .../phoenix/mapreduce/PhoenixRecordReader.java     |  197 +
 .../phoenix/mapreduce/PhoenixRecordWritable.java   |    0
 .../phoenix/mapreduce/PhoenixRecordWriter.java     |    0
 .../PhoenixServerBuildIndexInputFormat.java        |  218 +
 .../mapreduce/PhoenixTTLDeleteJobMapper.java       |  241 +
 .../apache/phoenix/mapreduce/PhoenixTTLTool.java   |    0
 .../phoenix/mapreduce/PhoenixTextInputFormat.java  |    0
 .../phoenix/mapreduce/RegexBulkLoadTool.java       |    0
 .../phoenix/mapreduce/RegexToKeyValueMapper.java   |    0
 .../mapreduce/bulkload/TableRowkeyPair.java        |    0
 .../phoenix/mapreduce/bulkload/TargetTableRef.java |    0
 .../bulkload/TargetTableRefFunctions.java          |    0
 .../mapreduce/index/DirectHTableWriter.java        |    0
 .../mapreduce/index/IndexScrutinyMapper.java       |  530 ++
 .../index/IndexScrutinyMapperForTest.java          |    0
 .../mapreduce/index/IndexScrutinyTableOutput.java  |    0
 .../phoenix/mapreduce/index/IndexScrutinyTool.java |  542 ++
 .../apache/phoenix/mapreduce/index/IndexTool.java  | 1247 ++++
 .../phoenix/mapreduce/index/IndexToolUtil.java     |    0
 .../phoenix/mapreduce/index/IndexUpgradeTool.java  |  930 +++
 .../index/IndexVerificationOutputRepository.java   |  406 ++
 .../index/IndexVerificationOutputRow.java          |    0
 .../index/IndexVerificationResultRepository.java   |  415 ++
 .../mapreduce/index/PhoenixIndexDBWritable.java    |    0
 .../index/PhoenixIndexImportDirectMapper.java      |    0
 .../index/PhoenixIndexImportDirectReducer.java     |    0
 .../index/PhoenixIndexPartialBuildMapper.java      |  193 +
 .../index/PhoenixIndexToolJobCounters.java         |    0
 .../index/PhoenixScrutinyJobCounters.java          |    0
 .../index/PhoenixServerBuildIndexDBWritable.java   |    0
 .../index/PhoenixServerBuildIndexMapper.java       |    0
 .../mapreduce/index/SourceTargetColumnNames.java   |    0
 .../index/automation/PhoenixAsyncIndex.java        |    0
 .../index/automation/PhoenixMRJobCallable.java     |    0
 .../index/automation/PhoenixMRJobSubmitter.java    |    0
 .../index/automation/YarnApplication.java          |    0
 .../transform/PhoenixTransformReducer.java         |    0
 .../transform/PhoenixTransformRepairMapper.java    |  205 +
 .../PhoenixTransformWithViewsInputFormat.java      |  129 +
 .../phoenix/mapreduce/transform/TransformTool.java | 1006 +++
 .../util/ColumnInfoToStringEncoderDecoder.java     |    0
 .../util/DefaultMultiViewJobStatusTracker.java     |    0
 .../util/DefaultMultiViewSplitStrategy.java        |    0
 .../util/DefaultPhoenixMultiViewListProvider.java  |    0
 .../phoenix/mapreduce/util/IndexColumnNames.java   |    0
 .../mapreduce/util/MultiViewJobStatusTracker.java  |    0
 .../mapreduce/util/MultiViewSplitStrategy.java     |    0
 .../mapreduce/util/PhoenixConfigurationUtil.java   |  897 +++
 .../mapreduce/util/PhoenixMapReduceUtil.java       |    0
 .../mapreduce/util/PhoenixMultiInputUtil.java      |    0
 .../util/PhoenixMultiViewListProvider.java         |    0
 .../phoenix/mapreduce/util/ViewInfoTracker.java    |    0
 .../phoenix/mapreduce/util/ViewInfoWritable.java   |    0
 .../replication/SystemCatalogWALEntryFilter.java   |    0
 .../apache/phoenix/schema/MetaDataSplitPolicy.java |    0
 .../schema/SplitOnLeadingVarCharColumnsPolicy.java |    0
 .../phoenix/schema/SystemFunctionSplitPolicy.java  |    0
 .../phoenix/schema/SystemStatsSplitPolicy.java     |    0
 .../phoenix/schema/SystemTaskSplitPolicy.java      |    0
 .../schema/stats/DefaultStatisticsCollector.java   |  394 ++
 .../schema/stats/NoOpStatisticsCollector.java      |    0
 .../phoenix/schema/stats/StatisticsCollector.java  |    0
 .../schema/stats/StatisticsCollectorFactory.java   |    0
 .../phoenix/schema/stats/StatisticsScanner.java    |    0
 .../phoenix/schema/stats/StatisticsWriter.java     |  312 +
 .../phoenix/schema/stats/UpdateStatisticsTool.java |    0
 .../org/apache/phoenix/schema/task/ServerTask.java |  116 +
 .../apache/phoenix/schema/transform/Transform.java |  456 ++
 .../util/MergeViewIndexIdSequencesTool.java        |    0
 .../org/apache/phoenix/util/PhoenixMRJobUtil.java  |    0
 .../java/org/apache/phoenix/util/RepairUtil.java   |    0
 .../org/apache/phoenix/util/ServerIndexUtil.java   |  108 +
 .../java/org/apache/phoenix/util/ServerUtil.java   |  283 +
 .../org/apache/phoenix/util/ServerViewUtil.java    |  143 +
 .../phoenix/util/ZKBasedMasterElectionUtil.java    |    0
 phoenix-core/pom.xml                               |  999 ++-
 ...WALReplayWithIndexWritesAndCompressedWALIT.java |    1 -
 .../phoenix/end2end/BackwardCompatibilityIT.java   |    4 -
 .../end2end/BackwardCompatibilityTestUtil.java     |    6 +-
 .../apache/phoenix/end2end/BasePermissionsIT.java  |    2 +-
 .../end2end/ConcurrentMutationsExtendedIT.java     |    4 +-
 .../ConcurrentUpsertsWithoutIndexedColsIT.java     |    4 +-
 .../org/apache/phoenix/end2end/CreateSchemaIT.java |   10 +-
 .../org/apache/phoenix/end2end/CreateTableIT.java  |    6 +-
 .../org/apache/phoenix/end2end/DropSchemaIT.java   |    8 +-
 .../end2end/ExplainPlanWithStatsEnabledIT.java     |    4 +-
 .../apache/phoenix/end2end/IndexExtendedIT.java    |    3 +-
 .../apache/phoenix/end2end/IndexRebuildTaskIT.java |    4 +-
 .../end2end/IndexRepairRegionScannerIT.java        |    4 +-
 .../end2end/IndexScrutinyWithMaxLookbackIT.java    |    4 +-
 .../end2end/IndexToolForNonTxGlobalIndexIT.java    |    3 +-
 .../end2end/IndexVerificationOldDesignIT.java      |    3 +-
 .../phoenix/end2end/LogicalTableNameBaseIT.java    |    4 +-
 .../phoenix/end2end/MaxLookbackExtendedIT.java     |    4 +-
 .../org/apache/phoenix/end2end/MaxLookbackIT.java  |    4 +-
 .../apache/phoenix/end2end/MetaDataEndPointIT.java |    2 +-
 .../MigrateSystemTablesToSystemNamespaceIT.java    |    2 +-
 .../phoenix/end2end/ParallelIteratorsIT.java       |    4 +-
 .../phoenix/end2end/ParallelStatsDisabledIT.java   |    5 +-
 .../end2end/PhoenixRegionServerEndpointIT.java     |    3 +-
 .../apache/phoenix/end2end/PhoenixTTLToolIT.java   |    4 +-
 .../end2end/PreMatureTimelyAbortScanIt.java        |    4 +-
 .../phoenix/end2end/SchemaRegistryFailureIT.java   |    2 +-
 .../org/apache/phoenix/end2end/StoreNullsIT.java   |    4 +-
 .../SystemTablesCreationOnConnectionIT.java        |    3 +-
 .../phoenix/end2end/SystemTablesUpgradeIT.java     |    2 +-
 .../org/apache/phoenix/end2end/TableTTLIT.java     |    4 +-
 .../java/org/apache/phoenix/end2end/UpgradeIT.java |    6 +-
 .../org/apache/phoenix/end2end/UpsertSelectIT.java |    4 +-
 .../org/apache/phoenix/end2end/ViewMetadataIT.java |    2 +-
 .../java/org/apache/phoenix/end2end/ViewTTLIT.java |   26 +-
 .../org/apache/phoenix/end2end/ViewUtilIT.java     |    6 +-
 .../index/IndexRebuildIncrementDisableCountIT.java |    2 +-
 .../phoenix/end2end/index/IndexTestUtil.java       |    5 +-
 .../end2end/index/IndexTwoPhaseCreateIT.java       |    5 +-
 .../index/IndexVerificationOutputRepositoryIT.java |    2 +-
 .../index/IndexVerificationResultRepositoryIT.java |    4 +-
 .../index/InvalidIndexStateClientSideIT.java       |    6 +-
 .../apache/phoenix/end2end/index/LocalIndexIT.java |    5 +-
 .../end2end/index/PartialIndexRebuilderIT.java     |    7 +-
 .../phoenix/end2end/join/HashJoinCacheIT.java      |    2 +-
 .../phoenix/end2end/transform/TransformIT.java     |    4 +-
 .../transform/TransformMonitorExtendedIT.java      |    4 +-
 .../end2end/transform/TransformMonitorIT.java      |    3 +-
 .../phoenix/end2end/transform/TransformToolIT.java |    6 +-
 .../monitoring/PhoenixTableLevelMetricsIT.java     |   71 +-
 .../phoenix/trace/PhoenixTracingEndToEndIT.java    |    4 +-
 .../hbase/ipc/PhoenixRpcSchedulerFactory.java      |  108 -
 .../hbase/ipc/controller/IndexRpcController.java   |   57 -
 .../InvalidateMetadataCacheController.java         |   51 -
 .../ipc/controller/MetadataRpcController.java      |   74 -
 .../ServerToServerRpcControllerImpl.java           |   75 -
 .../regionserver/IndexHalfStoreFileReader.java     |  174 -
 .../IndexHalfStoreFileReaderGenerator.java         |  305 -
 .../apache/phoenix/cache/ServerCacheClient.java    |  554 --
 .../apache/phoenix/cache/ServerMetadataCache.java  |  193 -
 .../java/org/apache/phoenix/cache/TenantCache.java |   42 -
 .../org/apache/phoenix/cache/TenantCacheImpl.java  |  287 -
 .../apache/phoenix/compile/AggregationManager.java |  115 -
 .../org/apache/phoenix/compile/DeleteCompiler.java | 1030 ----
 .../org/apache/phoenix/compile/FromCompiler.java   | 1234 ----
 .../apache/phoenix/compile/GroupByCompiler.java    |  476 --
 .../org/apache/phoenix/compile/JoinCompiler.java   | 1590 -----
 .../apache/phoenix/compile/PostDDLCompiler.java    |  372 --
 .../phoenix/compile/PostLocalIndexDDLCompiler.java |  133 -
 .../apache/phoenix/compile/ProjectionCompiler.java |  796 ---
 .../org/apache/phoenix/compile/QueryCompiler.java  |  815 ---
 .../org/apache/phoenix/compile/ScanRanges.java     |  785 ---
 .../phoenix/compile/ServerBuildIndexCompiler.java  |  161 -
 .../ServerBuildTransformingTableCompiler.java      |   99 -
 .../org/apache/phoenix/compile/UpsertCompiler.java | 1455 -----
 .../org/apache/phoenix/compile/WhereCompiler.java  |  958 ---
 .../phoenix/coprocessor/AddColumnMutator.java      |  467 --
 .../coprocessor/BaseScannerRegionObserver.java     |  634 --
 .../apache/phoenix/coprocessor/ColumnMutator.java  |   66 -
 .../phoenix/coprocessor/DropColumnMutator.java     |  305 -
 .../coprocessor/GlobalIndexRegionScanner.java      | 1517 -----
 .../GroupedAggregateRegionObserver.java            |  642 --
 .../HashJoinCacheNotFoundException.java            |   45 -
 .../phoenix/coprocessor/HashJoinRegionScanner.java |  413 --
 .../coprocessor/IndexRebuildRegionScanner.java     |  389 --
 .../coprocessor/IndexRepairRegionScanner.java      |  460 --
 .../phoenix/coprocessor/IndexerRegionScanner.java  |  455 --
 .../InvalidateServerMetadataCacheRequest.java      |   53 -
 .../phoenix/coprocessor/MetaDataEndpointImpl.java  | 4805 ---------------
 .../phoenix/coprocessor/MetaDataProtocol.java      |  521 --
 .../coprocessor/MetaDataRegionObserver.java        |  672 --
 .../coprocessor/PhoenixRegionServerEndpoint.java   |  113 -
 .../coprocessor/PhoenixTTLRegionObserver.java      |  340 --
 .../phoenix/coprocessor/ScanRegionObserver.java    |  220 -
 .../coprocessor/SequenceRegionObserver.java        |  471 --
 .../coprocessor/ServerCachingEndpointImpl.java     |  123 -
 .../phoenix/coprocessor/ServerCachingProtocol.java |   61 -
 .../phoenix/coprocessor/TTLRegionScanner.java      |  228 -
 .../org/apache/phoenix/coprocessor/TableInfo.java  |   79 -
 .../phoenix/coprocessor/TaskRegionObserver.java    |  288 -
 .../UncoveredGlobalIndexRegionScanner.java         |  233 -
 .../coprocessor/UncoveredIndexRegionScanner.java   |  402 --
 .../UncoveredLocalIndexRegionScanner.java          |  132 -
 .../UngroupedAggregateRegionObserver.java          |  979 ---
 .../UngroupedAggregateRegionScanner.java           |  719 ---
 .../phoenix/coprocessor/WhereConstantParser.java   |  110 -
 .../metrics/MetricsMetadataCachingSource.java      |  230 -
 .../metrics/MetricsMetadataCachingSourceImpl.java  |  122 -
 .../MetricsPhoenixCoprocessorSourceFactory.java    |   57 -
 .../metrics/MetricsPhoenixTTLSource.java           |   61 -
 .../metrics/MetricsPhoenixTTLSourceImpl.java       |   58 -
 .../coprocessor/tasks/DropChildViewsTask.java      |  107 -
 .../coprocessor/tasks/IndexRebuildTask.java        |  194 -
 .../coprocessor/tasks/TransformMonitorTask.java    |  216 -
 .../apache/phoenix/exception/SQLExceptionCode.java |  697 ---
 .../exception/UpgradeInProgressException.java      |   31 -
 .../org/apache/phoenix/execute/AggregatePlan.java  |  371 --
 .../org/apache/phoenix/execute/BaseQueryPlan.java  |  582 --
 .../phoenix/execute/ClientAggregatePlan.java       |  384 --
 .../org/apache/phoenix/execute/HashJoinPlan.java   |  700 ---
 .../org/apache/phoenix/execute/MutationState.java  | 2310 -------
 .../execute/PhoenixTxIndexMutationGenerator.java   |  523 --
 .../java/org/apache/phoenix/execute/ScanPlan.java  |  378 --
 .../org/apache/phoenix/execute/TupleProjector.java |  495 --
 .../expression/RowValueConstructorExpression.java  |  277 -
 .../phoenix/filter/BooleanExpressionFilter.java    |  135 -
 .../MultiEncodedCQKeyValueComparisonFilter.java    |  415 --
 .../filter/MultiKeyValueComparisonFilter.java      |  291 -
 .../filter/SystemCatalogViewIndexIdFilter.java     |  161 -
 .../phoenix/hbase/index/IndexRegionObserver.java   | 1676 -----
 .../org/apache/phoenix/hbase/index/Indexer.java    |  780 ---
 .../hbase/index/builder/BaseIndexBuilder.java      |  138 -
 .../hbase/index/builder/BaseIndexCodec.java        |   36 -
 .../hbase/index/builder/IndexBuildManager.java     |  182 -
 .../phoenix/hbase/index/builder/IndexBuilder.java  |  153 -
 .../phoenix/hbase/index/covered/IndexCodec.java    |   88 -
 .../phoenix/hbase/index/covered/IndexMetaData.java |   55 -
 .../phoenix/hbase/index/covered/TableState.java    |   76 -
 .../hbase/index/metrics/MetricsIndexerSource.java  |  213 -
 .../hbase/index/util/IndexManagementUtil.java      |  293 -
 .../AbstractParallelWriterIndexCommitter.java      |  241 -
 .../TrackingParallelWriterIndexCommitter.java      |  302 -
 .../apache/phoenix/index/GlobalIndexChecker.java   |  658 --
 .../org/apache/phoenix/index/IndexMaintainer.java  | 2300 -------
 .../phoenix/index/IndexMetaDataCacheClient.java    |  158 -
 .../phoenix/index/IndexMetaDataCacheFactory.java   |   82 -
 .../apache/phoenix/index/PhoenixIndexBuilder.java  |  394 --
 .../apache/phoenix/index/PhoenixIndexCodec.java    |  139 -
 .../phoenix/index/PhoenixIndexFailurePolicy.java   |  596 --
 .../apache/phoenix/index/PhoenixIndexMetaData.java |  101 -
 .../phoenix/index/PhoenixIndexMetaDataBuilder.java |  107 -
 .../phoenix/index/PhoenixTransactionalIndexer.java |  246 -
 .../phoenix/iterate/BaseResultIterators.java       | 1771 ------
 .../phoenix/iterate/ChunkedResultIterator.java     |  249 -
 .../phoenix/iterate/ConcatResultIterator.java      |  150 -
 .../org/apache/phoenix/iterate/ExplainTable.java   |  550 --
 .../iterate/NonAggregateRegionScannerFactory.java  |  410 --
 .../phoenix/iterate/OrderedResultIterator.java     |  426 --
 .../phoenix/iterate/RegionScannerFactory.java      |  464 --
 .../iterate/RegionScannerResultIterator.java       |   88 -
 .../phoenix/iterate/RoundRobinResultIterator.java  |  354 --
 .../RowKeyOrderedAggregateResultIterator.java      |  200 -
 .../phoenix/iterate/ScanningResultIterator.java    |  236 -
 .../apache/phoenix/iterate/SerialIterators.java    |  231 -
 .../apache/phoenix/iterate/SnapshotScanner.java    |  279 -
 .../phoenix/iterate/SpoolingResultIterator.java    |  381 --
 .../phoenix/iterate/TableResultIterator.java       |  344 --
 .../iterate/TableSnapshotResultIterator.java       |  220 -
 .../phoenix/iterate/UnionResultIterators.java      |  166 -
 .../ParallelPhoenixNullComparingResultSet.java     |  333 -
 .../phoenix/jdbc/PhoenixDatabaseMetaData.java      | 1951 ------
 .../apache/phoenix/jdbc/PhoenixEmbeddedDriver.java |  198 -
 .../org/apache/phoenix/jdbc/PhoenixResultSet.java  | 1649 -----
 .../org/apache/phoenix/jdbc/PhoenixStatement.java  | 2650 --------
 .../org/apache/phoenix/join/HashCacheClient.java   |  228 -
 .../org/apache/phoenix/join/HashCacheFactory.java  |  174 -
 .../phoenix/mapreduce/MultiHfileOutputFormat.java  |  737 ---
 .../phoenix/mapreduce/PhoenixInputFormat.java      |  293 -
 .../phoenix/mapreduce/PhoenixRecordReader.java     |  197 -
 .../PhoenixServerBuildIndexInputFormat.java        |  218 -
 .../mapreduce/PhoenixTTLDeleteJobMapper.java       |  241 -
 .../mapreduce/index/IndexScrutinyMapper.java       |  530 --
 .../phoenix/mapreduce/index/IndexScrutinyTool.java |  542 --
 .../apache/phoenix/mapreduce/index/IndexTool.java  | 1247 ----
 .../phoenix/mapreduce/index/IndexUpgradeTool.java  |  930 ---
 .../index/IndexVerificationOutputRepository.java   |  406 --
 .../index/IndexVerificationResultRepository.java   |  415 --
 .../index/PhoenixIndexPartialBuildMapper.java      |  194 -
 .../transform/PhoenixTransformRepairMapper.java    |  205 -
 .../PhoenixTransformWithViewsInputFormat.java      |  129 -
 .../phoenix/mapreduce/transform/TransformTool.java | 1006 ---
 .../phoenix/mapreduce/util/ConnectionUtil.java     |  141 -
 .../mapreduce/util/PhoenixConfigurationUtil.java   | 1071 ----
 .../phoenix/monitoring/LatencyHistogram.java       |   46 -
 .../apache/phoenix/monitoring/SizeHistogram.java   |   47 -
 .../ConnectionQueryServicesHistogram.java          |   43 -
 .../parse/PhoenixRowTimestampParseNode.java        |   98 -
 .../phoenix/query/ConnectionQueryServices.java     |  237 -
 .../phoenix/query/ConnectionQueryServicesImpl.java | 6441 --------------------
 .../query/ConnectionlessQueryServicesImpl.java     |  834 ---
 .../query/DelegateConnectionQueryServices.java     |  442 --
 .../org/apache/phoenix/query/QueryConstants.java   |  590 --
 .../org/apache/phoenix/query/QueryServices.java    |  480 --
 .../apache/phoenix/query/QueryServicesOptions.java |  977 ---
 .../org/apache/phoenix/schema/MetaDataClient.java  | 6028 ------------------
 .../main/java/org/apache/phoenix/schema/PRow.java  |   89 -
 .../java/org/apache/phoenix/schema/PTableImpl.java | 2469 --------
 .../java/org/apache/phoenix/schema/Sequence.java   |  639 --
 .../schema/stats/DefaultStatisticsCollector.java   |  394 --
 .../phoenix/schema/stats/StatisticsUtil.java       |  252 -
 .../phoenix/schema/stats/StatisticsWriter.java     |  312 -
 .../java/org/apache/phoenix/schema/task/Task.java  |  529 --
 .../apache/phoenix/schema/transform/Transform.java |  795 ---
 .../transaction/OmidTransactionProvider.java       |  136 -
 .../phoenix/transaction/TransactionFactory.java    |   86 -
 .../apache/phoenix/util/EncodedColumnsUtil.java    |  207 -
 .../java/org/apache/phoenix/util/IndexUtil.java    | 1019 ----
 .../java/org/apache/phoenix/util/MetaDataUtil.java | 1243 ----
 .../org/apache/phoenix/util/PhoenixRuntime.java    | 1713 ------
 .../java/org/apache/phoenix/util/ScanUtil.java     | 1589 -----
 .../java/org/apache/phoenix/util/ServerUtil.java   |  450 --
 .../apache/phoenix/util/TableViewFinderResult.java |   49 -
 .../org/apache/phoenix/util/TransactionUtil.java   |  171 -
 .../java/org/apache/phoenix/util/UpgradeUtil.java  | 2925 ---------
 .../phoenix/util/ValidateLastDDLTimestampUtil.java |  211 -
 .../java/org/apache/phoenix/util/ViewUtil.java     |  994 ---
 .../org/apache/phoenix/util/WALAnnotationUtil.java |   78 -
 .../phoenix/cache/ServerMetadataCacheTest.java     |    4 +-
 .../org/apache/phoenix/cache/TenantCacheTest.java  |    4 +-
 .../apache/phoenix/compile/QueryCompilerTest.java  |   10 +-
 .../apache/phoenix/compile/QueryOptimizerTest.java |    4 +-
 .../execute/LiteralResultIteratorPlanTest.java     |    2 +-
 .../index/covered/CoveredColumnIndexCodec.java     |    2 +-
 .../CoveredColumnIndexSpecifierBuilder.java        |   11 +-
 .../index/covered/CoveredIndexCodecForTesting.java |    2 +-
 .../hbase/index/covered/LocalTableStateTest.java   |    2 +-
 .../hbase/index/covered/NonTxIndexBuilderTest.java |    2 +-
 .../org/apache/phoenix/index/ShouldVerifyTest.java |    8 +-
 .../phoenix/iterate/OrderedResultIteratorTest.java |    4 +-
 .../util/PhoenixConfigurationUtilTest.java         |   20 +-
 .../java/org/apache/phoenix/query/BaseTest.java    |    5 -
 .../apache/phoenix/schema/MetaDataClientTest.java  |    2 +-
 .../org/apache/phoenix/util/ClientUtilTest.java    |   93 +
 .../org/apache/phoenix/util/MetaDataUtilTest.java  |    5 +-
 .../apache/phoenix/util/PropertiesUtilTest.java    |    7 +-
 .../java/org/apache/phoenix/util/ScanUtilTest.java |    4 +-
 .../org/apache/phoenix/util/ServerUtilTest.java    |   93 -
 phoenix-pherf/pom.xml                              |   15 +-
 .../src/main/config/checkstyle/checker.xml         |   21 +-
 pom.xml                                            |   78 +-
 src/main/config/checkstyle/checker.xml             |   21 +-
 1596 files changed, 102397 insertions(+), 101545 deletions(-)

diff --cc phoenix-core-client/src/main/java/org/apache/hadoop/hbase/ipc/controller/InvalidateMetadataCacheController.java
index 0000000000,ba7fb6339d..cdfa9da168
mode 000000,100644..100644
--- a/phoenix-core-client/src/main/java/org/apache/hadoop/hbase/ipc/controller/InvalidateMetadataCacheController.java
+++ b/phoenix-core-client/src/main/java/org/apache/hadoop/hbase/ipc/controller/InvalidateMetadataCacheController.java
@@@ -1,0 -1,41 +1,51 @@@
 -/*
++/**
+  * 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.hadoop.hbase.ipc.controller;
+ 
+ import org.apache.hadoop.conf.Configuration;
 -import org.apache.hadoop.hbase.ipc.RpcControllerFactory;
 -import org.slf4j.Logger;
 -import org.slf4j.LoggerFactory;
++import org.apache.hadoop.hbase.TableName;
++import org.apache.hadoop.hbase.ipc.DelegatingHBaseRpcController;
++import org.apache.hadoop.hbase.ipc.HBaseRpcController;
++import org.apache.phoenix.util.IndexUtil;
+ 
+ /**
 - * {@link RpcControllerFactory} that should only be used when
 - * making server-server remote RPCs to the region servers hosting Phoenix SYSTEM tables.
++ * Controller used to invalidate server side metadata cache RPCs.
+  */
 -public class ServerSideRPCControllerFactory  {
++public class InvalidateMetadataCacheController extends DelegatingHBaseRpcController {
++    private int priority;
++
++    public InvalidateMetadataCacheController(HBaseRpcController delegate, Configuration conf) {
++        super(delegate);
++        this.priority = IndexUtil.getInvalidateMetadataCachePriority(conf);
++    }
+ 
 -    private static final Logger LOG = LoggerFactory.getLogger(ServerSideRPCControllerFactory.class);
 -    protected final Configuration conf;
++    @Override
++    public void setPriority(int priority) {
++        this.priority = priority;
++    }
+ 
 -    public ServerSideRPCControllerFactory(Configuration conf) {
 -        this.conf = conf;
++    @Override
++    public void setPriority(TableName tn) {
++        // Nothing
+     }
+ 
 -    public ServerToServerRpcController newController() {
 -        return new ServerToServerRpcControllerImpl(this.conf);
++    @Override
++    public int getPriority() {
++        return this.priority;
+     }
+ }
diff --cc phoenix-core-client/src/main/java/org/apache/phoenix/cache/ServerMetadataCache.java
index 0000000000,0000000000..4e47a1382a
new file mode 100644
--- /dev/null
+++ b/phoenix-core-client/src/main/java/org/apache/phoenix/cache/ServerMetadataCache.java
@@@ -1,0 -1,0 +1,193 @@@
++/*
++ * 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.cache;
++
++import java.sql.Connection;
++import java.sql.SQLException;
++import java.util.Properties;
++import java.util.concurrent.TimeUnit;
++
++import org.apache.hadoop.conf.Configuration;
++import org.apache.hadoop.hbase.util.Bytes;
++import org.apache.phoenix.coprocessorclient.metrics.MetricsMetadataCachingSource;
++import org.apache.phoenix.coprocessorclient.metrics.MetricsPhoenixCoprocessorSourceFactory;
++import org.apache.phoenix.hbase.index.util.ImmutableBytesPtr;
++import org.apache.phoenix.schema.PTable;
++import org.apache.phoenix.thirdparty.com.google.common.annotations.VisibleForTesting;
++import org.apache.phoenix.thirdparty.com.google.common.cache.Cache;
++import org.apache.phoenix.thirdparty.com.google.common.cache.CacheBuilder;
++import org.apache.phoenix.thirdparty.com.google.common.cache.RemovalListener;
++import org.apache.phoenix.util.PhoenixRuntime;
++import org.apache.phoenix.util.QueryUtil;
++import org.apache.phoenix.util.SchemaUtil;
++import org.slf4j.Logger;
++import org.slf4j.LoggerFactory;
++
++import static org.apache.phoenix.util.PhoenixRuntime.TENANT_ID_ATTRIB;
++/**
++ * This manages the cache for all the objects(data table, views, indexes) on each region server.
++ * Currently, it only stores LAST_DDL_TIMESTAMP in the cache.
++ */
++public class ServerMetadataCache {
++    private static final Logger LOGGER = LoggerFactory.getLogger(ServerMetadataCache.class);
++    private static final String PHOENIX_COPROC_REGIONSERVER_CACHE_TTL_MS =
++            "phoenix.coprocessor.regionserver.cache.ttl.ms";
++    // Keeping default cache expiry for 30 mins since we won't have stale entry
++    // for more than 30 mins.
++    private static final long DEFAULT_PHOENIX_COPROC_REGIONSERVER_CACHE_TTL_MS
++            = 30 * 60 * 1000L; // 30 mins
++    private static final String PHOENIX_COPROC_REGIONSERVER_CACHE_SIZE
++            = "phoenix.coprocessor.regionserver.cache.size";
++    private static final long DEFAULT_PHOENIX_COPROC_REGIONSERVER_CACHE_SIZE = 10000L;
++    private static volatile ServerMetadataCache INSTANCE;
++    private Configuration conf;
++    // key is the combination of <tenantID, schema name, table name>, value is the lastDDLTimestamp
++    private final Cache<ImmutableBytesPtr, Long> lastDDLTimestampMap;
++    private Connection connectionForTesting;
++    private MetricsMetadataCachingSource metricsSource;
++
++    /**
++     * Creates/gets an instance of ServerMetadataCache.
++     * @param conf configuration
++     * @return cache
++     */
++    public static ServerMetadataCache getInstance(Configuration conf) {
++        ServerMetadataCache result = INSTANCE;
++        if (result == null) {
++            synchronized (ServerMetadataCache.class) {
++                result = INSTANCE;
++                if (result == null) {
++                    INSTANCE = result = new ServerMetadataCache(conf);
++                }
++            }
++        }
++        return result;
++    }
++
++    private ServerMetadataCache(Configuration conf) {
++        this.conf = conf;
++        this.metricsSource = MetricsPhoenixCoprocessorSourceFactory
++                                .getInstance().getMetadataCachingSource();
++        long maxTTL = conf.getLong(PHOENIX_COPROC_REGIONSERVER_CACHE_TTL_MS,
++                DEFAULT_PHOENIX_COPROC_REGIONSERVER_CACHE_TTL_MS);
++        long maxSize = conf.getLong(PHOENIX_COPROC_REGIONSERVER_CACHE_SIZE,
++                DEFAULT_PHOENIX_COPROC_REGIONSERVER_CACHE_SIZE);
++        lastDDLTimestampMap = CacheBuilder.newBuilder()
++                .removalListener((RemovalListener<ImmutableBytesPtr, Long>) notification -> {
++                    String key = notification.getKey().toString();
++                    LOGGER.debug("Expiring " + key + " because of "
++                            + notification.getCause().name());
++                })
++                // maximum number of entries this cache can handle.
++                .maximumSize(maxSize)
++                .expireAfterAccess(maxTTL, TimeUnit.MILLISECONDS)
++                .build();
++    }
++
++    /**
++     * Returns the last DDL timestamp from the table.
++     * If not found in cache, then query SYSCAT regionserver.
++     * @param tenantID tenant id
++     * @param schemaName schema name
++     * @param tableName table name
++     * @return last DDL timestamp
++     * @throws Exception
++     */
++    public long getLastDDLTimestampForTable(byte[] tenantID, byte[] schemaName, byte[] tableName)
++            throws SQLException {
++        String fullTableNameStr = SchemaUtil.getTableName(schemaName, tableName);
++        byte[] tableKey = SchemaUtil.getTableKey(tenantID, schemaName, tableName);
++        ImmutableBytesPtr tableKeyPtr = new ImmutableBytesPtr(tableKey);
++        // Lookup in cache if present.
++        Long lastDDLTimestamp = lastDDLTimestampMap.getIfPresent(tableKeyPtr);
++        if (lastDDLTimestamp != null) {
++            metricsSource.incrementRegionServerMetadataCacheHitCount();
++            LOGGER.trace("Retrieving last ddl timestamp value from cache for tableName: {}",
++                    fullTableNameStr);
++            return lastDDLTimestamp;
++        }
++        metricsSource.incrementRegionServerMetadataCacheMissCount();
++        PTable table;
++        String tenantIDStr = Bytes.toString(tenantID);
++        if (tenantIDStr == null || tenantIDStr.isEmpty()) {
++            tenantIDStr = null;
++        }
++        Properties properties = new Properties();
++        if (tenantIDStr != null) {
++            properties.setProperty(TENANT_ID_ATTRIB, tenantIDStr);
++        }
++        try (Connection connection = getConnection(properties)) {
++            // Using PhoenixRuntime#getTableNoCache since se don't want to read cached value.
++            table = PhoenixRuntime.getTableNoCache(connection, fullTableNameStr);
++            // TODO PhoenixRuntime#getTableNoCache can throw TableNotFoundException.
++            //  In that case, do we want to throw non retryable exception back to the client?
++            // Update cache with the latest DDL timestamp from SYSCAT server.
++            lastDDLTimestampMap.put(tableKeyPtr, table.getLastDDLTimestamp());
++        }
++        return table.getLastDDLTimestamp();
++    }
++
++    /**
++     * Invalidate cache for the given tenantID, schema name and table name.
++     * Guava cache is thread safe so we don't have to synchronize it explicitly.
++     * @param tenantID tenantID
++     * @param schemaName schemaName
++     * @param tableName tableName
++     */
++    public void invalidate(byte[] tenantID, byte[] schemaName, byte[] tableName) {
++        String fullTableNameStr = SchemaUtil.getTableName(schemaName, tableName);
++        LOGGER.debug("Invalidating server metadata cache for tenantID: {}, full table: {}",
++                Bytes.toString(tenantID), fullTableNameStr);
++        byte[] tableKey = SchemaUtil.getTableKey(tenantID, schemaName, tableName);
++        ImmutableBytesPtr tableKeyPtr = new ImmutableBytesPtr(tableKey);
++        lastDDLTimestampMap.invalidate(tableKeyPtr);
++    }
++
++    /**
++     * This should be used only in the tests. DO NOT use this in production code.
++     */
++    @VisibleForTesting
++    public Long getLastDDLTimestampForTableFromCacheOnly(byte[] tenantID, byte[] schemaName,
++                                                         byte[] tableName) {
++        byte[] tableKey = SchemaUtil.getTableKey(tenantID, schemaName, tableName);
++        ImmutableBytesPtr tableKeyPtr = new ImmutableBytesPtr(tableKey);
++        return lastDDLTimestampMap.getIfPresent(tableKeyPtr);
++    }
++
++    // This is used by tests to override specific connection to use.
++    private Connection getConnection(Properties properties) throws SQLException {
++        return connectionForTesting != null ? connectionForTesting
++                : QueryUtil.getConnectionOnServer(properties, this.conf);
++    }
++
++    @VisibleForTesting
++    public void setConnectionForTesting(Connection connection) {
++        this.connectionForTesting = connection;
++    }
++
++    @VisibleForTesting
++    public static  void resetCache() {
++        LOGGER.info("Resetting ServerMetadataCache");
++        INSTANCE = null;
++    }
++
++    @VisibleForTesting
++    public static void setInstance(ServerMetadataCache cache) {
++        INSTANCE = cache;
++    }
++}
diff --cc phoenix-core-client/src/main/java/org/apache/phoenix/coprocessorclient/InvalidateServerMetadataCacheRequest.java
index 0000000000,0000000000..7ac94c8968
new file mode 100644
--- /dev/null
+++ b/phoenix-core-client/src/main/java/org/apache/phoenix/coprocessorclient/InvalidateServerMetadataCacheRequest.java
@@@ -1,0 -1,0 +1,53 @@@
++/*
++ * 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.coprocessorclient;
++
++import org.apache.hadoop.hbase.util.Bytes;
++import org.apache.phoenix.util.SchemaUtil;
++
++public class InvalidateServerMetadataCacheRequest {
++    private final byte[] tenantId;
++    private final byte[] schemaName;
++    private final byte[] tableName;
++
++    public InvalidateServerMetadataCacheRequest(byte[] tenantId, byte[] schemaName,
++                                                byte[] tableName) {
++        this.tenantId = tenantId;
++        this.schemaName = schemaName;
++        this.tableName = tableName;
++    }
++
++    public byte[] getTenantId() {
++        return tenantId;
++    }
++
++    public byte[] getSchemaName() {
++        return schemaName;
++    }
++
++    public byte[] getTableName() {
++        return tableName;
++    }
++
++    @Override
++    public String toString() {
++        String fullTableName = SchemaUtil.getTableName(schemaName, tableName);
++        return "tenantId = " + Bytes.toString(tenantId)
++                + ", table name = " + fullTableName;
++    }
++}
diff --cc phoenix-core-client/src/main/java/org/apache/phoenix/coprocessorclient/metrics/MetricsMetadataCachingSource.java
index 0000000000,0000000000..2d810d5fa4
new file mode 100644
--- /dev/null
+++ b/phoenix-core-client/src/main/java/org/apache/phoenix/coprocessorclient/metrics/MetricsMetadataCachingSource.java
@@@ -1,0 -1,0 +1,230 @@@
++/*
++ * 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.coprocessorclient.metrics;
++
++import org.apache.hadoop.hbase.metrics.BaseSource;
++import org.apache.phoenix.thirdparty.com.google.common.annotations.VisibleForTesting;
++
++/**
++ * Interface for metrics about Distributed Metadata Caching
++ */
++public interface MetricsMetadataCachingSource extends BaseSource {
++    // Metrics2 and JMX constants
++    String METRICS_NAME = "MetadataCaching";
++    String METRICS_CONTEXT = "phoenix";
++    String METRICS_DESCRIPTION = "Metrics about Distributed Metadata Caching";
++    String METRICS_JMX_CONTEXT = "RegionServer,sub=" + METRICS_NAME;
++
++    String REGIONSERVER_METADATA_CACHE_HITS = "numRegionServerMetadataCacheHits";
++    String REGIONSERVER_METADATA_CACHE_HITS_DESC
++            = "Number of cache hits in PhoenixRegionServerEndpoint "
++                + "when serving validate ddl timestamp requests.";
++
++    String REGIONSERVER_METADATA_CACHE_MISSES = "numRegionServerMetadataCacheMisses";
++    String REGIONSERVER_METADATA_CACHE_MISSES_DESC
++            = "Number of cache misses in PhoenixRegionServerEndpoint "
++                + "when serving validate ddl timestamp requests.";
++
++    String VALIDATE_LAST_DDL_TIMESTAMP_REQUESTS = "numValidateLastDDLTimestampRequests";
++    String VALIDATE_LAST_DDL_TIMESTAMP_REQUEST_DESC
++            = "Number of validate last ddl timestamp requests.";
++
++    String METADATA_CACHE_INVALIDATION_OPERATIONS = "numMetadataCacheInvalidationOps";
++    String METADATA_CACHE_INVALIDATION_OPERATIONS_DESC = "Number of times we invoke "
++                                                    + "cache invalidation within a DDL operation";
++
++    String METADATA_CACHE_INVALIDATION_SUCCESS = "numMetadataCacheInvalidationOpsSuccess";
++    String METADATA_CACHE_INVALIDATION_SUCCESS_DESC
++            = "Number of times cache invalidation was successful.";
++
++    String METADATA_CACHE_INVALIDATION_FAILURE = "numMetadataCacheInvalidationOpsFailure";
++    String METADATA_CACHE_INVALIDATION_FAILURE_DESC = "Number of times cache invalidation failed.";
++
++    String METADATA_CACHE_INVALIDATION_RPC_TIME = "metadataCacheInvalidationRpcTimeMs";
++    String METADATA_CACHE_INVALIDATION_RPC_TIME_DESC = "Histogram for the time in milliseconds for"
++                                                + " cache invalidation RPC";
++    String METADATA_CACHE_INVALIDATION_TOTAL_TIME = "metadataCacheInvalidationTotalTimeMs";
++    String METADATA_CACHE_INVALIDATION_TOTAL_TIME_DESC
++            = "Histogram for the total time in milliseconds "
++                + "for cache invalidation on all regionservers";
++
++    /**
++     * Report the number of cache hits when validating last ddl timestamps.
++     */
++    void incrementRegionServerMetadataCacheHitCount();
++
++    /**
++     * Report the number of cache misses when validating last ddl timestamps.
++     */
++    void incrementRegionServerMetadataCacheMissCount();
++
++    /**
++     * Report the number of requests for validating last ddl timestamps.
++     */
++    void incrementValidateTimestampRequestCount();
++
++    /**
++     * Report number of cache invalidations performed.
++     */
++    void incrementMetadataCacheInvalidationOperationsCount();
++
++    /**
++     * Report number of cache invalidations which were successful.
++     */
++    void incrementMetadataCacheInvalidationSuccessCount();
++
++    /**
++     * Report number of cache invalidations which failed.
++     */
++    void incrementMetadataCacheInvalidationFailureCount();
++
++    /**
++     * Add to the cache invalidation rpc time histogram.
++     */
++    void addMetadataCacheInvalidationRpcTime(long t);
++
++    /**
++     * Add to the cache invalidation total time histogram.
++     * @param t
++     */
++    void addMetadataCacheInvalidationTotalTime(long t);
++
++    /**
++     * Return current values of all metrics.
++     * @return {@link MetadataCachingMetricValues} object
++     */
++    @VisibleForTesting
++    MetadataCachingMetricValues getCurrentMetricValues();
++
++    /**
++     * Class to represent values of all metrics related to server metadata caching.
++     */
++    @VisibleForTesting
++    class MetadataCachingMetricValues {
++        private long cacheHitCount;
++        private long cacheMissCount;
++        private long validateDDLTimestampRequestsCount;
++        private long cacheInvalidationOpsCount;
++        private long cacheInvalidationSuccessCount;
++        private long cacheInvalidationFailureCount;
++        private long cacheInvalidationRpcTimeCount;
++        private long cacheInvalidationTotalTimeCount;
++
++        MetadataCachingMetricValues(Builder builder) {
++            this.cacheHitCount = builder.cacheHitCount;
++            this.cacheMissCount = builder.cacheMissCount;
++            this.validateDDLTimestampRequestsCount = builder.validateDDLTimestampRequestsCount;
++            this.cacheInvalidationOpsCount = builder.cacheInvalidationOpsCount;
++            this.cacheInvalidationSuccessCount = builder.cacheInvalidationSuccessCount;
++            this.cacheInvalidationFailureCount = builder.cacheInvalidationFailureCount;
++            this.cacheInvalidationRpcTimeCount = builder.cacheInvalidationRpcTimeCount;
++            this.cacheInvalidationTotalTimeCount = builder.cacheInvalidationTotalTimeCount;
++        }
++
++        public long getCacheHitCount() {
++            return cacheHitCount;
++        }
++
++        public long getCacheMissCount() {
++            return cacheMissCount;
++        }
++
++        public long getValidateDDLTimestampRequestsCount() {
++            return validateDDLTimestampRequestsCount;
++        }
++
++        public long getCacheInvalidationOpsCount() {
++            return cacheInvalidationOpsCount;
++        }
++
++        public long getCacheInvalidationSuccessCount() {
++            return cacheInvalidationSuccessCount;
++        }
++
++        public long getCacheInvalidationFailureCount() {
++            return cacheInvalidationFailureCount;
++        }
++
++        public long getCacheInvalidationRpcTimeCount() {
++            return cacheInvalidationRpcTimeCount;
++        }
++
++        public long getCacheInvalidationTotalTimeCount() {
++            return cacheInvalidationTotalTimeCount;
++        }
++
++        /**
++         * Builder for {@link MetadataCachingMetricValues}
++         */
++        public static class Builder {
++            private long cacheHitCount;
++            private long cacheMissCount;
++            private long validateDDLTimestampRequestsCount;
++            private long cacheInvalidationOpsCount;
++            private long cacheInvalidationSuccessCount;
++            private long cacheInvalidationFailureCount;
++            private long cacheInvalidationRpcTimeCount;
++            private long cacheInvalidationTotalTimeCount;
++
++            public MetadataCachingMetricValues build() {
++                return new MetadataCachingMetricValues(this);
++            }
++
++            public Builder setCacheHitCount(long c) {
++                this.cacheHitCount = c;
++                return this;
++            }
++            public Builder setCacheMissCount(long cacheMissCount) {
++                this.cacheMissCount = cacheMissCount;
++                return this;
++            }
++
++            public Builder setValidateDDLTimestampRequestsCount(
++                    long validateDDLTimestampRequestsCount) {
++                this.validateDDLTimestampRequestsCount = validateDDLTimestampRequestsCount;
++                return this;
++            }
++
++            public Builder setCacheInvalidationOpsCount(long cacheInvalidationOpsCount) {
++                this.cacheInvalidationOpsCount = cacheInvalidationOpsCount;
++                return this;
++            }
++
++            public Builder setCacheInvalidationSuccessCount(long cacheInvalidationSuccessCount) {
++                this.cacheInvalidationSuccessCount = cacheInvalidationSuccessCount;
++                return this;
++            }
++
++            public Builder setCacheInvalidationFailureCount(long cacheInvalidationFailureCount) {
++                this.cacheInvalidationFailureCount = cacheInvalidationFailureCount;
++                return this;
++            }
++
++            public Builder setCacheInvalidationRpcTimeCount(long cacheInvalidationRpcTimeCount) {
++                this.cacheInvalidationRpcTimeCount = cacheInvalidationRpcTimeCount;
++                return this;
++            }
++
++            public Builder setCacheInvalidationTotalTimeCount(
++                    long cacheInvalidationTotalTimeCount) {
++                this.cacheInvalidationTotalTimeCount = cacheInvalidationTotalTimeCount;
++                return this;
++            }
++        }
++    }
++}
diff --cc phoenix-core-client/src/main/java/org/apache/phoenix/coprocessorclient/metrics/MetricsMetadataCachingSourceImpl.java
index 0000000000,0000000000..1fc249bcc2
new file mode 100644
--- /dev/null
+++ b/phoenix-core-client/src/main/java/org/apache/phoenix/coprocessorclient/metrics/MetricsMetadataCachingSourceImpl.java
@@@ -1,0 -1,0 +1,122 @@@
++/*
++ * 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.coprocessorclient.metrics;
++
++import org.apache.hadoop.hbase.metrics.BaseSourceImpl;
++import org.apache.hadoop.metrics2.MetricHistogram;
++import org.apache.hadoop.metrics2.lib.MutableFastCounter;
++
++/**
++ * Implementation for tracking Distributed Metadata Caching metrics.
++ */
++public class MetricsMetadataCachingSourceImpl
++        extends BaseSourceImpl
++        implements MetricsMetadataCachingSource {
++
++    private final MutableFastCounter cacheHitCounter;
++    private final MutableFastCounter cacheMissCounter;
++    private final MutableFastCounter validateDDLTimestampRequestCounter;
++    private final MutableFastCounter cacheInvalidationOpsCounter;
++    private final MutableFastCounter cacheInvalidationSuccessCounter;
++    private final MutableFastCounter cacheInvalidationFailureCounter;
++    private final MetricHistogram cacheInvalidationRpcTimeHistogram;
++    private final MetricHistogram cacheInvalidationTotalTimeHistogram;
++
++    public MetricsMetadataCachingSourceImpl() {
++        this(METRICS_NAME, METRICS_DESCRIPTION, METRICS_CONTEXT, METRICS_JMX_CONTEXT);
++    }
++
++    public MetricsMetadataCachingSourceImpl(String metricsName,
++                                       String metricsDescription,
++                                       String metricsContext,
++                                       String metricsJmxContext) {
++        super(metricsName, metricsDescription, metricsContext, metricsJmxContext);
++        cacheHitCounter = getMetricsRegistry().newCounter(
++                REGIONSERVER_METADATA_CACHE_HITS, REGIONSERVER_METADATA_CACHE_HITS_DESC, 0L);
++        cacheMissCounter = getMetricsRegistry().newCounter(
++            REGIONSERVER_METADATA_CACHE_MISSES, REGIONSERVER_METADATA_CACHE_MISSES_DESC, 0L);
++        validateDDLTimestampRequestCounter = getMetricsRegistry().newCounter(
++            VALIDATE_LAST_DDL_TIMESTAMP_REQUESTS, VALIDATE_LAST_DDL_TIMESTAMP_REQUEST_DESC, 0L);
++        cacheInvalidationOpsCounter = getMetricsRegistry().newCounter(
++            METADATA_CACHE_INVALIDATION_OPERATIONS,
++                METADATA_CACHE_INVALIDATION_OPERATIONS_DESC, 0L);
++        cacheInvalidationSuccessCounter = getMetricsRegistry().newCounter(
++            METADATA_CACHE_INVALIDATION_SUCCESS, METADATA_CACHE_INVALIDATION_SUCCESS_DESC, 0L);
++        cacheInvalidationFailureCounter = getMetricsRegistry().newCounter(
++            METADATA_CACHE_INVALIDATION_FAILURE, METADATA_CACHE_INVALIDATION_FAILURE_DESC, 0L);
++        cacheInvalidationRpcTimeHistogram = getMetricsRegistry().newHistogram(
++            METADATA_CACHE_INVALIDATION_RPC_TIME, METADATA_CACHE_INVALIDATION_RPC_TIME_DESC);
++        cacheInvalidationTotalTimeHistogram = getMetricsRegistry().newHistogram(
++            METADATA_CACHE_INVALIDATION_TOTAL_TIME, METADATA_CACHE_INVALIDATION_TOTAL_TIME_DESC);
++    }
++
++    @Override
++    public void incrementRegionServerMetadataCacheHitCount() {
++        cacheHitCounter.incr();
++    }
++
++    @Override
++    public void incrementRegionServerMetadataCacheMissCount() {
++        cacheMissCounter.incr();
++    }
++
++    @Override
++    public void incrementValidateTimestampRequestCount() {
++        validateDDLTimestampRequestCounter.incr();
++    }
++
++    @Override
++    public void addMetadataCacheInvalidationRpcTime(long t) {
++        cacheInvalidationRpcTimeHistogram.add(t);
++    }
++
++    @Override
++    public void addMetadataCacheInvalidationTotalTime(long t) {
++        cacheInvalidationTotalTimeHistogram.add(t);
++    }
++
++    @Override
++    public void incrementMetadataCacheInvalidationOperationsCount() {
++        cacheInvalidationOpsCounter.incr();
++    }
++
++    @Override
++    public void incrementMetadataCacheInvalidationSuccessCount() {
++        cacheInvalidationSuccessCounter.incr();
++    }
++
++    @Override
++    public void incrementMetadataCacheInvalidationFailureCount() {
++        cacheInvalidationFailureCounter.incr();
++    }
++
++    @Override
++    public MetadataCachingMetricValues getCurrentMetricValues() {
++        return new MetadataCachingMetricValues
++                .Builder()
++                .setCacheHitCount(cacheHitCounter.value())
++                .setCacheMissCount(cacheMissCounter.value())
++                .setValidateDDLTimestampRequestsCount(validateDDLTimestampRequestCounter.value())
++                .setCacheInvalidationRpcTimeCount(cacheInvalidationRpcTimeHistogram.getCount())
++                .setCacheInvalidationTotalTimeCount(cacheInvalidationTotalTimeHistogram.getCount())
++                .setCacheInvalidationOpsCount(cacheInvalidationOpsCounter.value())
++                .setCacheInvalidationSuccessCount(cacheInvalidationSuccessCounter.value())
++                .setCacheInvalidationFailureCount(cacheInvalidationFailureCounter.value())
++                .build();
++    }
++}
diff --cc phoenix-core-client/src/main/java/org/apache/phoenix/coprocessorclient/metrics/MetricsPhoenixCoprocessorSourceFactory.java
index 0000000000,0742f4ba6c..280a116f68
mode 000000,100644..100644
--- a/phoenix-core-client/src/main/java/org/apache/phoenix/coprocessorclient/metrics/MetricsPhoenixCoprocessorSourceFactory.java
+++ b/phoenix-core-client/src/main/java/org/apache/phoenix/coprocessorclient/metrics/MetricsPhoenixCoprocessorSourceFactory.java
@@@ -1,0 -1,45 +1,57 @@@
+ /*
+  * 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.coprocessorclient.metrics;
+ /**
+  * Factory object to create various metric sources for phoenix related coprocessors.
+  */
+ public class MetricsPhoenixCoprocessorSourceFactory {
+ 
+     private static final MetricsPhoenixCoprocessorSourceFactory
+             INSTANCE = new MetricsPhoenixCoprocessorSourceFactory();
+     // Holds the PHOENIX_TTL related metrics.
+     private static volatile MetricsPhoenixTTLSource phoenixTTLSource;
++    private static volatile MetricsMetadataCachingSource metadataCachingSource;
+ 
+     public static MetricsPhoenixCoprocessorSourceFactory getInstance() {
+         return INSTANCE;
+     }
+ 
+     // return the metric source for PHOENIX_TTL coproc.
+     public MetricsPhoenixTTLSource getPhoenixTTLSource() {
+         if (INSTANCE.phoenixTTLSource == null) {
+             synchronized (MetricsPhoenixTTLSource.class) {
+                 if (INSTANCE.phoenixTTLSource == null) {
+                     INSTANCE.phoenixTTLSource = new MetricsPhoenixTTLSourceImpl();
+                 }
+             }
+         }
+         return INSTANCE.phoenixTTLSource;
+     }
++
++    public MetricsMetadataCachingSource getMetadataCachingSource() {
++        if (INSTANCE.metadataCachingSource == null) {
++            synchronized (MetricsMetadataCachingSource.class) {
++                if (INSTANCE.metadataCachingSource == null) {
++                    INSTANCE.metadataCachingSource = new MetricsMetadataCachingSourceImpl();
++                }
++            }
++        }
++        return INSTANCE.metadataCachingSource;
++    }
+ }
diff --cc phoenix-core-client/src/main/java/org/apache/phoenix/exception/SQLExceptionCode.java
index 0000000000,6f2dc5bc1a..3f50f4a694
mode 000000,100644..100644
--- a/phoenix-core-client/src/main/java/org/apache/phoenix/exception/SQLExceptionCode.java
+++ b/phoenix-core-client/src/main/java/org/apache/phoenix/exception/SQLExceptionCode.java
@@@ -1,0 -1,694 +1,697 @@@
+ /*
+  * 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.exception;
+ 
+ import java.sql.BatchUpdateException;
+ import java.sql.SQLException;
+ import java.sql.SQLTimeoutException;
+ import java.util.Map;
+ 
+ import org.apache.phoenix.coprocessorclient.MetaDataProtocol;
+ import org.apache.phoenix.hbase.index.util.IndexManagementUtil;
+ import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData;
+ import org.apache.phoenix.query.QueryConstants;
+ import org.apache.phoenix.query.QueryServices;
+ import org.apache.phoenix.schema.AmbiguousColumnException;
+ import org.apache.phoenix.schema.AmbiguousTableException;
+ import org.apache.phoenix.schema.ColumnAlreadyExistsException;
+ import org.apache.phoenix.schema.ColumnFamilyNotFoundException;
+ import org.apache.phoenix.schema.ColumnNotFoundException;
+ import org.apache.phoenix.schema.ConcurrentTableMutationException;
+ import org.apache.phoenix.schema.FunctionAlreadyExistsException;
+ import org.apache.phoenix.schema.FunctionNotFoundException;
+ import org.apache.phoenix.schema.IndexNotFoundException;
+ import org.apache.phoenix.schema.MaxMutationSizeBytesExceededException;
+ import org.apache.phoenix.schema.MaxMutationSizeExceededException;
+ import org.apache.phoenix.schema.MaxPhoenixColumnSizeExceededException;
+ import org.apache.phoenix.schema.PTable;
+ import org.apache.phoenix.schema.PTableType;
+ import org.apache.phoenix.schema.ReadOnlyTableException;
+ import org.apache.phoenix.schema.SchemaAlreadyExistsException;
+ import org.apache.phoenix.schema.SchemaNotFoundException;
+ import org.apache.phoenix.schema.SequenceAlreadyExistsException;
+ import org.apache.phoenix.schema.SequenceNotFoundException;
+ import org.apache.phoenix.schema.StaleRegionBoundaryCacheException;
+ import org.apache.phoenix.schema.TableAlreadyExistsException;
+ import org.apache.phoenix.schema.TableNotFoundException;
+ import org.apache.phoenix.schema.TypeMismatchException;
+ import org.apache.phoenix.schema.types.PDataType;
+ import org.apache.phoenix.util.MetaDataUtil;
+ 
+ import org.apache.phoenix.thirdparty.com.google.common.collect.Maps;
+ 
+ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.CHANGE_DETECTION_ENABLED;
+ 
+ 
+ /**
+  * Various SQLException Information. Including a vendor-specific errorcode and a standard SQLState.
+  *
+  *
+  * @since 1.0
+  */
+ public enum SQLExceptionCode {
+ 
+     /**
+      * Connection Exception (errorcode 01, sqlstate 08)
+      */
+     IO_EXCEPTION(101, "08000", "Unexpected IO exception."),
+     MALFORMED_CONNECTION_URL(102, "08001", "Malformed connection url."),
+     CANNOT_ESTABLISH_CONNECTION(103, "08004", "Unable to establish connection."),
+ 
+     /**
+      * Data Exception (errorcode 02, sqlstate 22)
+      */
+     ILLEGAL_DATA(201, "22000", "Illegal data."),
+     DIVIDE_BY_ZERO(202, "22012", "Divide by zero."),
+     TYPE_MISMATCH(203, "22005", "Type mismatch.", new Factory() {
+         @Override
+         public SQLException newException(SQLExceptionInfo info) {
+             return new TypeMismatchException(info.getMessage());
+         }
+     }),
+     VALUE_IN_UPSERT_NOT_CONSTANT(204, "22008", "Values in UPSERT must evaluate to a constant."),
+     MALFORMED_URL(205, "22009", "Malformed URL."),
+     DATA_EXCEEDS_MAX_CAPACITY(206, "22003", "The data exceeds the max capacity for the data type."),
+     MISSING_MAX_LENGTH(207, "22004", "Max length must be specified for type."),
+     NONPOSITIVE_MAX_LENGTH(208, "22006", "Max length must have a positive length for type."),
+     DECIMAL_PRECISION_OUT_OF_RANGE(209, "22003", "Decimal precision outside of range. Should be within 1 and " + PDataType.MAX_PRECISION + "."),
+     SERVER_ARITHMETIC_ERROR(212, "22012", "Arithmetic error on server."),
+     VALUE_OUTSIDE_RANGE(213,"22003","Value outside range."),
+     VALUE_IN_LIST_NOT_CONSTANT(214, "22008", "Values in IN must evaluate to a constant."),
+     SINGLE_ROW_SUBQUERY_RETURNS_MULTIPLE_ROWS(215, "22015", "Single-row sub-query returns more than one row."),
+     SUBQUERY_RETURNS_DIFFERENT_NUMBER_OF_FIELDS(216, "22016", "Sub-query must return the same number of fields as the left-hand-side expression of 'IN'."),
+     AMBIGUOUS_JOIN_CONDITION(217, "22017", "Ambiguous or non-equi join condition specified. Consider using table list with where clause."),
+     CONSTRAINT_VIOLATION(218, "23018", "Constraint violation."),
+     SUBQUERY_SELECT_LIST_COLUMN_MUST_HAS_ALIAS(219,"23019","Every column in subquery select lists must has alias when used for join."),
+ 
+     CONCURRENT_TABLE_MUTATION(301, "23000", "Concurrent modification to table.", new Factory() {
+         @Override
+         public SQLException newException(SQLExceptionInfo info) {
+             return new ConcurrentTableMutationException(info.getSchemaName(), info.getTableName());
+         }
+     }),
+     CANNOT_INDEX_COLUMN_ON_TYPE(302, "23100", "The column cannot be index due to its type."),
+     INVALID_INDEX_WHERE_WITH_SUBQUERY(303, "23101",
+             " Index where clause cannot include a subquery."),
+     CANNOT_EVALUATE_INDEX_WHERE(304, "23102",
+             "Invalid index where clause. It cannot be evaluated on a data table row."),
+     /**
+      * Invalid Cursor State (errorcode 04, sqlstate 24)
+      */
+     CURSOR_BEFORE_FIRST_ROW(401, "24015","Cursor before first row."),
+     CURSOR_PAST_LAST_ROW(402, "24016", "Cursor past last row."),
+ 
+     /**
+      * Syntax Error or Access Rule Violation (errorcode 05, sqlstate 42)
+      */
+     AMBIGUOUS_TABLE(501, "42000", "Table name exists in more than one table schema and is used without being qualified.", new Factory() {
+         @Override
+         public SQLException newException(SQLExceptionInfo info) {
+             return new AmbiguousTableException(info.getTableName(), info.getRootCause());
+         }
+     }),
+     AMBIGUOUS_COLUMN(502, "42702", "Column reference ambiguous or duplicate names.", new Factory() {
+         @Override
+         public SQLException newException(SQLExceptionInfo info) {
+             return new AmbiguousColumnException(info.getColumnName(), info.getRootCause());
+         }
+     }),
+     INDEX_MISSING_PK_COLUMNS(503, "42602", "Index table missing PK Columns."),
+      COLUMN_NOT_FOUND(504, "42703", "Undefined column.", new Factory() {
+         @Override
+         public SQLException newException(SQLExceptionInfo info) {
+             return new ColumnNotFoundException(info.getSchemaName(), info.getTableName(), info.getFamilyName(), info.getColumnName());
+         }
+     }),
+     READ_ONLY_TABLE(505, "42000", "Table is read only.", new Factory() {
+         @Override
+         public SQLException newException(SQLExceptionInfo info) {
+             return new ReadOnlyTableException(info.getMessage(), info.getSchemaName(), info.getTableName(), info.getFamilyName());
+         }
+     }),
+     CANNOT_DROP_PK(506, "42817", "Primary key column may not be dropped."),
+     PRIMARY_KEY_MISSING(509, "42888", "The table does not have a primary key."),
+     PRIMARY_KEY_ALREADY_EXISTS(510, "42889", "The table already has a primary key."),
+     ORDER_BY_NOT_IN_SELECT_DISTINCT(511, "42890", "All ORDER BY expressions must appear in SELECT DISTINCT:"),
+     INVALID_PRIMARY_KEY_CONSTRAINT(512, "42891", "Invalid column reference in primary key constraint."),
+     ARRAY_NOT_ALLOWED_IN_PRIMARY_KEY(513, "42892", "Array type not allowed as primary key constraint."),
+     COLUMN_EXIST_IN_DEF(514, "42892", "A duplicate column name was detected in the object definition or ALTER TABLE/VIEW statement.", new Factory() {
+         @Override
+         public SQLException newException(SQLExceptionInfo info) {
+             return new ColumnAlreadyExistsException(info.getSchemaName(), info.getTableName(), info.getColumnName());
+         }
+     }),
+     ORDER_BY_ARRAY_NOT_SUPPORTED(515, "42893", "ORDER BY of an array type is not allowed."),
+     NON_EQUALITY_ARRAY_COMPARISON(516, "42894", "Array types may only be compared using = or !=."),
+     /**
+      *  Invalid Transaction State (errorcode 05, sqlstate 25)
+      */
+      READ_ONLY_CONNECTION(518,"25502","Mutations are not permitted for a read-only connection."),
+ 
+      VARBINARY_ARRAY_NOT_SUPPORTED(519, "42896", "VARBINARY ARRAY is not supported."),
+ 
+      /**
+       *  Expression Index exceptions.
+       */
+      AGGREGATE_EXPRESSION_NOT_ALLOWED_IN_INDEX(520, "42897", "Aggregate expression not allowed in an index."),
+      NON_DETERMINISTIC_EXPRESSION_NOT_ALLOWED_IN_INDEX(521, "42898", "Non-deterministic expression not allowed in an index."),
+      STATELESS_EXPRESSION_NOT_ALLOWED_IN_INDEX(522, "42899", "Stateless expression not allowed in an index."),
+      
+      /**
+       *  Transaction exceptions.
+       */
+      TRANSACTION_CONFLICT_EXCEPTION(523, "42900", "Transaction aborted due to conflict with other mutations."),
+      TRANSACTION_EXCEPTION(524, "42901", "Transaction aborted due to error."),
+ 
+      /**
+       * Union All related errors
+       */
+      SELECT_COLUMN_NUM_IN_UNIONALL_DIFFS(525, "42902", "SELECT column number differs in a Union All query is not allowed."),
+      SELECT_COLUMN_TYPE_IN_UNIONALL_DIFFS(526, "42903", "SELECT column types differ in a Union All query is not allowed."),
+ 
+      /**
+       * Row timestamp column related errors
+       */
+      ROWTIMESTAMP_ONE_PK_COL_ONLY(527, "42904", "Only one column that is part of the primary key can be declared as a ROW_TIMESTAMP."),
+      ROWTIMESTAMP_PK_COL_ONLY(528, "42905", "Only columns part of the primary key can be declared as a ROW_TIMESTAMP."),
+      ROWTIMESTAMP_CREATE_ONLY(529, "42906", "A column can be added as ROW_TIMESTAMP only in CREATE TABLE."),
+      ROWTIMESTAMP_COL_INVALID_TYPE(530, "42907", "A column can be added as ROW_TIMESTAMP only if it is of type DATE, BIGINT, TIME OR TIMESTAMP."),
+      ROWTIMESTAMP_NOT_ALLOWED_ON_VIEW(531, "42908", "Declaring a column as row_timestamp is not allowed for views."),
+      INVALID_SCN(532, "42909", "Value of SCN cannot be less than zero."),
+      INVALID_REPLAY_AT(533, "42910", "Value of REPLAY_AT cannot be less than zero."),
+      UNEQUAL_SCN_AND_BUILD_INDEX_AT(534, "42911", "If both specified, values of CURRENT_SCN and BUILD_INDEX_AT must be equal."),
+      ONLY_INDEX_UPDATABLE_AT_SCN(535, "42912", "Only an index may be updated when the BUILD_INDEX_AT property is specified"),
+      PARENT_TABLE_NOT_FOUND(536, "42913", "Can't drop the index because the parent table in the DROP statement is incorrect."),
+     CANNOT_QUERY_TABLE_WITH_SCN_OLDER_THAN_MAX_LOOKBACK_AGE(538, "42915",
+         "Cannot use SCN to look further back in the past beyond the configured max lookback age"),
+ 
+      /**
+      * HBase and Phoenix specific implementation defined sub-classes.
+      * Column family related exceptions.
+      *
+      * For the following exceptions, use errorcode 10.
+      */
+     SINGLE_PK_MAY_NOT_BE_NULL(1000, "42I00", "Single column primary key may not be NULL."),
+     COLUMN_FAMILY_NOT_FOUND(1001, "42I01", "Undefined column family.", new Factory() {
+         @Override
+         public SQLException newException(SQLExceptionInfo info) {
+             return new ColumnFamilyNotFoundException(info.getSchemaName(), info.getTableName(), info.getFamilyName());
+         }
+     }),
+     PROPERTIES_FOR_FAMILY(1002, "42I02","Properties may not be defined for an unused family name."),
+     // Primary/row key related exceptions.
+     PRIMARY_KEY_WITH_FAMILY_NAME(1003, "42J01", "Primary key columns must not have a family name."),
+     PRIMARY_KEY_OUT_OF_ORDER(1004, "42J02", "Order of columns in primary key constraint must match the order in which they're declared."),
+     VARBINARY_IN_ROW_KEY(1005, "42J03", "The VARBINARY/ARRAY type can only be used as the last part of a multi-part row key."),
+     NOT_NULLABLE_COLUMN_IN_ROW_KEY(1006, "42J04", "Only nullable columns may be added to primary key."),
+     VARBINARY_LAST_PK(1015, "42J04", "Cannot add column to table when the last PK column is of type VARBINARY or ARRAY."),
+     NULLABLE_FIXED_WIDTH_LAST_PK(1023, "42J04", "Cannot add column to table when the last PK column is nullable and fixed width."),
+     CANNOT_MODIFY_VIEW_PK(1036, "42J04", "Cannot modify the primary key of a VIEW if last PK column of parent is variable length."),
+     BASE_TABLE_COLUMN(1037, "42J04", "Cannot modify columns of base table used by tenant-specific tables."),
+     UNALLOWED_COLUMN_FAMILY(1090, "42J04", "Column family names should not contain local index column prefix: "+QueryConstants.LOCAL_INDEX_COLUMN_FAMILY_PREFIX),
+     // Key/value column related errors
+     KEY_VALUE_NOT_NULL(1007, "42K01", "A non primary key column may only be declared as not null on tables with immutable rows."),
+     // View related errors.
+     VIEW_WITH_TABLE_CONFIG(1008, "42L01", "A view may not contain table configuration properties."),
+     VIEW_WITH_PROPERTIES(1009, "42L02", "Properties may not be defined for a view."),
+     // Table related errors that are not in standard code.
+     CANNOT_MUTATE_TABLE(1010, "42M01", "Not allowed to mutate table."),
+     UNEXPECTED_MUTATION_CODE(1011, "42M02", "Unexpected mutation code."),
+     TABLE_UNDEFINED(1012, "42M03", "Table undefined.", new Factory() {
+         @Override
+         public SQLException newException(SQLExceptionInfo info) {
+             return new TableNotFoundException(info.getSchemaName(), info.getTableName());
+         }
+     }),
+     INDEX_UNDEFINED(1042, "42M06", "Index undefined.", new Factory() {
+         @Override
+         public SQLException newException(SQLExceptionInfo info) {
+             return new IndexNotFoundException(info.getSchemaName(), info.getTableName());
+         }
+     }),
+     TABLE_ALREADY_EXIST(1013, "42M04", "Table already exists.", new Factory() {
+         @Override
+         public SQLException newException(SQLExceptionInfo info) {
+             return new TableAlreadyExistsException(info.getSchemaName(), info.getTableName());
+         }
+     }),
+     TABLES_NOT_IN_SYNC(1140, "42M05", "Tables not in sync for some properties."),
+ 
+     // High Availability Errors
+     HA_CLOSED_AFTER_FAILOVER(1984, "F1Q84", "Connection closed after failover happened.",
+         i -> new FailoverSQLException(i.getMessage(), i.getHaGroupInfo(), i.getRootCause())),
+     HA_NO_ACTIVE_CLUSTER(1985, "F1Q85", "No ACTIVE HBase cluster found.",
+         i -> new FailoverSQLException(i.getMessage(), i.getHaGroupInfo(), i.getRootCause())),
+     HA_READ_FROM_CLUSTER_FAILED_ON_NULL(1986, "F1Q86", "Unable to read from cluster for null."),
+     HA_INVALID_PROPERTIES(1987, "F1Q87", "Invalid properties to get a Phoenix HA connection."),
+     HA_CLUSTER_CAN_NOT_CONNECT(1988, "F1Q88", "Cluster can not serve any requests for this HA group"),
+ 
+ 
+     // Syntax error
+     TYPE_NOT_SUPPORTED_FOR_OPERATOR(1014, "42Y01", "The operator does not support the operand type."),
+     AGGREGATE_IN_GROUP_BY(1016, "42Y26", "Aggregate expressions may not be used in GROUP BY."),
+     AGGREGATE_IN_WHERE(1017, "42Y26", "Aggregate may not be used in WHERE."),
+     AGGREGATE_WITH_NOT_GROUP_BY_COLUMN(1018, "42Y27", "Aggregate may not contain columns not in GROUP BY."),
+     ONLY_AGGREGATE_IN_HAVING_CLAUSE(1019, "42Y26", "Only aggregate maybe used in the HAVING clause."),
+     UPSERT_COLUMN_NUMBERS_MISMATCH(1020, "42Y60", "Number of columns upserting must match number of values."),
+     // Table properties exception.
+     INVALID_BUCKET_NUM(1021, "42Y80", "Salt bucket numbers should be with 1 and 256."),
+     NO_SPLITS_ON_SALTED_TABLE(1022, "42Y81", "Should not specify split points on salted table with default row key order."),
+     SALT_ONLY_ON_CREATE_TABLE(1024, "42Y82", "Salt bucket number may only be specified when creating a table."),
+     NO_NORMALIZER_ON_SALTED_TABLE(1147, "42Y86", "Should not enable normalizer on salted table."),
+     SET_UNSUPPORTED_PROP_ON_ALTER_TABLE(1025, "42Y83", "Unsupported property set in ALTER TABLE command."),
+     CANNOT_ADD_NOT_NULLABLE_COLUMN(1038, "42Y84", "Only nullable columns may be added for a pre-existing table."),
+     NO_MUTABLE_INDEXES(1026, "42Y85", "Mutable secondary indexes are only supported for HBase version " + MetaDataUtil.decodeHBaseVersionAsString(MetaDataProtocol.MUTABLE_SI_VERSION_THRESHOLD) + " and above."),
+     INVALID_INDEX_STATE_TRANSITION(1028, "42Y87", "Invalid index state transition."),
+     INVALID_MUTABLE_INDEX_CONFIG(1029, "42Y88", "Mutable secondary indexes must have the "
+             + IndexManagementUtil.WAL_EDIT_CODEC_CLASS_KEY + " property set to "
+             + IndexManagementUtil.INDEX_WAL_EDIT_CODEC_CLASS_NAME + " in the hbase-sites.xml of every region server."),
+     CANNOT_CREATE_DEFAULT(1031, "42Y90", "Cannot create column with a stateful default value."),
+     CANNOT_CREATE_DEFAULT_ROWTIMESTAMP(1032, "42Y90", "Cannot create ROW_TIMESTAMP column with a default value."),
+ 
+     CANNOT_CREATE_TENANT_SPECIFIC_TABLE(1030, "42Y89", "Cannot create table for tenant-specific connection."),
+     DEFAULT_COLUMN_FAMILY_ONLY_ON_CREATE_TABLE(1034, "42Y93", "Default column family may only be specified when creating a table."),
+     INSUFFICIENT_MULTI_TENANT_COLUMNS(1040, "42Y96", "A MULTI_TENANT table must have two or more PK columns with the first column being NOT NULL."),
+     TENANTID_IS_OF_WRONG_TYPE(1041, "42Y97", "The TenantId could not be converted to correct format for this table."),
+     VIEW_WHERE_IS_CONSTANT(1045, "43A02", "WHERE clause in VIEW should not evaluate to a constant."),
+     CANNOT_UPDATE_VIEW_COLUMN(1046, "43A03", "Column updated in VIEW may not differ from value specified in WHERE clause."),
+     TOO_MANY_INDEXES(1047, "43A04", "Too many indexes have already been created on the physical table."),
+     NO_LOCAL_INDEX_ON_TABLE_WITH_IMMUTABLE_ROWS(1048,"43A05","Local indexes aren't allowed on tables with immutable rows."),
+     COLUMN_FAMILY_NOT_ALLOWED_TABLE_PROPERTY(1049, "43A06", "Column family not allowed for table properties."),
+     COLUMN_FAMILY_NOT_ALLOWED_FOR_PROPERTY(1050, "43A07", "Setting  or altering any of the following properties: "
+             + MetaDataUtil.SYNCED_DATA_TABLE_AND_INDEX_COL_FAM_PROPERTIES.toString()
+             + " for a column family is not supported since they must be kept in sync. You can only set these properties for the entire table."),
+     CANNOT_ALTER_PROPERTY(1051, "43A08", "Property can be specified or changed only when creating a table."),
+     CANNOT_SET_PROPERTY_FOR_COLUMN_NOT_ADDED(1052, "43A09", "Property cannot be specified for a column family that is not being added or modified."),
+     CANNOT_SET_TABLE_PROPERTY_ADD_COLUMN(1053, "43A10", "Table level property cannot be set when adding a column."),
+ 
+     NO_LOCAL_INDEXES(1054, "43A11", "Local secondary indexes are not supported for HBase versions " +
+         MetaDataUtil.decodeHBaseVersionAsString(MetaDataProtocol.MIN_LOCAL_SI_VERSION_DISALLOW) + " through " + MetaDataUtil.decodeHBaseVersionAsString(MetaDataProtocol.MAX_LOCAL_SI_VERSION_DISALLOW) + " inclusive."),
+     UNALLOWED_LOCAL_INDEXES(1055, "43A12", "Local secondary indexes are configured to not be allowed."),
+     
+     DESC_VARBINARY_NOT_SUPPORTED(1056, "43A13", "Descending VARBINARY columns not supported."),
+     NO_TABLE_SPECIFIED_FOR_WILDCARD_SELECT(1057, "42Y10", "No table specified for wildcard select."),
+     UNSUPPORTED_GROUP_BY_EXPRESSIONS(1058, "43A14", "Only a single VARBINARY, ARRAY, or nullable BINARY type may be referenced in a GROUP BY."),
+     
+     DEFAULT_COLUMN_FAMILY_ON_SHARED_TABLE(1069, "43A69", "Default column family not allowed on VIEW or shared INDEX."),
+     ONLY_TABLE_MAY_BE_DECLARED_TRANSACTIONAL(1070, "44A01", "Only tables may be declared as transactional."),
+     TX_MAY_NOT_SWITCH_TO_NON_TX(1071, "44A02", "A transactional table may not be switched to non transactional."),
+ 	STORE_NULLS_MUST_BE_TRUE_FOR_TRANSACTIONAL(1072, "44A03", "Store nulls must be true when a table is transactional."),
+     CANNOT_START_TRANSACTION_WITH_SCN_SET(1073, "44A04", "Cannot start a transaction on a connection with SCN set."),
+     TX_MAX_VERSIONS_MUST_BE_GREATER_THAN_ONE(1074, "44A05", "A transactional table must define VERSION of greater than one."),
+     CANNOT_SPECIFY_SCN_FOR_TXN_TABLE(1075, "44A06", "Cannot use a connection with SCN set for a transactional table."),
+     NULL_TRANSACTION_CONTEXT(1076, "44A07", "No Transaction Context available."),
+     TRANSACTION_FAILED(1077, "44A08", "Transaction Failure "),
+     CANNOT_CREATE_TXN_TABLE_IF_TXNS_DISABLED(1078, "44A09", "Cannot create a transactional table if transactions are disabled."),
+     CANNOT_ALTER_TO_BE_TXN_IF_TXNS_DISABLED(1079, "44A10", "Cannot alter table to be transactional table if transactions are disabled."),
+     CANNOT_CREATE_TXN_TABLE_WITH_ROW_TIMESTAMP(1080, "44A11", "Cannot create a transactional" +
+             " table with ROW_TIMESTAMP column."),
+     CANNOT_ALTER_TO_BE_TXN_WITH_ROW_TIMESTAMP(1081, "44A12", "Cannot alter table to be transactional table if transactions are disabled."),
+     TX_MUST_BE_ENABLED_TO_SET_TX_CONTEXT(1082, "44A13", "Cannot set transaction context if transactions are disabled."),
+     TX_MUST_BE_ENABLED_TO_SET_AUTO_FLUSH(1083, "44A14", "Cannot set auto flush if transactions are disabled."),
+     TX_MUST_BE_ENABLED_TO_SET_ISOLATION_LEVEL(1084, "44A15", "Cannot set isolation level to TRANSACTION_REPEATABLE_READ if transactions are disabled."),
+     TX_UNABLE_TO_GET_WRITE_FENCE(1085, "44A16", "Unable to obtain write fence for DDL operation."),
+     
+     SEQUENCE_NOT_CASTABLE_TO_AUTO_PARTITION_ID_COLUMN(1086, "44A17", "Sequence Value not castable to auto-partition id column"),
+     CANNOT_COERCE_AUTO_PARTITION_ID(1087, "44A18", "Auto-partition id cannot be coerced"),
+     CANNOT_CREATE_INDEX_ON_MUTABLE_TABLE_WITH_ROWTIMESTAMP(1088, "44A19", "Cannot create an index on a mutable table that has a ROW_TIMESTAMP column."),
+     UNKNOWN_TRANSACTION_PROVIDER(1089,"44A20", "Unknown TRANSACTION_PROVIDER: "),
+     CANNOT_START_TXN_IF_TXN_DISABLED(1091, "44A22", "Cannot start transaction if transactions are disabled."),
+     CANNOT_MIX_TXN_PROVIDERS(1092, "44A23", "Cannot mix transaction providers: "),
+     CANNOT_ALTER_TABLE_FROM_NON_TXN_TO_TXNL(1093, "44A24", "Cannot alter table from non transactional to transactional for "),
+     UNSUPPORTED_COLUMN_ENCODING_FOR_TXN_PROVIDER(1094, "44A25", "Column encoding is not supported for"),
+     UNSUPPORTED_STORAGE_FORMAT_FOR_TXN_PROVIDER(1095, "44A26", "Only ONE_CELL_PER_COLUMN storage scheme is supported for"),
+     CANNOT_SWITCH_TXN_PROVIDERS(1096, "44A27", "Cannot switch transaction providers."),
+     TTL_UNSUPPORTED_FOR_TXN_TABLE(10947, "44A28", "TTL is not supported for"),
+     CANNOT_CREATE_LOCAL_INDEX_FOR_TXN_TABLE(10948, "44A29", "Local indexes cannot be created for"),
+     CANNOT_SET_OR_ALTER_PROPERTY_FOR_INDEX(10949, "44A30", "Cannot set or alter the following properties on an index: "
+             + MetaDataUtil.SYNCED_DATA_TABLE_AND_INDEX_COL_FAM_PROPERTIES.toString()),
+     CANNOT_SET_OR_ALTER_UPDATE_CACHE_FREQ_FOR_INDEX(10950, "44A31", "Cannot set or alter "
+             + PhoenixDatabaseMetaData.UPDATE_CACHE_FREQUENCY + " on an index"),
+     PHOENIX_TTL_SUPPORTED_FOR_VIEWS_ONLY(10951, "44A32", PhoenixDatabaseMetaData.PHOENIX_TTL
+             + " property can only be set for views"),
+     CANNOT_SET_OR_ALTER_PHOENIX_TTL_FOR_TABLE_WITH_TTL(10952, "44A33", "Cannot set or alter "
+             + PhoenixDatabaseMetaData.PHOENIX_TTL + " property on an table with TTL,"),
+     ABOVE_INDEX_NON_ASYNC_THRESHOLD(1097, "44A34", "The estimated read size for index creation "
+             + "is higher than " + QueryServices.CLIENT_INDEX_ASYNC_THRESHOLD+ ". You can edit the"
+             + " limit or create ASYNC index."),
+     CANNOT_SET_OR_ALTER_PHOENIX_TTL(10953, "44A35", "Cannot set or alter "
+             + PhoenixDatabaseMetaData.PHOENIX_TTL + " property on an view when parent/child view has PHOENIX_TTL set,"),
+     CHANGE_DETECTION_SUPPORTED_FOR_TABLES_AND_VIEWS_ONLY(10954, "44A36",
+         CHANGE_DETECTION_ENABLED + " is only supported on tables and views"),
+     CANNOT_CREATE_INDEX_CHILD_VIEWS_EXTEND_PK(10955, "44A37", "Index can be created "
+             + "only if none of the child views extends primary key"),
+     VIEW_CANNOT_EXTEND_PK_WITH_PARENT_INDEXES(10956, "44A38", "View can extend parent primary key"
+             + " only if none of the parents have indexes in the parent hierarchy"),
+ 
+     /** Sequence related */
+     SEQUENCE_ALREADY_EXIST(1200, "42Z00", "Sequence already exists.", new Factory() {
+         @Override
+         public SQLException newException(SQLExceptionInfo info) {
+             return new SequenceAlreadyExistsException(info.getSchemaName(), info.getTableName());
+         }
+     }),
+     SEQUENCE_UNDEFINED(1201, "42Z01", "Sequence undefined.", new Factory() {
+         @Override
+         public SQLException newException(SQLExceptionInfo info) {
+             return new SequenceNotFoundException(info.getSchemaName(), info.getTableName());
+         }
+     }),
+     START_WITH_MUST_BE_CONSTANT(1202, "42Z02", "Sequence START WITH value must be an integer or long constant."),
+     INCREMENT_BY_MUST_BE_CONSTANT(1203, "42Z03", "Sequence INCREMENT BY value must be an integer or long constant."),
+     CACHE_MUST_BE_NON_NEGATIVE_CONSTANT(1204, "42Z04", "Sequence CACHE value must be a non negative integer constant."),
+     INVALID_USE_OF_NEXT_VALUE_FOR(1205, "42Z05", "NEXT VALUE FOR may only be used as in a SELECT or an UPSERT VALUES expression."),
+     CANNOT_CALL_CURRENT_BEFORE_NEXT_VALUE(1206, "42Z06", "NEXT VALUE FOR must be called before CURRENT VALUE FOR is called."),
+     EMPTY_SEQUENCE_CACHE(1207, "42Z07", "No more cached sequence values."),
+     MINVALUE_MUST_BE_CONSTANT(1208, "42Z08", "Sequence MINVALUE must be an integer or long constant."),
+     MAXVALUE_MUST_BE_CONSTANT(1209, "42Z09", "Sequence MAXVALUE must be an integer or long constant."),
+     MINVALUE_MUST_BE_LESS_THAN_OR_EQUAL_TO_MAXVALUE(1210, "42Z10", "Sequence MINVALUE must be less than or equal to MAXVALUE."),
+     STARTS_WITH_MUST_BE_BETWEEN_MIN_MAX_VALUE(1211, "42Z11",
+             "STARTS WITH value must be greater than or equal to MINVALUE and less than or equal to MAXVALUE."),
+     SEQUENCE_VAL_REACHED_MAX_VALUE(1212, "42Z12", "Reached MAXVALUE of sequence."),
+     SEQUENCE_VAL_REACHED_MIN_VALUE(1213, "42Z13", "Reached MINVALUE of sequence."),
+     INCREMENT_BY_MUST_NOT_BE_ZERO(1214, "42Z14", "Sequence INCREMENT BY value cannot be zero."),
+     NUM_SEQ_TO_ALLOCATE_MUST_BE_CONSTANT(1215, "42Z15", "Sequence NEXT n VALUES FOR must be a positive integer or constant." ),
+     NUM_SEQ_TO_ALLOCATE_NOT_SUPPORTED(1216, "42Z16", "Sequence NEXT n VALUES FOR is not supported for Sequences with the CYCLE flag." ),
+     AUTO_PARTITION_SEQUENCE_UNDEFINED(1217, "42Z17", "Auto Partition Sequence undefined", new Factory() {
+         @Override
+         public SQLException newException(SQLExceptionInfo info) {
+             return new SequenceNotFoundException(info.getSchemaName(), info.getTableName());
+         }
+     }),
+     CANNOT_UPDATE_PK_ON_DUP_KEY(1218, "42Z18", "Primary key columns may not be udpated in ON DUPLICATE KEY UPDATE clause." ),
+     CANNOT_USE_ON_DUP_KEY_FOR_IMMUTABLE(1219, "42Z19", "The ON DUPLICATE KEY UPDATE clause may not be used for immutable tables." ),
+     CANNOT_USE_ON_DUP_KEY_FOR_TRANSACTIONAL(1220, "42Z20", "The ON DUPLICATE KEY UPDATE clause may not be used for transactional tables." ),
+     DUPLICATE_COLUMN_IN_ON_DUP_KEY(1221, "42Z21", "Duplicate column in ON DUPLICATE KEY UPDATE." ),
+     AGGREGATION_NOT_ALLOWED_IN_ON_DUP_KEY(1222, "42Z22", "Aggregation in ON DUPLICATE KEY UPDATE is not allowed." ),
+     CANNOT_SET_SCN_IN_ON_DUP_KEY(1223, "42Z23", "The CURRENT_SCN may not be set for statement using ON DUPLICATE KEY." ),
+     CANNOT_USE_ON_DUP_KEY_WITH_GLOBAL_IDX(1224, "42Z24", "The ON DUPLICATE KEY clause may not be used when a table has a global index." ),
+ 
+     /** Parser error. (errorcode 06, sqlState 42P) */
+     PARSER_ERROR(601, "42P00", "Syntax error.", Factory.SYNTAX_ERROR),
+     MISSING_TOKEN(602, "42P00", "Syntax error.", Factory.SYNTAX_ERROR),
+     UNWANTED_TOKEN(603, "42P00", "Syntax error.", Factory.SYNTAX_ERROR),
+     MISMATCHED_TOKEN(604, "42P00", "Syntax error.", Factory.SYNTAX_ERROR),
+     UNKNOWN_FUNCTION(605, "42P00", "Syntax error.", Factory.SYNTAX_ERROR),
+ 
+     /**
+      * Implementation defined class. Execution exceptions (errorcode 11, sqlstate XCL).
+      */
+     RESULTSET_CLOSED(1101, "XCL01", "ResultSet is closed."),
+     GET_TABLE_REGIONS_FAIL(1102, "XCL02", "Cannot get all table regions."),
+     EXECUTE_QUERY_NOT_APPLICABLE(1103, "XCL03", "executeQuery may not be used."),
+     EXECUTE_UPDATE_NOT_APPLICABLE(1104, "XCL04", "executeUpdate may not be used."),
+     SPLIT_POINT_NOT_CONSTANT(1105, "XCL05", "Split points must be constants."),
+     BATCH_EXCEPTION(1106, "XCL06", "Exception while executing batch."),
+     EXECUTE_UPDATE_WITH_NON_EMPTY_BATCH(1107, "XCL07", "An executeUpdate is prohibited when the batch is not empty. Use clearBatch to empty the batch first."),
+     STALE_REGION_BOUNDARY_CACHE(1108, "XCL08", "Cache of region boundaries are out of date.", new Factory() {
+         @Override
+         public SQLException newException(SQLExceptionInfo info) {
+             return new StaleRegionBoundaryCacheException(info.getSchemaName(), info.getTableName());
+         }
+     }),
+     CANNOT_SPLIT_LOCAL_INDEX(1109,"XCL09", "Local index may not be pre-split."),
+     CANNOT_SALT_LOCAL_INDEX(1110,"XCL10", "Local index may not be salted."),
+     CONNECTION_CLOSED(1111, "XCL11", "Connectioin is closed."),
+ 
+     INDEX_FAILURE_BLOCK_WRITE(1120, "XCL20", "Writes to table blocked until index can be updated."),
+     INDEX_WRITE_FAILURE(1121, "XCL21", "Write to the index failed."),
+     
+     UPDATE_CACHE_FREQUENCY_INVALID(1130, "XCL30", "UPDATE_CACHE_FREQUENCY cannot be set to ALWAYS if APPEND_ONLY_SCHEMA is true."),
+     CANNOT_DROP_COL_APPEND_ONLY_SCHEMA(1131, "XCL31", "Cannot drop column from table that with append only schema."),
+     CANNOT_DROP_VIEW_REFERENCED_COL(1132, "XCL32", "Cannot drop column that is referenced in view where clause."),
+     
+     CANNOT_ALTER_IMMUTABLE_ROWS_PROPERTY(1133, "XCL33", "IMMUTABLE_ROWS property can be changed only if the table storage scheme is ONE_CELL_PER_KEYVALUE_COLUMN"),
+     CANNOT_ALTER_TABLE_PROPERTY_ON_VIEW(1134, "XCL34", "Altering this table property on a view is not allowed"),
+     
+     IMMUTABLE_TABLE_PROPERTY_INVALID(1135, "XCL35", "IMMUTABLE table property cannot be used with CREATE IMMUTABLE TABLE statement "),
+     
+     MAX_COLUMNS_EXCEEDED(1136, "XCL36", "The number of columns exceed the maximum supported by the table's qualifier encoding scheme"),
+     INVALID_IMMUTABLE_STORAGE_SCHEME_AND_COLUMN_QUALIFIER_BYTES(1137, "XCL37", "If IMMUTABLE_STORAGE_SCHEME property is not set to ONE_CELL_PER_COLUMN COLUMN_ENCODED_BYTES cannot be 0"),
+     INVALID_IMMUTABLE_STORAGE_SCHEME_CHANGE(1138, "XCL38", "IMMUTABLE_STORAGE_SCHEME property cannot be changed from/to ONE_CELL_PER_COLUMN "),
+     CANNOT_SET_GUIDE_POST_WIDTH(1139, "XCL39", "Guide post width can only be set on base data tables"),
+     CANNOT_CREATE_VIEWS_ON_SYSTEM_TABLES(1141, "XCL41", "Cannot create views on tables of type" +
+             PTableType.SYSTEM),
+     UNABLE_TO_CREATE_CHILD_LINK(1142, "XCL42", "Error creating parent-child link (Link type=" +
+             PTable.LinkType.CHILD_TABLE + ") for view"),
+     UNABLE_TO_UPDATE_PARENT_TABLE(1143, "XCL43", "Error Updating the parent table"),
+     UNABLE_TO_DELETE_CHILD_LINK(1144, "XCL44", "Error deleting parent-child link (Link type=" +
+             PTable.LinkType.CHILD_TABLE + ") for view"),
+     TABLE_NOT_IN_REGION(1145, "XCL45", "No modifications allowed on this table. "
+     + "Table not in this region."),
+     UNABLE_TO_UPSERT_TASK(1146, "XCL46",
+         "Error upserting records in SYSTEM.TASK table"),
+     INVALID_CQ(1148, "XCL48",
+             "ENCODED_QUALIFIER is less than INITIAL_VALUE."),
+     DUPLICATE_CQ(1149, "XCL49",
+             "Duplicate ENCODED_QUALIFIER."),
+     MISSING_CQ(1150, "XCL49",
+             "Missing ENCODED_QUALIFIER."),
+     EXECUTE_BATCH_FOR_STMT_WITH_RESULT_SET(1151, "XCL51", "A batch operation can't include a "
+             + "statement that produces result sets.", Factory.BATCH_UPDATE_ERROR),
+ 
+ 
+     /**
+      * Implementation defined class. Phoenix internal error. (errorcode 20, sqlstate INT).
+      */
+     CANNOT_CALL_METHOD_ON_TYPE(2001, "INT01", "Cannot call method on the argument type."),
+     CLASS_NOT_UNWRAPPABLE(2002, "INT03", "Class not unwrappable."),
+     PARAM_INDEX_OUT_OF_BOUND(2003, "INT04", "Parameter position is out of range."),
+     PARAM_VALUE_UNBOUND(2004, "INT05", "Parameter value unbound."),
+     INTERRUPTED_EXCEPTION(2005, "INT07", "Interrupted exception."),
+     INCOMPATIBLE_CLIENT_SERVER_JAR(2006, "INT08", "Incompatible jars detected between client and server."),
+     OUTDATED_JARS(2007, "INT09", "Outdated jars."),
+     INDEX_METADATA_NOT_FOUND(2008, "INT10", "Unable to find cached index metadata. "),
+     UNKNOWN_ERROR_CODE(2009, "INT11", "Unknown error code."),
+     CONCURRENT_UPGRADE_IN_PROGRESS(2010, "INT12", ""),
+     UPGRADE_REQUIRED(2011, "INT13", ""),
+     UPGRADE_NOT_REQUIRED(2012, "INT14", ""),
+     GET_TABLE_ERROR(2013, "INT15", "MetadataEndpointImpl doGetTable called for table not present " +
+             "on region"),
+     ROW_VALUE_CONSTRUCTOR_OFFSET_NOT_COERCIBLE(2014, "INT16", "Row Value Constructor Offset Not Coercible to a Primary or Indexed RowKey."),
+     ROW_VALUE_CONSTRUCTOR_OFFSET_INTERNAL_ERROR(2015, "INT17", "Row Value Constructor Offset had an Unexpected Error."),
+     ROW_VALUE_CONSTRUCTOR_OFFSET_NOT_ALLOWED_IN_QUERY(2016, "INT18", "Row Value Constructor Offset Not Allowed In Query."),
+ 
+     OPERATION_TIMED_OUT(6000, "TIM01", "Operation timed out.", new Factory() {
+         @Override
+         public SQLException newException(SQLExceptionInfo info) {
+             final String reason = info.getMessage() != null
+                 ? info.getMessage() : OPERATION_TIMED_OUT.getMessage();
+             return new SQLTimeoutException(reason,
+                 OPERATION_TIMED_OUT.getSQLState(),
+                 OPERATION_TIMED_OUT.getErrorCode(),
+                 info.getRootCause());
+         }
+     }),
+     FUNCTION_UNDEFINED(6001, "42F01", "Function undefined.", new Factory() {
+         @Override
+         public SQLException newException(SQLExceptionInfo info) {
+             return new FunctionNotFoundException(info.getFunctionName());
+         }
+     }),
+     FUNCTION_ALREADY_EXIST(6002, "42F02", "Function already exists.", new Factory() {
+         @Override
+         public SQLException newException(SQLExceptionInfo info) {
+             return new FunctionAlreadyExistsException(info.getSchemaName(), info.getTableName());
+         }
+     }),
+     UNALLOWED_USER_DEFINED_FUNCTIONS(6003, "42F03",
+             "User defined functions are configured to not be allowed. To allow configure "
+                     + QueryServices.ALLOW_USER_DEFINED_FUNCTIONS_ATTRIB + " to true."), 
+ 
+     SCHEMA_ALREADY_EXISTS(721, "42M04", "Schema with given name already exists", new Factory() {
+         @Override
+         public SQLException newException(SQLExceptionInfo info) {
+             return new SchemaAlreadyExistsException(info.getSchemaName());
+         }
+     }),
+     SCHEMA_NOT_FOUND(722, "43M05", "Schema does not exist", new Factory() {
+         @Override
+         public SQLException newException(SQLExceptionInfo info) {
+             return new SchemaNotFoundException(info.getSchemaName());
+         }
+     }),
+     CANNOT_MUTATE_SCHEMA(723, "43M06", "Cannot mutate schema as schema has existing tables"),
+     SCHEMA_NOT_ALLOWED(724, "43M07", "Schema name not allowed!!"),
+     CREATE_SCHEMA_NOT_ALLOWED(725, "43M08", "Cannot create schema because config "
+             + QueryServices.IS_NAMESPACE_MAPPING_ENABLED + " for enabling name space mapping isn't enabled."),
+     INCONSISTENT_NAMESPACE_MAPPING_PROPERTIES(726, "43M10", " Inconsistent namespace mapping properties."),
+     ASYNC_NOT_ALLOWED(727, "43M11", " ASYNC option is not allowed."),
+     NEW_CONNECTION_THROTTLED(728, "410M1", "Could not create connection " +
+         "because this client already has the maximum number" +
+         " of connections to the target cluster."),
+     MAX_MUTATION_SIZE_EXCEEDED(729, "LIM01", "MutationState size is bigger" +
+             " than maximum allowed number of rows, try upserting rows in smaller batches or " +
+             "using autocommit on for deletes.", new Factory() {
+         @Override
+         public SQLException newException(SQLExceptionInfo info) {
+             return new MaxMutationSizeExceededException(
+                     info.getMaxMutationSize(), info.getMutationSize());
+         }
+     }),
+     MAX_MUTATION_SIZE_BYTES_EXCEEDED(730, "LIM02", "MutationState size is " +
+             "bigger than maximum allowed number of bytes, try upserting rows in smaller batches " +
+             "or using autocommit on for deletes.", new Factory() {
+         @Override
+         public SQLException newException(SQLExceptionInfo info) {
+             return new MaxMutationSizeBytesExceededException(info.getMaxMutationSizeBytes(),
+                     info.getMutationSizeBytes());
+         }
+     }),
+     NEW_INTERNAL_CONNECTION_THROTTLED(731, "410M1", "Could not create connection " +
+             "because the internal connections already has the maximum number" +
+             " of connections to the target cluster."),
+     MAX_HBASE_CLIENT_KEYVALUE_MAXSIZE_EXCEEDED(732,
+             "LIM03", "The Phoenix Column size is bigger than maximum " +
+             "HBase client key value allowed size for ONE_CELL_PER_COLUMN table, " +
+             "try upserting column in smaller value", new Factory() {
+         @Override
+         public SQLException newException(SQLExceptionInfo info) {
+             return new MaxPhoenixColumnSizeExceededException(info.getMessage(), info.getMaxPhoenixColumnSizeBytes(),
+                     info.getPhoenixColumnSizeBytes());
+         }
+     }),
+     INSUFFICIENT_MEMORY(999, "50M01", "Unable to allocate enough memory."),
+     HASH_JOIN_CACHE_NOT_FOUND(900, "HJ01", "Hash Join cache not found"),
+ 
+     STATS_COLLECTION_DISABLED_ON_SERVER(1401, "STS01", "Stats collection attempted but is disabled on server"),
+ 
+     CANNOT_UPSERT_WITH_SCN_FOR_ROW_TIMESTAMP_COLUMN(901,"43M12",
+             "Cannot use a connection with SCN set to upsert data for " +
+                     "table with ROW_TIMESTAMP column."),
+     CANNOT_UPSERT_WITH_SCN_FOR_TABLE_WITH_INDEXES(903,"43M14",
+             "Cannot use a connection with SCN set to upsert data for a table with indexes."),
+ 
+     CANNOT_PERFORM_DDL_WITH_PENDING_MUTATIONS(904, "43M15",
+             "Cannot perform DDL with pending mutations. Commit or rollback mutations before performing DDL"),
+ 
+     NOT_SUPPORTED_CASCADE_FEATURE_PK(905, "43M16", "CASCADE INDEX feature is not supported to add new PK column in INDEX"),
+ 
+     INCORRECT_INDEX_NAME(906, "43M17", "The list contains one or more incorrect index name(s)"),
+ 
+     NOT_SUPPORTED_CASCADE_FEATURE_LOCAL_INDEX(907, "43M18",
+         "CASCADE INDEX feature is not supported for local index"),
+ 
+     INVALID_REGION_SPLIT_POLICY(908, "43M19",
+         "REGION SPLIT POLICY is incorrect."),
+     ERROR_WRITING_TO_SCHEMA_REGISTRY(909, "4320",
+             "Error writing DDL change to external schema registry"),
+ 
+     CANNOT_TRANSFORM_ALREADY_TRANSFORMING_TABLE(910, "43M21",
+                                         "Cannot transform an index or a table who is already going through a transform."),
+ 
+     CANNOT_TRANSFORM_LOCAL_OR_VIEW_INDEX(911, "43M22", "Cannot transform a view index or a local index. For view index, consider creating a new view index."),
+ 
+     CANNOT_TRANSFORM_TABLE_WITH_LOCAL_INDEX(912, "43M23", "Cannot transform a table with a local index."),
+ 
+     CANNOT_TRANSFORM_TABLE_WITH_APPEND_ONLY_SCHEMA(913, "43M24", "Cannot transform a table with append-only schema."),
+ 
+     CANNOT_TRANSFORM_TRANSACTIONAL_TABLE(914, "43M25", "Cannot transform a transactional table."),
+ 
++    STALE_METADATA_CACHE_EXCEPTION(915, "43M26", "Stale metadata cache exception",
++        info -> new StaleMetadataCacheException(info.getMessage())),
++
+     //SQLCode for testing exceptions
+     FAILED_KNOWINGLY_FOR_TEST(7777, "TEST", "Exception was thrown to test something");
+ 
+     private final int errorCode;
+     private final String sqlState;
+     private final String message;
+     private final Factory factory;
+ 
+     private SQLExceptionCode(int errorCode, String sqlState, String message) {
+         this(errorCode, sqlState, message, Factory.DEFAULT);
+     }
+ 
+     private SQLExceptionCode(int errorCode, String sqlState, String message, Factory factory) {
+         this.errorCode = errorCode;
+         this.sqlState = sqlState;
+         this.message = message;
+         this.factory = factory;
+     }
+ 
+     public String getSQLState() {
+         return sqlState;
+     }
+ 
+     public String getMessage() {
+         return message;
+     }
+ 
+     public int getErrorCode() {
+         return errorCode;
+     }
+ 
+     @Override
+     public String toString() {
+         return "ERROR " + errorCode + " (" + sqlState + "): " + message;
+     }
+ 
+     public Factory getExceptionFactory() {
+         return factory;
+     }
+ 
+     public static interface Factory {
+         Factory DEFAULT = new Factory() {
+ 
+             @Override
+             public SQLException newException(SQLExceptionInfo info) {
+                 return new SQLException(info.toString(), info.getCode().getSQLState(),
+                         info.getCode().getErrorCode(), info.getRootCause());
+             }
+             
+         };
+         Factory SYNTAX_ERROR = new Factory() {
+ 
+             @Override
+             public SQLException newException(SQLExceptionInfo info) {
+                 return new PhoenixParserException(info.getMessage(), info.getRootCause());
+             }
+             
+         };
+         Factory BATCH_UPDATE_ERROR = new Factory() {
+ 
+             @Override
+             public SQLException newException(SQLExceptionInfo info) {
+                 return new BatchUpdateException(info.toString(), info.getCode().getSQLState(),
+                         info.getCode().getErrorCode(), (int[]) null, info.getRootCause());
+             }
+ 
+         };
+         SQLException newException(SQLExceptionInfo info);
+     }
+     
+     private static final Map<Integer,SQLExceptionCode> errorCodeMap = Maps.newHashMapWithExpectedSize(SQLExceptionCode.values().length);
+     static {
+         for (SQLExceptionCode code : SQLExceptionCode.values()) {
+             SQLExceptionCode otherCode = errorCodeMap.put(code.getErrorCode(), code);
+             if (otherCode != null) {
+                 throw new IllegalStateException("Duplicate error code for " + code + " and " + otherCode);
+             }
+         }
+     }
+     
+     public static SQLExceptionCode fromErrorCode(int errorCode) {
+         SQLExceptionCode code = errorCodeMap.get(errorCode);
+         if (code == null) {
+             return SQLExceptionCode.UNKNOWN_ERROR_CODE;
+         }
+         return code;
+     }
+ 
+ }
diff --cc phoenix-core-client/src/main/java/org/apache/phoenix/execute/MutationState.java
index 0000000000,834365452b..60df3a570f
mode 000000,100644..100644
--- a/phoenix-core-client/src/main/java/org/apache/phoenix/execute/MutationState.java
+++ b/phoenix-core-client/src/main/java/org/apache/phoenix/execute/MutationState.java
@@@ -1,0 -1,2274 +1,2309 @@@
+ /*
+  * 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 static org.apache.phoenix.monitoring.MetricType.DELETE_AGGREGATE_FAILURE_SQL_COUNTER;
+ import static org.apache.phoenix.monitoring.MetricType.DELETE_AGGREGATE_SUCCESS_SQL_COUNTER;
+ import static org.apache.phoenix.monitoring.MetricType.UPSERT_AGGREGATE_FAILURE_SQL_COUNTER;
+ import static org.apache.phoenix.monitoring.MetricType.UPSERT_AGGREGATE_SUCCESS_SQL_COUNTER;
+ import static org.apache.phoenix.monitoring.MetricType.NUM_METADATA_LOOKUP_FAILURES;
+ import static org.apache.phoenix.query.QueryServices.SOURCE_OPERATION_ATTRIB;
+ import static org.apache.phoenix.thirdparty.com.google.common.base.Preconditions.checkNotNull;
+ import static org.apache.phoenix.monitoring.GlobalClientMetrics.GLOBAL_MUTATION_BATCH_FAILED_COUNT;
+ import static org.apache.phoenix.monitoring.GlobalClientMetrics.GLOBAL_MUTATION_BATCH_SIZE;
+ import static org.apache.phoenix.monitoring.GlobalClientMetrics.GLOBAL_MUTATION_BYTES;
+ import static org.apache.phoenix.monitoring.GlobalClientMetrics.GLOBAL_MUTATION_COMMIT_TIME;
+ import static org.apache.phoenix.monitoring.GlobalClientMetrics.GLOBAL_MUTATION_INDEX_COMMIT_FAILURE_COUNT;
+ import static org.apache.phoenix.monitoring.GlobalClientMetrics.GLOBAL_MUTATION_SYSCAT_TIME;
+ import static org.apache.phoenix.query.QueryServices.WILDCARD_QUERY_DYNAMIC_COLS_ATTRIB;
+ import static org.apache.phoenix.query.QueryServicesOptions.DEFAULT_WILDCARD_QUERY_DYNAMIC_COLS_ATTRIB;
+ 
+ import java.io.IOException;
+ import java.sql.SQLException;
+ import java.sql.Timestamp;
+ import java.util.ArrayList;
+ import java.util.Arrays;
+ import java.util.Collection;
+ import java.util.Collections;
+ import java.util.HashMap;
+ import java.util.Iterator;
+ import java.util.LinkedHashMap;
+ import java.util.List;
+ import java.util.Map;
+ import java.util.Map.Entry;
+ import java.util.Set;
+ 
+ import javax.annotation.Nonnull;
+ import javax.annotation.concurrent.Immutable;
+ 
+ import org.apache.hadoop.hbase.HConstants;
+ import org.apache.hadoop.hbase.TableName;
+ import org.apache.hadoop.hbase.client.Delete;
+ import org.apache.hadoop.hbase.client.Mutation;
+ import org.apache.hadoop.hbase.client.Put;
+ import org.apache.hadoop.hbase.client.Table;
+ import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
+ import org.apache.hadoop.hbase.util.Bytes;
+ import org.apache.hadoop.hbase.util.Pair;
+ import org.apache.htrace.Span;
+ import org.apache.htrace.TraceScope;
+ import org.apache.phoenix.cache.ServerCacheClient.ServerCache;
+ import org.apache.phoenix.compile.MutationPlan;
+ import org.apache.phoenix.coprocessorclient.BaseScannerRegionObserverConstants;
+ import org.apache.phoenix.coprocessorclient.MetaDataProtocol.MetaDataMutationResult;
+ import org.apache.phoenix.exception.SQLExceptionCode;
+ import org.apache.phoenix.exception.SQLExceptionInfo;
++import org.apache.phoenix.exception.StaleMetadataCacheException;
+ import org.apache.phoenix.hbase.index.exception.IndexWriteException;
+ import org.apache.phoenix.hbase.index.util.ImmutableBytesPtr;
+ import org.apache.phoenix.index.IndexMaintainer;
+ import org.apache.phoenix.index.IndexMetaDataCacheClient;
+ import org.apache.phoenix.index.PhoenixIndexBuilderHelper;
+ import org.apache.phoenix.index.PhoenixIndexFailurePolicyHelper;
+ import org.apache.phoenix.index.PhoenixIndexFailurePolicyHelper.MutateCommand;
+ import org.apache.phoenix.index.PhoenixIndexMetaData;
+ import org.apache.phoenix.jdbc.PhoenixConnection;
+ import org.apache.phoenix.jdbc.PhoenixStatement.Operation;
+ import org.apache.phoenix.monitoring.GlobalClientMetrics;
+ import org.apache.phoenix.monitoring.MutationMetricQueue;
+ import org.apache.phoenix.monitoring.MutationMetricQueue.MutationMetric;
+ import org.apache.phoenix.monitoring.MutationMetricQueue.NoOpMutationMetricsQueue;
+ import org.apache.phoenix.monitoring.ReadMetricQueue;
+ import org.apache.phoenix.monitoring.TableMetricsManager;
+ import org.apache.phoenix.query.QueryConstants;
+ import org.apache.phoenix.query.QueryServices;
+ import org.apache.phoenix.query.QueryServicesOptions;
+ import org.apache.phoenix.schema.IllegalDataException;
+ import org.apache.phoenix.schema.MaxMutationSizeBytesExceededException;
+ import org.apache.phoenix.schema.MaxMutationSizeExceededException;
+ import org.apache.phoenix.schema.MetaDataClient;
+ import org.apache.phoenix.schema.PColumn;
+ import org.apache.phoenix.schema.PIndexState;
+ import org.apache.phoenix.schema.PMetaData;
+ import org.apache.phoenix.schema.PName;
+ import org.apache.phoenix.schema.PRow;
+ import org.apache.phoenix.schema.PTable;
+ import org.apache.phoenix.schema.PTableRef;
+ import org.apache.phoenix.schema.PTableType;
+ import org.apache.phoenix.schema.RowKeySchema;
+ import org.apache.phoenix.schema.TableNotFoundException;
+ import org.apache.phoenix.schema.TableRef;
+ import org.apache.phoenix.schema.ValueSchema.Field;
+ import org.apache.phoenix.schema.types.PLong;
+ import org.apache.phoenix.schema.types.PTimestamp;
+ import org.apache.phoenix.thirdparty.com.google.common.base.Strings;
+ import org.apache.phoenix.trace.util.Tracing;
+ import org.apache.phoenix.transaction.PhoenixTransactionContext;
+ import org.apache.phoenix.transaction.PhoenixTransactionContext.PhoenixVisibilityLevel;
+ import org.apache.phoenix.transaction.TransactionFactory;
+ import org.apache.phoenix.transaction.TransactionFactory.Provider;
+ import org.apache.phoenix.util.ClientUtil;
+ import org.apache.phoenix.util.EncodedColumnsUtil;
+ import org.apache.phoenix.util.EnvironmentEdgeManager;
+ import org.apache.phoenix.util.IndexUtil;
+ import org.apache.phoenix.util.LogUtil;
+ import org.apache.phoenix.util.PhoenixKeyValueUtil;
+ import org.apache.phoenix.util.SQLCloseable;
+ import org.apache.phoenix.util.SchemaUtil;
+ import org.apache.phoenix.util.SizedUtil;
+ import org.apache.phoenix.util.TransactionUtil;
++import org.apache.phoenix.util.ValidateLastDDLTimestampUtil;
+ import org.apache.phoenix.util.WALAnnotationUtil;
+ import org.slf4j.Logger;
+ import org.slf4j.LoggerFactory;
+ 
+ import org.apache.phoenix.thirdparty.com.google.common.base.Preconditions;
+ import org.apache.phoenix.thirdparty.com.google.common.base.Predicate;
+ import org.apache.phoenix.thirdparty.com.google.common.collect.Iterators;
+ import org.apache.phoenix.thirdparty.com.google.common.collect.Lists;
+ import org.apache.phoenix.thirdparty.com.google.common.collect.Maps;
+ import org.apache.phoenix.thirdparty.com.google.common.collect.Sets;
+ 
+ /**
+  * Tracks the uncommitted state
+  */
+ public class MutationState implements SQLCloseable {
+     private static final Logger LOGGER = LoggerFactory.getLogger(MutationState.class);
+     private static final int[] EMPTY_STATEMENT_INDEX_ARRAY = new int[0];
+     private static final int MAX_COMMIT_RETRIES = 3;
+ 
+     private final PhoenixConnection connection;
+     private final int maxSize;
+     private final long maxSizeBytes;
+     private final long batchSize;
+     private final long batchSizeBytes;
+     private long batchCount = 0L;
+     // For each table, maintain a list of mutation batches. Each element in the
+     // list is a set of row mutations which can be sent in a single commit batch.
+     // A regular upsert and a conditional upsert on the same row conflict with
+     // each other so they are split and send separately in different commit batches.
+     private final Map<TableRef, List<MultiRowMutationState>> mutationsMap;
+     private final Set<String> uncommittedPhysicalNames = Sets.newHashSetWithExpectedSize(10);
+ 
+     private long sizeOffset;
+     private int numRows = 0;
+     private long estimatedSize = 0;
+     private int[] uncommittedStatementIndexes = EMPTY_STATEMENT_INDEX_ARRAY;
+     private boolean isExternalTxContext = false;
++    private boolean validateLastDdlTimestamp;
+     private Map<TableRef, List<MultiRowMutationState>> txMutations = Collections.emptyMap();
+ 
+     private PhoenixTransactionContext phoenixTransactionContext = PhoenixTransactionContext.NULL_CONTEXT;
+ 
+     private final MutationMetricQueue mutationMetricQueue;
+     private ReadMetricQueue readMetricQueue;
+ 
+     private Map<String, Long> timeInExecuteMutationMap = new HashMap<>();
+     private static boolean allUpsertsMutations = true;
+     private static boolean allDeletesMutations = true;
+ 
+     public static void resetAllMutationState(){
+         allDeletesMutations = true;
+         allUpsertsMutations = true;
+     }
+ 
+     public MutationState(int maxSize, long maxSizeBytes, PhoenixConnection connection) {
+         this(maxSize, maxSizeBytes, connection, false, null);
+     }
+ 
+     public MutationState(int maxSize, long maxSizeBytes, PhoenixConnection connection,
+            PhoenixTransactionContext txContext) {
+         this(maxSize, maxSizeBytes, connection, false, txContext);
+     }
+ 
+     public MutationState(MutationState mutationState) {
+         this(mutationState, mutationState.connection);
+     }
+ 
+     public MutationState(MutationState mutationState, PhoenixConnection connection) {
+         this(mutationState.maxSize, mutationState.maxSizeBytes, connection, true, mutationState
+                 .getPhoenixTransactionContext());
+     }
+ 
+     public MutationState(int maxSize, long maxSizeBytes, PhoenixConnection connection,
+            long sizeOffset) {
+         this(maxSize, maxSizeBytes, connection, false, null, sizeOffset);
+     }
+ 
+     private MutationState(int maxSize, long maxSizeBytes, PhoenixConnection connection,
+             boolean subTask, PhoenixTransactionContext txContext) {
+         this(maxSize, maxSizeBytes, connection, subTask, txContext, 0);
+     }
+ 
+     private MutationState(int maxSize, long maxSizeBytes, PhoenixConnection connection,
+             boolean subTask, PhoenixTransactionContext txContext, long sizeOffset) {
+         this(maxSize, maxSizeBytes, connection, Maps.<TableRef, List<MultiRowMutationState>> newHashMapWithExpectedSize(5),
+                 subTask, txContext);
+         this.sizeOffset = sizeOffset;
+     }
+ 
+     MutationState(int maxSize, long maxSizeBytes, PhoenixConnection connection,
+             Map<TableRef, List<MultiRowMutationState>> mutationsMap, boolean subTask, PhoenixTransactionContext txContext) {
+         this.maxSize = maxSize;
+         this.maxSizeBytes = maxSizeBytes;
+         this.connection = connection;
+         this.batchSize = connection.getMutateBatchSize();
+         this.batchSizeBytes = connection.getMutateBatchSizeBytes();
+         this.mutationsMap = mutationsMap;
+         boolean isMetricsEnabled = connection.isRequestLevelMetricsEnabled();
+         this.mutationMetricQueue = isMetricsEnabled ? new MutationMetricQueue()
+                 : NoOpMutationMetricsQueue.NO_OP_MUTATION_METRICS_QUEUE;
++        this.validateLastDdlTimestamp = ValidateLastDDLTimestampUtil
++                                            .getValidateLastDdlTimestampEnabled(this.connection);
+         if (subTask) {
+             // this code path is only used while running child scans, we can't pass the txContext to child scans
+             // as it is not thread safe, so we use the tx member variable
+             phoenixTransactionContext = txContext.newTransactionContext(txContext, subTask);
+         } else if (txContext != null) {
+             isExternalTxContext = true;
+             phoenixTransactionContext = txContext.newTransactionContext(txContext, subTask);
+         }
+     }
+ 
+     public MutationState(TableRef table, MultiRowMutationState mutations, long sizeOffset,
+            int maxSize, long maxSizeBytes, PhoenixConnection connection) throws SQLException {
+         this(maxSize, maxSizeBytes, connection, false, null, sizeOffset);
+         if (!mutations.isEmpty()) {
+             addMutations(this.mutationsMap, table, mutations);
+         }
+         this.numRows = mutations.size();
+         this.estimatedSize = PhoenixKeyValueUtil.getEstimatedRowMutationSizeWithBatch(this.mutationsMap);
+ 
+         throwIfTooBig();
+     }
+ 
+     // add a new batch of row mutations
+     private void addMutations(Map<TableRef, List<MultiRowMutationState>> mutationMap, TableRef table,
+             MultiRowMutationState mutations) {
+         List<MultiRowMutationState> batches = mutationMap.get(table);
+         if (batches == null) {
+             batches = Lists.newArrayListWithExpectedSize(1);
+         }
+         batches.add(mutations);
+         mutationMap.put(table, batches);
+     }
+ 
+     // remove a batch of mutations which have been committed
+     private void removeMutations(Map<TableRef, List<MultiRowMutationState>> mutationMap, TableRef table){
+         List<MultiRowMutationState> batches = mutationMap.get(table);
+         if (batches == null || batches.isEmpty()) {
+             mutationMap.remove(table);
+             return;
+         }
+ 
+         // mutation batches are committed in FIFO order so always remove from the head
+         batches.remove(0);
+         if (batches.isEmpty()) {
+             mutationMap.remove(table);
+         }
+     }
+ 
+     public long getEstimatedSize() {
+         return estimatedSize;
+     }
+ 
+     public int getMaxSize() {
+         return maxSize;
+     }
+ 
+     public long getMaxSizeBytes() {
+         return maxSizeBytes;
+     }
+ 
+     public PhoenixTransactionContext getPhoenixTransactionContext() {
+         return phoenixTransactionContext;
+     }
+ 
+     /**
+      * Commit a write fence when creating an index so that we can detect when a data table transaction is started before
+      * the create index but completes after it. In this case, we need to rerun the data table transaction after the
+      * index creation so that the index rows are generated.
+      * 
+      * @param dataTable
+      *            the data table upon which an index is being added
+      * @throws SQLException
+      */
+     public void commitDDLFence(PTable dataTable) throws SQLException {
+         // Is this still useful after PHOENIX-6627?
+         if (dataTable.isTransactional()) {
+             try {
+                 phoenixTransactionContext.commitDDLFence(dataTable);
+             } finally {
+                 // The client expects a transaction to be in progress on the txContext while the
+                 // VisibilityFence.prepareWait() starts a new tx and finishes/aborts it. After it's
+                 // finished, we start a new one here.
+                 // TODO: seems like an autonomous tx capability would be useful here.
+                 phoenixTransactionContext.begin();
+             }
+         }
+     }
+ 
+     public boolean checkpointIfNeccessary(MutationPlan plan) throws SQLException {
+         if (!phoenixTransactionContext.isTransactionRunning() || plan.getTargetRef() == null
+                 || plan.getTargetRef().getTable() == null || !plan.getTargetRef().getTable().isTransactional()) { return false; }
+         Set<TableRef> sources = plan.getSourceRefs();
+         if (sources.isEmpty()) { return false; }
+         // For a DELETE statement, we're always querying the table being deleted from. This isn't
+         // a problem, but it potentially could be if there are other references to the same table
+         // nested in the DELETE statement (as a sub query or join, for example).
+         TableRef ignoreForExcludeCurrent = plan.getOperation() == Operation.DELETE && sources.size() == 1 ? plan
+                 .getTargetRef() : null;
+         boolean excludeCurrent = false;
+         String targetPhysicalName = plan.getTargetRef().getTable().getPhysicalName().getString();
+         for (TableRef source : sources) {
+             if (source.getTable().isTransactional() && !source.equals(ignoreForExcludeCurrent)) {
+                 String sourcePhysicalName = source.getTable().getPhysicalName().getString();
+                 if (targetPhysicalName.equals(sourcePhysicalName)) {
+                     excludeCurrent = true;
+                     break;
+                 }
+             }
+         }
+         // If we're querying the same table we're updating, we must exclude our writes to
+         // it from being visible.
+         if (excludeCurrent) {
+             // If any source tables have uncommitted data prior to last checkpoint,
+             // then we must create a new checkpoint.
+             boolean hasUncommittedData = false;
+             for (TableRef source : sources) {
+                 String sourcePhysicalName = source.getTable().getPhysicalName().getString();
+                 // Tracking uncommitted physical table names is an optimization that prevents us from
+                 // having to do a checkpoint if no data has yet been written. If we're using an
+                 // external transaction context, it's possible that data was already written at the
+                 // current transaction timestamp, so we always checkpoint in that case is we're
+                 // reading and writing to the same table.
+                 if (source.getTable().isTransactional()
+                         && (isExternalTxContext || uncommittedPhysicalNames.contains(sourcePhysicalName))) {
+                     hasUncommittedData = true;
+                     break;
+                 }
+             }
+ 
+             phoenixTransactionContext.checkpoint(hasUncommittedData);
+ 
+             if (hasUncommittedData) {
+                 uncommittedPhysicalNames.clear();
+             }
+             return true;
+         }
+         return false;
+     }
+ 
+     // Though MutationState is not thread safe in general, this method should be because it may
+     // be called by TableResultIterator in a multi-threaded manner. Since we do not want to expose
+     // the Transaction outside of MutationState, this seems reasonable, as the member variables
+     // would not change as these threads are running. We also clone mutationState to ensure that
+     // the transaction context won't change due to a commit when auto commit is true.
+     public Table getHTable(PTable table) throws SQLException {
+         Table htable = this.getConnection().getQueryServices().getTable(table.getPhysicalName().getBytes());
+         if (table.isTransactional() && phoenixTransactionContext.isTransactionRunning()) {
+             // We're only using this table for reading, so we want it wrapped even if it's an index
+             htable = phoenixTransactionContext.getTransactionalTable(htable, table.isImmutableRows() || table.getType() == PTableType.INDEX);
+         }
+         return htable;
+     }
+ 
+     public PhoenixConnection getConnection() {
+         return connection;
+     }
+ 
+     public boolean isTransactionStarted() {
+         return phoenixTransactionContext.isTransactionRunning();
+     }
+ 
+     public long getInitialWritePointer() {
+         return phoenixTransactionContext.getTransactionId(); // First write pointer - won't change with checkpointing
+     }
+ 
+     // For testing
+     public long getWritePointer() {
+         return phoenixTransactionContext.getWritePointer();
+     }
+ 
+     // For testing
+     public PhoenixVisibilityLevel getVisibilityLevel() {
+         return phoenixTransactionContext.getVisibilityLevel();
+     }
+ 
+     public boolean startTransaction(Provider provider) throws SQLException {
+         if (provider == null) { return false; }
+         if (!connection.getQueryServices().getProps()
+                 .getBoolean(QueryServices.TRANSACTIONS_ENABLED, QueryServicesOptions.DEFAULT_TRANSACTIONS_ENABLED)) { throw new SQLExceptionInfo.Builder(
+                 SQLExceptionCode.CANNOT_START_TXN_IF_TXN_DISABLED).build().buildException(); }
+         if (connection.getSCN() != null) { throw new SQLExceptionInfo.Builder(
+                 SQLExceptionCode.CANNOT_START_TRANSACTION_WITH_SCN_SET).build().buildException(); }
+ 
+         if (phoenixTransactionContext == PhoenixTransactionContext.NULL_CONTEXT) {
+             phoenixTransactionContext = provider.getTransactionProvider().getTransactionContext(connection);
+         } else {
+             if (provider != phoenixTransactionContext.getProvider()) { throw new SQLExceptionInfo.Builder(
+                     SQLExceptionCode.CANNOT_MIX_TXN_PROVIDERS)
+                     .setMessage(phoenixTransactionContext.getProvider().name() + " and " + provider.name()).build()
+                     .buildException(); }
+         }
+         if (!isTransactionStarted()) {
+             // Clear any transactional state in case transaction was ended outside
+             // of Phoenix so we don't carry the old transaction state forward. We
+             // cannot call reset() here due to the case of having mutations and
+             // then transitioning from non transactional to transactional (which
+             // would end up clearing our uncommitted state).
+             resetTransactionalState();
+             phoenixTransactionContext.begin();
+             return true;
+         }
+ 
+         return false;
+     }
+ 
+     public static MutationState emptyMutationState(int maxSize, long maxSizeBytes,
+                   PhoenixConnection connection) {
+         MutationState state = new MutationState(maxSize, maxSizeBytes, connection,
+                 Collections.<TableRef, List<MultiRowMutationState>> emptyMap(), false, null);
+         state.sizeOffset = 0;
+         return state;
+     }
+ 
+     private void throwIfTooBig() throws SQLException {
+         if (numRows > maxSize) {
+             int mutationSize = numRows;
+             resetState();
+             throw new MaxMutationSizeExceededException(maxSize, mutationSize);
+         }
+         if (estimatedSize > maxSizeBytes) {
+             long mutationSizeByte = estimatedSize;
+             resetState();
+             throw new MaxMutationSizeBytesExceededException(maxSizeBytes, mutationSizeByte);
+         }
+     }
+ 
+     public long getUpdateCount() {
+         return sizeOffset + numRows;
+     }
+ 
+     public int getNumRows() {
+         return numRows;
+     }
+ 
+     private MultiRowMutationState getLastMutationBatch(Map<TableRef, List<MultiRowMutationState>> mutations, TableRef tableRef) {
+         List<MultiRowMutationState> mutationBatches = mutations.get(tableRef);
+         if (mutationBatches == null || mutationBatches.isEmpty()) {
+             return null;
+         }
+         return mutationBatches.get(mutationBatches.size() - 1);
+     }
+ 
+     private void joinMutationState(TableRef tableRef, MultiRowMutationState srcRows,
+         Map<TableRef, List<MultiRowMutationState>> dstMutations) {
+         PTable table = tableRef.getTable();
+         boolean isIndex = table.getType() == PTableType.INDEX;
+         boolean incrementRowCount = dstMutations == this.mutationsMap;
+         // we only need to check if the new mutation batch (srcRows) conflicts with the
+         // last mutation batch since we try to merge it with that only
+         MultiRowMutationState existingRows = getLastMutationBatch(dstMutations, tableRef);
+ 
+         if (existingRows == null) { // no rows found for this table
+             // Size new map at batch size as that's what it'll likely grow to.
+             MultiRowMutationState newRows = new MultiRowMutationState(connection.getMutateBatchSize());
+             newRows.putAll(srcRows);
+             addMutations(dstMutations, tableRef, newRows);
+             if (incrementRowCount && !isIndex) {
+                 numRows += srcRows.size();
+                 // if we added all the rows from newMutationState we can just increment the
+                 // estimatedSize by newMutationState.estimatedSize
+                 estimatedSize += srcRows.estimatedSize;
+             }
+             return;
+         }
+ 
+         // for conflicting rows
+         MultiRowMutationState conflictingRows = new MultiRowMutationState(connection.getMutateBatchSize());
+ 
+         // Rows for this table already exist, check for conflicts
+         for (Map.Entry<ImmutableBytesPtr, RowMutationState> rowEntry : srcRows.entrySet()) {
+             ImmutableBytesPtr key = rowEntry.getKey();
+             RowMutationState newRowMutationState = rowEntry.getValue();
+             RowMutationState existingRowMutationState = existingRows.get(key);
+             if (existingRowMutationState == null) {
+                 existingRows.put(key, newRowMutationState);
+                 if (incrementRowCount && !isIndex) { // Don't count index rows in row count
+                     numRows++;
+                     // increment estimated size by the size of the new row
+                     estimatedSize += newRowMutationState.calculateEstimatedSize();
+                 }
+                 continue;
+             }
+             Map<PColumn, byte[]> existingValues = existingRowMutationState.getColumnValues();
+             Map<PColumn, byte[]> newValues = newRowMutationState.getColumnValues();
+             if (existingValues != PRow.DELETE_MARKER && newValues != PRow.DELETE_MARKER) {
+                 // Check if we can merge existing column values with new column values
+                 long beforeMergeSize = existingRowMutationState.calculateEstimatedSize();
+                 boolean isMerged = existingRowMutationState.join(rowEntry.getValue());
+                 if (isMerged) {
+                     // decrement estimated size by the size of the old row
+                     estimatedSize -= beforeMergeSize;
+                     // increment estimated size by the size of the new row
+                     estimatedSize += existingRowMutationState.calculateEstimatedSize();
+                 } else {
+                     // cannot merge regular upsert and conditional upsert
+                     // conflicting row is not a new row so no need to increment numRows
+                     conflictingRows.put(key, newRowMutationState);
+                 }
+             } else {
+                 existingRows.put(key, newRowMutationState);
+             }
+         }
+ 
+         if (!conflictingRows.isEmpty()) {
+             addMutations(dstMutations, tableRef, conflictingRows);
+         }
+     }
+ 
+     private void joinMutationState(Map<TableRef, List<MultiRowMutationState>> srcMutations,
+             Map<TableRef, List<MultiRowMutationState>> dstMutations) {
+         // Merge newMutation with this one, keeping state from newMutation for any overlaps
+         for (Map.Entry<TableRef, List<MultiRowMutationState>> entry : srcMutations.entrySet()) {
+             TableRef tableRef = entry.getKey();
+             for (MultiRowMutationState srcRows : entry.getValue()) {
+                 // Replace existing entries for the table with new entries
+                 joinMutationState(tableRef, srcRows, dstMutations);
+             }
+         }
+     }
+ 
+     /**
+      * Combine a newer mutation with this one, where in the event of overlaps, the newer one will take precedence.
+      * Combine any metrics collected for the newer mutation.
+      * 
+      * @param newMutationState
+      *            the newer mutation state
+      */
+     public void join(MutationState newMutationState) throws SQLException {
+         if (this == newMutationState) { // Doesn't make sense
+             return;
+         }
+ 
+         phoenixTransactionContext.join(newMutationState.getPhoenixTransactionContext());
+ 
+         this.sizeOffset += newMutationState.sizeOffset;
+         joinMutationState(newMutationState.mutationsMap, this.mutationsMap);
+         if (!newMutationState.txMutations.isEmpty()) {
+             if (txMutations.isEmpty()) {
+                 txMutations = Maps.newHashMapWithExpectedSize(this.mutationsMap.size());
+             }
+             joinMutationState(newMutationState.txMutations, this.txMutations);
+         }
+         mutationMetricQueue.combineMetricQueues(newMutationState.mutationMetricQueue);
+         if (readMetricQueue == null) {
+             readMetricQueue = newMutationState.readMetricQueue;
+         } else if (readMetricQueue != null && newMutationState.readMetricQueue != null) {
+             readMetricQueue.combineReadMetrics(newMutationState.readMetricQueue);
+         }
+         throwIfTooBig();
+     }
+ 
+     private static ImmutableBytesPtr getNewRowKeyWithRowTimestamp(ImmutableBytesPtr ptr, long rowTimestamp, PTable table) {
+         RowKeySchema schema = table.getRowKeySchema();
+         int rowTimestampColPos = table.getRowTimestampColPos();
+         Field rowTimestampField = schema.getField(rowTimestampColPos);
+         byte[] rowTimestampBytes = rowTimestampField.getDataType() == PTimestamp.INSTANCE ?
+             PTimestamp.INSTANCE.toBytes(new Timestamp(rowTimestamp), rowTimestampField.getSortOrder()) :
+             PLong.INSTANCE.toBytes(rowTimestamp, rowTimestampField.getSortOrder());
+         int oldOffset = ptr.getOffset();
+         int oldLength = ptr.getLength();
+         // Move the pointer to the start byte of the row timestamp pk
+         schema.position(ptr, 0, rowTimestampColPos);
+         byte[] b = ptr.get();
+         int newOffset = ptr.getOffset();
+         int length = ptr.getLength();
+         for (int i = newOffset; i < newOffset + length; i++) {
+             // modify the underlying bytes array with the bytes of the row timestamp
+             b[i] = rowTimestampBytes[i - newOffset];
+         }
+         // move the pointer back to where it was before.
+         ptr.set(ptr.get(), oldOffset, oldLength);
+         return ptr;
+     }
+ 
+     private Iterator<Pair<PTable, List<Mutation>>> addRowMutations(final TableRef tableRef,
+             final MultiRowMutationState values, final long mutationTimestamp, final long serverTimestamp,
+             boolean includeAllIndexes, final boolean sendAll) {
+         final PTable table = tableRef.getTable();
+         final List<PTable> indexList = includeAllIndexes ? 
+                 Lists.newArrayList(IndexMaintainer.maintainedIndexes(table.getIndexes().iterator())) : 
+                     IndexUtil.getClientMaintainedIndexes(table);
+         final Iterator<PTable> indexes = indexList.iterator();
+         final List<Mutation> mutationList = Lists.newArrayListWithExpectedSize(values.size());
+         final List<Mutation> mutationsPertainingToIndex = indexes.hasNext() ? Lists
+                 .newArrayListWithExpectedSize(values.size()) : null;
+         generateMutations(tableRef, mutationTimestamp, serverTimestamp, values, mutationList,
+                 mutationsPertainingToIndex);
+         return new Iterator<Pair<PTable, List<Mutation>>>() {
+             boolean isFirst = true;
+             Map<byte[], List<Mutation>> indexMutationsMap = null;
+ 
+             @Override
+             public boolean hasNext() {
+                 return isFirst || indexes.hasNext();
+             }
+ 
+             @Override
+             public Pair<PTable, List<Mutation>> next() {
+                 if (isFirst) {
+                     isFirst = false;
+                     return new Pair<>(table, mutationList);
+                 }
+ 
+                 PTable index = indexes.next();
+ 
+                 List<Mutation> indexMutations = null;
+                 try {
+                     if (!mutationsPertainingToIndex.isEmpty()) {
+                         if (table.isTransactional()) {
+                             if (indexMutationsMap == null) {
+                                 PhoenixTxIndexMutationGenerator generator = PhoenixTxIndexMutationGenerator.newGenerator(connection, table,
+                                         indexList, mutationsPertainingToIndex.get(0).getAttributesMap());
+                                 try (Table htable = connection.getQueryServices().getTable(
+                                         table.getPhysicalName().getBytes())) {
+                                     Collection<Pair<Mutation, byte[]>> allMutations = generator.getIndexUpdates(htable,
+                                             mutationsPertainingToIndex.iterator());
+                                     indexMutationsMap = Maps.newTreeMap(Bytes.BYTES_COMPARATOR);
+                                     for (Pair<Mutation, byte[]> mutation : allMutations) {
+                                         List<Mutation> mutations = indexMutationsMap.get(mutation.getSecond());
+                                         if (mutations == null) {
+                                             mutations = Lists.newArrayList();
+                                             indexMutationsMap.put(mutation.getSecond(), mutations);
+                                         }
+                                         mutations.add(mutation.getFirst());
+                                     }
+                                 }
+                             }
+                             indexMutations = indexMutationsMap.get(index.getPhysicalName().getBytes());
+                         } else {
+                             indexMutations = IndexUtil.generateIndexData(table, index, values,
+                                     mutationsPertainingToIndex, connection.getKeyValueBuilder(), connection);
+                         }
+                     }
+ 
+                     // we may also have to include delete mutations for immutable tables if we are not processing all
+                     // the tables in the mutations map
+                     if (!sendAll) {
+                         TableRef key = new TableRef(index);
+                         List<MultiRowMutationState> multiRowMutationState = mutationsMap.remove(key);
+                         if (multiRowMutationState != null) {
+                             final List<Mutation> deleteMutations = Lists.newArrayList();
+                             // for index table there will only be 1 mutation batch in the list
+                             generateMutations(key, mutationTimestamp, serverTimestamp, multiRowMutationState.get(0), deleteMutations, null);
+                             if (indexMutations == null) {
+                                 indexMutations = deleteMutations;
+                             } else {
+                                 indexMutations.addAll(deleteMutations);
+                             }
+                         }
+                     }
+                 } catch (SQLException | IOException e) {
+                     throw new IllegalDataException(e);
+                 }
+                 return new Pair<PTable, List<Mutation>>(index,
+                         indexMutations == null ? Collections.<Mutation> emptyList()
+                                 : indexMutations);
+             }
+ 
+             @Override
+             public void remove() {
+                 throw new UnsupportedOperationException();
+             }
+ 
+         };
+     }
+ 
+     private void generateMutations(final TableRef tableRef, final long mutationTimestamp, final long serverTimestamp,
+             final MultiRowMutationState values, final List<Mutation> mutationList,
+             final List<Mutation> mutationsPertainingToIndex) {
+         final PTable table = tableRef.getTable();
+         boolean tableWithRowTimestampCol = table.getRowTimestampColPos() != -1;
+         Iterator<Map.Entry<ImmutableBytesPtr, RowMutationState>> iterator = values.entrySet().iterator();
+         long timestampToUse = mutationTimestamp;
+         MultiRowMutationState modifiedValues = new MultiRowMutationState(16);
+         boolean wildcardIncludesDynamicCols = connection.getQueryServices().getProps().getBoolean(
+                 WILDCARD_QUERY_DYNAMIC_COLS_ATTRIB, DEFAULT_WILDCARD_QUERY_DYNAMIC_COLS_ATTRIB);
+         while (iterator.hasNext()) {
+             Map.Entry<ImmutableBytesPtr, RowMutationState> rowEntry = iterator.next();
+             byte[] onDupKeyBytes = rowEntry.getValue().getOnDupKeyBytes();
+             boolean hasOnDupKey = onDupKeyBytes != null;
+             ImmutableBytesPtr key = rowEntry.getKey();
+             RowMutationState state = rowEntry.getValue();
+             if (tableWithRowTimestampCol) {
+                 RowTimestampColInfo rowTsColInfo = state.getRowTimestampColInfo();
+                 if (rowTsColInfo.useServerTimestamp()) {
+                     // regenerate the key with this timestamp.
+                     key = getNewRowKeyWithRowTimestamp(key, serverTimestamp, table);
+                     // since we are about to modify the byte[] stored in key (which changes its hashcode)
+                     // we need to remove the entry from the values map and add a new entry with the modified byte[]
+                     modifiedValues.put(key, state);
+                     iterator.remove();
+                     timestampToUse = serverTimestamp;
+                 } else {
+                     if (rowTsColInfo.getTimestamp() != null) {
+                         timestampToUse = rowTsColInfo.getTimestamp();
+                     }
+                 }
+             }
+             PRow row = table.newRow(connection.getKeyValueBuilder(), timestampToUse, key, hasOnDupKey);
+             List<Mutation> rowMutations, rowMutationsPertainingToIndex;
+             if (rowEntry.getValue().getColumnValues() == PRow.DELETE_MARKER) { // means delete
+                 row.delete();
+                 rowMutations = row.toRowMutations();
+                 String sourceOfDelete = getConnection().getSourceOfOperation();
+                 if (sourceOfDelete != null) {
+                     byte[] sourceOfDeleteBytes = Bytes.toBytes(sourceOfDelete);
+                     // Set the source of operation attribute.
+                     for (Mutation mutation: rowMutations) {
+                         mutation.setAttribute(SOURCE_OPERATION_ATTRIB, sourceOfDeleteBytes);
+                     }
+                 }
+                 // The DeleteCompiler already generates the deletes for indexes, so no need to do it again
+                 rowMutationsPertainingToIndex = Collections.emptyList();
+ 
+             } else {
+                 for (Map.Entry<PColumn, byte[]> valueEntry : rowEntry.getValue().getColumnValues().entrySet()) {
+                     row.setValue(valueEntry.getKey(), valueEntry.getValue());
+                 }
+                 if (wildcardIncludesDynamicCols && row.setAttributesForDynamicColumnsIfReqd()) {
+                     row.setAttributeToProcessDynamicColumnsMetadata();
+                 }
+                 rowMutations = row.toRowMutations();
+                 // Pass through ON DUPLICATE KEY info through mutations
+                 // In the case of the same clause being used on many statements, this will be
+                 // inefficient because we're transmitting the same information for each mutation.
+                 // TODO: use our ServerCache
+                 for (Mutation mutation : rowMutations) {
+                     if (onDupKeyBytes != null) {
+                         mutation.setAttribute(PhoenixIndexBuilderHelper.ATOMIC_OP_ATTRIB, onDupKeyBytes);
+                     }
+                 }
+                 rowMutationsPertainingToIndex = rowMutations;
+             }
+             annotateMutationsWithMetadata(table, rowMutations);
+             mutationList.addAll(rowMutations);
+             if (mutationsPertainingToIndex != null) mutationsPertainingToIndex.addAll(rowMutationsPertainingToIndex);
+         }
+         values.putAll(modifiedValues);
+     }
+ 
+     private void annotateMutationsWithMetadata(PTable table, List<Mutation> rowMutations) {
+         if (table == null) {
+             return;
+         }
+         // Annotate each mutation with enough phoenix metadata so that anyone interested can
+         // deterministically figure out exactly what Phoenix schema object created the mutation
+         // Server-side we can annotate the HBase WAL with these.
+         for (Mutation mutation : rowMutations) {
+             annotateMutationWithMetadata(table, mutation);
+         }
+ 
+         //only annotate external schema id if the change detection flag is on the table.
+         if (!table.isChangeDetectionEnabled()) {
+             return;
+         }
+         //annotate each mutation with enough metadata so that anyone interested can
+         // deterministically figure out exactly what Phoenix schema object created the mutation
+         // Server-side we can annotate the HBase WAL with these.
+         for (Mutation mutation : rowMutations) {
+             annotateMutationWithMetadataWithExternalSchemaId(table, mutation);
+         }
+ 
+     }
+ 
+     private void annotateMutationWithMetadataWithExternalSchemaId(PTable table, Mutation mutation) {
+         byte[] externalSchemaRegistryId = table.getExternalSchemaId() != null ?
+                 Bytes.toBytes(table.getExternalSchemaId()) : null;
+         WALAnnotationUtil.annotateMutation(mutation, externalSchemaRegistryId);
+     }
+ 
+     private void annotateMutationWithMetadata(PTable table, Mutation mutation) {
+         byte[] tenantId = table.getTenantId() != null ? table.getTenantId().getBytes() : null;
+         byte[] schemaName = table.getSchemaName() != null ? table.getSchemaName().getBytes() : null;
+         byte[] tableName = table.getTableName() != null ? table.getTableName().getBytes() : null;
+         byte[] tableType = table.getType().getValue().getBytes();
+         byte[] externalSchemaRegistryId = table.getExternalSchemaId() != null ?
+                 Bytes.toBytes(table.getExternalSchemaId()) : null;
+         byte[] lastDDLTimestamp =
+                 table.getLastDDLTimestamp() != null ? Bytes.toBytes(table.getLastDDLTimestamp()) : null;
+         WALAnnotationUtil.annotateMutation(mutation, tenantId, schemaName, tableName, tableType, lastDDLTimestamp);
+     }
+ 
+     /**
+      * Get the unsorted list of HBase mutations for the tables with uncommitted data.
+      * 
+      * @return list of HBase mutations for uncommitted data.
+      */
+     public Iterator<Pair<byte[], List<Mutation>>> toMutations(Long timestamp) {
+         return toMutations(false, timestamp);
+     }
+ 
+     public Iterator<Pair<byte[], List<Mutation>>> toMutations() {
+         return toMutations(false, null);
+     }
+ 
+     public Iterator<Pair<byte[], List<Mutation>>> toMutations(final boolean includeMutableIndexes) {
+         return toMutations(includeMutableIndexes, null);
+     }
+ 
+     public Iterator<Pair<byte[], List<Mutation>>> toMutations(final boolean includeMutableIndexes,
+             final Long tableTimestamp) {
+         final Iterator<Map.Entry<TableRef, List<MultiRowMutationState>>> iterator = this.mutationsMap.entrySet().iterator();
+         if (!iterator.hasNext()) { return Collections.emptyIterator(); }
+         Long scn = connection.getSCN();
+         final long serverTimestamp = getTableTimestamp(tableTimestamp, scn);
+         final long mutationTimestamp = getMutationTimestamp(scn);
+         return new Iterator<Pair<byte[], List<Mutation>>>() {
+             private Map.Entry<TableRef, List<MultiRowMutationState>> current = iterator.next();
+             private int batchOffset = 0;
+             private Iterator<Pair<byte[], List<Mutation>>> innerIterator = init();
+ 
+             private Iterator<Pair<byte[], List<Mutation>>> init() {
+                 final Iterator<Pair<PTable, List<Mutation>>> mutationIterator =
+                     addRowMutations(current.getKey(), current.getValue().get(batchOffset),
+                         mutationTimestamp, serverTimestamp, includeMutableIndexes, true);
+ 
+                 return new Iterator<Pair<byte[], List<Mutation>>>() {
+                     @Override
+                     public boolean hasNext() {
+                         return mutationIterator.hasNext();
+                     }
+ 
+                     @Override
+                     public Pair<byte[], List<Mutation>> next() {
+                         Pair<PTable, List<Mutation>> pair = mutationIterator.next();
+                         return new Pair<byte[], List<Mutation>>(pair.getFirst().getPhysicalName()
+                                 .getBytes(), pair.getSecond());
+                     }
+ 
+                     @Override
+                     public void remove() {
+                         mutationIterator.remove();
+                     }
+                 };
+             }
+ 
+             @Override
+             public boolean hasNext() {
+                 return innerIterator.hasNext() ||
+                     batchOffset + 1 < current.getValue().size() ||
+                     iterator.hasNext();
+             }
+ 
+             @Override
+             public Pair<byte[], List<Mutation>> next() {
+                 if (!innerIterator.hasNext()) {
+                     ++batchOffset;
+                     if (batchOffset == current.getValue().size()) {
+                         current = iterator.next();
+                         batchOffset = 0;
+                     }
+                     innerIterator = init();
+                 }
+                 return innerIterator.next();
+             }
+ 
+             @Override
+             public void remove() {
+                 throw new UnsupportedOperationException();
+             }
+ 
+         };
+     }
+ 
+     public static long getTableTimestamp(final Long tableTimestamp, Long scn) {
+         return (tableTimestamp != null && tableTimestamp != QueryConstants.UNSET_TIMESTAMP) ? tableTimestamp
+                 : (scn == null ? HConstants.LATEST_TIMESTAMP : scn);
+     }
+ 
+     public static long getMutationTimestamp(final Long scn) {
+         return scn == null ? HConstants.LATEST_TIMESTAMP : scn;
+     }
+ 
+     /**
+      * Validates that the meta data is valid against the server meta data if we haven't yet done so. Otherwise, for
+      * every UPSERT VALUES call, we'd need to hit the server to see if the meta data has changed.
+      * 
+      * @return the server time to use for the upsert
+      * @throws SQLException
+      *             if the table or any columns no longer exist
+      */
+     private long[] validateAll(Map<TableRef, MultiRowMutationState> commitBatch) throws SQLException {
+         int i = 0;
+         long[] timeStamps = new long[commitBatch.size()];
+         for (Map.Entry<TableRef, MultiRowMutationState> entry : commitBatch.entrySet()) {
+             TableRef tableRef = entry.getKey();
+             timeStamps[i++] = validateAndGetServerTimestamp(tableRef, entry.getValue());
+         }
+         return timeStamps;
+     }
+ 
+     private long validateAndGetServerTimestamp(TableRef tableRef, MultiRowMutationState rowKeyToColumnMap)
+             throws SQLException {
+         MetaDataClient client = new MetaDataClient(connection);
+         long serverTimeStamp = tableRef.getTimeStamp();
+         PTable table = null;
+         long startTime = EnvironmentEdgeManager.currentTimeMillis();
+         try {
+             // If we're auto committing, we've already validated the schema when we got the ColumnResolver,
+             // so no need to do it again here.
+             table = tableRef.getTable();
+ 
+             // We generally don't re-resolve SYSTEM tables, but if it relies on ROW_TIMESTAMP, we must
+             // get the latest timestamp in order to upsert data with the correct server-side timestamp
+             // in case the ROW_TIMESTAMP is not provided in the UPSERT statement.
+             boolean hitServerForLatestTimestamp =
+                     table.getRowTimestampColPos() != -1 && table.getType() == PTableType.SYSTEM;
+             MetaDataMutationResult result = client.updateCache(table.getSchemaName().getString(),
+                     table.getTableName().getString(), hitServerForLatestTimestamp);
+             PTable resolvedTable = result.getTable();
+             if (resolvedTable == null) { throw new TableNotFoundException(table.getSchemaName().getString(), table
+                     .getTableName().getString()); }
+             // Always update tableRef table as the one we've cached may be out of date since when we executed
+             // the UPSERT VALUES call and updated in the cache before this.
+             tableRef.setTable(resolvedTable);
+             List<PTable> indexes = resolvedTable.getIndexes();
+             for (PTable idxTtable : indexes) {
+                 // If index is still active, but has a non zero INDEX_DISABLE_TIMESTAMP value, then infer that
+                 // our failure mode is block writes on index failure.
+                 if ((idxTtable.getIndexState() == PIndexState.ACTIVE || idxTtable.getIndexState() == PIndexState.PENDING_ACTIVE)
+                         && idxTtable.getIndexDisableTimestamp() > 0) { throw new SQLExceptionInfo.Builder(
+                         SQLExceptionCode.INDEX_FAILURE_BLOCK_WRITE).setSchemaName(table.getSchemaName().getString())
+                         .setTableName(table.getTableName().getString()).build().buildException(); }
+             }
+             long timestamp = result.getMutationTime();
 -            if (timestamp != QueryConstants.UNSET_TIMESTAMP) {
 -                serverTimeStamp = timestamp;
 -                if (result.wasUpdated()) {
 -                    List<PColumn> columns = Lists.newArrayListWithExpectedSize(table.getColumns().size());
 -                    for (Map.Entry<ImmutableBytesPtr, RowMutationState> rowEntry : rowKeyToColumnMap.entrySet()) {
 -                        RowMutationState valueEntry = rowEntry.getValue();
 -                        if (valueEntry != null) {
 -                            Map<PColumn, byte[]> colValues = valueEntry.getColumnValues();
 -                            if (colValues != PRow.DELETE_MARKER) {
 -                                for (PColumn column : colValues.keySet()) {
 -                                    if (!column.isDynamic()) columns.add(column);
++            serverTimeStamp = timestamp;
++
++            /* when last_ddl_timestamp validation is enabled,
++             we don't know if this table's cache result was force updated
++             during the validation, so always validate columns */
++            if ((timestamp != QueryConstants.UNSET_TIMESTAMP && result.wasUpdated())
++                    || this.validateLastDdlTimestamp) {
++                List<PColumn> columns
++                        = Lists.newArrayListWithExpectedSize(table.getColumns().size());
++                for (Map.Entry<ImmutableBytesPtr, RowMutationState>
++                        rowEntry : rowKeyToColumnMap.entrySet()) {
++                    RowMutationState valueEntry = rowEntry.getValue();
++                    if (valueEntry != null) {
++                        Map<PColumn, byte[]> colValues = valueEntry.getColumnValues();
++                        if (colValues != PRow.DELETE_MARKER) {
++                            for (PColumn column : colValues.keySet()) {
++                                if (!column.isDynamic()) {
++                                    columns.add(column);
+                                 }
+                             }
+                         }
+                     }
 -                    for (PColumn column : columns) {
 -                        if (column != null) {
 -                            resolvedTable.getColumnFamily(column.getFamilyName().getString()).getPColumnForColumnName(
 -                                    column.getName().getString());
 -                        }
++                }
++                for (PColumn column : columns) {
++                    if (column != null) {
++                        resolvedTable.getColumnFamily(column.getFamilyName().getString())
++                                .getPColumnForColumnName(column.getName().getString());
+                     }
+                 }
+             }
+         } catch(Throwable e) {
+             if (table != null) {
+                 TableMetricsManager.updateMetricsForSystemCatalogTableMethod(table.getTableName().toString(),
+                         NUM_METADATA_LOOKUP_FAILURES, 1);
+             }
+             throw e;
+         } finally {
+             long endTime = EnvironmentEdgeManager.currentTimeMillis();
+             GLOBAL_MUTATION_SYSCAT_TIME.update(endTime - startTime);
+         }
+         return serverTimeStamp == QueryConstants.UNSET_TIMESTAMP ? HConstants.LATEST_TIMESTAMP : serverTimeStamp;
+     }
+ 
+     static MutationBytes calculateMutationSize(List<Mutation> mutations,
+             boolean updateGlobalClientMetrics) {
+         long byteSize = 0;
+         long temp;
+         long deleteSize = 0, deleteCounter = 0;
+         long upsertsize = 0, upsertCounter = 0;
+         long atomicUpsertsize = 0;
+         if (GlobalClientMetrics.isMetricsEnabled()) {
+             for (Mutation mutation : mutations) {
+                 temp = PhoenixKeyValueUtil.calculateMutationDiskSize(mutation);
+                 byteSize += temp;
+                 if (mutation instanceof Delete) {
+                     deleteSize += temp;
+                     deleteCounter++;
+                     allUpsertsMutations = false;
+                 } else if (mutation instanceof Put) {
+                     upsertsize += temp;
+                     upsertCounter++;
+                     if (mutation.getAttribute(PhoenixIndexBuilderHelper.ATOMIC_OP_ATTRIB) != null) {
+                         atomicUpsertsize += temp;
+                     }
+                     allDeletesMutations = false;
+                 } else {
+                     allUpsertsMutations = false;
+                     allDeletesMutations = false;
+                 }
+             }
+         }
+         if (updateGlobalClientMetrics) {
+             GLOBAL_MUTATION_BYTES.update(byteSize);
+         }
+         return new MutationBytes(deleteCounter, deleteSize, byteSize, upsertCounter, upsertsize, atomicUpsertsize);
+     }
+ 
+     public long getBatchSizeBytes() {
+         return batchSizeBytes;
+     }
+ 
+     public long getBatchCount() {
+         return batchCount;
+     }
+ 
+     public static final class MutationBytes {
+ 
+         private long deleteMutationCounter;
+         private long deleteMutationBytes;
+         private long totalMutationBytes;
+         private long upsertMutationCounter;
+         private long upsertMutationBytes;
+         private long atomicUpsertMutationBytes; // needed to calculate atomic upsert commit time
+ 
+         public MutationBytes(long deleteMutationCounter, long deleteMutationBytes, long totalMutationBytes,
+                              long upsertMutationCounter, long upsertMutationBytes, long atomicUpsertMutationBytes) {
+             this.deleteMutationCounter = deleteMutationCounter;
+             this.deleteMutationBytes = deleteMutationBytes;
+             this.totalMutationBytes = totalMutationBytes;
+             this.upsertMutationCounter = upsertMutationCounter;
+             this.upsertMutationBytes = upsertMutationBytes;
+             this.atomicUpsertMutationBytes = atomicUpsertMutationBytes;
+         }
+ 
+ 
+         public long getDeleteMutationCounter() {
+             return deleteMutationCounter;
+         }
+ 
+         public long getDeleteMutationBytes() {
+             return deleteMutationBytes;
+         }
+ 
+         public long getTotalMutationBytes() {
+             return totalMutationBytes;
+         }
+ 
+         public long getUpsertMutationCounter() {
+             return upsertMutationCounter;
+         }
+ 
+         public long getUpsertMutationBytes() {
+             return upsertMutationBytes;
+         }
+ 
+         public long getAtomicUpsertMutationBytes() { return atomicUpsertMutationBytes; }
+     }
+ 
+     public enum MutationMetadataType {
+         TENANT_ID,
+         SCHEMA_NAME,
+         LOGICAL_TABLE_NAME,
+         TIMESTAMP,
+         TABLE_TYPE,
+         EXTERNAL_SCHEMA_ID
+     }
+ 
+     private static class TableInfo {
+ 
+         private final boolean isDataTable;
+         @Nonnull
+         private final PName hTableName;
+         @Nonnull
+         private final TableRef origTableRef;
+         private final PTable pTable;
+ 
+         public TableInfo(boolean isDataTable, PName hTableName, TableRef origTableRef, PTable pTable) {
+             super();
+             checkNotNull(hTableName);
+             checkNotNull(origTableRef);
+             this.isDataTable = isDataTable;
+             this.hTableName = hTableName;
+             this.origTableRef = origTableRef;
+             this.pTable = pTable;
+         }
+ 
+         public boolean isDataTable() {
+             return isDataTable;
+         }
+ 
+         public PName getHTableName() {
+             return hTableName;
+         }
+ 
+         public TableRef getOrigTableRef() {
+             return origTableRef;
+         }
+ 
+         public PTable getPTable() {
+             return pTable;
+         }
+ 
+         @Override
+         public int hashCode() {
+             final int prime = 31;
+             int result = 1;
+             result = prime * result + hTableName.hashCode();
+             result = prime * result + (isDataTable ? 1231 : 1237);
+             return result;
+         }
+ 
+         @Override
+         public boolean equals(Object obj) {
+             if (this == obj) return true;
+             if (obj == null) return false;
+             if (getClass() != obj.getClass()) return false;
+             TableInfo other = (TableInfo)obj;
+             if (!hTableName.equals(other.hTableName)) return false;
+             if (isDataTable != other.isDataTable) return false;
+             if (!pTable.equals(other.pTable)) return false;
+ 
+             return true;
+         }
+ 
+     }
+ 
+     /**
+      * Split the mutation batches for each table into separate commit batches.
+      * Each commit batch contains only one mutation batch (MultiRowMutationState) for a table.
+      * @param tableRefIterator
+      * @return List of commit batches
+      */
+     private List<Map<TableRef, MultiRowMutationState>> createCommitBatches(Iterator<TableRef> tableRefIterator) {
+         List<Map<TableRef, MultiRowMutationState>> commitBatches = Lists.newArrayList();
+         while (tableRefIterator.hasNext()) {
+             final TableRef tableRef = tableRefIterator.next();
+             List<MultiRowMutationState> batches = this.mutationsMap.get(tableRef);
+             if (batches == null) {
+                 continue;
+             }
+             for (MultiRowMutationState batch : batches) {
+                 // get the first commit batch which doesn't have any mutations for the table
+                 Map<TableRef, MultiRowMutationState> nextCommitBatch = getNextCommitBatchForTable(commitBatches, tableRef);
+                 // add the next mutation batch of the table to the commit batch
+                 nextCommitBatch.put(tableRef, batch);
+             }
+         }
+         return commitBatches;
+     }
+ 
+     // visible for testing
+     List<Map<TableRef, MultiRowMutationState>> createCommitBatches() {
+         return createCommitBatches(this.mutationsMap.keySet().iterator());
+     }
+ 
+     /**
+      * Return the first commit batch which doesn't have any mutations for the passed table.
+      * If no such commit batch exists, creates a new commit batch, adds it to the list of
+      * commit batches and returns it.
+      * @param commitBatchesList current list of commit batches
+      * @param tableRef
+      * @return commit batch
+      */
+     private Map<TableRef, MultiRowMutationState> getNextCommitBatchForTable(List<Map<TableRef, MultiRowMutationState>> commitBatchesList,
+         TableRef tableRef) {
+         Map<TableRef, MultiRowMutationState> nextCommitBatch = null;
+         for (Map<TableRef, MultiRowMutationState> commitBatch : commitBatchesList) {
+             if (commitBatch.get(tableRef) == null) {
+                 nextCommitBatch = commitBatch;
+                 break;
+             }
+         }
+         if (nextCommitBatch == null) {
+             // create a new commit batch and add it to the list of commit batches
+             nextCommitBatch = Maps.newHashMapWithExpectedSize(this.mutationsMap.size());
+             commitBatchesList.add(nextCommitBatch);
+         }
+         return nextCommitBatch;
+     }
+ 
+     private void send(Iterator<TableRef> tableRefIterator) throws SQLException {
+         boolean sendAll = false;
+         boolean validateServerTimestamps = false;
+         List<Map<TableRef, MultiRowMutationState>> commitBatches;
+         if (tableRefIterator == null) {
+             commitBatches = createCommitBatches(this.mutationsMap.keySet().iterator());
+             sendAll = true;
+             validateServerTimestamps = true;
+         } else {
+             commitBatches = createCommitBatches(tableRefIterator);
+         }
+ 
++        //if enabled, validate last ddl timestamps for all tables in the mutationsMap
++        //for now, force update client cache for all tables if StaleMetadataCacheException is seen
++        //mutationsMap can be empty, for e.g. during a DDL operation
++        if (this.validateLastDdlTimestamp && !this.mutationsMap.isEmpty()) {
++            List<TableRef> tableRefs = new ArrayList<>(this.mutationsMap.keySet());
++            try {
++                ValidateLastDDLTimestampUtil.validateLastDDLTimestamp(
++                        connection, tableRefs, true, true);
++            } catch (StaleMetadataCacheException e) {
++                GlobalClientMetrics
++                        .GLOBAL_CLIENT_STALE_METADATA_CACHE_EXCEPTION_COUNTER.increment();
++                MetaDataClient mc = new MetaDataClient(connection);
++                PName tenantId = connection.getTenantId();
++                LOGGER.debug("Force updating client metadata cache for {}",
++                        ValidateLastDDLTimestampUtil.getInfoString(tenantId, tableRefs));
++                for (TableRef tableRef : tableRefs) {
++                    String schemaName = tableRef.getTable().getSchemaName().toString();
++                    String tableName = tableRef.getTable().getTableName().toString();
++                    mc.updateCache(tenantId, schemaName, tableName, true);
++                }
++            }
++        }
++
+         for (Map<TableRef, MultiRowMutationState> commitBatch : commitBatches) {
+             long [] serverTimestamps = validateServerTimestamps ? validateAll(commitBatch) : null;
+             sendBatch(commitBatch, serverTimestamps, sendAll);
+         }
+     }
+ 
+     private void sendBatch(Map<TableRef, MultiRowMutationState> commitBatch, long[] serverTimeStamps, boolean sendAll) throws SQLException {
+         int i = 0;
+         Map<TableInfo, List<Mutation>> physicalTableMutationMap = Maps.newLinkedHashMap();
+ 
+         // add tracing for this operation
+         try (TraceScope trace = Tracing.startNewSpan(connection, "Committing mutations to tables")) {
+             Span span = trace.getSpan();
+             ImmutableBytesWritable indexMetaDataPtr = new ImmutableBytesWritable();
+             for (Map.Entry<TableRef, MultiRowMutationState> entry : commitBatch.entrySet()) {
+                 // at this point we are going through mutations for each table
+                 final TableRef tableRef = entry.getKey();
+                 MultiRowMutationState multiRowMutationState = entry.getValue();
+                 if (multiRowMutationState == null || multiRowMutationState.isEmpty()) {
+                     continue;
+                 }
+                 // Validate as we go if transactional since we can undo if a problem occurs (which is unlikely)
+                 long
+                     serverTimestamp =
+                     serverTimeStamps == null ?
+                         validateAndGetServerTimestamp(tableRef, multiRowMutationState) :
+                         serverTimeStamps[i++];
+                 final PTable table = tableRef.getTable();
+                 Long scn = connection.getSCN();
+                 long mutationTimestamp = scn == null ?
+                     (table.isTransactional() == true ? HConstants.LATEST_TIMESTAMP : EnvironmentEdgeManager.currentTimeMillis())
+                     : scn;
+                 Iterator<Pair<PTable, List<Mutation>>>
+                     mutationsIterator =
+                     addRowMutations(tableRef, multiRowMutationState, mutationTimestamp,
+                         serverTimestamp, false, sendAll);
+                 // build map from physical table to mutation list
+                 boolean isDataTable = true;
+                 while (mutationsIterator.hasNext()) {
+                     Pair<PTable, List<Mutation>> pair = mutationsIterator.next();
+                     PTable logicalTable = pair.getFirst();
+                     List<Mutation> mutationList = pair.getSecond();
+ 
+                     TableInfo tableInfo = new TableInfo(isDataTable, logicalTable.getPhysicalName(),
+                             tableRef, logicalTable);
+ 
+                     List<Mutation>
+                         oldMutationList =
+                         physicalTableMutationMap.put(tableInfo, mutationList);
+                     if (oldMutationList != null) mutationList.addAll(0, oldMutationList);
+                     isDataTable = false;
+                 }
+                 // For transactions, track the statement indexes as we send data
+                 // over because our CommitException should include all statements
+                 // involved in the transaction since none of them would have been
+                 // committed in the event of a failure.
+                 if (table.isTransactional()) {
+                     addUncommittedStatementIndexes(multiRowMutationState.values());
+                     if (txMutations.isEmpty()) {
+                         txMutations = Maps.newHashMapWithExpectedSize(this.mutationsMap.size());
+                     }
+                     // Keep all mutations we've encountered until a commit or rollback.
+                     // This is not ideal, but there's not good way to get the values back
+                     // in the event that we need to replay the commit.
+                     // Copy TableRef so we have the original PTable and know when the
+                     // indexes have changed.
+                     joinMutationState(new TableRef(tableRef), multiRowMutationState, txMutations);
+                 }
+             }
+ 
+             Map<TableInfo, List<Mutation>> unverifiedIndexMutations = new LinkedHashMap<>();
+             Map<TableInfo, List<Mutation>> verifiedOrDeletedIndexMutations = new LinkedHashMap<>();
+             filterIndexCheckerMutations(physicalTableMutationMap, unverifiedIndexMutations,
+                     verifiedOrDeletedIndexMutations);
+ 
+             // Phase 1: Send index mutations with the empty column value = "unverified"
+             sendMutations(unverifiedIndexMutations.entrySet().iterator(), span, indexMetaDataPtr, false);
+ 
+             // Phase 2: Send data table and other indexes
+             sendMutations(physicalTableMutationMap.entrySet().iterator(), span, indexMetaDataPtr, false);
+ 
+             // Phase 3: Send put index mutations with the empty column value = "verified" and/or delete index mutations
+             try {
+                 sendMutations(verifiedOrDeletedIndexMutations.entrySet().iterator(), span, indexMetaDataPtr, true);
+             } catch (SQLException ex) {
+                 LOGGER.warn(
+                         "Ignoring exception that happened during setting index verified value to verified=TRUE ",
+                         ex);
+             }
+         }
+     }
+ 
+     private void sendMutations(Iterator<Entry<TableInfo, List<Mutation>>> mutationsIterator, Span span, ImmutableBytesWritable indexMetaDataPtr, boolean isVerifiedPhase)
+             throws SQLException {
+         while (mutationsIterator.hasNext()) {
+             Entry<TableInfo, List<Mutation>> pair = mutationsIterator.next();
+             TableInfo tableInfo = pair.getKey();
+             byte[] htableName = tableInfo.getHTableName().getBytes();
+             String htableNameStr = tableInfo.getHTableName().getString();
+             List<Mutation> mutationList = pair.getValue();
+             List<List<Mutation>> mutationBatchList =
+                     getMutationBatchList(batchSize, batchSizeBytes, mutationList);
+ 
+             // create a span per target table
+             // TODO maybe we can be smarter about the table name to string here?
+             Span child = Tracing.child(span, "Writing mutation batch for table: " + Bytes.toString(htableName));
+ 
+             int retryCount = 0;
+             boolean shouldRetry = false;
+             long numMutations = 0;
+             long mutationSizeBytes = 0;
+             long mutationCommitTime = 0;
+             long numFailedMutations = 0;
+             long numFailedPhase3Mutations = 0;
+ 
+             long startTime = EnvironmentEdgeManager.currentTimeMillis();
+             MutationBytes totalMutationBytesObject = null;
+             boolean shouldRetryIndexedMutation = false;
+             IndexWriteException iwe = null;
+             do {
+                 TableRef origTableRef = tableInfo.getOrigTableRef();
+                 PTable table = origTableRef.getTable();
+                 table.getIndexMaintainers(indexMetaDataPtr, connection);
+                 final ServerCache cache = tableInfo.isDataTable() ?
+                         IndexMetaDataCacheClient.setMetaDataOnMutations(connection, table,
+                                 mutationList, indexMetaDataPtr) : null;
+                 // If we haven't retried yet, retry for this case only, as it's possible that
+                 // a split will occur after we send the index metadata cache to all known
+                 // region servers.
+                 shouldRetry = cache != null;
+                 SQLException sqlE = null;
+                 Table hTable = connection.getQueryServices().getTable(htableName);
+                 List<Mutation> currentMutationBatch = null;
+                 boolean areAllBatchesSuccessful = false;
+ 
+                 try {
+                     if (table.isTransactional()) {
+                         // Track tables to which we've sent uncommitted data
+                         if (tableInfo.isDataTable()) {
+                             uncommittedPhysicalNames.add(table.getPhysicalName().getString());
+                             phoenixTransactionContext.markDMLFence(table);
+                         }
+                         // Only pass true for last argument if the index is being written to on it's own (i.e. initial
+                         // index population), not if it's being written to for normal maintenance due to writes to
+                         // the data table. This case is different because the initial index population does not need
+                         // to be done transactionally since the index is only made active after all writes have
+                         // occurred successfully.
+                         hTable = phoenixTransactionContext.getTransactionalTableWriter(connection, table, hTable, tableInfo.isDataTable() && table.getType() == PTableType.INDEX);
+                     }
+                     numMutations = mutationList.size();
+                     GLOBAL_MUTATION_BATCH_SIZE.update(numMutations);
+                     totalMutationBytesObject = calculateMutationSize(mutationList, true);
+ 
+                     child.addTimelineAnnotation("Attempt " + retryCount);
+                     Iterator<List<Mutation>> itrListMutation = mutationBatchList.iterator();
+                     while (itrListMutation.hasNext()) {
+                         final List<Mutation> mutationBatch = itrListMutation.next();
+                         currentMutationBatch = mutationBatch;
+                         if (shouldRetryIndexedMutation) {
+                             // if there was an index write failure, retry the mutation in a loop
+                             final Table finalHTable = hTable;
+                             final ImmutableBytesWritable finalindexMetaDataPtr =
+                                     indexMetaDataPtr;
+                             final PTable finalPTable = table;
+                             PhoenixIndexFailurePolicyHelper.doBatchWithRetries(new MutateCommand() {
+                                 @Override
+                                 public void doMutation() throws IOException {
+                                     try {
+                                         finalHTable.batch(mutationBatch, null);
+                                     } catch (InterruptedException e) {
+                                         Thread.currentThread().interrupt();
+                                         throw new IOException(e);
+                                     } catch (IOException e) {
+                                         e = updateTableRegionCacheIfNecessary(e);
+                                         throw e;
+                                     }
+                                 }
+ 
+                                 @Override
+                                 public List<Mutation> getMutationList() {
+                                     return mutationBatch;
+                                 }
+ 
+                                 private IOException
+                                 updateTableRegionCacheIfNecessary(IOException ioe) {
+                                     SQLException sqlE =
+                                             ClientUtil.parseLocalOrRemoteServerException(ioe);
+                                     if (sqlE != null
+                                             && sqlE.getErrorCode() == SQLExceptionCode.INDEX_METADATA_NOT_FOUND
+                                             .getErrorCode()) {
+                                         try {
+                                             connection.getQueryServices().clearTableRegionCache(
+                                                     finalHTable.getName());
+                                             IndexMetaDataCacheClient.setMetaDataOnMutations(
+                                                     connection, finalPTable, mutationBatch,
+                                                     finalindexMetaDataPtr);
+                                         } catch (SQLException e) {
+                                             return ClientUtil.createIOException(
+                                                     "Exception during updating index meta data cache",
+                                                     ioe);
+                                         }
+                                     }
+                                     return ioe;
+                                 }
+                             }, iwe, connection, connection.getQueryServices().getProps());
+                             shouldRetryIndexedMutation = false;
+                         } else {
+                             hTable.batch(mutationBatch, null);
+                         }
+                         // remove each batch from the list once it gets applied
+                         // so when failures happens for any batch we only start
+                         // from that batch only instead of doing duplicate reply of already
+                         // applied batches from entire list, also we can set
+                         // REPLAY_ONLY_INDEX_WRITES for first batch
+                         // only in case of 1121 SQLException
+                         itrListMutation.remove();
+ 
+                         batchCount++;
+                         if (LOGGER.isDebugEnabled())
+                             LOGGER.debug("Sent batch of " + mutationBatch.size() + " for "
+                                     + Bytes.toString(htableName));
+                     }
+                     child.stop();
+                     child.stop();
+                     shouldRetry = false;
+                     numFailedMutations = 0;
+ 
+                     // Remove batches as we process them
+                     removeMutations(this.mutationsMap, origTableRef);
+                     if (tableInfo.isDataTable()) {
+                         numRows -= numMutations;
+                         // recalculate the estimated size
+                         estimatedSize = PhoenixKeyValueUtil.getEstimatedRowMutationSizeWithBatch(this.mutationsMap);
+                     }
+                     areAllBatchesSuccessful = true;
+                 } catch (Exception e) {
+                     long serverTimestamp = ClientUtil.parseServerTimestamp(e);
+                     SQLException inferredE = ClientUtil.parseServerExceptionOrNull(e);
+                     if (inferredE != null) {
+                         if (shouldRetry
+                                 && retryCount == 0
+                                 && inferredE.getErrorCode() == SQLExceptionCode.INDEX_METADATA_NOT_FOUND
+                                 .getErrorCode()) {
+                             // Swallow this exception once, as it's possible that we split after sending the index
+                             // metadata
+                             // and one of the region servers doesn't have it. This will cause it to have it the next
+                             // go around.
+                             // If it fails again, we don't retry.
+                             String msg = "Swallowing exception and retrying after clearing meta cache on connection. "
+                                     + inferredE;
+                             LOGGER.warn(LogUtil.addCustomAnnotations(msg, connection));
+                             connection.getQueryServices().clearTableRegionCache(TableName.valueOf(htableName));
+ 
+                             // add a new child span as this one failed
+                             child.addTimelineAnnotation(msg);
+                             child.stop();
+                             child = Tracing.child(span, "Failed batch, attempting retry");
+ 
+                             continue;
+                         } else if (inferredE.getErrorCode() == SQLExceptionCode.INDEX_WRITE_FAILURE.getErrorCode()) {
+                             iwe = PhoenixIndexFailurePolicyHelper.getIndexWriteException(inferredE);
+                             if (iwe != null && !shouldRetryIndexedMutation) {
+                                 // For an index write failure, the data table write succeeded,
+                                 // so when we retry we need to set REPLAY_WRITES
+                                 // for first batch in list only.
+                                 for (Mutation m : mutationBatchList.get(0)) {
+                                     if (!PhoenixIndexMetaData.isIndexRebuild(
+                                             m.getAttributesMap())){
+                                         m.setAttribute(BaseScannerRegionObserverConstants.REPLAY_WRITES,
+                                                 BaseScannerRegionObserverConstants.REPLAY_ONLY_INDEX_WRITES
+                                         );
+                                     }
+                                     PhoenixKeyValueUtil.setTimestamp(m, serverTimestamp);
+                                 }
+                                 shouldRetry = true;
+                                 shouldRetryIndexedMutation = true;
+                                 continue;
+                             }
+                         }
+                         e = inferredE;
+                     }
+                     // Throw to client an exception that indicates the statements that
+                     // were not committed successfully.
+                     int[] uncommittedStatementIndexes = getUncommittedStatementIndexes();
+                     sqlE = new CommitException(e, uncommittedStatementIndexes, serverTimestamp);
+ 
+                     numFailedMutations = uncommittedStatementIndexes.length;
+ 
+                     if (isVerifiedPhase) {
+                         numFailedPhase3Mutations = numFailedMutations;
+                         GLOBAL_MUTATION_INDEX_COMMIT_FAILURE_COUNT.update(numFailedPhase3Mutations);
+                     }
+                 } finally {
+                     mutationCommitTime = EnvironmentEdgeManager.currentTimeMillis() - startTime;
+                     GLOBAL_MUTATION_COMMIT_TIME.update(mutationCommitTime);
+                     MutationMetric failureMutationMetrics = MutationMetric.EMPTY_METRIC;
+                     if (!areAllBatchesSuccessful) {
+                         failureMutationMetrics =
+                                 updateMutationBatchFailureMetrics(currentMutationBatch,
+                                         htableNameStr, numFailedMutations,
+                                         table.isTransactional());
+                     }
+ 
+                     MutationMetric committedMutationsMetric =
+                             getCommittedMutationsMetric(
+                                     totalMutationBytesObject,
+                                     mutationBatchList,
+                                     numMutations,
+                                     numFailedMutations,
+                                     numFailedPhase3Mutations,
+                                     mutationCommitTime);
+                     // Combine failure mutation metrics with committed ones for the final picture
+                     committedMutationsMetric.combineMetric(failureMutationMetrics);
+                     mutationMetricQueue.addMetricsForTable(htableNameStr, committedMutationsMetric);
+ 
+                     if (allUpsertsMutations ^ allDeletesMutations) {
+                         //success cases are updated for both cases autoCommit=true and conn.commit explicit
+                         if (areAllBatchesSuccessful){
+                             TableMetricsManager
+                                     .updateMetricsMethod(htableNameStr, allUpsertsMutations ? UPSERT_AGGREGATE_SUCCESS_SQL_COUNTER :
+                                             DELETE_AGGREGATE_SUCCESS_SQL_COUNTER, 1);
+                         }
+                         //Failures cases are updated only for conn.commit explicit case.
+                         if (!areAllBatchesSuccessful && !connection.getAutoCommit()){
+                             TableMetricsManager.updateMetricsMethod(htableNameStr, allUpsertsMutations ? UPSERT_AGGREGATE_FAILURE_SQL_COUNTER :
+                                     DELETE_AGGREGATE_FAILURE_SQL_COUNTER, 1);
+                         }
+                         // Update size and latency histogram metrics.
+                         TableMetricsManager.updateSizeHistogramMetricsForMutations(htableNameStr,
+                                 committedMutationsMetric.getTotalMutationsSizeBytes().getValue(), allUpsertsMutations);
+                         Long latency = timeInExecuteMutationMap.get(htableNameStr);
+                         if (latency == null) {
+                             latency = 0l;
+                         }
+                         latency += mutationCommitTime;
+                         TableMetricsManager.updateLatencyHistogramForMutations(htableNameStr,
+                                 latency, allUpsertsMutations);
+                     }
+                     resetAllMutationState();
+ 
+                     try {
+                         if (cache != null) cache.close();
+                     } finally {
+                         try {
+                             hTable.close();
+                         } catch (IOException e) {
+                             if (sqlE != null) {
+                                 sqlE.setNextException(ClientUtil.parseServerException(e));
+                             } else {
+                                 sqlE = ClientUtil.parseServerException(e);
+                             }
+                         }
+                         if (sqlE != null) { throw sqlE; }
+                     }
+                 }
+             } while (shouldRetry && retryCount++ < 1);
+         }
+     }
+ 
+     /**
+      * Update metrics related to failed mutations
+      * @param failedMutationBatch the batch of mutations that failed
+      * @param tableName table that was to be mutated
+      * @param numFailedMutations total number of failed mutations
+      * @param isTransactional true if the table is transactional
+      */
+     public static MutationMetricQueue.MutationMetric updateMutationBatchFailureMetrics(
+             List<Mutation> failedMutationBatch,
+             String tableName,
+             long numFailedMutations,
+             boolean isTransactional) {
+ 
+         if (failedMutationBatch == null || failedMutationBatch.isEmpty() ||
+                 Strings.isNullOrEmpty(tableName)) {
+             return MutationMetricQueue.MutationMetric.EMPTY_METRIC;
+         }
+ 
+         long numUpsertMutationsInBatch = 0L;
+         long numDeleteMutationsInBatch = 0L;
+ 
+         for (Mutation m : failedMutationBatch) {
+             if (m instanceof Put) {
+                 numUpsertMutationsInBatch++;
+             } else if (m instanceof Delete) {
+                 numDeleteMutationsInBatch++;
+             }
+         }
+ 
+         long totalFailedMutation = numUpsertMutationsInBatch + numDeleteMutationsInBatch;
+         //this case should not happen but the if condition makes sense if this ever happens
+         if (totalFailedMutation < numFailedMutations) {
+             LOGGER.warn(
+                     "total failed mutation less than num of failed mutation.  This is not expected.");
+             totalFailedMutation = numFailedMutations;
+         }
+ 
+         long totalNumFailedMutations = allDeletesMutations && !isTransactional
+                 ? numDeleteMutationsInBatch : totalFailedMutation;
+         GLOBAL_MUTATION_BATCH_FAILED_COUNT.update(totalNumFailedMutations);
+ 
+         // Update the MUTATION_BATCH_FAILED_SIZE counter with the number of failed delete mutations
+         // in case we are dealing with all deletes for a non-transactional table, since there is a
+         // bug in sendMutations where we don't get the correct value for numFailedMutations when
+         // we don't use transactions
+         return new MutationMetricQueue.MutationMetric(0, 0, 0, 0, 0, 0,
+                 totalNumFailedMutations,
+                 0, 0, 0, 0,
+                 numUpsertMutationsInBatch,
+                 allUpsertsMutations ? 1 : 0,
+                 numDeleteMutationsInBatch,
+                 allDeletesMutations ? 1 : 0);
+     }
+ 
+     /**
+      * Get mutation metrics that correspond to committed mutations only
+      * @param totalMutationBytesObject MutationBytes object corresponding to all the mutations we
+      *                                 attempted to commit including those that failed, those that
+      *                                 were already sent and those that were unsent
+      * @param unsentMutationBatchList list of mutation batches that are unsent
+      * @param numMutations total number of mutations
+      * @param numFailedMutations number of failed mutations in the most recent failed batch
+      * @param numFailedPhase3Mutations number of mutations failed in phase 3 of index commits
+      * @param mutationCommitTime time taken for committing all mutations
+      * @return mutation metric object just accounting for mutations that are already
+      * successfully committed
+      */
+     static MutationMetric getCommittedMutationsMetric(
+             MutationBytes totalMutationBytesObject, List<List<Mutation>> unsentMutationBatchList,
+             long numMutations, long numFailedMutations,
+             long numFailedPhase3Mutations, long mutationCommitTime) {
+         long committedUpsertMutationBytes = totalMutationBytesObject == null ? 0 :
+                 totalMutationBytesObject.getUpsertMutationBytes();
+         long committedAtomicUpsertMutationBytes = totalMutationBytesObject == null ? 0:
+                 totalMutationBytesObject.getAtomicUpsertMutationBytes();
+         long committedDeleteMutationBytes = totalMutationBytesObject == null ? 0 :
+                 totalMutationBytesObject.getDeleteMutationBytes();
+         long committedUpsertMutationCounter = totalMutationBytesObject == null ? 0 :
+                 totalMutationBytesObject.getUpsertMutationCounter();
+         long committedDeleteMutationCounter = totalMutationBytesObject == null ? 0 :
+                 totalMutationBytesObject.getDeleteMutationCounter();
+         long committedTotalMutationBytes = totalMutationBytesObject == null ? 0 :
+                 totalMutationBytesObject.getTotalMutationBytes();
+         long upsertMutationCommitTime = 0L;
+         long atomicUpsertMutationCommitTime = 0L;
+         long deleteMutationCommitTime = 0L;
+ 
+         if (totalMutationBytesObject != null && numFailedMutations != 0) {
+             List<Mutation> uncommittedMutationsList = new ArrayList<>();
+             for (List<Mutation> mutationBatch : unsentMutationBatchList) {
+                 uncommittedMutationsList.addAll(mutationBatch);
+             }
+             // Calculate the uncommitted mutations
+             MutationBytes uncommittedMutationBytesObject =
+                     calculateMutationSize(uncommittedMutationsList, false);
+             committedUpsertMutationBytes -=
+                     uncommittedMutationBytesObject.getUpsertMutationBytes();
+             committedAtomicUpsertMutationBytes -=
+                     uncommittedMutationBytesObject.getAtomicUpsertMutationBytes();
+             committedDeleteMutationBytes -=
+                     uncommittedMutationBytesObject.getDeleteMutationBytes();
+             committedUpsertMutationCounter -=
+                     uncommittedMutationBytesObject.getUpsertMutationCounter();
+             committedDeleteMutationCounter -=
+                     uncommittedMutationBytesObject.getDeleteMutationCounter();
+             committedTotalMutationBytes -=
+                     uncommittedMutationBytesObject.getTotalMutationBytes();
+         }
+ 
+         // TODO: For V1, we don't expect mixed upserts and deletes so this is fine,
+         //  but we may need to support it later, at which point we should segregate upsert
+         //  mutation time vs delete mutation time
+         if (committedTotalMutationBytes > 0) {
+             upsertMutationCommitTime =
+                     (long)Math.floor((double)(committedUpsertMutationBytes * mutationCommitTime)/
+                             committedTotalMutationBytes);
+             atomicUpsertMutationCommitTime =
+                 (long)Math.floor((double)(committedAtomicUpsertMutationBytes * mutationCommitTime)/
+                             committedTotalMutationBytes);
+             deleteMutationCommitTime =
+                     (long)Math.ceil((double)(committedDeleteMutationBytes * mutationCommitTime)/
+                             committedTotalMutationBytes);
+         }
+         return new MutationMetric(numMutations,
+                 committedUpsertMutationBytes,
+                 committedDeleteMutationBytes,
+                 upsertMutationCommitTime,
+                 atomicUpsertMutationCommitTime,
+                 deleteMutationCommitTime,
+                 0, // num failed mutations have been counted already in updateMutationBatchFailureMetrics()
+                 committedUpsertMutationCounter,
+                 committedDeleteMutationCounter,
+                 committedTotalMutationBytes,
+                 numFailedPhase3Mutations,
+                 0, 0, 0, 0 );
+     }
+ 
+     private void filterIndexCheckerMutations(Map<TableInfo, List<Mutation>> mutationMap,
+             Map<TableInfo, List<Mutation>> unverifiedIndexMutations,
+             Map<TableInfo, List<Mutation>> verifiedOrDeletedIndexMutations) throws SQLException {
+         Iterator<Entry<TableInfo, List<Mutation>>> mapIter = mutationMap.entrySet().iterator();
+ 
+         while (mapIter.hasNext()) {
+             Entry<TableInfo, List<Mutation>> pair = mapIter.next();
+             TableInfo tableInfo = pair.getKey();
+             if (!tableInfo.getPTable().getType().equals(PTableType.INDEX)) {
+                 continue;
+             }
+             PTable logicalTable = tableInfo.getPTable();
+             if (tableInfo.getOrigTableRef().getTable().isImmutableRows()
+                     && IndexUtil.isGlobalIndexCheckerEnabled(connection,
+                     tableInfo.getHTableName())) {
+ 
+                 byte[] emptyCF = SchemaUtil.getEmptyColumnFamily(logicalTable);
+                 byte[] emptyCQ = EncodedColumnsUtil.getEmptyKeyValueInfo(logicalTable).getFirst();
+                 List<Mutation> mutations = pair.getValue();
+ 
+                 for (Mutation m : mutations) {
+                     if (m == null) {
+                         continue;
+                     }
+                     if (m instanceof Delete) {
+                         if (tableInfo.getOrigTableRef().getTable().getIndexType()
+                                 != PTable.IndexType.UNCOVERED_GLOBAL) {
+                             Put put = new Put(m.getRow());
+                             put.addColumn(emptyCF, emptyCQ, IndexUtil.getMaxTimestamp(m),
+                                     QueryConstants.UNVERIFIED_BYTES);
+                             // The Delete gets marked as unverified in Phase 1 and gets deleted on Phase 3.
+                             addToMap(unverifiedIndexMutations, tableInfo, put);
+                         }
+                         // Uncovered indexes do not use two phase commit write and thus do not use
+                         // the verified status stored in the empty column. The index rows are
+                         // deleted only after their data table rows are deleted
+                         addToMap(verifiedOrDeletedIndexMutations, tableInfo, m);
+                     } else if (m instanceof Put) {
+                         long timestamp = IndexUtil.getMaxTimestamp(m);
+ 
+                         // Phase 1 index mutations are set to unverified
+                         // Send entire mutation with the unverified status
+                         // Remove the empty column prepared by Index codec as we need to change its value
+                         IndexUtil.removeEmptyColumn(m, emptyCF, emptyCQ);
+                         ((Put) m).addColumn(emptyCF, emptyCQ, timestamp,
+                                 QueryConstants.UNVERIFIED_BYTES);
+                         addToMap(unverifiedIndexMutations, tableInfo, m);
+ 
+                         // Phase 3 mutations are verified
+                         // Uncovered indexes do not use two phase commit write. The index rows are
+                         // updated only once and before their data table rows are updated. So
+                         // index rows do not have phase-3 put mutations
+                         if (tableInfo.getOrigTableRef().getTable().getIndexType()
+                                 != PTable.IndexType.UNCOVERED_GLOBAL) {
+                             Put verifiedPut = new Put(m.getRow());
+                             verifiedPut.addColumn(emptyCF, emptyCQ, timestamp,
+                                  QueryConstants.VERIFIED_BYTES);
+                             addToMap(verifiedOrDeletedIndexMutations, tableInfo, verifiedPut);
+                         }
+                     } else {
+                         addToMap(unverifiedIndexMutations, tableInfo, m);
+                     }
+                 }
+ 
+                 mapIter.remove();
+             }
+ 
+         }
+     }
+ 
+     private void addToMap(Map<TableInfo, List<Mutation>> map, TableInfo tableInfo, Mutation mutation) {
+         List<Mutation> mutations = null;
+         if (map.containsKey(tableInfo)) {
+             mutations = map.get(tableInfo);
+         } else {
+             mutations = Lists.newArrayList();
+         }
+         mutations.add(mutation);
+         map.put(tableInfo, mutations);
+     }
+ 
+     /**
+      *
+      * Split the list of mutations into multiple lists. since a single row update can contain multiple mutations,
+      * we only check if the current batch has exceeded the row or size limit for different rows,
+      * so that mutations for a single row don't end up in different batches.
+      *
+      * @param allMutationList
+      *            List of HBase mutations
+      * @return List of lists of mutations
+      */
+     public static List<List<Mutation>> getMutationBatchList(long batchSize, long batchSizeBytes, List<Mutation> allMutationList) {
+         Preconditions.checkArgument(batchSize> 1,
+                 "Mutation types are put or delete, for one row all mutations must be in one batch.");
+         Preconditions.checkArgument(batchSizeBytes > 0, "Batch size must be larger than 0");
+         List<List<Mutation>> mutationBatchList = Lists.newArrayList();
+         List<Mutation> currentList = Lists.newArrayList();
+         List<Mutation> sameRowList = Lists.newArrayList();
+         long currentBatchSizeBytes = 0L;
+         for (int i = 0; i < allMutationList.size(); ) {
+             long sameRowBatchSize = 1L;
+             Mutation mutation = allMutationList.get(i);
+             long sameRowMutationSizeBytes = PhoenixKeyValueUtil.calculateMutationDiskSize(mutation);
+             sameRowList.add(mutation);
+             while (i + 1 < allMutationList.size() &&
+                     Bytes.compareTo(allMutationList.get(i + 1).getRow(), mutation.getRow()) == 0) {
+                 Mutation sameRowMutation = allMutationList.get(i + 1);
+                 sameRowList.add(sameRowMutation);
+                 sameRowMutationSizeBytes += PhoenixKeyValueUtil.calculateMutationDiskSize(sameRowMutation);
+                 sameRowBatchSize++;
+                 i++;
+             }
+ 
+             if (currentList.size() + sameRowBatchSize > batchSize ||
+                     currentBatchSizeBytes + sameRowMutationSizeBytes > batchSizeBytes) {
+                 if (currentList.size() > 0) {
+                     mutationBatchList.add(currentList);
+                     currentList = Lists.newArrayList();
+                     currentBatchSizeBytes = 0L;
+                 }
+             }
+ 
+             currentList.addAll(sameRowList);
+             currentBatchSizeBytes += sameRowMutationSizeBytes;
+             sameRowList.clear();
+             i++;
+         }
+ 
+         if (currentList.size() > 0) {
+             mutationBatchList.add(currentList);
+         }
+         return mutationBatchList;
+     }
+ 
+     public byte[] encodeTransaction() throws SQLException {
+         return phoenixTransactionContext.encodeTransaction();
+     }
+ 
+     private void addUncommittedStatementIndexes(Collection<RowMutationState> rowMutations) {
+         for (RowMutationState rowMutationState : rowMutations) {
+             uncommittedStatementIndexes = joinSortedIntArrays(uncommittedStatementIndexes,
+                     rowMutationState.getStatementIndexes());
+         }
+     }
+ 
+     private int[] getUncommittedStatementIndexes() {
+         for (List<MultiRowMutationState> batches : mutationsMap.values()) {
+             for (MultiRowMutationState rowMutationMap : batches) {
+                 addUncommittedStatementIndexes(rowMutationMap.values());
+             }
+         }
+         return uncommittedStatementIndexes;
+     }
+ 
+     @Override
+     public void close() throws SQLException {}
+ 
+     private void resetState() {
+         numRows = 0;
+         estimatedSize = 0;
+         this.mutationsMap.clear();
+         phoenixTransactionContext = PhoenixTransactionContext.NULL_CONTEXT;
+     }
+ 
+     private void resetTransactionalState() {
+         phoenixTransactionContext.reset();
+         txMutations = Collections.emptyMap();
+         uncommittedPhysicalNames.clear();
+         uncommittedStatementIndexes = EMPTY_STATEMENT_INDEX_ARRAY;
+     }
+ 
+     public void rollback() throws SQLException {
+         try {
+             phoenixTransactionContext.abort();
+         } finally {
+             resetState();
+         }
+     }
+ 
+     public void commit() throws SQLException {
+         Map<TableRef, List<MultiRowMutationState>> txMutations = Collections.emptyMap();
+         int retryCount = 0;
+         do {
+             boolean sendSuccessful = false;
+             boolean retryCommit = false;
+             SQLException sqlE = null;
+             try {
+                 send();
+                 txMutations = this.txMutations;
+                 sendSuccessful = true;
+             } catch (SQLException e) {
+                 sqlE = e;
+             } finally {
+                 try {
+                     boolean finishSuccessful = false;
+                     try {
+                         if (sendSuccessful) {
+                             phoenixTransactionContext.commit();
+                             finishSuccessful = true;
+                         }
+                     } catch (SQLException e) {
+                         if (LOGGER.isInfoEnabled())
+                             LOGGER.info(e.getClass().getName() + " at timestamp " + getInitialWritePointer()
+                                     + " with retry count of " + retryCount);
+                         retryCommit = (e.getErrorCode() == SQLExceptionCode.TRANSACTION_CONFLICT_EXCEPTION
+                             .getErrorCode() && retryCount < MAX_COMMIT_RETRIES);
+                         if (sqlE == null) {
+                             sqlE = e;
+                         } else {
+                             sqlE.setNextException(e);
+                         }
+                     } finally {
+                         // If send fails or finish fails, abort the tx
+                         if (!finishSuccessful) {
+                             try {
+                                 phoenixTransactionContext.abort();
+                                 if (LOGGER.isInfoEnabled()) LOGGER.info("Abort successful");
+                             } catch (SQLException e) {
+                                 if (LOGGER.isInfoEnabled()) LOGGER.info("Abort failed with " + e);
+                                 if (sqlE == null) {
+                                     sqlE = e;
+                                 } else {
+                                     sqlE.setNextException(e);
+                                 }
+                             }
+                         }
+                     }
+                 } finally {
+                     TransactionFactory.Provider provider = phoenixTransactionContext.getProvider();
+                     try {
+                         resetState();
+                     } finally {
+                         if (retryCommit) {
+                             startTransaction(provider);
+                             // Add back read fences
+                             Set<TableRef> txTableRefs = txMutations.keySet();
+                             for (TableRef tableRef : txTableRefs) {
+                                 PTable dataTable = tableRef.getTable();
+                                 phoenixTransactionContext.markDMLFence(dataTable);
+                             }
+                             try {
+                                 // Only retry if an index was added
+                                 retryCommit = shouldResubmitTransaction(txTableRefs);
+                             } catch (SQLException e) {
+                                 retryCommit = false;
+                                 if (sqlE == null) {
+                                     sqlE = e;
+                                 } else {
+                                     sqlE.setNextException(e);
+                                 }
+                             }
+                         }
+                         if (sqlE != null && !retryCommit) { throw sqlE; }
+                     }
+                 }
+             }
+             // Retry commit once if conflict occurred and index was added
+             if (!retryCommit) {
+                 break;
+             }
+             retryCount++;
+             mutationsMap.putAll(txMutations);
+         } while (true);
+     }
+ 
+     /**
+      * Determines whether indexes were added to mutated tables while the transaction was in progress.
+      * 
+      * @return true if indexes were added and false otherwise.
+      * @throws SQLException
+      */
+     private boolean shouldResubmitTransaction(Set<TableRef> txTableRefs) throws SQLException {
+         if (LOGGER.isInfoEnabled()) LOGGER.info("Checking for index updates as of " + getInitialWritePointer());
+         MetaDataClient client = new MetaDataClient(connection);
+         PMetaData cache = connection.getMetaDataCache();
+         boolean addedAnyIndexes = false;
+         boolean allImmutableTables = !txTableRefs.isEmpty();
+         PTable dataTable = null;
+         try {
+             for (TableRef tableRef : txTableRefs) {
+                 dataTable = tableRef.getTable();
+                 List<PTable> oldIndexes;
+                 PTableRef ptableRef = cache.getTableRef(dataTable.getKey());
+                 oldIndexes = ptableRef.getTable().getIndexes();
+                 // Always check at server for metadata change, as it's possible that the table is configured to not check
+                 // for metadata changes
+                 // but in this case, the tx manager is telling us it's likely that there has been a change.
+                 MetaDataMutationResult result = client.updateCache(dataTable.getTenantId(), dataTable.getSchemaName()
+                         .getString(), dataTable.getTableName().getString(), true);
+                 long timestamp = TransactionUtil.getResolvedTime(connection, result);
+                 tableRef.setTimeStamp(timestamp);
+                 PTable updatedDataTable = result.getTable();
+                 if (updatedDataTable == null) {
+                     throw new TableNotFoundException(dataTable.getSchemaName().getString(),
+                             dataTable.getTableName().getString());
+                 }
+                 allImmutableTables &= updatedDataTable.isImmutableRows();
+                 tableRef.setTable(updatedDataTable);
+                 if (!addedAnyIndexes) {
+                     // TODO: in theory we should do a deep equals check here, as it's possible
+                     // that an index was dropped and recreated with the same name but different
+                     // indexed/covered columns.
+                     addedAnyIndexes = (!oldIndexes.equals(updatedDataTable.getIndexes()));
+                     if (LOGGER.isInfoEnabled())
+                         LOGGER.info((addedAnyIndexes ? "Updates " : "No updates ") + "as of " + timestamp + " to "
+                                 + updatedDataTable.getName().getString() + " with indexes " + updatedDataTable.getIndexes());
+                 }
+             }
+             if (LOGGER.isInfoEnabled())
+                 LOGGER.info((addedAnyIndexes ? "Updates " : "No updates ") + "to indexes as of " + getInitialWritePointer()
+                         + " over " + (allImmutableTables ? " all immutable tables" : " some mutable tables"));
+             // If all tables are immutable, we know the conflict we got was due to our DDL/DML fence.
+             // If any indexes were added, then the conflict might be due to DDL/DML fence.
+             return allImmutableTables || addedAnyIndexes;
+         } catch (Throwable e) {
+             if (dataTable != null) {
+                 TableMetricsManager.updateMetricsForSystemCatalogTableMethod(
+                         dataTable.getTableName().toString(), NUM_METADATA_LOOKUP_FAILURES, 1);
+             }
+             throw e;
+         }
+     }
+ 
+     /**
+      * Send to HBase any uncommitted data for transactional tables.
+      * 
+      * @return true if any data was sent and false otherwise.
+      * @throws SQLException
+      */
+     public boolean sendUncommitted() throws SQLException {
+         return sendUncommitted(mutationsMap.keySet().iterator());
+     }
+ 
+     /**
+      * Support read-your-own-write semantics by sending uncommitted data to HBase prior to running a query. In this way,
+      * they are visible to subsequent reads but are not actually committed until commit is called.
+      * 
+      * @param tableRefs
+      * @return true if any data was sent and false otherwise.
+      * @throws SQLException
+      */
+     public boolean sendUncommitted(Iterator<TableRef> tableRefs) throws SQLException {
+ 
+         if (phoenixTransactionContext.isTransactionRunning()) {
+             // Initialize visibility so that transactions see their own writes.
+             // The checkpoint() method will set it to not see writes if necessary.
+             phoenixTransactionContext.setVisibilityLevel(PhoenixVisibilityLevel.SNAPSHOT);
+         }
+ 
+         Iterator<TableRef> filteredTableRefs = Iterators.filter(tableRefs, new Predicate<TableRef>() {
+             @Override
+             public boolean apply(TableRef tableRef) {
+                 return tableRef.getTable().isTransactional();
+             }
+         });
+         if (filteredTableRefs.hasNext()) {
+             // FIXME: strip table alias to prevent equality check from failing due to alias mismatch on null alias.
+             // We really should be keying the tables based on the physical table name.
+             List<TableRef> strippedAliases = Lists.newArrayListWithExpectedSize(mutationsMap.keySet().size());
+             while (filteredTableRefs.hasNext()) {
+                 TableRef tableRef = filteredTableRefs.next();
+                 // REVIEW: unclear if we need this given we start transactions when resolving a table
+                 if (tableRef.getTable().isTransactional()) {
+                     startTransaction(tableRef.getTable().getTransactionProvider());
+                 }
+                 strippedAliases.add(new TableRef(null, tableRef.getTable(), tableRef.getTimeStamp(), tableRef
+                         .getLowerBoundTimeStamp(), tableRef.hasDynamicCols()));
+             }
+             send(strippedAliases.iterator());
+             return true;
+         }
+         return false;
+     }
+ 
+     public void send() throws SQLException {
+         send(null);
+     }
+ 
+     public static int[] joinSortedIntArrays(int[] a, int[] b) {
+         int[] result = new int[a.length + b.length];
+         int i = 0, j = 0, k = 0, current;
+         while (i < a.length && j < b.length) {
+             current = a[i] < b[j] ? a[i++] : b[j++];
+             for (; i < a.length && a[i] == current; i++)
+                 ;
+             for (; j < b.length && b[j] == current; j++)
+                 ;
+             result[k++] = current;
+         }
+         while (i < a.length) {
+             for (current = a[i++]; i < a.length && a[i] == current; i++)
+                 ;
+             result[k++] = current;
+         }
+         while (j < b.length) {
+             for (current = b[j++]; j < b.length && b[j] == current; j++)
+                 ;
+             result[k++] = current;
+         }
+         return Arrays.copyOf(result, k);
+     }
+ 
+     @Immutable
+     public static class RowTimestampColInfo {
+         private final boolean useServerTimestamp;
+         private final Long rowTimestamp;
+ 
+         public static final RowTimestampColInfo NULL_ROWTIMESTAMP_INFO = new RowTimestampColInfo(false, null);
+ 
+         public RowTimestampColInfo(boolean autoGenerate, Long value) {
+             this.useServerTimestamp = autoGenerate;
+             this.rowTimestamp = value;
+         }
+ 
+         public boolean useServerTimestamp() {
+             return useServerTimestamp;
+         }
+ 
+         public Long getTimestamp() {
+             return rowTimestamp;
+         }
+     }
+ 
+     public static class MultiRowMutationState {
+         private Map<ImmutableBytesPtr, RowMutationState> rowKeyToRowMutationState;
+         private long estimatedSize;
+ 
+         public MultiRowMutationState(int size) {
+             this.rowKeyToRowMutationState = Maps.newHashMapWithExpectedSize(size);
+             this.estimatedSize = 0;
+         }
+ 
+         public RowMutationState put(ImmutableBytesPtr ptr, RowMutationState rowMutationState) {
+             estimatedSize += rowMutationState.calculateEstimatedSize();
+             return rowKeyToRowMutationState.put(ptr, rowMutationState);
+         }
+ 
+         public RowMutationState get(ImmutableBytesPtr ptr) {
+             return rowKeyToRowMutationState.get(ptr);
+         }
+ 
+         public void putAll(MultiRowMutationState other) {
+             estimatedSize += other.estimatedSize;
+             rowKeyToRowMutationState.putAll(other.rowKeyToRowMutationState);
+         }
+ 
+         public boolean isEmpty() {
+             return rowKeyToRowMutationState.isEmpty();
+         }
+ 
+         public int size() {
+             return rowKeyToRowMutationState.size();
+         }
+ 
+         public Set<Entry<ImmutableBytesPtr, RowMutationState>> entrySet() {
+             return rowKeyToRowMutationState.entrySet();
+         }
+ 
+         public void clear() {
+             rowKeyToRowMutationState.clear();
+             estimatedSize = 0;
+         }
+ 
+         public Collection<RowMutationState> values() {
+             return rowKeyToRowMutationState.values();
+         }
+     }
+ 
+     public static class RowMutationState {
+         @Nonnull
+         private Map<PColumn, byte[]> columnValues;
+         private int[] statementIndexes;
+         @Nonnull
+         private final RowTimestampColInfo rowTsColInfo;
+         private byte[] onDupKeyBytes;
+         private long colValuesSize;
+ 
+         public RowMutationState(@Nonnull Map<PColumn, byte[]> columnValues, long colValuesSize, int statementIndex,
+                 @Nonnull RowTimestampColInfo rowTsColInfo, byte[] onDupKeyBytes) {
+             checkNotNull(columnValues);
+             checkNotNull(rowTsColInfo);
+             this.columnValues = columnValues;
+             this.statementIndexes = new int[] { statementIndex };
+             this.rowTsColInfo = rowTsColInfo;
+             this.onDupKeyBytes = onDupKeyBytes;
+             this.colValuesSize = colValuesSize;
+         }
+ 
+         public long calculateEstimatedSize() {
+             return colValuesSize + statementIndexes.length * SizedUtil.INT_SIZE + SizedUtil.LONG_SIZE
+                     + (onDupKeyBytes != null ? onDupKeyBytes.length : 0);
+         }
+ 
+         byte[] getOnDupKeyBytes() {
+             return onDupKeyBytes;
+         }
+ 
+         public Map<PColumn, byte[]> getColumnValues() {
+             return columnValues;
+         }
+ 
+         int[] getStatementIndexes() {
+             return statementIndexes;
+         }
+ 
+         /**
+          * Join the newRow with the current row if it doesn't conflict with it.
+          * A regular upsert conflicts with a conditional upsert
+          * @param newRow
+          * @return True if the rows were successfully joined else False
+          */
+         boolean join(RowMutationState newRow) {
+             if (isConflicting(newRow)) {
+                 return false;
+             }
+             // If we already have a row and the new row has an ON DUPLICATE KEY clause
+             // ignore the new values (as that's what the server will do).
+             if (newRow.onDupKeyBytes == null) {
+                 // increment the column value size by the new row column value size
+                 colValuesSize += newRow.colValuesSize;
+                 for (Map.Entry<PColumn, byte[]> entry : newRow.columnValues.entrySet()) {
+                     PColumn col = entry.getKey();
+                     byte[] oldValue = columnValues.put(col, entry.getValue());
+                     if (oldValue != null) {
+                         // decrement column value size by the size of all column values that were replaced
+                         colValuesSize -= (col.getEstimatedSize() + oldValue.length);
+                     }
+                 }
+             }
+             // Concatenate ON DUPLICATE KEY bytes to allow multiple
+             // increments of the same row in the same commit batch.
+             this.onDupKeyBytes = PhoenixIndexBuilderHelper.combineOnDupKey(this.onDupKeyBytes, newRow.onDupKeyBytes);
+             statementIndexes = joinSortedIntArrays(statementIndexes, newRow.getStatementIndexes());
+             return true;
+         }
+ 
+         @Nonnull
+         RowTimestampColInfo getRowTimestampColInfo() {
+             return rowTsColInfo;
+         }
+ 
+         public boolean isConflicting(RowMutationState newRowMutationState) {
+             return (this.onDupKeyBytes != null && newRowMutationState.onDupKeyBytes == null ||
+                 this.onDupKeyBytes == null && newRowMutationState.onDupKeyBytes != null);
+         }
+     }
+ 
+     public ReadMetricQueue getReadMetricQueue() {
+         return readMetricQueue;
+     }
+ 
+     public void setReadMetricQueue(ReadMetricQueue readMetricQueue) {
+         this.readMetricQueue = readMetricQueue;
+     }
+ 
+     public MutationMetricQueue getMutationMetricQueue() {
+         return mutationMetricQueue;
+     }
+ 
+     public void addExecuteMutationTime(long time, String tableName) {
+         Long timeSpent = timeInExecuteMutationMap.get(tableName);
+         if (timeSpent == null) {
+             timeSpent = 0l;
+         }
+         timeSpent += time;
+         timeInExecuteMutationMap.put(tableName, timeSpent);
+     }
+ 
+     public void resetExecuteMutationTimeMap() {
+         timeInExecuteMutationMap.clear();
+     }
+ 
+     public boolean isEmpty() {
+         return mutationsMap != null ? mutationsMap.isEmpty() : true;
+     }
+ }
diff --cc phoenix-core-client/src/main/java/org/apache/phoenix/jdbc/PhoenixStatement.java
index 0000000000,2b47e7d50b..aec3b4d78d
mode 000000,100644..100644
--- a/phoenix-core-client/src/main/java/org/apache/phoenix/jdbc/PhoenixStatement.java
+++ b/phoenix-core-client/src/main/java/org/apache/phoenix/jdbc/PhoenixStatement.java
@@@ -1,0 -1,2599 +1,2650 @@@
+ /*
+  * 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.jdbc;
+ 
+ import static org.apache.phoenix.monitoring.GlobalClientMetrics.GLOBAL_MUTATION_SQL_COUNTER;
+ import static org.apache.phoenix.monitoring.GlobalClientMetrics.GLOBAL_QUERY_TIME;
+ import static org.apache.phoenix.monitoring.GlobalClientMetrics.GLOBAL_SELECT_SQL_COUNTER;
+ import static org.apache.phoenix.monitoring.MetricType.ATOMIC_UPSERT_SQL_COUNTER;
+ import static org.apache.phoenix.monitoring.MetricType.ATOMIC_UPSERT_SQL_QUERY_TIME;
+ import static org.apache.phoenix.monitoring.MetricType.DELETE_AGGREGATE_FAILURE_SQL_COUNTER;
+ import static org.apache.phoenix.monitoring.MetricType.DELETE_FAILED_SQL_COUNTER;
+ import static org.apache.phoenix.monitoring.MetricType.DELETE_SQL_COUNTER;
+ import static org.apache.phoenix.monitoring.MetricType.DELETE_SQL_QUERY_TIME;
+ import static org.apache.phoenix.monitoring.MetricType.DELETE_SUCCESS_SQL_COUNTER;
+ import static org.apache.phoenix.monitoring.MetricType.MUTATION_SQL_COUNTER;
+ import static org.apache.phoenix.monitoring.MetricType.SELECT_AGGREGATE_FAILURE_SQL_COUNTER;
+ import static org.apache.phoenix.monitoring.MetricType.SELECT_FAILED_SQL_COUNTER;
+ import static org.apache.phoenix.monitoring.MetricType.SELECT_POINTLOOKUP_FAILED_SQL_COUNTER;
+ import static org.apache.phoenix.monitoring.MetricType.SELECT_POINTLOOKUP_SUCCESS_SQL_COUNTER;
+ import static org.apache.phoenix.monitoring.MetricType.SELECT_SCAN_FAILED_SQL_COUNTER;
+ import static org.apache.phoenix.monitoring.MetricType.SELECT_SCAN_SUCCESS_SQL_COUNTER;
+ import static org.apache.phoenix.monitoring.MetricType.SELECT_SQL_COUNTER;
+ import static org.apache.phoenix.monitoring.MetricType.SELECT_SQL_QUERY_TIME;
+ import static org.apache.phoenix.monitoring.MetricType.SELECT_SUCCESS_SQL_COUNTER;
+ import static org.apache.phoenix.monitoring.MetricType.UPSERT_AGGREGATE_FAILURE_SQL_COUNTER;
+ import static org.apache.phoenix.monitoring.MetricType.UPSERT_FAILED_SQL_COUNTER;
+ import static org.apache.phoenix.monitoring.MetricType.UPSERT_SQL_COUNTER;
+ import static org.apache.phoenix.monitoring.MetricType.UPSERT_SQL_QUERY_TIME;
+ import static org.apache.phoenix.monitoring.MetricType.UPSERT_SUCCESS_SQL_COUNTER;
+ 
+ import java.io.File;
+ import java.io.IOException;
+ import java.io.Reader;
+ import java.sql.BatchUpdateException;
+ import java.sql.ParameterMetaData;
+ import java.sql.PreparedStatement;
+ import java.sql.ResultSet;
+ import java.sql.SQLException;
+ import java.sql.SQLFeatureNotSupportedException;
+ import java.sql.SQLWarning;
+ import java.sql.Statement;
+ import java.text.Format;
+ import java.util.ArrayList;
+ import java.util.Arrays;
+ import java.util.Calendar;
+ import java.util.Collections;
+ import java.util.Iterator;
+ import java.util.List;
+ import java.util.Map;
+ import java.util.Properties;
+ import java.util.Set;
+ 
 -
+ import org.apache.hadoop.conf.Configuration;
+ import org.apache.hadoop.fs.FileSystem;
+ import org.apache.hadoop.fs.Path;
+ import org.apache.hadoop.hbase.Cell;
+ import org.apache.hadoop.hbase.CellComparator;
+ import org.apache.hadoop.hbase.client.Consistency;
+ import org.apache.hadoop.hbase.client.Scan;
+ import org.apache.hadoop.hbase.util.Pair;
+ import org.apache.phoenix.call.CallRunner;
+ import org.apache.phoenix.compile.BaseMutationPlan;
+ import org.apache.phoenix.compile.CloseStatementCompiler;
+ import org.apache.phoenix.compile.ColumnProjector;
+ import org.apache.phoenix.compile.CreateFunctionCompiler;
+ import org.apache.phoenix.compile.CreateIndexCompiler;
+ import org.apache.phoenix.compile.CreateSchemaCompiler;
+ import org.apache.phoenix.compile.CreateSequenceCompiler;
+ import org.apache.phoenix.compile.CreateTableCompiler;
+ import org.apache.phoenix.compile.DeclareCursorCompiler;
+ import org.apache.phoenix.compile.DeleteCompiler;
+ import org.apache.phoenix.compile.DropSequenceCompiler;
+ import org.apache.phoenix.compile.ExplainPlan;
+ import org.apache.phoenix.compile.ExpressionProjector;
+ import org.apache.phoenix.compile.GroupByCompiler.GroupBy;
+ import org.apache.phoenix.compile.ListJarsQueryPlan;
+ import org.apache.phoenix.compile.MutationPlan;
+ import org.apache.phoenix.compile.OpenStatementCompiler;
+ import org.apache.phoenix.compile.OrderByCompiler.OrderBy;
+ import org.apache.phoenix.compile.QueryCompiler;
+ 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.compile.StatementPlan;
+ import org.apache.phoenix.compile.TraceQueryPlan;
+ import org.apache.phoenix.compile.UpsertCompiler;
+ import org.apache.phoenix.coprocessorclient.MetaDataProtocol;
+ import org.apache.phoenix.exception.SQLExceptionCode;
+ import org.apache.phoenix.exception.SQLExceptionInfo;
++import org.apache.phoenix.exception.StaleMetadataCacheException;
+ import org.apache.phoenix.exception.UpgradeRequiredException;
+ import org.apache.phoenix.execute.MutationState;
+ import org.apache.phoenix.execute.visitor.QueryPlanVisitor;
+ import org.apache.phoenix.expression.KeyValueColumnExpression;
+ import org.apache.phoenix.expression.RowKeyColumnExpression;
+ import org.apache.phoenix.iterate.ExplainTable;
+ import org.apache.phoenix.iterate.MaterializedResultIterator;
+ import org.apache.phoenix.iterate.ParallelScanGrouper;
+ import org.apache.phoenix.iterate.ResultIterator;
+ import org.apache.phoenix.log.ActivityLogInfo;
+ import org.apache.phoenix.log.AuditQueryLogger;
+ import org.apache.phoenix.log.LogLevel;
+ import org.apache.phoenix.log.QueryLogInfo;
+ import org.apache.phoenix.log.QueryLogger;
+ import org.apache.phoenix.log.QueryLoggerUtil;
+ import org.apache.phoenix.log.QueryStatus;
++import org.apache.phoenix.monitoring.GlobalClientMetrics;
+ import org.apache.phoenix.monitoring.TableMetricsManager;
+ import org.apache.phoenix.optimize.Cost;
+ import org.apache.phoenix.parse.AddColumnStatement;
+ import org.apache.phoenix.parse.AddJarsStatement;
+ import org.apache.phoenix.parse.AliasedNode;
+ import org.apache.phoenix.parse.AlterIndexStatement;
+ import org.apache.phoenix.parse.AlterSessionStatement;
+ import org.apache.phoenix.parse.BindableStatement;
+ import org.apache.phoenix.parse.ChangePermsStatement;
+ import org.apache.phoenix.parse.CloseStatement;
+ import org.apache.phoenix.parse.ColumnDef;
+ import org.apache.phoenix.parse.ColumnName;
+ import org.apache.phoenix.parse.CreateFunctionStatement;
+ import org.apache.phoenix.parse.CreateIndexStatement;
+ import org.apache.phoenix.parse.CreateSchemaStatement;
+ import org.apache.phoenix.parse.CreateSequenceStatement;
+ import org.apache.phoenix.parse.CreateTableStatement;
+ import org.apache.phoenix.parse.CursorName;
+ import org.apache.phoenix.parse.DMLStatement;
+ import org.apache.phoenix.parse.DeclareCursorStatement;
+ import org.apache.phoenix.parse.DeleteJarStatement;
+ import org.apache.phoenix.parse.DeleteStatement;
+ import org.apache.phoenix.parse.ExplainType;
+ import org.apache.phoenix.parse.ShowCreateTableStatement;
+ import org.apache.phoenix.parse.ShowCreateTable;
+ import org.apache.phoenix.parse.DropColumnStatement;
+ import org.apache.phoenix.parse.DropFunctionStatement;
+ import org.apache.phoenix.parse.DropIndexStatement;
+ import org.apache.phoenix.parse.DropSchemaStatement;
+ import org.apache.phoenix.parse.DropSequenceStatement;
+ import org.apache.phoenix.parse.DropTableStatement;
+ import org.apache.phoenix.parse.ExecuteUpgradeStatement;
+ import org.apache.phoenix.parse.ExplainStatement;
+ import org.apache.phoenix.parse.FetchStatement;
+ import org.apache.phoenix.parse.FilterableStatement;
+ import org.apache.phoenix.parse.HintNode;
+ import org.apache.phoenix.parse.IndexKeyConstraint;
+ import org.apache.phoenix.parse.LimitNode;
+ import org.apache.phoenix.parse.ListJarsStatement;
+ import org.apache.phoenix.parse.LiteralParseNode;
+ import org.apache.phoenix.parse.MutableStatement;
+ import org.apache.phoenix.parse.NamedNode;
+ import org.apache.phoenix.parse.NamedTableNode;
+ import org.apache.phoenix.parse.OffsetNode;
+ import org.apache.phoenix.parse.OpenStatement;
+ import org.apache.phoenix.parse.OrderByNode;
+ import org.apache.phoenix.parse.PFunction;
+ import org.apache.phoenix.parse.ParseNode;
+ import org.apache.phoenix.parse.ParseNodeFactory;
+ import org.apache.phoenix.parse.PrimaryKeyConstraint;
+ import org.apache.phoenix.parse.SQLParser;
+ import org.apache.phoenix.parse.SelectStatement;
+ import org.apache.phoenix.parse.ShowSchemasStatement;
+ import org.apache.phoenix.parse.ShowTablesStatement;
+ import org.apache.phoenix.parse.TableName;
+ import org.apache.phoenix.parse.TableNode;
+ import org.apache.phoenix.parse.TraceStatement;
+ import org.apache.phoenix.parse.UDFParseNode;
+ import org.apache.phoenix.parse.UpdateStatisticsStatement;
+ import org.apache.phoenix.parse.UpsertStatement;
+ import org.apache.phoenix.parse.UseSchemaStatement;
+ import org.apache.phoenix.query.HBaseFactoryProvider;
+ import org.apache.phoenix.query.KeyRange;
+ import org.apache.phoenix.query.QueryConstants;
+ import org.apache.phoenix.query.QueryServices;
+ import org.apache.phoenix.query.QueryServicesOptions;
+ import org.apache.phoenix.schema.ExecuteQueryNotApplicableException;
+ import org.apache.phoenix.schema.ExecuteUpdateNotApplicableException;
+ import org.apache.phoenix.schema.FunctionNotFoundException;
+ import org.apache.phoenix.schema.MetaDataClient;
+ import org.apache.phoenix.schema.MetaDataEntityNotFoundException;
+ import org.apache.phoenix.schema.PColumnImpl;
+ import org.apache.phoenix.schema.PDatum;
+ import org.apache.phoenix.schema.PIndexState;
++import org.apache.phoenix.schema.PName;
+ import org.apache.phoenix.schema.PNameFactory;
++import org.apache.phoenix.schema.PTable;
+ import org.apache.phoenix.schema.PTable.IndexType;
+ import org.apache.phoenix.schema.PTableType;
+ import org.apache.phoenix.schema.RowKeyValueAccessor;
+ import org.apache.phoenix.schema.Sequence;
+ import org.apache.phoenix.schema.SortOrder;
+ import org.apache.phoenix.schema.TableRef;
+ import org.apache.phoenix.schema.stats.StatisticsCollectionScope;
+ import org.apache.phoenix.schema.tuple.MultiKeyValueTuple;
+ import org.apache.phoenix.schema.tuple.Tuple;
+ import org.apache.phoenix.schema.types.PDataType;
+ import org.apache.phoenix.schema.types.PLong;
+ import org.apache.phoenix.schema.types.PVarchar;
+ import org.apache.phoenix.trace.util.Tracing;
+ import org.apache.phoenix.util.ByteUtil;
+ import org.apache.phoenix.util.ClientUtil;
+ import org.apache.phoenix.util.CursorUtil;
+ import org.apache.phoenix.util.PhoenixKeyValueUtil;
+ import org.apache.phoenix.util.EnvironmentEdgeManager;
+ import org.apache.phoenix.util.LogUtil;
+ import org.apache.phoenix.util.ParseNodeUtil;
+ import org.apache.phoenix.util.PhoenixContextExecutor;
+ import org.apache.phoenix.util.PhoenixRuntime;
+ import org.apache.phoenix.util.QueryUtil;
+ import org.apache.phoenix.util.SQLCloseable;
+ import org.apache.phoenix.util.ParseNodeUtil.RewriteResult;
++import org.apache.phoenix.util.ValidateLastDDLTimestampUtil;
+ import org.slf4j.Logger;
+ import org.slf4j.LoggerFactory;
+ 
+ import org.apache.phoenix.thirdparty.com.google.common.base.Throwables;
+ import org.apache.phoenix.thirdparty.com.google.common.collect.ListMultimap;
+ import org.apache.phoenix.thirdparty.com.google.common.collect.Lists;
+ import org.apache.phoenix.thirdparty.com.google.common.math.IntMath;
+ import org.apache.phoenix.thirdparty.com.google.common.base.Strings;
+ /**
+  * 
+  * JDBC Statement implementation of Phoenix.
+  * Currently only the following methods are supported:
+  * - {@link #executeQuery(String)}
+  * - {@link #executeUpdate(String)}
+  * - {@link #execute(String)}
+  * - {@link #getResultSet()}
+  * - {@link #getUpdateCount()}
+  * - {@link #close()}
+  * The Statement only supports the following options:
+  * - ResultSet.FETCH_FORWARD
+  * - ResultSet.TYPE_FORWARD_ONLY
+  * - ResultSet.CLOSE_CURSORS_AT_COMMIT
+  * 
+  * 
+  * @since 0.1
+  */
+ public class PhoenixStatement implements PhoenixMonitoredStatement, SQLCloseable {
+ 	
+     private static final Logger LOGGER = LoggerFactory.getLogger(PhoenixStatement.class);
+     
+     public enum Operation {
+         QUERY("queried", false),
+         DELETE("deleted", true),
+         UPSERT("upserted", true),
+         UPGRADE("upgrade", true),
+         ADMIN("admin", true);
+ 
+         private final String toString;
+         private final boolean isMutation;
+         Operation(String toString, boolean isMutation) {
+             this.toString = toString;
+             this.isMutation = isMutation;
+         }
+         
+         public boolean isMutation() {
+             return isMutation;
+         }
+         
+         @Override
+         public String toString() {
+             return toString;
+         }
+     }
+ 
+     protected final PhoenixConnection connection;
+     private static final int NO_UPDATE = -1;
+     private static final String TABLE_UNKNOWN = "";
+     private QueryPlan lastQueryPlan;
+     private PhoenixResultSet lastResultSet;
+     private int lastUpdateCount = NO_UPDATE;
+ 
+     private String lastUpdateTable = TABLE_UNKNOWN;
+     private Operation lastUpdateOperation;
+     private boolean isClosed = false;
+     private boolean closeOnCompletion = false;
+     private int maxRows;
+     private int fetchSize = -1;
+     private int queryTimeoutMillis;
+     // Caching per Statement
+     protected final Calendar localCalendar = Calendar.getInstance();
++    private boolean validateLastDdlTimestamp;
+ 
+     public PhoenixStatement(PhoenixConnection connection) {
+         this.connection = connection;
+         this.queryTimeoutMillis = getDefaultQueryTimeoutMillis();
++        this.validateLastDdlTimestamp = ValidateLastDDLTimestampUtil
++                                            .getValidateLastDdlTimestampEnabled(this.connection);
+     }
+ 
+     /**
+      * Internally to Phoenix we allow callers to set the query timeout in millis
+      * via the phoenix.query.timeoutMs. Therefore we store the time in millis.
+      */
+     private int getDefaultQueryTimeoutMillis() {
+         return connection.getQueryServices().getProps().getInt(QueryServices.THREAD_TIMEOUT_MS_ATTRIB, 
+             QueryServicesOptions.DEFAULT_THREAD_TIMEOUT_MS);
+     }
+ 
+     protected List<PhoenixResultSet> getResultSets() {
+         if (lastResultSet != null) {
+             return Collections.singletonList(lastResultSet);
+         } else {
+             return Collections.emptyList();
+         }
+     }
+     
+     public PhoenixResultSet newResultSet(ResultIterator iterator, RowProjector projector, StatementContext context) throws SQLException {
+         return new PhoenixResultSet(iterator, projector, context);
+     }
+     
+     protected QueryPlan optimizeQuery(CompilableStatement stmt) throws SQLException {
+         QueryPlan plan = stmt.compilePlan(this, Sequence.ValueOp.VALIDATE_SEQUENCE);
+         return connection.getQueryServices().getOptimizer().optimize(this, plan);
+     }
+     
+     protected PhoenixResultSet executeQuery(final CompilableStatement stmt, final QueryLogger queryLogger)
+             throws SQLException {
 -        return executeQuery(stmt, true, queryLogger, false);
++        return executeQuery(stmt, true, queryLogger, false, this.validateLastDdlTimestamp);
+     }
+ 
+     protected PhoenixResultSet executeQuery(final CompilableStatement stmt, final QueryLogger queryLogger, boolean noCommit)
+             throws SQLException {
 -        return executeQuery(stmt, true, queryLogger, noCommit);
++        return executeQuery(stmt, true, queryLogger, noCommit, this.validateLastDdlTimestamp);
+     }
+ 
++
+     private PhoenixResultSet executeQuery(final CompilableStatement stmt,
 -                                          final boolean doRetryOnMetaNotFoundError, final QueryLogger queryLogger, final boolean noCommit) throws SQLException {
++                                          final boolean doRetryOnMetaNotFoundError,
++                                          final QueryLogger queryLogger, final boolean noCommit,
++                                          boolean shouldValidateLastDdlTimestamp)
++            throws SQLException {
+         GLOBAL_SELECT_SQL_COUNTER.increment();
+ 
+         try {
+             return CallRunner
+                     .run(new CallRunner.CallableThrowable<PhoenixResultSet, SQLException>() {
+                         @Override public PhoenixResultSet call() throws SQLException {
+                             final long startTime = EnvironmentEdgeManager.currentTimeMillis();
+                             boolean success = false;
++                            boolean updateMetrics = true;
+                             boolean pointLookup = false;
+                             String tableName = null;
+                             clearResultSet();
+                             PhoenixResultSet rs = null;
+                             try {
+                                 PhoenixConnection conn = getConnection();
+                                 conn.checkOpen();
+ 
+                                 if (conn.getQueryServices().isUpgradeRequired() && !conn
+                                         .isRunningUpgrade()
+                                         && stmt.getOperation() != Operation.UPGRADE) {
+                                     throw new UpgradeRequiredException();
+                                 }
+                                 QueryPlan
+                                         plan =
+                                         stmt.compilePlan(PhoenixStatement.this,
+                                                 Sequence.ValueOp.VALIDATE_SEQUENCE);
+                                 // Send mutations to hbase, so they are visible to subsequent reads.
+                                 // Use original plan for data table so that data and immutable indexes will be sent
+                                 // TODO: for joins, we need to iterate through all tables, but we need the original table,
+                                 // not the projected table, so plan.getContext().getResolver().getTables() won't work.
+                                 if (plan.getContext().getScanRanges().isPointLookup()) {
+                                     pointLookup = true;
+                                 }
+                                 Iterator<TableRef> tableRefs = plan.getSourceRefs().iterator();
+                                 connection.getMutationState().sendUncommitted(tableRefs);
+                                 plan =
+                                         connection.getQueryServices().getOptimizer()
+                                                 .optimize(PhoenixStatement.this, plan);
++                                setLastQueryPlan(plan);
++
++                                //verify metadata for the table/view/index in the query plan
++                                //plan.getTableRef can be null in some cases like EXPLAIN <query>
++                                if (shouldValidateLastDdlTimestamp && plan.getTableRef() != null) {
++                                    ValidateLastDDLTimestampUtil.validateLastDDLTimestamp(
++                                        connection, Arrays.asList(plan.getTableRef()), false, true);
++                                }
+ 
+                                 if (plan.getTableRef() != null
+                                         && plan.getTableRef().getTable() != null && !Strings
+                                         .isNullOrEmpty(
+                                                 plan.getTableRef().getTable().getPhysicalName()
+                                                         .toString())) {
+                                     tableName = plan.getTableRef().getTable().getPhysicalName()
+                                             .toString();
+                                 }
+                                 // this will create its own trace internally, so we don't wrap this
+                                 // whole thing in tracing
+                                 ResultIterator resultIterator = plan.iterator();
+                                 if (LOGGER.isDebugEnabled()) {
+                                     String explainPlan = QueryUtil.getExplainPlan(resultIterator);
+                                     LOGGER.debug(LogUtil.addCustomAnnotations(
+                                             "Explain plan: " + explainPlan, connection));
+                                 }
+                                 StatementContext context = plan.getContext();
+                                 context.setQueryLogger(queryLogger);
+                                 if (queryLogger.isDebugEnabled()) {
+                                     queryLogger.log(QueryLogInfo.EXPLAIN_PLAN_I,
+                                             QueryUtil.getExplainPlan(resultIterator));
+                                     queryLogger.log(QueryLogInfo.GLOBAL_SCAN_DETAILS_I,
+                                             context.getScan() != null ?
+                                                     context.getScan().toString() :
+                                                     null);
+                                 }
+                                 context.getOverallQueryMetrics().startQuery();
+                                 rs =
+                                         newResultSet(resultIterator, plan.getProjector(),
+                                                 plan.getContext());
+                                 // newResultset sets lastResultset
+                                 setLastQueryPlan(plan);
+                                 setLastUpdateCount(NO_UPDATE);
+                                 setLastUpdateTable(tableName == null ? TABLE_UNKNOWN : tableName);
+                                 setLastUpdateOperation(stmt.getOperation());
+                                 // If transactional, this will move the read pointer forward
+                                 if (connection.getAutoCommit() && !noCommit) {
+                                     connection.commit();
+                                 }
+                                 connection.incrementStatementExecutionCounter();
+                                 success = true;
+                             }
+                             //Force update cache and retry if meta not found error occurs
+                             catch (MetaDataEntityNotFoundException e) {
+                                 if (doRetryOnMetaNotFoundError && e.getTableName() != null) {
+                                     if (LOGGER.isDebugEnabled()) {
+                                         LOGGER.debug("Reloading table {} data from server",
+                                                 e.getTableName());
+                                     }
+                                     if (new MetaDataClient(connection)
+                                             .updateCache(connection.getTenantId(),
+                                                     e.getSchemaName(), e.getTableName(), true)
+                                             .wasUpdated()) {
++                                        updateMetrics = false;
+                                         //TODO we can log retry count and error for debugging in LOG table
 -                                        return executeQuery(stmt, false, queryLogger, noCommit);
++                                        return executeQuery(stmt, false, queryLogger, noCommit,
++                                                                shouldValidateLastDdlTimestamp);
+                                     }
+                                 }
+                                 throw e;
 -                            } catch (RuntimeException e) {
++                            } catch (StaleMetadataCacheException e) {
++                                GlobalClientMetrics
++                                        .GLOBAL_CLIENT_STALE_METADATA_CACHE_EXCEPTION_COUNTER
++                                        .increment();
++                                updateMetrics = false;
++                                PTable pTable = lastQueryPlan.getTableRef().getTable();
++                                String schemaN = pTable.getSchemaName().toString();
++                                String tableN = pTable.getTableName().toString();
++                                PName tenantId = connection.getTenantId();
++                                LOGGER.debug("Force updating client metadata cache for {}",
++                                        ValidateLastDDLTimestampUtil.getInfoString(tenantId,
++                                                Arrays.asList(getLastQueryPlan().getTableRef())));
+ 
++                                // if the index metadata was stale, we will update the client cache
++                                // for the parent table, which will also add the new index metadata
++                                PTableType tableType =pTable.getType();
++                                if (tableType == PTableType.INDEX) {
++                                    schemaN = pTable.getParentSchemaName().toString();
++                                    tableN = pTable.getParentTableName().toString();
++                                }
++                                // force update client metadata cache for the table/view
++                                // this also updates the cache for all ancestors in case of a view
++                                new MetaDataClient(connection)
++                                        .updateCache(tenantId, schemaN, tableN, true);
++                                // skip last ddl timestamp validation in the retry
++                                return executeQuery(stmt, doRetryOnMetaNotFoundError, queryLogger,
++                                                        noCommit, false);
++                            }
++                            catch (RuntimeException e) {
+                                 // FIXME: Expression.evaluate does not throw SQLException
+                                 // so this will unwrap throws from that.
+                                 if (e.getCause() instanceof SQLException) {
+                                     throw (SQLException) e.getCause();
+                                 }
+                                 throw e;
+                             } finally {
 -                                // Regardless of whether the query was successfully handled or not,
 -                                // update the time spent so far. If needed, we can separate out the
 -                                // success times and failure times.
 -                                GLOBAL_QUERY_TIME.update(EnvironmentEdgeManager.currentTimeMillis()
 -                                        - startTime);
 -                                long
 -                                        executeQueryTimeSpent =
 -                                        EnvironmentEdgeManager.currentTimeMillis() - startTime;
 -                                if (tableName != null) {
++                                if (updateMetrics) {
++                                    // Regardless of whether the query was successfully handled or not,
++                                    // update the time spent so far. If needed, we can separate out the
++                                    // success times and failure times.
++                                    GLOBAL_QUERY_TIME.update(EnvironmentEdgeManager.currentTimeMillis()
++                                            - startTime);
++                                    long
++                                            executeQueryTimeSpent =
++                                            EnvironmentEdgeManager.currentTimeMillis() - startTime;
++                                    if (tableName != null) {
+ 
 -                                    TableMetricsManager
 -                                            .updateMetricsMethod(tableName, SELECT_SQL_COUNTER, 1);
 -                                    TableMetricsManager
 -                                            .updateMetricsMethod(tableName, SELECT_SQL_QUERY_TIME,
 -                                                    executeQueryTimeSpent);
 -                                    if (success) {
 -                                        TableMetricsManager.updateMetricsMethod(tableName,
 -                                                SELECT_SUCCESS_SQL_COUNTER, 1);
 -                                        TableMetricsManager.updateMetricsMethod(tableName,
 -                                                pointLookup ?
 -                                                        SELECT_POINTLOOKUP_SUCCESS_SQL_COUNTER :
 -                                                        SELECT_SCAN_SUCCESS_SQL_COUNTER, 1);
 -                                    } else {
 -                                        TableMetricsManager.updateMetricsMethod(tableName,
 -                                                SELECT_FAILED_SQL_COUNTER, 1);
 -                                        TableMetricsManager.updateMetricsMethod(tableName,
 -                                                SELECT_AGGREGATE_FAILURE_SQL_COUNTER, 1);
 -                                        TableMetricsManager.updateMetricsMethod(tableName,
 -                                                pointLookup ?
 -                                                        SELECT_POINTLOOKUP_FAILED_SQL_COUNTER :
 -                                                        SELECT_SCAN_FAILED_SQL_COUNTER, 1);
++                                        TableMetricsManager
++                                                .updateMetricsMethod(tableName, SELECT_SQL_COUNTER, 1);
++                                        TableMetricsManager
++                                                .updateMetricsMethod(tableName, SELECT_SQL_QUERY_TIME,
++                                                        executeQueryTimeSpent);
++                                        if (success) {
++                                            TableMetricsManager.updateMetricsMethod(tableName,
++                                                    SELECT_SUCCESS_SQL_COUNTER, 1);
++                                            TableMetricsManager.updateMetricsMethod(tableName,
++                                                    pointLookup ?
++                                                            SELECT_POINTLOOKUP_SUCCESS_SQL_COUNTER :
++                                                            SELECT_SCAN_SUCCESS_SQL_COUNTER, 1);
++                                        } else {
++                                            TableMetricsManager.updateMetricsMethod(tableName,
++                                                    SELECT_FAILED_SQL_COUNTER, 1);
++                                            TableMetricsManager.updateMetricsMethod(tableName,
++                                                    SELECT_AGGREGATE_FAILURE_SQL_COUNTER, 1);
++                                            TableMetricsManager.updateMetricsMethod(tableName,
++                                                    pointLookup ?
++                                                            SELECT_POINTLOOKUP_FAILED_SQL_COUNTER :
++                                                            SELECT_SCAN_FAILED_SQL_COUNTER, 1);
++                                        }
++                                    }
++                                    if (rs != null) {
++                                        rs.setQueryTime(executeQueryTimeSpent);
+                                     }
 -                                }
 -                                if (rs != null) {
 -                                    rs.setQueryTime(executeQueryTimeSpent);
+                                 }
+                             }
+                             return rs;
+                         }
+                     }, PhoenixContextExecutor.inContext());
+         } catch (Exception e) {
+             if (queryLogger.isDebugEnabled()) {
+                 queryLogger
+                         .log(QueryLogInfo.EXCEPTION_TRACE_I, Throwables.getStackTraceAsString(e));
+                 queryLogger.log(QueryLogInfo.QUERY_STATUS_I, QueryStatus.FAILED.toString());
+                 queryLogger.sync(null, null);
+             }
+             Throwables.propagateIfInstanceOf(e, SQLException.class);
+             Throwables.propagate(e);
+             throw new IllegalStateException(); // Can't happen as Throwables.propagate() always throws
+         }
+     }
+ 
+     public String getTargetForAudit(CompilableStatement stmt) {
+         String target = null;
+         try {
+             if (stmt instanceof ExecutableUpsertStatement) {
+                 return ((ExecutableUpsertStatement) stmt).getTable().getName().toString();
+             } else if (stmt instanceof ExecutableDeleteStatement) {
+                 return ((ExecutableDeleteStatement) stmt).getTable().getName().toString();
+             } else if (stmt instanceof ExecutableCreateTableStatement) {
+                 target = ((ExecutableCreateTableStatement)stmt).getTableName().toString();
+             } else if (stmt instanceof ExecutableDropTableStatement) {
+                 target = ((ExecutableDropTableStatement)stmt).getTableName().toString();
+             } else if (stmt instanceof ExecutableAddColumnStatement) {
+                 target = ((ExecutableAddColumnStatement)stmt).getTable().getName().toString();
+             } else if (stmt instanceof ExecutableCreateSchemaStatement) {
+                 return ((ExecutableCreateSchemaStatement) stmt).getSchemaName();
+             } else if (stmt instanceof ExecutableDropSchemaStatement) {
+                 target = ((ExecutableDropSchemaStatement)stmt).getSchemaName();
+             }
+         } catch (Exception e) {
+             target = stmt.getClass().getName();
+         }
+         return target;
+     }
+ 
+ 
+     protected int executeMutation(final CompilableStatement stmt, final AuditQueryLogger queryLogger) throws SQLException {
+         return executeMutation(stmt, true, queryLogger);
+     }
+ 
+     private int executeMutation(final CompilableStatement stmt, final boolean doRetryOnMetaNotFoundError, final AuditQueryLogger queryLogger) throws SQLException {
+         if (connection.isReadOnly()) {
+             throw new SQLExceptionInfo.Builder(
+                 SQLExceptionCode.READ_ONLY_CONNECTION).
+                 build().buildException();
+         }
+ 	    GLOBAL_MUTATION_SQL_COUNTER.increment();
+         try {
+             return CallRunner
+                     .run(
+                         new CallRunner.CallableThrowable<Integer, SQLException>() {
+                         @Override
+                             public Integer call() throws SQLException {
+                             boolean success = false;
+                             String tableName = null;
+                             boolean isUpsert = false;
+                             boolean isAtomicUpsert = false;
+                             boolean isDelete = false;
+                             MutationState state = null;
+                             MutationPlan plan = null;
+                             final long startExecuteMutationTime = EnvironmentEdgeManager.currentTimeMillis();
+                             clearResultSet();
+                             try {
+                                 PhoenixConnection conn = getConnection();
+                                 if (conn.getQueryServices().isUpgradeRequired() && !conn.isRunningUpgrade()
+                                         && stmt.getOperation() != Operation.UPGRADE) {
+                                     throw new UpgradeRequiredException();
+                                 }
+                                 state = connection.getMutationState();
+                                 plan = stmt.compilePlan(PhoenixStatement.this, Sequence.ValueOp.VALIDATE_SEQUENCE);
+                                 isUpsert = stmt instanceof ExecutableUpsertStatement;
+                                 isDelete = stmt instanceof ExecutableDeleteStatement;
+                                 isAtomicUpsert = isUpsert && ((ExecutableUpsertStatement)stmt).getOnDupKeyPairs() != null;
+                                 if (plan.getTargetRef() != null && plan.getTargetRef().getTable() != null) {
+                                     if (!Strings.isNullOrEmpty(plan.getTargetRef().getTable().getPhysicalName().toString())) {
+                                         tableName = plan.getTargetRef().getTable().getPhysicalName().toString();
+                                     }
+                                     if (plan.getTargetRef().getTable().isTransactional()) {
+                                         state.startTransaction(plan.getTargetRef().getTable().getTransactionProvider());
+                                     }
+                                 }
+                                 Iterator<TableRef> tableRefs = plan.getSourceRefs().iterator();
+                                 state.sendUncommitted(tableRefs);
+                                 state.checkpointIfNeccessary(plan);
+                                 checkIfDDLStatementandMutationState(stmt, state);
+                                 MutationState lastState = plan.execute();
+                                 state.join(lastState);
+                                 if (connection.getAutoCommit()) {
+                                     connection.commit();
+                                 }
+                                 setLastQueryPlan(null);
+                                 // Unfortunately, JDBC uses an int for update count, so we
+                                 // just max out at Integer.MAX_VALUE
+                                 int lastUpdateCount = (int) Math.min(Integer.MAX_VALUE, lastState.getUpdateCount());
+                                 setLastUpdateCount(lastUpdateCount);
+                                 setLastUpdateOperation(stmt.getOperation());
+                                 setLastUpdateTable(tableName == null ? TABLE_UNKNOWN : tableName);
+                                 connection.incrementStatementExecutionCounter();
+                                 if (queryLogger.isAuditLoggingEnabled()) {
+                                     queryLogger.log(QueryLogInfo.TABLE_NAME_I, getTargetForAudit(stmt));
+                                     queryLogger.log(QueryLogInfo.QUERY_STATUS_I, QueryStatus.COMPLETED.toString());
+                                     queryLogger.log(QueryLogInfo.NO_OF_RESULTS_ITERATED_I, lastUpdateCount);
+                                     queryLogger.syncAudit();
+                                 }
+ 
+                                 success = true;
+                                 return lastUpdateCount;
+                             }
+                             //Force update cache and retry if meta not found error occurs
+                             catch (MetaDataEntityNotFoundException e) {
+                                 if (doRetryOnMetaNotFoundError && e.getTableName() != null) {
+                                     if (LOGGER.isDebugEnabled()) {
+                                         LOGGER.debug("Reloading table {} data from server",  e.getTableName());
+                                     }
+                                     if (new MetaDataClient(connection).updateCache(connection.getTenantId(),
+                                         e.getSchemaName(), e.getTableName(), true).wasUpdated()) {
+                                         return executeMutation(stmt, false, queryLogger);
+                                     }
+                                 }
+                                 throw e;
+                             }catch (RuntimeException e) {
+                                 // FIXME: Expression.evaluate does not throw SQLException
+                                 // so this will unwrap throws from that.
+                                 if (e.getCause() instanceof SQLException) {
+                                     throw (SQLException) e.getCause();
+                                 }
+                                 throw e;
+                             } finally {
+                                 // Regardless of whether the mutation was successfully handled or not,
+                                 // update the time spent so far. If needed, we can separate out the
+                                 // success times and failure times.
+                                 if (tableName != null) {
+                                     // Counts for both ddl and dml
+                                     TableMetricsManager.updateMetricsMethod(tableName,
+                                             MUTATION_SQL_COUNTER, 1);
+                                     // Only count dml operations
+                                     if (isUpsert || isDelete) {
+                                         long executeMutationTimeSpent =
+                                                 EnvironmentEdgeManager.currentTimeMillis() - startExecuteMutationTime;
+ 
+                                         TableMetricsManager.updateMetricsMethod(tableName, isUpsert ?
+                                                 UPSERT_SQL_COUNTER : DELETE_SQL_COUNTER, 1);
+                                         TableMetricsManager.updateMetricsMethod(tableName, isUpsert ?
+                                                 UPSERT_SQL_QUERY_TIME : DELETE_SQL_QUERY_TIME, executeMutationTimeSpent);
+                                         if (isAtomicUpsert) {
+                                             TableMetricsManager.updateMetricsMethod(tableName,
+                                                 ATOMIC_UPSERT_SQL_COUNTER, 1);
+                                             TableMetricsManager.updateMetricsMethod(tableName,
+                                                 ATOMIC_UPSERT_SQL_QUERY_TIME, executeMutationTimeSpent);
+                                         }
+ 
+                                         if (success) {
+                                             TableMetricsManager.updateMetricsMethod(tableName, isUpsert ?
+                                                     UPSERT_SUCCESS_SQL_COUNTER : DELETE_SUCCESS_SQL_COUNTER, 1);
+                                         } else {
+                                             TableMetricsManager.updateMetricsMethod(tableName, isUpsert ?
+                                                     UPSERT_FAILED_SQL_COUNTER : DELETE_FAILED_SQL_COUNTER, 1);
+                                             //Failures are updated for executeMutation phase and for autocommit=true case here.
+                                             TableMetricsManager.updateMetricsMethod(tableName, isUpsert ? UPSERT_AGGREGATE_FAILURE_SQL_COUNTER:
+                                                     DELETE_AGGREGATE_FAILURE_SQL_COUNTER, 1);
+                                         }
+                                         if (plan instanceof DeleteCompiler.ServerSelectDeleteMutationPlan
+                                                 || plan instanceof UpsertCompiler.ServerUpsertSelectMutationPlan) {
+                                             TableMetricsManager.updateLatencyHistogramForMutations(
+                                                     tableName, executeMutationTimeSpent, false);
+                                             // We won't have size histograms for delete mutations when auto commit is set to true and
+                                             // if plan is of ServerSelectDeleteMutationPlan or ServerUpsertSelectMutationPlan
+                                             // since the update happens on server.
+                                         } else {
+                                             state.addExecuteMutationTime(
+                                                     executeMutationTimeSpent, tableName);
+                                         }
+                                     }
+                                 }
+ 
+                             }
+                         }
+                     }, PhoenixContextExecutor.inContext(),
+                         Tracing.withTracing(connection, this.toString()));
+         } catch (Exception e) {
+             if (queryLogger.isAuditLoggingEnabled()) {
+                 queryLogger.log(QueryLogInfo.TABLE_NAME_I, getTargetForAudit(stmt));
+                 queryLogger.log(QueryLogInfo.EXCEPTION_TRACE_I, Throwables.getStackTraceAsString(e));
+                 queryLogger.log(QueryLogInfo.QUERY_STATUS_I, QueryStatus.FAILED.toString());
+                 queryLogger.syncAudit();
+             }
+             Throwables.propagateIfInstanceOf(e, SQLException.class);
+             Throwables.propagate(e);
+             throw new IllegalStateException(); // Can't happen as Throwables.propagate() always throws
+         }
+     }
+ 
+     protected static interface CompilableStatement extends BindableStatement {
+         public <T extends StatementPlan> T compilePlan (PhoenixStatement stmt, Sequence.ValueOp seqAction) throws SQLException;
+     }
+     
+     private static class ExecutableSelectStatement extends SelectStatement implements CompilableStatement {
+         private ExecutableSelectStatement(TableNode from, HintNode hint, boolean isDistinct, List<AliasedNode> select, ParseNode where,
+                 List<ParseNode> groupBy, ParseNode having, List<OrderByNode> orderBy, LimitNode limit, OffsetNode offset, int bindCount, boolean isAggregate, boolean hasSequence, Map<String, UDFParseNode> udfParseNodes) {
+             this(from, hint, isDistinct, select, where, groupBy, having, orderBy, limit,offset, bindCount, isAggregate, hasSequence, Collections.<SelectStatement>emptyList(), udfParseNodes);
+         }
+ 
+         private ExecutableSelectStatement(TableNode from, HintNode hint, boolean isDistinct, List<AliasedNode> select, ParseNode where,
+                 List<ParseNode> groupBy, ParseNode having, List<OrderByNode> orderBy, LimitNode limit, OffsetNode offset, int bindCount, boolean isAggregate,
+                 boolean hasSequence, List<SelectStatement> selects, Map<String, UDFParseNode> udfParseNodes) {
+             super(from, hint, isDistinct, select, where, groupBy, having, orderBy, limit, offset, bindCount, isAggregate, hasSequence, selects, udfParseNodes);
+         }
+         
+         private ExecutableSelectStatement(ExecutableSelectStatement select) {
+             this(select.getFrom(), select.getHint(), select.isDistinct(), select.getSelect(), select.getWhere(),
+                     select.getGroupBy(), select.getHaving(), select.getOrderBy(), select.getLimit(), select.getOffset(), select.getBindCount(),
+                     select.isAggregate(), select.hasSequence(), select.getSelects(), select.getUdfParseNodes());
+         }
+ 		
+         
+         @SuppressWarnings("unchecked")
+         @Override
+         public QueryPlan compilePlan(PhoenixStatement phoenixStatement, Sequence.ValueOp seqAction) throws SQLException {
+             if (!getUdfParseNodes().isEmpty()) {
+                 phoenixStatement.throwIfUnallowedUserDefinedFunctions(getUdfParseNodes());
+             }
+ 
+             RewriteResult rewriteResult =
+                     ParseNodeUtil.rewrite(this, phoenixStatement.getConnection());
+             QueryPlan queryPlan = new QueryCompiler(
+                     phoenixStatement,
+                     rewriteResult.getRewrittenSelectStatement(),
+                     rewriteResult.getColumnResolver(),
+                     Collections.<PDatum>emptyList(),
+                     phoenixStatement.getConnection().getIteratorFactory(),
+                     new SequenceManager(phoenixStatement),
+                     true,
+                     false,
+                     null).compile();
+             queryPlan.getContext().getSequenceManager().validateSequences(seqAction);
+             return queryPlan;
+         }
+ 
+     }
+     
+     private static final byte[] EXPLAIN_PLAN_FAMILY = QueryConstants.SINGLE_COLUMN_FAMILY;
+     private static final byte[] EXPLAIN_PLAN_COLUMN = PVarchar.INSTANCE.toBytes("Plan");
+     private static final String EXPLAIN_PLAN_ALIAS = "PLAN";
+     private static final String EXPLAIN_PLAN_TABLE_NAME = "PLAN_TABLE";
+     private static final PDatum EXPLAIN_PLAN_DATUM = new PDatum() {
+         @Override
+         public boolean isNullable() {
+             return true;
+         }
+         @Override
+         public PDataType getDataType() {
+             return PVarchar.INSTANCE;
+         }
+         @Override
+         public Integer getMaxLength() {
+             return null;
+         }
+         @Override
+         public Integer getScale() {
+             return null;
+         }
+         @Override
+         public SortOrder getSortOrder() {
+             return SortOrder.getDefault();
+         }
+     };
+     private static final String EXPLAIN_PLAN_BYTES_ESTIMATE_COLUMN_NAME = "BytesEstimate";
+     private static final byte[] EXPLAIN_PLAN_BYTES_ESTIMATE =
+             PVarchar.INSTANCE.toBytes(EXPLAIN_PLAN_BYTES_ESTIMATE_COLUMN_NAME);
+     public static final String EXPLAIN_PLAN_BYTES_ESTIMATE_COLUMN_ALIAS = "EST_BYTES_READ";
+     private static final PColumnImpl EXPLAIN_PLAN_BYTES_ESTIMATE_COLUMN =
+             new PColumnImpl(PNameFactory.newName(EXPLAIN_PLAN_BYTES_ESTIMATE),
+                     PNameFactory.newName(EXPLAIN_PLAN_FAMILY), PLong.INSTANCE, null, null, true, 1,
+                     SortOrder.getDefault(), 0, null, false, null, false, false,
+                     EXPLAIN_PLAN_BYTES_ESTIMATE, 0, false);
+ 
+     private static final String EXPLAIN_PLAN_ROWS_ESTIMATE_COLUMN_NAME = "RowsEstimate";
+     private static final byte[] EXPLAIN_PLAN_ROWS_ESTIMATE =
+             PVarchar.INSTANCE.toBytes(EXPLAIN_PLAN_ROWS_ESTIMATE_COLUMN_NAME);
+     public static final String EXPLAIN_PLAN_ROWS_COLUMN_ALIAS = "EST_ROWS_READ";
+     private static final PColumnImpl EXPLAIN_PLAN_ROWS_ESTIMATE_COLUMN =
+             new PColumnImpl(PNameFactory.newName(EXPLAIN_PLAN_ROWS_ESTIMATE),
+                     PNameFactory.newName(EXPLAIN_PLAN_FAMILY), PLong.INSTANCE, null, null, true, 2,
+                     SortOrder.getDefault(), 0, null, false, null, false, false,
+                     EXPLAIN_PLAN_ROWS_ESTIMATE, 0, false);
+ 
+     private static final String EXPLAIN_PLAN_ESTIMATE_INFO_TS_COLUMN_NAME = "EstimateInfoTS";
+     private static final byte[] EXPLAIN_PLAN_ESTIMATE_INFO_TS =
+             PVarchar.INSTANCE.toBytes(EXPLAIN_PLAN_ESTIMATE_INFO_TS_COLUMN_NAME);
+     public static final String EXPLAIN_PLAN_ESTIMATE_INFO_TS_COLUMN_ALIAS = "EST_INFO_TS";
+     private static final PColumnImpl EXPLAIN_PLAN_ESTIMATE_INFO_TS_COLUMN =
+             new PColumnImpl(PNameFactory.newName(EXPLAIN_PLAN_ESTIMATE_INFO_TS),
+                 PNameFactory.newName(EXPLAIN_PLAN_FAMILY), PLong.INSTANCE, null, null, true, 3,
+                 SortOrder.getDefault(), 0, null, false, null, false, false,
+                 EXPLAIN_PLAN_ESTIMATE_INFO_TS, 0, false);
+ 
+     private static final RowProjector EXPLAIN_PLAN_ROW_PROJECTOR_WITH_BYTE_ROW_ESTIMATES =
+             new RowProjector(Arrays
+                     .<ColumnProjector> asList(
+                         new ExpressionProjector(EXPLAIN_PLAN_ALIAS, EXPLAIN_PLAN_ALIAS,
+                                 EXPLAIN_PLAN_TABLE_NAME,
+                                 new RowKeyColumnExpression(EXPLAIN_PLAN_DATUM,
+                                         new RowKeyValueAccessor(Collections
+                                                 .<PDatum> singletonList(EXPLAIN_PLAN_DATUM), 0)),
+                                 false),
+                         new ExpressionProjector(EXPLAIN_PLAN_BYTES_ESTIMATE_COLUMN_ALIAS,
+                                 EXPLAIN_PLAN_BYTES_ESTIMATE_COLUMN_ALIAS,
+                                 EXPLAIN_PLAN_TABLE_NAME, new KeyValueColumnExpression(
+                                         EXPLAIN_PLAN_BYTES_ESTIMATE_COLUMN),
+                                 false),
+                         new ExpressionProjector(EXPLAIN_PLAN_ROWS_COLUMN_ALIAS,
+                                 EXPLAIN_PLAN_ROWS_COLUMN_ALIAS,
+                                 EXPLAIN_PLAN_TABLE_NAME,
+                                 new KeyValueColumnExpression(EXPLAIN_PLAN_ROWS_ESTIMATE_COLUMN),
+                                 false),
+                         new ExpressionProjector(EXPLAIN_PLAN_ESTIMATE_INFO_TS_COLUMN_ALIAS,
+                                 EXPLAIN_PLAN_ESTIMATE_INFO_TS_COLUMN_ALIAS,
+                                 EXPLAIN_PLAN_TABLE_NAME,
+                                 new KeyValueColumnExpression(EXPLAIN_PLAN_ESTIMATE_INFO_TS_COLUMN),
+                                 false)),
+                     0, true);
+ 
+     private static class ExecutableExplainStatement extends ExplainStatement implements CompilableStatement {
+ 
+         ExecutableExplainStatement(BindableStatement statement, ExplainType explainType) {
+             super(statement, explainType);
+         }
+ 
+         @Override
+         public CompilableStatement getStatement() {
+             return (CompilableStatement) super.getStatement();
+         }
+         
+         @Override
+         public int getBindCount() {
+             return getStatement().getBindCount();
+         }
+ 
+         @SuppressWarnings("unchecked")
+         @Override
+         public QueryPlan compilePlan(PhoenixStatement stmt, Sequence.ValueOp seqAction) throws SQLException {
+             CompilableStatement compilableStmt = getStatement();
+             StatementPlan compilePlan = compilableStmt.compilePlan(stmt, Sequence.ValueOp.VALIDATE_SEQUENCE);
+             // For a QueryPlan, we need to get its optimized plan; for a MutationPlan, its enclosed QueryPlan
+             // has already been optimized during compilation.
+             if (compilePlan instanceof QueryPlan) {
+                 QueryPlan dataPlan = (QueryPlan) compilePlan;
+                 compilePlan = stmt.getConnection().getQueryServices().getOptimizer().optimize(stmt, dataPlan);
+             }
+             final StatementPlan plan = compilePlan;
+             List<String> planSteps = plan.getExplainPlan().getPlanSteps();
+             ExplainType explainType = getExplainType();
+             if (explainType == ExplainType.DEFAULT) {
+                 List<String> updatedExplainPlanSteps = new ArrayList<>(planSteps);
+                 updatedExplainPlanSteps.removeIf(planStep -> planStep != null
+                         && planStep.contains(ExplainTable.REGION_LOCATIONS));
+                 planSteps = Collections.unmodifiableList(updatedExplainPlanSteps);
+             }
+             List<Tuple> tuples = Lists.newArrayListWithExpectedSize(planSteps.size());
+             Long estimatedBytesToScan = plan.getEstimatedBytesToScan();
+             Long estimatedRowsToScan = plan.getEstimatedRowsToScan();
+             Long estimateInfoTimestamp = plan.getEstimateInfoTimestamp();
+             for (String planStep : planSteps) {
+                 byte[] row = PVarchar.INSTANCE.toBytes(planStep);
+                 List<Cell> cells = Lists.newArrayListWithCapacity(3);
+                 cells.add(PhoenixKeyValueUtil.newKeyValue(row, EXPLAIN_PLAN_FAMILY, EXPLAIN_PLAN_COLUMN,
+                     MetaDataProtocol.MIN_TABLE_TIMESTAMP, ByteUtil.EMPTY_BYTE_ARRAY));
+                 if (estimatedBytesToScan != null) {
+                     cells.add(PhoenixKeyValueUtil.newKeyValue(row, EXPLAIN_PLAN_FAMILY, EXPLAIN_PLAN_BYTES_ESTIMATE,
+                         MetaDataProtocol.MIN_TABLE_TIMESTAMP,
+                         PLong.INSTANCE.toBytes(estimatedBytesToScan)));
+                 }
+                 if (estimatedRowsToScan != null) {
+                     cells.add(PhoenixKeyValueUtil.newKeyValue(row, EXPLAIN_PLAN_FAMILY, EXPLAIN_PLAN_ROWS_ESTIMATE,
+                         MetaDataProtocol.MIN_TABLE_TIMESTAMP,
+                         PLong.INSTANCE.toBytes(estimatedRowsToScan)));
+                 }
+                 if (estimateInfoTimestamp != null) {
+                     cells.add(PhoenixKeyValueUtil.newKeyValue(row, EXPLAIN_PLAN_FAMILY, EXPLAIN_PLAN_ESTIMATE_INFO_TS,
+                         MetaDataProtocol.MIN_TABLE_TIMESTAMP,
+                         PLong.INSTANCE.toBytes(estimateInfoTimestamp)));
+                 }
+                 Collections.sort(cells, CellComparator.getInstance());
+                 Tuple tuple = new MultiKeyValueTuple(cells);
+                 tuples.add(tuple);
+             }
+             final Long estimatedBytes = estimatedBytesToScan;
+             final Long estimatedRows = estimatedRowsToScan;
+             final Long estimateTs = estimateInfoTimestamp;
+             final ResultIterator iterator = new MaterializedResultIterator(tuples);
+             return new QueryPlan() {
+ 
+                 @Override
+                 public ParameterMetaData getParameterMetaData() {
+                     return PhoenixParameterMetaData.EMPTY_PARAMETER_META_DATA;
+                 }
+ 
+                 @Override
+                 public ExplainPlan getExplainPlan() throws SQLException {
+                     return new ExplainPlan(Collections.singletonList("EXPLAIN PLAN"));
+                 }
+ 
+                 @Override
+                 public ResultIterator iterator() throws SQLException {
+                     return iterator;
+                 }
+                 
+                 @Override
+                 public ResultIterator iterator(ParallelScanGrouper scanGrouper) throws SQLException {
+                     return iterator;
+                 }
+ 
+                 @Override
+                 public ResultIterator iterator(ParallelScanGrouper scanGrouper, Scan scan) throws SQLException {
+                     return iterator;
+                 }
+ 
+                 @Override
+                 public long getEstimatedSize() {
+                     return 0;
+                 }
+ 
+                 @Override
+                 public Cost getCost() {
+                     return Cost.ZERO;
+                 }
+ 
+                 @Override
+                 public TableRef getTableRef() {
+                     return null;
+                 }
+ 
+                 @Override
+                 public Set<TableRef> getSourceRefs() {
+                     return Collections.emptySet();
+                 }
+ 
+                 @Override
+                 public RowProjector getProjector() {
+                     return EXPLAIN_PLAN_ROW_PROJECTOR_WITH_BYTE_ROW_ESTIMATES;
+                 }
+ 
+                 @Override
+                 public Integer getLimit() {
+                     return null;
+                 }
+ 
+                 @Override
+                 public Integer getOffset() {
+                     return null;
+                 }
+ 
+                 @Override
+                 public OrderBy getOrderBy() {
+                     return OrderBy.EMPTY_ORDER_BY;
+                 }
+ 
+                 @Override
+                 public GroupBy getGroupBy() {
+                     return GroupBy.EMPTY_GROUP_BY;
+                 }
+ 
+                 @Override
+                 public List<KeyRange> getSplits() {
+                     return Collections.emptyList();
+                 }
+ 
+                 @Override
+                 public List<List<Scan>> getScans() {
+                     return Collections.emptyList();
+                 }
+ 
+                 @Override
+                 public StatementContext getContext() {
+                     return plan.getContext();
+                 }
+ 
+                 @Override
+                 public FilterableStatement getStatement() {
+                     return null;
+                 }
+ 
+                 @Override
+                 public boolean isDegenerate() {
+                     return false;
+                 }
+ 
+                 @Override
+                 public boolean isRowKeyOrdered() {
+                     return true;
+                 }
+ 
+                 @Override
+                 public Operation getOperation() {
+                     return ExecutableExplainStatement.this.getOperation();
+                 }
+ 
+                 @Override
+                 public boolean useRoundRobinIterator() throws SQLException {
+                     return false;
+                 }
+ 
+                 @Override
+                 public <T> T accept(QueryPlanVisitor<T> visitor) {
+                     return visitor.defaultReturn(this);
+                 }
+ 
+                 @Override
+                 public Long getEstimatedRowsToScan() {
+                     return estimatedRows;
+                 }
+ 
+                 @Override
+                 public Long getEstimatedBytesToScan() {
+                     return estimatedBytes;
+                 }
+                 
+                 @Override
+                 public Long getEstimateInfoTimestamp() throws SQLException {
+                     return estimateTs;
+                 }
+ 
+                 @Override
+                 public List<OrderBy> getOutputOrderBys() {
+                     return Collections.<OrderBy> emptyList();
+                 }
+ 
+                 @Override
+                 public boolean isApplicable() {
+                     return true;
+                 }
+             };
+         }
+     }
+ 
+     private static class ExecutableUpsertStatement extends UpsertStatement implements CompilableStatement {
+         private ExecutableUpsertStatement(NamedTableNode table, HintNode hintNode, List<ColumnName> columns,
+                 List<ParseNode> values, SelectStatement select, int bindCount, Map<String, UDFParseNode> udfParseNodes,
+                 List<Pair<ColumnName, ParseNode>> onDupKeyPairs) {
+             super(table, hintNode, columns, values, select, bindCount, udfParseNodes, onDupKeyPairs);
+         }
+ 
+         @SuppressWarnings("unchecked")
+         @Override
+         public MutationPlan compilePlan(PhoenixStatement stmt, Sequence.ValueOp seqAction) throws SQLException {
+             if (!getUdfParseNodes().isEmpty()) {
+                 stmt.throwIfUnallowedUserDefinedFunctions(getUdfParseNodes());
+             }
+ 			UpsertCompiler compiler = new UpsertCompiler(stmt, this.getOperation());
+             MutationPlan plan = compiler.compile(this);
+             plan.getContext().getSequenceManager().validateSequences(seqAction);
+             return plan;
+         }
+     }
+     
+     private static class ExecutableDeleteStatement extends DeleteStatement implements CompilableStatement {
+         private ExecutableDeleteStatement(NamedTableNode table, HintNode hint, ParseNode whereNode, List<OrderByNode> orderBy, LimitNode limit, int bindCount, Map<String, UDFParseNode> udfParseNodes) {
+             super(table, hint, whereNode, orderBy, limit, bindCount, udfParseNodes);
+         }
+ 
+         @SuppressWarnings("unchecked")
+         @Override
+         public MutationPlan compilePlan(PhoenixStatement stmt, Sequence.ValueOp seqAction) throws SQLException {
+             if (!getUdfParseNodes().isEmpty()) {
+                 stmt.throwIfUnallowedUserDefinedFunctions(getUdfParseNodes());
+             }
+ 		    DeleteCompiler compiler = new DeleteCompiler(stmt, this.getOperation());
+             MutationPlan plan = compiler.compile(this);
+             plan.getContext().getSequenceManager().validateSequences(seqAction);
+             return plan;
+         }
+     }
+     
+     private static class ExecutableCreateTableStatement extends CreateTableStatement implements CompilableStatement {
+         ExecutableCreateTableStatement(TableName tableName, ListMultimap<String,Pair<String,Object>> props, List<ColumnDef> columnDefs,
+                                        PrimaryKeyConstraint pkConstraint, List<ParseNode> splitNodes, PTableType tableType, boolean ifNotExists,
+                                        TableName baseTableName, ParseNode tableTypeIdNode, int bindCount, Boolean immutableRows,
+                                        Map<String, Integer> familyCounters, boolean noVerify) {
+             super(tableName, props, columnDefs, pkConstraint, splitNodes, tableType, ifNotExists,
+                     baseTableName, tableTypeIdNode, bindCount, immutableRows, familyCounters,
+                     noVerify);
+         }
+ 
+         @SuppressWarnings("unchecked")
+         @Override
+         public MutationPlan compilePlan(PhoenixStatement stmt, Sequence.ValueOp seqAction) throws SQLException {
+             CreateTableCompiler compiler = new CreateTableCompiler(stmt, this.getOperation());
+             return compiler.compile(this);
+         }
+     }
+ 
+     private static class ExecutableCreateSchemaStatement extends CreateSchemaStatement implements CompilableStatement {
+         ExecutableCreateSchemaStatement(String schemaName, boolean ifNotExists) {
+             super(schemaName, ifNotExists);
+         }
+ 
+         @SuppressWarnings("unchecked")
+         @Override
+         public MutationPlan compilePlan(PhoenixStatement stmt, Sequence.ValueOp seqAction) throws SQLException {
+             CreateSchemaCompiler compiler = new CreateSchemaCompiler(stmt);
+             return compiler.compile(this);
+         }
+     }
+ 
+     private static class ExecutableCreateFunctionStatement extends CreateFunctionStatement implements CompilableStatement {
+ 
+         public ExecutableCreateFunctionStatement(PFunction functionInfo, boolean temporary, boolean isReplace) {
+             super(functionInfo, temporary, isReplace);
+         }
+ 
+ 
+         @SuppressWarnings("unchecked")
+         @Override
+         public MutationPlan compilePlan(final PhoenixStatement stmt, Sequence.ValueOp seqAction) throws SQLException {
+             stmt.throwIfUnallowedUserDefinedFunctions(Collections.EMPTY_MAP);
+             CreateFunctionCompiler compiler = new CreateFunctionCompiler(stmt);
+             return compiler.compile(this);
+         }
+     }
+ 
+     private static class ExecutableDropFunctionStatement extends DropFunctionStatement implements CompilableStatement {
+ 
+         public ExecutableDropFunctionStatement(String functionName, boolean ifNotExists) {
+             super(functionName, ifNotExists);
+         }
+ 
+         @SuppressWarnings("unchecked")
+         @Override
+         public MutationPlan compilePlan(final PhoenixStatement stmt, Sequence.ValueOp seqAction) throws SQLException {
+                 final StatementContext context = new StatementContext(stmt);
+                 return new BaseMutationPlan(context, this.getOperation()) {
+ 
+                     @Override
+                     public ParameterMetaData getParameterMetaData() {
+                         return PhoenixParameterMetaData.EMPTY_PARAMETER_META_DATA;
+                     }
+ 
+                     @Override
+                     public ExplainPlan getExplainPlan() throws SQLException {
+                         return new ExplainPlan(Collections.singletonList("DROP FUNCTION"));
+                     }
+ 
+                     @Override
+                     public MutationState execute() throws SQLException {
+                         MetaDataClient client = new MetaDataClient(getContext().getConnection());
+                         return client.dropFunction(ExecutableDropFunctionStatement.this);
+                     }
+                 };
+         }
+     }
+     
+     private static class ExecutableAddJarsStatement extends AddJarsStatement implements CompilableStatement {
+ 
+         public ExecutableAddJarsStatement(List<LiteralParseNode> jarPaths) {
+             super(jarPaths);
+         }
+ 
+ 
+         @SuppressWarnings("unchecked")
+         @Override
+         public MutationPlan compilePlan(final PhoenixStatement stmt, Sequence.ValueOp seqAction) throws SQLException {
+             final StatementContext context = new StatementContext(stmt);
+             return new CustomMutationPlan(context, stmt);
+         }
+ 
+         private class CustomMutationPlan extends BaseMutationPlan {
+ 
+             private final StatementContext context;
+             private final PhoenixStatement stmt;
+ 
+             private CustomMutationPlan(StatementContext context, PhoenixStatement stmt) {
+                 super(context, ExecutableAddJarsStatement.this.getOperation());
+                 this.context = context;
+                 this.stmt = stmt;
+             }
+ 
+             @Override
+             public ParameterMetaData getParameterMetaData() {
+                 return PhoenixParameterMetaData.EMPTY_PARAMETER_META_DATA;
+             }
+ 
+             @Override
+             public ExplainPlan getExplainPlan() throws SQLException {
+                 return new ExplainPlan(Collections.singletonList("ADD JARS"));
+             }
+ 
+             @Override
+             public MutationState execute() throws SQLException {
+                 String dynamicJarsDir = stmt.getConnection().getQueryServices().getProps()
+                     .get(QueryServices.DYNAMIC_JARS_DIR_KEY);
+                 if (dynamicJarsDir == null) {
+                     throw new SQLException(QueryServices.DYNAMIC_JARS_DIR_KEY
+                         + " is not configured for placing the jars.");
+                 }
+                 dynamicJarsDir =
+                   dynamicJarsDir.endsWith("/") ? dynamicJarsDir : dynamicJarsDir + '/';
+                 Configuration conf = HBaseFactoryProvider.getConfigurationFactory()
+                     .getConfiguration();
+                 Path dynamicJarsDirPath = new Path(dynamicJarsDir);
+                 for (LiteralParseNode jarPath : getJarPaths()) {
+                     String jarPathStr = (String) jarPath.getValue();
+                     if (!jarPathStr.endsWith(".jar")) {
+                         throw new SQLException(jarPathStr + " is not a valid jar file path.");
+                     }
+                 }
+                 try {
+                     FileSystem fs = dynamicJarsDirPath.getFileSystem(conf);
+                     List<LiteralParseNode> jarPaths = getJarPaths();
+                     for (LiteralParseNode jarPath : jarPaths) {
+                         File f = new File((String) jarPath.getValue());
+                         fs.copyFromLocalFile(new Path(f.getAbsolutePath()), new Path(
+                             dynamicJarsDir + f.getName()));
+                     }
+                 } catch (IOException e) {
+                     throw new SQLException(e);
+                 }
+                 return new MutationState(0, 0, context.getConnection());
+             }
+         }
+     }
+     
+     private static class ExecutableDeclareCursorStatement extends DeclareCursorStatement implements CompilableStatement {
+         public ExecutableDeclareCursorStatement(CursorName cursor, SelectStatement select){
+             super(cursor, select);
+         }
+ 
+         @Override
+         public MutationPlan compilePlan(PhoenixStatement stmt, Sequence.ValueOp seqAction) throws SQLException {
+             ExecutableSelectStatement wrappedSelect = new ExecutableSelectStatement(
+             		(ExecutableSelectStatement) stmt.parseStatement(this.getQuerySQL()));
+             DeclareCursorCompiler compiler = new DeclareCursorCompiler(stmt, this.getOperation(),wrappedSelect.compilePlan(stmt, seqAction));
+             return compiler.compile(this);
+         }
+     }
+ 
+     private static class ExecutableOpenStatement extends OpenStatement implements CompilableStatement {
+         public ExecutableOpenStatement(CursorName cursor){
+             super(cursor);
+         }
+ 
+         @Override
+         public MutationPlan compilePlan(PhoenixStatement stmt, Sequence.ValueOp seqAction) throws SQLException {
+             OpenStatementCompiler compiler = new OpenStatementCompiler(stmt, this.getOperation());
+             return compiler.compile(this);
+         }
+     }
+ 
+     private static class ExecutableCloseStatement extends CloseStatement implements CompilableStatement {
+         public ExecutableCloseStatement(CursorName cursor){
+             super(cursor);
+         }
+ 
+         @Override
+         public MutationPlan compilePlan(PhoenixStatement stmt, Sequence.ValueOp seqAction) throws SQLException {
+             CloseStatementCompiler compiler = new CloseStatementCompiler(stmt, this.getOperation());
+             return compiler.compile(this);
+         }
+     }
+ 
+     private static class ExecutableFetchStatement extends FetchStatement implements CompilableStatement {
+         public ExecutableFetchStatement(CursorName cursor, boolean isNext, int fetchLimit) {
+             super(cursor, isNext, fetchLimit);
+         }
+ 
+         @Override
+         public QueryPlan compilePlan(PhoenixStatement stmt, Sequence.ValueOp seqAction) throws SQLException {
+             return CursorUtil.getFetchPlan(this.getCursorName().getName(), this.isNext(), this.getFetchSize());
+         }
+ 
+     }
+ 
+     private static class ExecutableDeleteJarStatement extends DeleteJarStatement implements CompilableStatement {
+ 
+         public ExecutableDeleteJarStatement(LiteralParseNode jarPath) {
+             super(jarPath);
+         }
+ 
+ 
+         @SuppressWarnings("unchecked")
+         @Override
+         public MutationPlan compilePlan(final PhoenixStatement stmt, Sequence.ValueOp seqAction) throws SQLException {
+             final StatementContext context = new StatementContext(stmt);
+             return new CustomMutationPlan(context, stmt);
+         }
+ 
+         private class CustomMutationPlan extends BaseMutationPlan {
+ 
+             private final StatementContext context;
+             private final PhoenixStatement stmt;
+ 
+             private CustomMutationPlan(StatementContext context, PhoenixStatement stmt) {
+                 super(context, ExecutableDeleteJarStatement.this.getOperation());
+                 this.context = context;
+                 this.stmt = stmt;
+             }
+ 
+             @Override
+             public ParameterMetaData getParameterMetaData() {
+                 return PhoenixParameterMetaData.EMPTY_PARAMETER_META_DATA;
+             }
+ 
+             @Override
+             public ExplainPlan getExplainPlan() throws SQLException {
+                 return new ExplainPlan(Collections.singletonList("DELETE JAR"));
+             }
+ 
+             @Override
+             public MutationState execute() throws SQLException {
+                 String dynamicJarsDir = stmt.getConnection().getQueryServices().getProps()
+                     .get(QueryServices.DYNAMIC_JARS_DIR_KEY);
+                 if (dynamicJarsDir == null) {
+                     throw new SQLException(QueryServices.DYNAMIC_JARS_DIR_KEY
+                             + " is not configured.");
+                 }
+                 dynamicJarsDir =
+                         dynamicJarsDir.endsWith("/") ? dynamicJarsDir : dynamicJarsDir + '/';
+                 Configuration conf = HBaseFactoryProvider.getConfigurationFactory()
+                     .getConfiguration();
+                 Path dynamicJarsDirPath = new Path(dynamicJarsDir);
+                 try {
+                     FileSystem fs = dynamicJarsDirPath.getFileSystem(conf);
+                     String jarPathStr = (String)getJarPath().getValue();
+                     if (!jarPathStr.endsWith(".jar")) {
+                         throw new SQLException(jarPathStr + " is not a valid jar file path.");
+                     }
+                     Path p = new Path(jarPathStr);
+                     if (fs.exists(p)) {
+                         fs.delete(p, false);
+                     }
+                 } catch(IOException e) {
+                     throw new SQLException(e);
+                 }
+                 return new MutationState(0, 0, context.getConnection());
+             }
+         }
+     }
+ 
+     private static class ExecutableListJarsStatement extends ListJarsStatement implements CompilableStatement {
+ 
+         public ExecutableListJarsStatement() {
+             super();
+         }
+ 
+ 
+         @SuppressWarnings("unchecked")
+         @Override
+         public QueryPlan compilePlan(final PhoenixStatement stmt, Sequence.ValueOp seqAction) throws SQLException {
+             return new ListJarsQueryPlan(stmt);
+         }
+     }
+ 
+     private static class ExecutableShowTablesStatement extends ShowTablesStatement
+         implements CompilableStatement {
+ 
+         public ExecutableShowTablesStatement(String schema, String pattern) {
+           super(schema, pattern);
+         }
+ 
+         @Override
+         public QueryPlan compilePlan(final PhoenixStatement stmt, Sequence.ValueOp seqAction)
+             throws SQLException {
+             PreparedStatement delegateStmt = QueryUtil.getTablesStmt(stmt.getConnection(), null,
+                 getTargetSchema(), getDbPattern(), null);
+             return ((PhoenixPreparedStatement) delegateStmt).compileQuery();
+         }
+     }
+ 
+     // Delegates to a SELECT query against SYSCAT.
+     private static class ExecutableShowSchemasStatement extends ShowSchemasStatement implements CompilableStatement {
+ 
+         public ExecutableShowSchemasStatement(String pattern) { super(pattern); }
+ 
+         @Override
+         public QueryPlan compilePlan(final PhoenixStatement stmt, Sequence.ValueOp seqAction) throws SQLException {
+             PreparedStatement delegateStmt =
+                 QueryUtil.getSchemasStmt(stmt.getConnection(), null, getSchemaPattern());
+             return ((PhoenixPreparedStatement) delegateStmt).compileQuery();
+         }
+     }
+ 
+     private static class ExecutableShowCreateTable extends ShowCreateTableStatement
+             implements CompilableStatement {
+ 
+         public ExecutableShowCreateTable(TableName tableName) {
+             super(tableName);
+         }
+ 
+         @Override
+         public QueryPlan compilePlan(final PhoenixStatement stmt, Sequence.ValueOp seqAction)
+                 throws SQLException {
+             PreparedStatement delegateStmt = QueryUtil.getShowCreateTableStmt(stmt.getConnection(), null,
+                     getTableName());
+             return ((PhoenixPreparedStatement) delegateStmt).compileQuery();
+         }
+     }
+ 
+     private static class ExecutableCreateIndexStatement extends CreateIndexStatement implements CompilableStatement {
+ 
+         public ExecutableCreateIndexStatement(NamedNode indexName, NamedTableNode dataTable,
+                 IndexKeyConstraint ikConstraint, List<ColumnName> includeColumns,
+                 List<ParseNode> splits, ListMultimap<String,Pair<String,Object>> props,
+                 boolean ifNotExists, IndexType indexType, boolean async, int bindCount, Map<String,
+                 UDFParseNode> udfParseNodes, ParseNode where) {
+             super(indexName, dataTable, ikConstraint, includeColumns, splits, props, ifNotExists,
+                     indexType, async , bindCount, udfParseNodes, where);
+         }
+ 
+         @SuppressWarnings("unchecked")
+         @Override
+         public MutationPlan compilePlan(PhoenixStatement stmt, Sequence.ValueOp seqAction) throws SQLException {
+             if (!getUdfParseNodes().isEmpty()) {
+                 stmt.throwIfUnallowedUserDefinedFunctions(getUdfParseNodes());
+             }
+ 			CreateIndexCompiler compiler = new CreateIndexCompiler(stmt, this.getOperation());
+             return compiler.compile(this);
+         }
+     }
+     
+     private static class ExecutableCreateSequenceStatement extends	CreateSequenceStatement implements CompilableStatement {
+ 
+         public ExecutableCreateSequenceStatement(TableName sequenceName, ParseNode startWith,
+                 ParseNode incrementBy, ParseNode cacheSize, ParseNode minValue, ParseNode maxValue,
+                 boolean cycle, boolean ifNotExists, int bindCount) {
+             super(sequenceName, startWith, incrementBy, cacheSize, minValue, maxValue, cycle,
+                     ifNotExists, bindCount);
+         }
+ 
+ 		@SuppressWarnings("unchecked")
+         @Override
+ 		public MutationPlan compilePlan(PhoenixStatement stmt, Sequence.ValueOp seqAction) throws SQLException {
+ 		    CreateSequenceCompiler compiler = new CreateSequenceCompiler(stmt, this.getOperation());
+             return compiler.compile(this);
+ 		}
+ 	}
+ 
+     private static class ExecutableDropSequenceStatement extends DropSequenceStatement implements CompilableStatement {
+ 
+ 
+         public ExecutableDropSequenceStatement(TableName sequenceName, boolean ifExists, int bindCount) {
+             super(sequenceName, ifExists, bindCount);
+         }
+ 
+         @SuppressWarnings("unchecked")
+         @Override
+         public MutationPlan compilePlan(PhoenixStatement stmt, Sequence.ValueOp seqAction) throws SQLException {
+             DropSequenceCompiler compiler = new DropSequenceCompiler(stmt, this.getOperation());
+             return compiler.compile(this);
+         }
+     }
+ 
+     private static class ExecutableDropTableStatement extends DropTableStatement implements CompilableStatement {
+ 
+         ExecutableDropTableStatement(TableName tableName, PTableType tableType, boolean ifExists, boolean cascade) {
+             super(tableName, tableType, ifExists, cascade, false);
+         }
+ 
+         @SuppressWarnings("unchecked")
+         @Override
+         public MutationPlan compilePlan(final PhoenixStatement stmt, Sequence.ValueOp seqAction) throws SQLException {
+             final StatementContext context = new StatementContext(stmt);
+             return new BaseMutationPlan(context, this.getOperation()) {
+ 
+                 @Override
+                 public ExplainPlan getExplainPlan() throws SQLException {
+                     return new ExplainPlan(Collections.singletonList("DROP TABLE"));
+                 }
+ 
+                 @Override
+                 public MutationState execute() throws SQLException {
+                     MetaDataClient client = new MetaDataClient(getContext().getConnection());
+                     return client.dropTable(ExecutableDropTableStatement.this);
+                 }
+             };
+         }
+     }
+ 
+     private static class ExecutableDropSchemaStatement extends DropSchemaStatement implements CompilableStatement {
+ 
+         ExecutableDropSchemaStatement(String schemaName, boolean ifExists, boolean cascade) {
+             super(schemaName, ifExists, cascade);
+         }
+ 
+         @SuppressWarnings("unchecked")
+         @Override
+         public MutationPlan compilePlan(final PhoenixStatement stmt, Sequence.ValueOp seqAction) throws SQLException {
+             final StatementContext context = new StatementContext(stmt);
+             return new BaseMutationPlan(context, this.getOperation()) {
+ 
+                 @Override
+                 public ExplainPlan getExplainPlan() throws SQLException {
+                     return new ExplainPlan(Collections.singletonList("DROP SCHEMA"));
+                 }
+ 
+                 @Override
+                 public MutationState execute() throws SQLException {
+                     MetaDataClient client = new MetaDataClient(getContext().getConnection());
+                     return client.dropSchema(ExecutableDropSchemaStatement.this);
+                 }
+             };
+         }
+     }
+ 
+     private static class ExecutableUseSchemaStatement extends UseSchemaStatement implements CompilableStatement {
+ 
+         ExecutableUseSchemaStatement(String schemaName) {
+             super(schemaName);
+         }
+ 
+         @SuppressWarnings("unchecked")
+         @Override
+         public MutationPlan compilePlan(final PhoenixStatement stmt, Sequence.ValueOp seqAction) throws SQLException {
+             final StatementContext context = new StatementContext(stmt);
+             return new BaseMutationPlan(context, this.getOperation()) {
+ 
+                 @Override
+                 public ExplainPlan getExplainPlan() throws SQLException {
+                     return new ExplainPlan(Collections.singletonList("USE SCHEMA"));
+                 }
+ 
+                 @Override
+                 public MutationState execute() throws SQLException {
+                     MetaDataClient client = new MetaDataClient(getContext().getConnection());
+                     return client.useSchema(ExecutableUseSchemaStatement.this);
+                 }
+             };
+         }
+     }
+ 
+     private static class ExecutableChangePermsStatement extends ChangePermsStatement implements CompilableStatement {
+ 
+         public ExecutableChangePermsStatement (String permsString, boolean isSchemaName, TableName tableName,
+                                                String schemaName, boolean isGroupName, LiteralParseNode userOrGroup, boolean isGrantStatement) {
+             super(permsString, isSchemaName, tableName, schemaName, isGroupName, userOrGroup, isGrantStatement);
+         }
+ 
+         @Override
+         public MutationPlan compilePlan(PhoenixStatement stmt, Sequence.ValueOp seqAction) throws SQLException {
+             final StatementContext context = new StatementContext(stmt);
+ 
+             return new BaseMutationPlan(context, this.getOperation()) {
+ 
+                 @Override
+                 public ExplainPlan getExplainPlan() throws SQLException {
+                     return new ExplainPlan(Collections.singletonList("GRANT PERMISSION"));
+                 }
+ 
+                 @Override
+                 public MutationState execute() throws SQLException {
+                     MetaDataClient client = new MetaDataClient(getContext().getConnection());
+                     return client.changePermissions(ExecutableChangePermsStatement.this);
+                 }
+             };
+         }
+     }
+ 
+     private static class ExecutableDropIndexStatement extends DropIndexStatement implements CompilableStatement {
+ 
+         public ExecutableDropIndexStatement(NamedNode indexName, TableName tableName, boolean ifExists) {
+             super(indexName, tableName, ifExists);
+         }
+ 
+         @SuppressWarnings("unchecked")
+         @Override
+         public MutationPlan compilePlan(final PhoenixStatement stmt, Sequence.ValueOp seqAction) throws SQLException {
+             final StatementContext context = new StatementContext(stmt);
+             return new BaseMutationPlan(context, this.getOperation()) {
+ 
+                 @Override
+                 public ExplainPlan getExplainPlan() throws SQLException {
+                     return new ExplainPlan(Collections.singletonList("DROP INDEX"));
+                 }
+ 
+                 @Override
+                 public MutationState execute() throws SQLException {
+                     MetaDataClient client = new MetaDataClient(getContext().getConnection());
+                     return client.dropIndex(ExecutableDropIndexStatement.this);
+                 }
+             };
+         }
+     }
+ 
+     private static class ExecutableAlterIndexStatement extends AlterIndexStatement implements CompilableStatement {
+ 
+         public ExecutableAlterIndexStatement(NamedTableNode indexTableNode, String dataTableName, boolean ifExists, PIndexState state, boolean isRebuildAll, boolean async, ListMultimap<String,Pair<String,Object>> props) {
+             super(indexTableNode, dataTableName, ifExists, state, isRebuildAll, async, props);
+         }
+ 
+         @SuppressWarnings("unchecked")
+         @Override
+         public MutationPlan compilePlan(final PhoenixStatement stmt, Sequence.ValueOp seqAction) throws SQLException {
+             final StatementContext context = new StatementContext(stmt);
+             return new BaseMutationPlan(context, this.getOperation()) {
+                 @Override
+                 public ExplainPlan getExplainPlan() throws SQLException {
+                     return new ExplainPlan(Collections.singletonList("ALTER INDEX"));
+                 }
+ 
+                 @Override
+                 public MutationState execute() throws SQLException {
+                     MetaDataClient client = new MetaDataClient(getContext().getConnection());
+                     return client.alterIndex(ExecutableAlterIndexStatement.this);
+                 }
+             };
+         }
+     }
+     
+     private static class ExecutableTraceStatement extends TraceStatement implements CompilableStatement {
+ 
+         public ExecutableTraceStatement(boolean isTraceOn, double samplingRate) {
+             super(isTraceOn, samplingRate);
+         }
+ 
+         @SuppressWarnings("unchecked")
+         @Override
+         public QueryPlan compilePlan(final PhoenixStatement stmt, Sequence.ValueOp seqAction) throws SQLException {
+             return new TraceQueryPlan(this, stmt);
+         }
+     }
+ 
+     private static class ExecutableAlterSessionStatement extends AlterSessionStatement implements CompilableStatement {
+ 
+         public ExecutableAlterSessionStatement(Map<String,Object> props) {
+             super(props);
+         }
+ 
+         @SuppressWarnings("unchecked")
+         @Override
+         public MutationPlan compilePlan(final PhoenixStatement stmt, Sequence.ValueOp seqAction) throws SQLException {
+             final StatementContext context = new StatementContext(stmt);
+             return new CustomMutationPlan(context);
+         }
+ 
+         private class CustomMutationPlan extends BaseMutationPlan {
+ 
+             private final StatementContext context;
+ 
+             private CustomMutationPlan(StatementContext context) {
+                 super(context, ExecutableAlterSessionStatement.this.getOperation());
+                 this.context = context;
+             }
+ 
+             @Override
+             public StatementContext getContext() {
+                 return context;
+             }
+ 
+             @Override
+             public ParameterMetaData getParameterMetaData() {
+                 return PhoenixParameterMetaData.EMPTY_PARAMETER_META_DATA;
+             }
+ 
+             @Override
+             public ExplainPlan getExplainPlan() throws SQLException {
+                 return new ExplainPlan(Collections.singletonList("ALTER SESSION"));
+             }
+ 
+ 
+             @Override
+             public MutationState execute() throws SQLException {
+                 Object consistency = getProps()
+                     .get(PhoenixRuntime.CONSISTENCY_ATTRIB.toUpperCase());
+                 if (consistency != null) {
+                     if (((String)consistency).equalsIgnoreCase(Consistency.TIMELINE.toString())) {
+                         getContext().getConnection().setConsistency(Consistency.TIMELINE);
+                     } else {
+                         getContext().getConnection().setConsistency(Consistency.STRONG);
+                     }
+                 }
+                 return new MutationState(0, 0, context.getConnection());
+             }
+         }
+     }
+ 
+     private static class ExecutableUpdateStatisticsStatement extends UpdateStatisticsStatement implements
+             CompilableStatement {
+         public ExecutableUpdateStatisticsStatement(NamedTableNode table, StatisticsCollectionScope scope, Map<String,Object> props) {
+             super(table, scope, props);
+         }
+ 
+         @SuppressWarnings("unchecked")
+         @Override
+         public MutationPlan compilePlan(final PhoenixStatement stmt, Sequence.ValueOp seqAction) throws SQLException {
+             final StatementContext context = new StatementContext(stmt);
+             return new BaseMutationPlan(context, this.getOperation()) {
+ 
+                 @Override
+                 public ExplainPlan getExplainPlan() throws SQLException {
+                     return new ExplainPlan(Collections.singletonList("UPDATE STATISTICS"));
+                 }
+ 
+                 @Override
+                 public MutationState execute() throws SQLException {
+                     MetaDataClient client = new MetaDataClient(getContext().getConnection());
+                     return client.updateStatistics(ExecutableUpdateStatisticsStatement.this);
+                 }
+             };
+         }
+ 
+     }
+     
+     private static class ExecutableExecuteUpgradeStatement extends ExecuteUpgradeStatement implements CompilableStatement {
+         @SuppressWarnings("unchecked")
+         @Override
+         public MutationPlan compilePlan(final PhoenixStatement stmt, Sequence.ValueOp seqAction) throws SQLException {
+             return new MutationPlan() {
+                 
+                 @Override
+                 public Set<TableRef> getSourceRefs() {
+                     return Collections.emptySet();
+                 }
+                 
+                 @Override
+                 public ParameterMetaData getParameterMetaData() {
+                     return PhoenixParameterMetaData.EMPTY_PARAMETER_META_DATA;
+                 }
+                 
+                 @Override
+                 public Operation getOperation() {
+                     return Operation.UPGRADE;
+                 }
+                 
+                 @Override
+                 public ExplainPlan getExplainPlan() throws SQLException {
+                     return new ExplainPlan(Collections.singletonList("EXECUTE UPGRADE"));
+                 }
+ 
+                 @Override
+                 public QueryPlan getQueryPlan() { return null; }
+ 
+                 @Override
+                 public StatementContext getContext() { return new StatementContext(stmt); }
+                 
+                 @Override
+                 public TableRef getTargetRef() {
+                     return TableRef.EMPTY_TABLE_REF;
+                 }
+                 
+                 @Override
+                 public MutationState execute() throws SQLException {
+                     PhoenixConnection phxConn = stmt.getConnection();
+                     Properties props = new Properties();
+                     phxConn.getQueryServices().upgradeSystemTables(phxConn.getURL(), props);
+                     return MutationState.emptyMutationState(-1, -1, phxConn);
+                 }
+ 
+                 @Override
+                 public Long getEstimatedRowsToScan() throws SQLException {
+                     return 0l;
+                 }
+ 
+                 @Override
+                 public Long getEstimatedBytesToScan() throws SQLException {
+                     return 0l;
+                 }
+ 
+                 @Override
+                 public Long getEstimateInfoTimestamp() throws SQLException {
+                     return 0l;
+                 }
+             };
+         }
+     }
+ 
+     private static class ExecutableAddColumnStatement extends AddColumnStatement implements CompilableStatement {
+ 
+         ExecutableAddColumnStatement(NamedTableNode table, PTableType tableType, List<ColumnDef> columnDefs, boolean ifNotExists, ListMultimap<String,Pair<String,Object>> props, boolean cascade, List<NamedNode> indexes) {
+             super(table, tableType, columnDefs, ifNotExists, props, cascade, indexes);
+         }
+ 
+         @SuppressWarnings("unchecked")
+         @Override
+         public MutationPlan compilePlan(final PhoenixStatement stmt, Sequence.ValueOp seqAction) throws SQLException {
+             final StatementContext context = new StatementContext(stmt);
+             return new BaseMutationPlan(context, this.getOperation()) {
+ 
+                 @Override
+                 public ExplainPlan getExplainPlan() throws SQLException {
+                     return new ExplainPlan(Collections.singletonList("ALTER " + getTableType() + " ADD COLUMN"));
+                 }
+ 
+                 @Override
+                 public MutationState execute() throws SQLException {
+                     MetaDataClient client = new MetaDataClient(getContext().getConnection());
+                     return client.addColumn(ExecutableAddColumnStatement.this);
+                 }
+             };
+         }
+     }
+ 
+     private static class ExecutableDropColumnStatement extends DropColumnStatement implements CompilableStatement {
+ 
+         ExecutableDropColumnStatement(NamedTableNode table, PTableType tableType, List<ColumnName> columnRefs, boolean ifExists) {
+             super(table, tableType, columnRefs, ifExists);
+         }
+ 
+         @SuppressWarnings("unchecked")
+         @Override
+         public MutationPlan compilePlan(final PhoenixStatement stmt, Sequence.ValueOp seqAction) throws SQLException {
+             final StatementContext context = new StatementContext(stmt);
+             return new BaseMutationPlan(context, this.getOperation()) {
+ 
+                 @Override
+                 public ExplainPlan getExplainPlan() throws SQLException {
+                     return new ExplainPlan(Collections.singletonList("ALTER " + getTableType() + " DROP COLUMN"));
+                 }
+ 
+                 @Override
+                 public MutationState execute() throws SQLException {
+                     MetaDataClient client = new MetaDataClient(getContext().getConnection());
+                     return client.dropColumn(ExecutableDropColumnStatement.this);
+                 }
+             };
+         }
+     }
+ 
+     protected static class ExecutableNodeFactory extends ParseNodeFactory {
+         @Override
+         public ExecutableSelectStatement select(TableNode from, HintNode hint, boolean isDistinct, List<AliasedNode> select, ParseNode where,
+                 List<ParseNode> groupBy, ParseNode having, List<OrderByNode> orderBy, LimitNode limit, OffsetNode offset, int bindCount, boolean isAggregate,
+                 boolean hasSequence, List<SelectStatement> selects, Map<String, UDFParseNode> udfParseNodes) {
+             return new ExecutableSelectStatement(from, hint, isDistinct, select, where, groupBy == null ? Collections.<ParseNode>emptyList() : groupBy,
+                     having, orderBy == null ? Collections.<OrderByNode>emptyList() : orderBy, limit, offset, bindCount, isAggregate, hasSequence, selects == null ? Collections.<SelectStatement>emptyList() : selects, udfParseNodes);
+         }
+ 
+         @Override
+         public ExecutableUpsertStatement upsert(NamedTableNode table, HintNode hintNode, List<ColumnName> columns, List<ParseNode> values, SelectStatement select, int bindCount, 
+                 Map<String, UDFParseNode> udfParseNodes, List<Pair<ColumnName,ParseNode>> onDupKeyPairs) {
+             return new ExecutableUpsertStatement(table, hintNode, columns, values, select, bindCount, udfParseNodes, onDupKeyPairs);
+         }
+ 
+         @Override
+         public ExecutableDeclareCursorStatement declareCursor(CursorName cursor, SelectStatement select) {
+             return new ExecutableDeclareCursorStatement(cursor, select);
+         }
+ 
+         @Override
+         public ExecutableFetchStatement fetch(CursorName cursor, boolean isNext, int fetchLimit) {
+             return new ExecutableFetchStatement(cursor, isNext, fetchLimit);
+         }
+ 
+         @Override
+         public ExecutableOpenStatement open(CursorName cursor) {
+             return new ExecutableOpenStatement(cursor);
+         }
+ 
+         @Override
+         public ExecutableCloseStatement close(CursorName cursor) {
+             return new ExecutableCloseStatement(cursor);
+         }
+ 
+         @Override
+         public ExecutableDeleteStatement delete(NamedTableNode table, HintNode hint, ParseNode whereNode, List<OrderByNode> orderBy, LimitNode limit, int bindCount, Map<String, UDFParseNode> udfParseNodes) {
+             return new ExecutableDeleteStatement(table, hint, whereNode, orderBy, limit, bindCount, udfParseNodes);
+         }
+ 
+         @Override
+         public CreateTableStatement createTable(TableName tableName, ListMultimap<String,Pair<String,Object>> props, List<ColumnDef> columns, PrimaryKeyConstraint pkConstraint, List<ParseNode> splits,
+                                                 PTableType tableType, boolean ifNotExists, TableName baseTableName, ParseNode tableTypeIdNode, int bindCount, Boolean immutableRows,
+                                                 Map<String, Integer> cqCounters, boolean noVerify) {
+             return new ExecutableCreateTableStatement(tableName, props, columns, pkConstraint, splits, tableType, ifNotExists, baseTableName, tableTypeIdNode, bindCount, immutableRows, cqCounters, noVerify);
+         }
+ 
+         @Override
+         public CreateTableStatement createTable(TableName tableName, ListMultimap<String,Pair<String,Object>> props, List<ColumnDef> columns, PrimaryKeyConstraint pkConstraint, List<ParseNode> splits,
+                                                 PTableType tableType, boolean ifNotExists, TableName baseTableName, ParseNode tableTypeIdNode, int bindCount, Boolean immutableRows, Map<String, Integer> cqCounters) {
+             return createTable(tableName, props, columns, pkConstraint, splits, tableType, ifNotExists, baseTableName, tableTypeIdNode, bindCount, immutableRows, cqCounters, false);
+         }
+ 
+         @Override
+         public CreateTableStatement createTable(TableName tableName, ListMultimap<String,Pair<String,Object>> props, List<ColumnDef> columns, PrimaryKeyConstraint pkConstraint, List<ParseNode> splits,
+                                                 PTableType tableType, boolean ifNotExists, TableName baseTableName, ParseNode tableTypeIdNode, int bindCount, Boolean immutableRows) {
+             return createTable(tableName, props, columns, pkConstraint, splits, tableType, ifNotExists, baseTableName, tableTypeIdNode, bindCount, immutableRows, null);
+         }
+ 
+         @Override
+         public CreateSchemaStatement createSchema(String schemaName, boolean ifNotExists) {
+             return new ExecutableCreateSchemaStatement(schemaName, ifNotExists);
+         }
+ 
+         @Override
+         public CreateSequenceStatement createSequence(TableName tableName, ParseNode startsWith,
+                 ParseNode incrementBy, ParseNode cacheSize, ParseNode minValue, ParseNode maxValue,
+                 boolean cycle, boolean ifNotExists, int bindCount) {
+             return new ExecutableCreateSequenceStatement(tableName, startsWith, incrementBy,
+                     cacheSize, minValue, maxValue, cycle, ifNotExists, bindCount);
+         }
+         
+         @Override
+         public CreateFunctionStatement createFunction(PFunction functionInfo, boolean temporary, boolean isReplace) {
+             return new ExecutableCreateFunctionStatement(functionInfo, temporary, isReplace);
+         }
+ 
+         @Override
+         public AddJarsStatement addJars(List<LiteralParseNode> jarPaths) {
+             return new ExecutableAddJarsStatement(jarPaths);
+         }
+ 
+         @Override
+         public DeleteJarStatement deleteJar(LiteralParseNode jarPath)  {
+             return new ExecutableDeleteJarStatement(jarPath);
+         }
+ 
+         @Override
+         public ListJarsStatement listJars() {
+             return new ExecutableListJarsStatement();
+         }
+ 
+ 
+         @Override
+         public DropSequenceStatement dropSequence(TableName tableName, boolean ifExists, int bindCount) {
+             return new ExecutableDropSequenceStatement(tableName, ifExists, bindCount);
+         }
+         
+         @Override
+         public CreateIndexStatement createIndex(NamedNode indexName, NamedTableNode dataTable,
+                 IndexKeyConstraint ikConstraint, List<ColumnName> includeColumns,
+                 List<ParseNode> splits, ListMultimap<String,Pair<String,Object>> props,
+                 boolean ifNotExists, IndexType indexType, boolean async, int bindCount, Map<String,
+                 UDFParseNode> udfParseNodes, ParseNode where) {
+             return new ExecutableCreateIndexStatement(indexName, dataTable, ikConstraint,
+                     includeColumns, splits, props, ifNotExists, indexType, async, bindCount,
+                     udfParseNodes, where);
+         }
+         
+         @Override
+         public AddColumnStatement addColumn(NamedTableNode table,  PTableType tableType, List<ColumnDef> columnDefs, boolean ifNotExists, ListMultimap<String,Pair<String,Object>> props, boolean cascade, List<NamedNode> indexes) {
+             return new ExecutableAddColumnStatement(table, tableType, columnDefs, ifNotExists, props, cascade, indexes);
+         }
+         
+         @Override
+         public DropColumnStatement dropColumn(NamedTableNode table,  PTableType tableType, List<ColumnName> columnNodes, boolean ifExists) {
+             return new ExecutableDropColumnStatement(table, tableType, columnNodes, ifExists);
+         }
+         
+         @Override
+         public DropTableStatement dropTable(TableName tableName, PTableType tableType, boolean ifExists, boolean cascade) {
+             return new ExecutableDropTableStatement(tableName, tableType, ifExists, cascade);
+         }
+ 
+         @Override
+         public DropSchemaStatement dropSchema(String schemaName, boolean ifExists, boolean cascade) {
+             return new ExecutableDropSchemaStatement(schemaName, ifExists, cascade);
+         }
+ 
+         @Override
+         public UseSchemaStatement useSchema(String schemaName) {
+             return new ExecutableUseSchemaStatement(schemaName);
+         }
+ 
+         @Override
+         public DropFunctionStatement dropFunction(String functionName, boolean ifExists) {
+             return new ExecutableDropFunctionStatement(functionName, ifExists);
+         }
+         
+         @Override
+         public DropIndexStatement dropIndex(NamedNode indexName, TableName tableName, boolean ifExists) {
+             return new ExecutableDropIndexStatement(indexName, tableName, ifExists);
+         }
+ 
+         @Override
+         public AlterIndexStatement alterIndex(NamedTableNode indexTableNode, String dataTableName, boolean ifExists, PIndexState state, boolean isRebuildAll, boolean async, ListMultimap<String,Pair<String,Object>> props) {
+             return new ExecutableAlterIndexStatement(indexTableNode, dataTableName, ifExists, state, isRebuildAll, async, props);
+         }
+ 
+         @Override
+         public TraceStatement trace(boolean isTraceOn, double samplingRate) {
+             return new ExecutableTraceStatement(isTraceOn, samplingRate);
+         }
+ 
+         @Override
+         public AlterSessionStatement alterSession(Map<String, Object> props) {
+             return new ExecutableAlterSessionStatement(props);
+         }
+ 
+         @Override
+         public ExplainStatement explain(BindableStatement statement, ExplainType explainType) {
+             return new ExecutableExplainStatement(statement, explainType);
+         }
+ 
+         @Override
+         public UpdateStatisticsStatement updateStatistics(NamedTableNode table, StatisticsCollectionScope scope, Map<String,Object> props) {
+             return new ExecutableUpdateStatisticsStatement(table, scope, props);
+         }
+         
+         @Override
+         public ExecuteUpgradeStatement executeUpgrade() {
+             return new ExecutableExecuteUpgradeStatement();
+         }
+ 
+         @Override
+         public ExecutableChangePermsStatement changePermsStatement(String permsString, boolean isSchemaName, TableName tableName,
+                                                          String schemaName, boolean isGroupName, LiteralParseNode userOrGroup, boolean isGrantStatement) {
+             return new ExecutableChangePermsStatement(permsString, isSchemaName, tableName, schemaName, isGroupName, userOrGroup,isGrantStatement);
+         }
+ 
+         @Override
+         public ShowTablesStatement showTablesStatement(String schema, String pattern) {
+             return new ExecutableShowTablesStatement(schema, pattern);
+         }
+ 
+         @Override
+         public ShowSchemasStatement showSchemasStatement(String pattern) {
+             return new ExecutableShowSchemasStatement(pattern);
+         }
+ 
+         @Override
+         public ShowCreateTable showCreateTable(TableName tableName) {
+             return new ExecutableShowCreateTable(tableName);
+         }
+ 
+     }
+     
+     static class PhoenixStatementParser extends SQLParser {
+         PhoenixStatementParser(String query, ParseNodeFactory nodeFactory) throws IOException {
+             super(query, nodeFactory);
+         }
+ 
+         PhoenixStatementParser(Reader reader) throws IOException {
+             super(reader);
+         }
+         
+         @Override
+         public CompilableStatement nextStatement(ParseNodeFactory nodeFactory) throws SQLException {
+             return (CompilableStatement) super.nextStatement(nodeFactory);
+         }
+ 
+         @Override
+         public CompilableStatement parseStatement() throws SQLException {
+             return (CompilableStatement) super.parseStatement();
+         }
+     }
+     
+     public Format getFormatter(PDataType type) {
+         return connection.getFormatter(type);
+     }
+     
+     protected final List<PhoenixPreparedStatement> batch = Lists.newArrayList();
+     
+     @Override
+     public void addBatch(String sql) throws SQLException {
+         batch.add(new PhoenixPreparedStatement(connection, sql));
+     }
+ 
+     @Override
+     public void clearBatch() throws SQLException {
+         batch.clear();
+     }
+ 
+     /**
+      * Execute the current batch of statements. If any exception occurs
+      * during execution, a {@link java.sql.BatchUpdateException}
+      * is thrown which compposes the update counts for statements executed so
+      * far.
+      */
+     @Override
+     public int[] executeBatch() throws SQLException {
+         int i = 0;
+         int[] returnCodes = new int [batch.size()];
+         Arrays.fill(returnCodes, -1);
+         boolean autoCommit = connection.getAutoCommit();
+         connection.setAutoCommit(false);
+         try {
+             for (i = 0; i < returnCodes.length; i++) {
+                 PhoenixPreparedStatement statement = batch.get(i);
+                 statement.executeForBatch();
+                 returnCodes[i] = statement.getUpdateCount();
+             }
+             // Flush all changes in batch if auto flush is true
+             flushIfNecessary();
+             // If we make it all the way through, clear the batch
+             clearBatch();
+             if (autoCommit) {
+                 connection.commit();
+             }
+             return returnCodes;
+         } catch (SQLException t) {
+             if (i == returnCodes.length) {
+                 // Exception after for loop, perhaps in commit(), discard returnCodes.
+                 throw new BatchUpdateException(t);
+             } else {
+                 returnCodes[i] = Statement.EXECUTE_FAILED;
+                 throw new BatchUpdateException(returnCodes, t);
+             }
+         } finally {
+             connection.setAutoCommit(autoCommit);
+         }
+     }
+ 
+     @Override
+     public void cancel() throws SQLException {
+         throw new SQLFeatureNotSupportedException();
+     }
+ 
+     @Override
+     public void clearWarnings() throws SQLException {
+     }
+ 
+     @Override
+     public void close() throws SQLException {
+         try {
+             clearResultSet();
+         } finally {
+             try {
+                 connection.removeStatement(this);
+             } finally {
+                 isClosed = true;
+             }
+         }
+     }
+ 
+     // From the ResultSet javadoc:
+     // A ResultSet object is automatically closed when the Statement object that generated it is
+     // closed, re-executed, or used to retrieve the next result from a sequence of multiple results.
+     private void clearResultSet() throws SQLException {
+         if (lastResultSet != null) {
+             try {
+                 lastResultSet.close();
+             } finally {
+                 lastResultSet = null;
+             }
+         }
+     }
+ 
+     // Called from ResultSet.close(). rs is already closed.
+     // We use a separate function to avoid calling close() again
+     void removeResultSet(ResultSet rs) throws SQLException {
+         if (rs == lastResultSet) {
+             lastResultSet = null;
+             if (closeOnCompletion) {
+                 this.close();
+             }
+         }
+     }
+ 
+     public List<Object> getParameters() {
+         return Collections.<Object>emptyList();
+     }
+     
+     protected CompilableStatement parseStatement(String sql) throws SQLException {
+         PhoenixStatementParser parser = null;
+         try {
+             parser = new PhoenixStatementParser(sql, new ExecutableNodeFactory());
+         } catch (IOException e) {
+             throw ClientUtil.parseServerException(e);
+         }
+         CompilableStatement statement = parser.parseStatement();
+         return statement;
+     }
+     
+     public QueryPlan optimizeQuery(String sql) throws SQLException {
+         QueryPlan plan = compileQuery(sql);
+         return connection.getQueryServices().getOptimizer().optimize(this, plan);
+     }
+ 
+     public QueryPlan compileQuery(String sql) throws SQLException {
+         CompilableStatement stmt = parseStatement(sql);
+         return compileQuery(stmt, sql);
+     }
+ 
+     public QueryPlan compileQuery(CompilableStatement stmt, String query) throws SQLException {
+         if (stmt.getOperation().isMutation()) {
+             throw new ExecuteQueryNotApplicableException(query);
+         }
+         return stmt.compilePlan(this, Sequence.ValueOp.VALIDATE_SEQUENCE);
+     }
+ 
+     public MutationPlan compileMutation(CompilableStatement stmt, String query) throws SQLException {
+         if (!stmt.getOperation().isMutation()) {
+             throw new ExecuteUpdateNotApplicableException(query);
+         }
+         return stmt.compilePlan(this, Sequence.ValueOp.VALIDATE_SEQUENCE);
+     }
+ 
+     public MutationPlan compileMutation(String sql) throws SQLException {
+         if (LOGGER.isDebugEnabled()) {
+             LOGGER.debug(LogUtil.addCustomAnnotations("Execute update: " + sql, connection));
+         }
+         CompilableStatement stmt = parseStatement(sql);
+         return compileMutation(stmt, sql);
+     }
+ 
+     public boolean isSystemTable(CompilableStatement stmt) {
+         boolean systemTable = false;
+         TableName tableName = null;
+         if (stmt instanceof ExecutableSelectStatement) {
+             TableNode from = ((ExecutableSelectStatement)stmt).getFrom();
+             if (from instanceof NamedTableNode) {
+                 tableName = ((NamedTableNode)from).getName();
+             }
+         } else if (stmt instanceof ExecutableUpsertStatement) {
+             tableName = ((ExecutableUpsertStatement)stmt).getTable().getName();
+         } else if (stmt instanceof ExecutableDeleteStatement) {
+             tableName = ((ExecutableDeleteStatement)stmt).getTable().getName();
+         } else if (stmt instanceof ExecutableAddColumnStatement) {
+             tableName = ((ExecutableAddColumnStatement)stmt).getTable().getName();
+         }
+ 
+         if (tableName != null && PhoenixDatabaseMetaData.SYSTEM_CATALOG_SCHEMA
+                 .equals(tableName.getSchemaName())) {
+             systemTable = true;
+         }
+ 
+         return systemTable;
+     }
+ 
+     public QueryLogger createQueryLogger(CompilableStatement stmt, String sql) throws SQLException {
+         if (connection.getLogLevel() == LogLevel.OFF) {
+             return QueryLogger.NO_OP_INSTANCE;
+         }
+ 
+         QueryLogger queryLogger = QueryLogger.getInstance(connection, isSystemTable(stmt));
+         QueryLoggerUtil.logInitialDetails(queryLogger, connection.getTenantId(),
+                 connection.getQueryServices(), sql, getParameters());
+         return queryLogger;
+     }
+ 
+     public AuditQueryLogger createAuditQueryLogger(CompilableStatement stmt, String sql) throws SQLException {
+         if (connection.getAuditLogLevel() == LogLevel.OFF) {
+             return AuditQueryLogger.NO_OP_INSTANCE;
+         }
+ 
+         AuditQueryLogger queryLogger = AuditQueryLogger.getInstance(connection, isSystemTable(stmt));
+         QueryLoggerUtil.logInitialDetails(queryLogger, connection.getTenantId(),
+                 connection.getQueryServices(), sql, getParameters());
+         return queryLogger;
+     }
+     
+     @Override
+     public ResultSet executeQuery(String sql) throws SQLException {
+         if (LOGGER.isDebugEnabled()) {
+             LOGGER.debug(LogUtil.addCustomAnnotations(
+                     "Execute query: " + sql, connection));
+         }
+         
+         CompilableStatement stmt = parseStatement(sql);
+         if (stmt.getOperation().isMutation()) {
+             throw new ExecuteQueryNotApplicableException(sql);
+         }
+         return executeQuery(stmt, createQueryLogger(stmt, sql));
+     }
+ 
+     @Override
+     public int executeUpdate(String sql) throws SQLException {
+         CompilableStatement stmt = parseStatement(sql);
+         if (!stmt.getOperation().isMutation) {
+             throw new ExecuteUpdateNotApplicableException(sql);
+         }
+         if (!batch.isEmpty()) {
+             throw new SQLExceptionInfo.Builder(SQLExceptionCode.EXECUTE_UPDATE_WITH_NON_EMPTY_BATCH)
+             .build().buildException();
+         }
+         int updateCount = executeMutation(stmt, createAuditQueryLogger(stmt, sql));
+         flushIfNecessary();
+         return updateCount;
+     }
+ 
+     private void flushIfNecessary() throws SQLException {
+         if (connection.getAutoFlush()) {
+             connection.flush();
+         }
+     }
+     
+     @Override
+     public boolean execute(String sql) throws SQLException {
+         CompilableStatement stmt = parseStatement(sql);
+         if (stmt.getOperation().isMutation()) {
+             if (!batch.isEmpty()) {
+                 throw new SQLExceptionInfo.Builder(SQLExceptionCode.EXECUTE_UPDATE_WITH_NON_EMPTY_BATCH)
+                 .build().buildException();
+             }
+             executeMutation(stmt, createAuditQueryLogger(stmt, sql));
+             flushIfNecessary();
+             return false;
+         }
+         
+         executeQuery(stmt, createQueryLogger(stmt, sql));
+         return true;
+     }
+ 
+     @Override
+     public boolean execute(String sql, int autoGeneratedKeys) throws SQLException {
+         return execute(sql);
+     }
+ 
+     @Override
+     public boolean execute(String sql, int[] columnIndexes) throws SQLException {
+         return execute(sql);
+     }
+ 
+     @Override
+     public boolean execute(String sql, String[] columnNames) throws SQLException {
+         return execute(sql);
+     }
+ 
+     @Override
+     public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
+         return executeUpdate(sql);
+     }
+ 
+     @Override
+     public int executeUpdate(String sql, int[] columnIndexes) throws SQLException {
+         return executeUpdate(sql);
+     }
+ 
+     @Override
+     public int executeUpdate(String sql, String[] columnNames) throws SQLException {
+         return executeUpdate(sql);
+     }
+ 
+     @Override
+     public PhoenixConnection getConnection() {
+         return connection;
+     }
+ 
+     @Override
+     public int getFetchDirection() throws SQLException {
+         return ResultSet.FETCH_FORWARD;
+     }
+ 
+     @Override
+     public int getFetchSize() throws SQLException {
+         if (fetchSize > 0) {
+             return fetchSize;
+         } else {
+             return connection.getQueryServices().getProps()
+                 .getInt(QueryServices.SCAN_CACHE_SIZE_ATTRIB,
+                     QueryServicesOptions.DEFAULT_SCAN_CACHE_SIZE);
+         }
+     }
+ 
+     @Override
+     public ResultSet getGeneratedKeys() throws SQLException {
+         throw new SQLFeatureNotSupportedException();
+     }
+ 
+     @Override
+     public int getMaxFieldSize() throws SQLException {
+         return 0; // TODO: 4000?
+     }
+ 
+     @Override
+     public int getMaxRows() throws SQLException {
+         return maxRows;
+     }
+ 
+     @Override
+     public boolean getMoreResults() throws SQLException {
+         return false;
+     }
+ 
+     @Override
+     public boolean getMoreResults(int current) throws SQLException {
+         return false;
+     }
+ 
+     // For testing
+     public QueryPlan getQueryPlan() {
+         return getLastQueryPlan();
+     }
+     
+     @Override
+     public ResultSet getResultSet() throws SQLException {
+         ResultSet rs = getLastResultSet();
+         return rs;
+     }
+ 
+     @Override
+     public int getResultSetConcurrency() throws SQLException {
+         return ResultSet.CONCUR_READ_ONLY;
+     }
+ 
+     @Override
+     public int getResultSetHoldability() throws SQLException {
+         // TODO: not sure this matters
+         return ResultSet.CLOSE_CURSORS_AT_COMMIT;
+     }
+ 
+     @Override
+     public int getResultSetType() throws SQLException {
+         return ResultSet.TYPE_FORWARD_ONLY;
+     }
+ 
+     @Override
+     public Operation getUpdateOperation() {
+         return getLastUpdateOperation();
+     }
+     
+     @Override
+     public int getUpdateCount() throws SQLException {
+         int updateCount = getLastUpdateCount();
+         // Only first call can get the update count, otherwise
+         // some SQL clients get into an infinite loop when an
+         // update occurs.
+         setLastUpdateCount(NO_UPDATE);
+         return updateCount;
+     }
+ 
+     @Override
+     public SQLWarning getWarnings() throws SQLException {
+         return null;
+     }
+ 
+     @Override
+     public boolean isClosed() throws SQLException {
+         return isClosed;
+     }
+ 
+     @Override
+     public boolean isPoolable() throws SQLException {
+         return false;
+     }
+ 
+     @Override
+     public void setCursorName(String name) throws SQLException {
+         throw new SQLFeatureNotSupportedException();
+     }
+ 
+     @Override
+     public void setEscapeProcessing(boolean enable) throws SQLException {
+         // TODO: any escaping we need to do?
+     }
+ 
+     @Override
+     public void setFetchDirection(int direction) throws SQLException {
+         if (direction != ResultSet.FETCH_FORWARD) {
+             throw new SQLFeatureNotSupportedException();
+         }
+     }
+ 
+     @Override
+     public void setFetchSize(int fetchSize) throws SQLException {
+         // TODO: map to Scan.setBatch() ?
+         this.fetchSize = fetchSize;
+     }
+ 
+     @Override
+     public void setMaxFieldSize(int max) throws SQLException {
+         throw new SQLFeatureNotSupportedException();
+     }
+ 
+     @Override
+     public void setMaxRows(int max) throws SQLException {
+         this.maxRows = max;
+     }
+ 
+     @Override
+     public void setPoolable(boolean poolable) throws SQLException {
+         if (poolable) {
+             throw new SQLFeatureNotSupportedException();
+         }
+     }
+ 
+     @Override
+     /**
+      * When setting the query timeout via JDBC timeouts must be expressed in seconds. Therefore
+      * we need to convert the default timeout to milliseconds for internal use. 
+      */
+     public void setQueryTimeout(int seconds) throws SQLException {
+         if (seconds < 0) {
+             this.queryTimeoutMillis = getDefaultQueryTimeoutMillis();
+         } else if (seconds == 0) {
+             this.queryTimeoutMillis = Integer.MAX_VALUE;
+         } else {
+             this.queryTimeoutMillis = seconds * 1000;
+         }
+     }
+ 
+     @Override
+     /**
+      * When getting the query timeout via JDBC timeouts must be expressed in seconds. Therefore
+      * we need to convert the default millisecond timeout to seconds. 
+      */
+     public int getQueryTimeout() throws SQLException {
+         // Convert milliseconds to seconds by taking the CEIL up to the next second
+         int scaledValue;
+         try {
+             scaledValue = IntMath.checkedAdd(queryTimeoutMillis, 999);
+         } catch (ArithmeticException e) {
+             scaledValue = Integer.MAX_VALUE;
+         }
+         return scaledValue / 1000;
+     }
+     
+     /**
+      * Returns the configured timeout in milliseconds. This
+      * internally enables the of use millisecond timeout granularity
+      * and honors the exact value configured by phoenix.query.timeoutMs.
+      */
+     public int getQueryTimeoutInMillis() {
+         return queryTimeoutMillis;
+     }
+     
+     @Override
+     public boolean isWrapperFor(Class<?> iface) throws SQLException {
+         return iface.isInstance(this);
+     }
+ 
+     @SuppressWarnings("unchecked")
+     @Override
+     public <T> T unwrap(Class<T> iface) throws SQLException {
+         if (!iface.isInstance(this)) {
+             throw new SQLExceptionInfo.Builder(SQLExceptionCode.CLASS_NOT_UNWRAPPABLE)
+                 .setMessage(this.getClass().getName() + " not unwrappable from " + iface.getName())
+                 .build().buildException();
+         }
+         return (T)this;
+     }
+ 
+     @Override
+     public void closeOnCompletion() throws SQLException {
+         closeOnCompletion = true;
+     }
+ 
+     @Override
+     public boolean isCloseOnCompletion() throws SQLException {
+         return closeOnCompletion;
+     }
+ 
+     private PhoenixResultSet getLastResultSet() {
+         return lastResultSet;
+     }
+ 
+     void setLastResultSet(PhoenixResultSet lastResultSet) {
+         this.lastResultSet = lastResultSet;
+     }
+ 
+     private int getLastUpdateCount() {
+         return lastUpdateCount;
+     }
+ 
+     private void setLastUpdateCount(int lastUpdateCount) {
+         this.lastUpdateCount = lastUpdateCount;
+     }
+ 
+     private String getLastUpdateTable() {
+         return lastUpdateTable;
+     }
+ 
+     private void setLastUpdateTable(String lastUpdateTable) {
+         if (!Strings.isNullOrEmpty(lastUpdateTable)) {
+             this.lastUpdateTable = lastUpdateTable;
+         }
+         if (getConnection().getActivityLogger().isLevelEnabled(ActivityLogInfo.TABLE_NAME.getLogLevel())) {
+             updateActivityOnConnection(ActivityLogInfo.TABLE_NAME, this.lastUpdateTable);
+         }
+     }
+ 
+     private Operation getLastUpdateOperation() {
+         return lastUpdateOperation;
+     }
+ 
+     private void setLastUpdateOperation(Operation lastUpdateOperation) {
+         this.lastUpdateOperation = lastUpdateOperation;
+         if (getConnection().getActivityLogger().isLevelEnabled(ActivityLogInfo.OP_NAME.getLogLevel())) {
+             updateActivityOnConnection(ActivityLogInfo.OP_NAME, this.lastUpdateOperation.toString());
+         }
+         if (getConnection().getActivityLogger().isLevelEnabled(ActivityLogInfo.OP_TIME.getLogLevel())) {
+             updateActivityOnConnection(ActivityLogInfo.OP_TIME, String.valueOf(EnvironmentEdgeManager.currentTimeMillis()));
+         }
+     }
+ 
+     private QueryPlan getLastQueryPlan() {
+         return lastQueryPlan;
+     }
+ 
+     private void setLastQueryPlan(QueryPlan lastQueryPlan) {
+         this.lastQueryPlan = lastQueryPlan;
+ 
+     }
+ 
+     private void updateActivityOnConnection(ActivityLogInfo item, String value) {
+         getConnection().getActivityLogger().log(item, value);
+     }
+ 
+     private void throwIfUnallowedUserDefinedFunctions(Map<String, UDFParseNode> udfParseNodes) throws SQLException {
+         if (!connection
+                 .getQueryServices()
+                 .getProps()
+                 .getBoolean(QueryServices.ALLOW_USER_DEFINED_FUNCTIONS_ATTRIB,
+                     QueryServicesOptions.DEFAULT_ALLOW_USER_DEFINED_FUNCTIONS)) {
+             if (udfParseNodes.isEmpty()) {
+                 throw new SQLExceptionInfo.Builder(SQLExceptionCode.UNALLOWED_USER_DEFINED_FUNCTIONS)
+                 .build().buildException();
+             }
+             throw new FunctionNotFoundException(udfParseNodes.keySet().toString());
+         }
+     }
+ 
+     /**
+      * Check if the statement is a DDL and if there are any uncommitted mutations Throw or log the
+      * message
+      */
+     private void checkIfDDLStatementandMutationState(final CompilableStatement stmt,
+             MutationState state) throws SQLException {
+         boolean throwUncommittedMutation =
+                 connection.getQueryServices().getProps().getBoolean(
+                     QueryServices.PENDING_MUTATIONS_DDL_THROW_ATTRIB,
+                     QueryServicesOptions.DEFAULT_PENDING_MUTATIONS_DDL_THROW);
+         if (stmt instanceof MutableStatement && !(stmt instanceof DMLStatement)
+                 && state.getNumRows() > 0) {
+             if (throwUncommittedMutation) {
+                 throw new SQLExceptionInfo.Builder(
+                         SQLExceptionCode.CANNOT_PERFORM_DDL_WITH_PENDING_MUTATIONS).build()
+                                 .buildException();
+             } else {
+                 LOGGER.warn(
+                     "There are Uncommitted mutations, which will be dropped on the execution of this DDL statement.");
+             }
+         }
+     }
+ 
+     public Calendar getLocalCalendar() {
+         return localCalendar;
+     }
+ 
+ }
diff --cc phoenix-core-client/src/main/java/org/apache/phoenix/query/ConnectionQueryServices.java
index 0000000000,8a1d31a67e..df9833fb5e
mode 000000,100644..100644
--- a/phoenix-core-client/src/main/java/org/apache/phoenix/query/ConnectionQueryServices.java
+++ b/phoenix-core-client/src/main/java/org/apache/phoenix/query/ConnectionQueryServices.java
@@@ -1,0 -1,230 +1,237 @@@
+ /*
+  * 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.query;
+ 
+ import java.sql.SQLException;
+ import java.util.List;
+ import java.util.Map;
+ import java.util.Properties;
+ import java.util.Set;
+ 
+ import org.apache.hadoop.conf.Configuration;
+ import org.apache.hadoop.hbase.HRegionLocation;
++import org.apache.hadoop.hbase.ServerName;
+ import org.apache.hadoop.hbase.TableName;
+ import org.apache.hadoop.hbase.client.Admin;
+ import org.apache.hadoop.hbase.client.Mutation;
+ import org.apache.hadoop.hbase.client.Table;
+ import org.apache.hadoop.hbase.client.TableDescriptor;
+ import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
+ import org.apache.hadoop.hbase.security.User;
+ import org.apache.hadoop.hbase.util.Pair;
+ import org.apache.phoenix.compile.MutationPlan;
++import org.apache.phoenix.coprocessorclient.InvalidateServerMetadataCacheRequest;
+ import org.apache.phoenix.coprocessorclient.MetaDataProtocol.MetaDataMutationResult;
+ import org.apache.phoenix.exception.SQLExceptionInfo;
+ import org.apache.phoenix.execute.MutationState;
+ import org.apache.phoenix.hbase.index.util.KeyValueBuilder;
+ import org.apache.phoenix.jdbc.PhoenixConnection;
+ import org.apache.phoenix.log.ConnectionLimiter;
+ import org.apache.phoenix.log.QueryLoggerDisruptor;
+ import org.apache.phoenix.parse.PFunction;
+ import org.apache.phoenix.schema.PColumn;
+ import org.apache.phoenix.schema.PMetaData;
+ import org.apache.phoenix.schema.PName;
+ import org.apache.phoenix.schema.PTable;
+ import org.apache.phoenix.schema.PTableType;
+ import org.apache.phoenix.schema.Sequence;
+ import org.apache.phoenix.schema.SequenceAllocation;
+ import org.apache.phoenix.schema.SequenceKey;
+ import org.apache.phoenix.schema.stats.GuidePostsInfo;
+ import org.apache.phoenix.schema.stats.GuidePostsKey;
+ import org.apache.phoenix.transaction.PhoenixTransactionClient;
+ import org.apache.phoenix.transaction.TransactionFactory;
+ 
+ 
+ public interface ConnectionQueryServices extends QueryServices, MetaDataMutated {
+     public static final int INITIAL_META_DATA_TABLE_CAPACITY = 100;
+ 
+     /**
+      * Get (and create if necessary) a child QueryService for a given tenantId.
+      * The QueryService will be cached for the lifetime of the parent QueryService
+      * @param tenantId the organization ID
+      * @return the child QueryService
+      */
+     public ConnectionQueryServices getChildQueryServices(ImmutableBytesWritable tenantId);
+ 
+     /**
+      * Get Table by the given name. It is the callers
+      * responsibility to close the returned Table reference.
+      *
+      * @param tableName the name of the HTable
+      * @return Table interface. It is caller's responsibility to close this
+      *     returned Table reference.
+      * @throws SQLException 
+      */
+     public Table getTable(byte[] tableName) throws SQLException;
+ 
+     /**
+      * Get Table by the given name. It is the responsibility of callers
+      * to close the returned Table interface. This method uses additional Admin
+      * API to ensure if table exists before returning Table interface from
+      * Connection. If table does not exist, this method will throw
+      * {@link org.apache.phoenix.schema.TableNotFoundException}
+      * It is caller's responsibility to close returned Table reference.
+      *
+      * @param tableName the name of the Table
+      * @return Table interface. It is caller's responsibility to close this
+      *     returned Table reference.
+      * @throws SQLException If something goes wrong while retrieving table
+      *     interface from connection managed by implementor. If table does not
+      *     exist, {@link org.apache.phoenix.schema.TableNotFoundException} will
+      *     be thrown.
+      */
+     Table getTableIfExists(byte[] tableName) throws SQLException;
+ 
+     public TableDescriptor getTableDescriptor(byte[] tableName) throws SQLException;
+ 
+     public HRegionLocation getTableRegionLocation(byte[] tableName, byte[] row) throws SQLException;
+     public List<HRegionLocation> getAllTableRegions(byte[] tableName) throws SQLException;
+ 
+     public PhoenixConnection connect(String url, Properties info) throws SQLException;
+ 
+     /**
+      * @param tableTimestamp timestamp of table if its present in the client side cache
+      * @param clientTimetamp if the client connection has an scn, or of the table is transactional
+      *            the txn write pointer
+      * @return PTable for the given tenant id, schema and table name
+      */
+     public MetaDataMutationResult getTable(PName tenantId, byte[] schemaName, byte[] tableName,
+             long tableTimestamp, long clientTimetamp) throws SQLException;
+     public MetaDataMutationResult getFunctions(PName tenantId, List<Pair<byte[], Long>> functionNameAndTimeStampPairs, long clientTimestamp) throws SQLException;
+ 
+     public MetaDataMutationResult createTable(List<Mutation> tableMetaData, byte[] tableName, PTableType tableType,
+                                               Map<String, Object> tableProps,
+                                               List<Pair<byte[], Map<String, Object>>> families, byte[][] splits,
+                                               boolean isNamespaceMapped, boolean allocateIndexId,
+                                               boolean isDoNotUpgradePropSet, PTable parentTable) throws SQLException;
+     public MetaDataMutationResult dropTable(List<Mutation> tableMetadata, PTableType tableType, boolean cascade) throws SQLException;
+     public MetaDataMutationResult dropFunction(List<Mutation> tableMetadata, boolean ifExists) throws SQLException;
+     public MetaDataMutationResult addColumn(List<Mutation> tableMetaData,
+                                             PTable table,
+                                             PTable parentTable,
+                                             PTable transformingNewTable,
+                                             Map<String, List<Pair<String, Object>>> properties,
+                                             Set<String> colFamiliesForPColumnsToBeAdded,
+                                             List<PColumn> columns) throws SQLException;
+     public MetaDataMutationResult dropColumn(List<Mutation> tableMetadata,
+                                              PTableType tableType, PTable parentTable) throws SQLException;
+     public MetaDataMutationResult updateIndexState(List<Mutation> tableMetadata, String parentTableName) throws SQLException;
+     public MetaDataMutationResult updateIndexState(List<Mutation> tableMetadata, String parentTableName,  Map<String, List<Pair<String,Object>>> stmtProperties,  PTable table) throws SQLException;
+ 
+     public MutationState updateData(MutationPlan plan) throws SQLException;
+ 
+     public void init(String url, Properties props) throws SQLException;
+ 
+     public int getLowestClusterHBaseVersion();
+     public Admin getAdmin() throws SQLException;
++    void refreshLiveRegionServers() throws SQLException;
++    List<ServerName> getLiveRegionServers();
+ 
+     void clearTableRegionCache(TableName name) throws SQLException;
+ 
+     boolean hasIndexWALCodec();
+     
+     long createSequence(String tenantId, String schemaName, String sequenceName, long startWith, long incrementBy, long cacheSize, long minValue, long maxValue, boolean cycle, long timestamp) throws SQLException;
+     long dropSequence(String tenantId, String schemaName, String sequenceName, long timestamp) throws SQLException;
+     void validateSequences(List<SequenceAllocation> sequenceAllocations, long timestamp, long[] values, SQLException[] exceptions, Sequence.ValueOp action) throws SQLException;
+     void incrementSequences(List<SequenceAllocation> sequenceAllocation, long timestamp, long[] values, SQLException[] exceptions) throws SQLException;
+     long currentSequenceValue(SequenceKey sequenceKey, long timestamp) throws SQLException;
+     void returnSequences(List<SequenceKey> sequenceKeys, long timestamp, SQLException[] exceptions) throws SQLException;
+ 
+     MetaDataMutationResult createFunction(List<Mutation> functionData, PFunction function, boolean temporary) throws SQLException;
+     void addConnection(PhoenixConnection connection) throws SQLException;
+     void removeConnection(PhoenixConnection connection) throws SQLException;
+ 
+     /**
+      * @return the {@link KeyValueBuilder} that is valid for the locally installed version of HBase.
+      */
+     public KeyValueBuilder getKeyValueBuilder();
+     
+     public enum Feature {LOCAL_INDEX, RENEW_LEASE};
+     public boolean supportsFeature(Feature feature);
+     
+     public String getUserName();
+     public void clearTableFromCache(final byte[] tenantId, final byte[] schemaName, final byte[] tableName, long clientTS) throws SQLException;
+ 
+     public GuidePostsInfo getTableStats(GuidePostsKey key) throws SQLException;
+     /**
+      * Removes cache {@link GuidePostsInfo} for the table with the given name. If no cached guideposts are present, this does nothing.
+      *
+      * @param key
+      */
+     void invalidateStats(GuidePostsKey key);
+     
+     
+     public long clearCache() throws SQLException;
+     public int getSequenceSaltBuckets();
+ 
+     public long getRenewLeaseThresholdMilliSeconds();
+     public boolean isRenewingLeasesEnabled();
+ 
+     public MetaDataMutationResult createSchema(List<Mutation> schemaMutations, String schemaName) throws SQLException;
+ 
+     MetaDataMutationResult getSchema(String schemaName, long clientTimestamp) throws SQLException;
+ 
+     public MetaDataMutationResult dropSchema(List<Mutation> schemaMetaData, String schemaName) throws SQLException;
+ 
+     boolean isUpgradeRequired();
+     void clearUpgradeRequired();
+     void upgradeSystemTables(String url, Properties props) throws SQLException;
+     
+     public Configuration getConfiguration();
+ 
+     public User getUser();
+ 
+     public QueryLoggerDisruptor getQueryDisruptor();
+     
+     public PhoenixTransactionClient initTransactionClient(TransactionFactory.Provider provider) throws SQLException;
+     
+     /**
+      * Writes a cell to SYSTEM.MUTEX using checkAndPut to ensure only a single client can execute a
+      * particular task. The params are used to generate the rowkey.
+      * @return true if this client was able to successfully acquire the mutex
+      */
+     public boolean writeMutexCell(String tenantId, String schemaName, String tableName,
+             String columnName, String familyName) throws SQLException;
+ 
+     /**
+      * Deletes a cell that was written to SYSTEM.MUTEX. The params are used to generate the rowkey.
+      */
+     public void deleteMutexCell(String tenantId, String schemaName, String tableName,
+             String columnName, String familyName) throws SQLException;
+ 
+     /**
+      * Close all phoenix connections created using this CQS.
+      *
+      * @param reasonBuilder exception builder for building reasons why connection is closed.
+      */
+     default void closeAllConnections(SQLExceptionInfo.Builder reasonBuilder) {
+         throw new UnsupportedOperationException();
+     }
+ 
+     PMetaData getMetaDataCache();
+     public default ConnectionLimiter getConnectionLimiter()  {
+         throw new UnsupportedOperationException();
+     }
+ 
+     int getConnectionCount(boolean isInternal);
++
++    void invalidateServerMetadataCache(List<InvalidateServerMetadataCacheRequest> requests)
++            throws Throwable;
+ }
diff --cc phoenix-core-client/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
index 0000000000,c60824a6aa..ec8fa2b41b
mode 000000,100644..100644
--- a/phoenix-core-client/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
+++ b/phoenix-core-client/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
@@@ -1,0 -1,6183 +1,6418 @@@
+ /*
+  * 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.query;
+ import static java.util.concurrent.TimeUnit.MILLISECONDS;
+ import static org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder.KEEP_DELETED_CELLS;
+ import static org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder.MAX_VERSIONS;
+ import static org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder.REPLICATION_SCOPE;
+ import static org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder.TTL;
++import static org.apache.hadoop.hbase.ipc.RpcControllerFactory.CUSTOM_CONTROLLER_CONF_KEY;
+ import static org.apache.phoenix.coprocessorclient.MetaDataProtocol.MIN_SYSTEM_TABLE_TIMESTAMP;
+ import static org.apache.phoenix.coprocessorclient.MetaDataProtocol.MIN_SYSTEM_TABLE_TIMESTAMP_4_15_0;
+ import static org.apache.phoenix.coprocessorclient.MetaDataProtocol.MIN_SYSTEM_TABLE_TIMESTAMP_4_16_0;
+ import static org.apache.phoenix.coprocessorclient.MetaDataProtocol.MIN_SYSTEM_TABLE_TIMESTAMP_5_2_0;
+ import static org.apache.phoenix.coprocessorclient.MetaDataProtocol.PHOENIX_MAJOR_VERSION;
+ import static org.apache.phoenix.coprocessorclient.MetaDataProtocol.PHOENIX_MINOR_VERSION;
+ import static org.apache.phoenix.coprocessorclient.MetaDataProtocol.PHOENIX_PATCH_NUMBER;
+ import static org.apache.phoenix.coprocessorclient.MetaDataProtocol.getVersion;
+ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.ARRAY_SIZE;
+ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_DEF;
+ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_FAMILY;
+ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_NAME;
+ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_SIZE;
+ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DATA_TABLE_NAME;
+ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DATA_TYPE;
+ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DECIMAL_DIGITS;
+ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DEFAULT_COLUMN_FAMILY_NAME;
+ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.IS_ROW_TIMESTAMP;
+ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.IS_VIEW_REFERENCED;
+ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.KEY_SEQ;
+ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.NULLABLE;
+ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.ORDINAL_POSITION;
+ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.PK_NAME;
+ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SORT_ORDER;
+ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SYSTEM_CATALOG_NAME;
+ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SYSTEM_CATALOG_NAME_BYTES;
+ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SYSTEM_CATALOG_SCHEMA;
+ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SYSTEM_CATALOG_TABLE;
+ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SYSTEM_FUNCTION_NAME_BYTES;
+ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SYSTEM_FUNCTION_HBASE_TABLE_NAME;
+ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SYSTEM_MUTEX_FAMILY_NAME_BYTES;
+ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SYSTEM_MUTEX_NAME;
+ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SYSTEM_MUTEX_TABLE_NAME;
+ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SYSTEM_SCHEMA_NAME;
+ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SYSTEM_STATS_NAME;
+ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SYSTEM_TASK_TABLE;
+ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TABLE_NAME;
+ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TABLE_SCHEM;
+ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TASK_TABLE_TTL;
+ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TENANT_ID;
+ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TRANSACTIONAL;
+ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TTL_FOR_MUTEX;
+ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.VIEW_CONSTANT;
+ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.VIEW_INDEX_ID;
+ import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SYSTEM_CATALOG_HBASE_TABLE_NAME;
+ import static org.apache.phoenix.monitoring.GlobalClientMetrics.GLOBAL_HCONNECTIONS_COUNTER;
+ import static org.apache.phoenix.monitoring.GlobalClientMetrics.GLOBAL_QUERY_SERVICES_COUNTER;
+ import static org.apache.phoenix.monitoring.GlobalClientMetrics.GLOBAL_HBASE_COUNTER_METADATA_INCONSISTENCY;
+ import static org.apache.phoenix.monitoring.MetricType.NUM_SYSTEM_TABLE_RPC_FAILURES;
+ import static org.apache.phoenix.monitoring.MetricType.NUM_SYSTEM_TABLE_RPC_SUCCESS;
+ import static org.apache.phoenix.monitoring.MetricType.TIME_SPENT_IN_SYSTEM_TABLE_RPC_CALLS;
+ import static org.apache.phoenix.query.QueryConstants.DEFAULT_COLUMN_FAMILY;
+ import static org.apache.phoenix.query.QueryServicesOptions.DEFAULT_DROP_METADATA;
+ import static org.apache.phoenix.query.QueryServicesOptions.DEFAULT_RENEW_LEASE_ENABLED;
+ import static org.apache.phoenix.query.QueryServicesOptions.DEFAULT_RENEW_LEASE_THREAD_POOL_SIZE;
+ import static org.apache.phoenix.query.QueryServicesOptions.DEFAULT_RENEW_LEASE_THRESHOLD_MILLISECONDS;
+ import static org.apache.phoenix.query.QueryServicesOptions.DEFAULT_RUN_RENEW_LEASE_FREQUENCY_INTERVAL_MILLISECONDS;
+ import static org.apache.phoenix.query.QueryServicesOptions.DEFAULT_TIMEOUT_DURING_UPGRADE_MS;
+ import static org.apache.phoenix.util.UpgradeUtil.addParentToChildLinks;
+ import static org.apache.phoenix.util.UpgradeUtil.addViewIndexToParentLinks;
+ import static org.apache.phoenix.util.UpgradeUtil.getSysTableSnapshotName;
+ import static org.apache.phoenix.util.UpgradeUtil.moveOrCopyChildLinks;
+ import static org.apache.phoenix.util.UpgradeUtil.syncTableAndIndexProperties;
+ import static org.apache.phoenix.util.UpgradeUtil.upgradeTo4_5_0;
+ 
+ import java.io.IOException;
+ import java.lang.management.ManagementFactory;
+ import java.lang.ref.WeakReference;
+ import java.nio.charset.StandardCharsets;
+ import java.sql.PreparedStatement;
+ import java.sql.ResultSetMetaData;
+ import java.sql.SQLException;
+ import java.sql.Statement;
+ import java.sql.Types;
+ import java.util.ArrayList;
+ import java.util.Arrays;
+ import java.util.Collection;
+ import java.util.Collections;
+ import java.util.HashMap;
+ import java.util.HashSet;
+ import java.util.List;
+ import java.util.Map;
+ import java.util.Map.Entry;
+ import java.util.Objects;
+ import java.util.Properties;
+ import java.util.Random;
+ import java.util.Set;
+ import java.util.concurrent.Callable;
++import java.util.concurrent.CompletableFuture;
++import java.util.concurrent.CompletionException;
+ import java.util.concurrent.ConcurrentHashMap;
+ import java.util.concurrent.ConcurrentMap;
+ import java.util.concurrent.CountDownLatch;
+ import java.util.concurrent.ExecutionException;
+ import java.util.concurrent.Executors;
++import java.util.concurrent.Future;
+ import java.util.concurrent.LinkedBlockingQueue;
+ import java.util.concurrent.ScheduledExecutorService;
+ import java.util.concurrent.ThreadFactory;
+ import java.util.concurrent.ThreadLocalRandom;
+ import java.util.concurrent.TimeUnit;
+ import java.util.concurrent.TimeoutException;
+ import java.util.concurrent.atomic.AtomicBoolean;
+ import java.util.concurrent.atomic.AtomicInteger;
+ import java.util.regex.Pattern;
+ 
+ import javax.annotation.concurrent.GuardedBy;
+ 
+ import com.google.protobuf.RpcController;
++import com.google.protobuf.ServiceException;
+ import org.apache.commons.lang3.StringUtils;
+ import org.apache.hadoop.conf.Configuration;
+ import org.apache.hadoop.hbase.HConstants;
+ import org.apache.hadoop.hbase.HRegionLocation;
+ import org.apache.hadoop.hbase.KeepDeletedCells;
+ import org.apache.hadoop.hbase.NamespaceDescriptor;
+ import org.apache.hadoop.hbase.NamespaceNotFoundException;
++import org.apache.hadoop.hbase.ServerName;
+ import org.apache.hadoop.hbase.TableExistsException;
+ import org.apache.hadoop.hbase.TableName;
+ import org.apache.hadoop.hbase.client.Admin;
+ import org.apache.hadoop.hbase.client.Append;
+ import org.apache.hadoop.hbase.client.CheckAndMutate;
+ import org.apache.hadoop.hbase.client.ClusterConnection;
+ import org.apache.hadoop.hbase.client.ColumnFamilyDescriptor;
+ import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder;
+ import org.apache.hadoop.hbase.client.Connection;
+ import org.apache.hadoop.hbase.client.CoprocessorDescriptorBuilder;
+ import org.apache.hadoop.hbase.client.Delete;
+ import org.apache.hadoop.hbase.client.Increment;
+ import org.apache.hadoop.hbase.client.Mutation;
+ import org.apache.hadoop.hbase.client.Put;
+ import org.apache.hadoop.hbase.client.Result;
+ import org.apache.hadoop.hbase.client.Table;
+ import org.apache.hadoop.hbase.client.TableDescriptor;
+ import org.apache.hadoop.hbase.client.TableDescriptorBuilder;
+ import org.apache.hadoop.hbase.client.coprocessor.Batch;
+ import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
+ import org.apache.hadoop.hbase.ipc.CoprocessorRpcUtils.BlockingRpcCallback;
+ import org.apache.hadoop.hbase.ipc.HBaseRpcController;
++import org.apache.hadoop.hbase.ipc.RpcControllerFactory;
+ import org.apache.hadoop.hbase.ipc.ServerRpcController;
++import org.apache.hadoop.hbase.ipc.controller.InvalidateMetadataCacheControllerFactory;
+ import org.apache.hadoop.hbase.ipc.controller.ServerToServerRpcController;
+ import org.apache.hadoop.hbase.ipc.controller.ServerSideRPCControllerFactory;
+ import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto;
+ import org.apache.hadoop.hbase.security.AccessDeniedException;
+ import org.apache.hadoop.hbase.security.User;
+ import org.apache.hadoop.hbase.snapshot.SnapshotCreationException;
+ import org.apache.hadoop.hbase.util.ByteStringer;
+ import org.apache.hadoop.hbase.util.Bytes;
+ import org.apache.hadoop.hbase.util.Pair;
+ import org.apache.hadoop.hbase.util.VersionInfo;
+ import org.apache.hadoop.hbase.zookeeper.ZKConfig;
+ import org.apache.hadoop.ipc.RemoteException;
+ import org.apache.phoenix.compile.MutationPlan;
+ import org.apache.phoenix.coprocessor.generated.ChildLinkMetaDataProtos.ChildLinkMetaDataService;
+ import org.apache.phoenix.coprocessor.generated.MetaDataProtos;
+ import org.apache.phoenix.coprocessor.generated.MetaDataProtos.AddColumnRequest;
+ import org.apache.phoenix.coprocessor.generated.MetaDataProtos.ClearCacheRequest;
+ import org.apache.phoenix.coprocessor.generated.MetaDataProtos.ClearCacheResponse;
+ import org.apache.phoenix.coprocessor.generated.MetaDataProtos.ClearTableFromCacheRequest;
+ import org.apache.phoenix.coprocessor.generated.MetaDataProtos.ClearTableFromCacheResponse;
+ import org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateFunctionRequest;
+ import org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateSchemaRequest;
+ import org.apache.phoenix.coprocessor.generated.MetaDataProtos.CreateTableRequest;
+ import org.apache.phoenix.coprocessor.generated.MetaDataProtos.DropColumnRequest;
+ import org.apache.phoenix.coprocessor.generated.MetaDataProtos.DropFunctionRequest;
+ import org.apache.phoenix.coprocessor.generated.MetaDataProtos.DropSchemaRequest;
+ import org.apache.phoenix.coprocessor.generated.MetaDataProtos.DropTableRequest;
+ import org.apache.phoenix.coprocessor.generated.MetaDataProtos.GetFunctionsRequest;
+ import org.apache.phoenix.coprocessor.generated.MetaDataProtos.GetSchemaRequest;
+ import org.apache.phoenix.coprocessor.generated.MetaDataProtos.GetTableRequest;
+ import org.apache.phoenix.coprocessor.generated.MetaDataProtos.GetVersionRequest;
+ import org.apache.phoenix.coprocessor.generated.MetaDataProtos.GetVersionResponse;
+ import org.apache.phoenix.coprocessor.generated.MetaDataProtos.MetaDataResponse;
+ import org.apache.phoenix.coprocessor.generated.MetaDataProtos.MetaDataService;
+ import org.apache.phoenix.coprocessor.generated.MetaDataProtos.UpdateIndexStateRequest;
++import org.apache.phoenix.coprocessor.generated.RegionServerEndpointProtos;
++import org.apache.phoenix.coprocessorclient.InvalidateServerMetadataCacheRequest;
++import org.apache.phoenix.coprocessorclient.metrics.MetricsMetadataCachingSource;
++import org.apache.phoenix.coprocessorclient.metrics.MetricsPhoenixCoprocessorSourceFactory;
+ import org.apache.phoenix.coprocessorclient.MetaDataProtocol;
+ import org.apache.phoenix.coprocessorclient.MetaDataProtocol.MetaDataMutationResult;
+ import org.apache.phoenix.coprocessorclient.MetaDataProtocol.MutationCode;
+ import org.apache.phoenix.coprocessorclient.SequenceRegionObserverConstants;
+ import org.apache.phoenix.exception.InvalidRegionSplitPolicyException;
+ import org.apache.phoenix.exception.PhoenixIOException;
+ import org.apache.phoenix.exception.RetriableUpgradeException;
+ import org.apache.phoenix.exception.SQLExceptionCode;
+ import org.apache.phoenix.exception.SQLExceptionInfo;
+ import org.apache.phoenix.exception.UpgradeInProgressException;
+ import org.apache.phoenix.exception.UpgradeNotRequiredException;
+ import org.apache.phoenix.exception.UpgradeRequiredException;
+ import org.apache.phoenix.execute.MutationState;
+ import org.apache.phoenix.hbase.index.util.KeyValueBuilder;
+ import org.apache.phoenix.hbase.index.util.VersionUtil;
+ import org.apache.phoenix.index.PhoenixIndexCodec;
+ import org.apache.phoenix.iterate.TableResultIterator;
+ import org.apache.phoenix.iterate.TableResultIterator.RenewLeaseStatus;
+ import org.apache.phoenix.jdbc.ConnectionInfo;
+ import org.apache.phoenix.jdbc.PhoenixConnection;
+ import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData;
+ import org.apache.phoenix.log.ConnectionLimiter;
+ import org.apache.phoenix.log.DefaultConnectionLimiter;
+ import org.apache.phoenix.log.LoggingConnectionLimiter;
+ import org.apache.phoenix.log.QueryLoggerDisruptor;
+ import org.apache.phoenix.monitoring.TableMetricsManager;
+ import org.apache.phoenix.parse.PFunction;
+ import org.apache.phoenix.parse.PSchema;
+ import org.apache.phoenix.protobuf.ProtobufUtil;
+ import org.apache.phoenix.schema.ColumnAlreadyExistsException;
+ import org.apache.phoenix.schema.ColumnFamilyNotFoundException;
+ import org.apache.phoenix.schema.ConnectionProperty;
+ import org.apache.phoenix.schema.EmptySequenceCacheException;
+ import org.apache.phoenix.schema.FunctionNotFoundException;
+ import org.apache.phoenix.schema.MetaDataClient;
+ import org.apache.phoenix.schema.NewerSchemaAlreadyExistsException;
+ import org.apache.phoenix.schema.NewerTableAlreadyExistsException;
+ import org.apache.phoenix.schema.PColumn;
+ import org.apache.phoenix.schema.PColumnFamily;
+ import org.apache.phoenix.schema.PColumnImpl;
+ import org.apache.phoenix.schema.PMetaData;
+ import org.apache.phoenix.schema.PMetaDataImpl;
+ import org.apache.phoenix.schema.PName;
+ import org.apache.phoenix.schema.PNameFactory;
+ import org.apache.phoenix.schema.PTable;
+ import org.apache.phoenix.schema.PTableImpl;
+ import org.apache.phoenix.schema.PTableKey;
+ import org.apache.phoenix.schema.PTableRef;
+ import org.apache.phoenix.schema.PTableType;
+ import org.apache.phoenix.schema.ReadOnlyTableException;
+ import org.apache.phoenix.schema.SaltingUtil;
+ import org.apache.phoenix.schema.Sequence;
+ import org.apache.phoenix.schema.SequenceAllocation;
+ import org.apache.phoenix.schema.SequenceKey;
+ import org.apache.phoenix.schema.SortOrder;
+ import org.apache.phoenix.schema.TableAlreadyExistsException;
+ import org.apache.phoenix.schema.TableNotFoundException;
+ import org.apache.phoenix.schema.TableProperty;
+ import org.apache.phoenix.schema.stats.GuidePostsInfo;
+ import org.apache.phoenix.schema.stats.GuidePostsKey;
+ import org.apache.phoenix.schema.types.PBoolean;
+ import org.apache.phoenix.schema.types.PDataType;
+ import org.apache.phoenix.schema.types.PInteger;
+ import org.apache.phoenix.schema.types.PLong;
+ import org.apache.phoenix.schema.types.PTimestamp;
+ import org.apache.phoenix.schema.types.PTinyint;
+ import org.apache.phoenix.schema.types.PUnsignedTinyint;
+ import org.apache.phoenix.schema.types.PVarbinary;
+ import org.apache.phoenix.schema.types.PVarchar;
+ import org.apache.phoenix.transaction.PhoenixTransactionClient;
+ import org.apache.phoenix.transaction.PhoenixTransactionContext;
+ import org.apache.phoenix.transaction.PhoenixTransactionProvider;
+ import org.apache.phoenix.transaction.TransactionFactory;
+ import org.apache.phoenix.transaction.TransactionFactory.Provider;
+ import org.apache.phoenix.util.ByteUtil;
+ import org.apache.phoenix.util.ClientUtil;
+ import org.apache.phoenix.util.Closeables;
+ import org.apache.phoenix.util.ConfigUtil;
+ import org.apache.phoenix.util.EnvironmentEdgeManager;
+ import org.apache.phoenix.util.IndexUtil;
+ import org.apache.phoenix.util.JDBCUtil;
+ import org.apache.phoenix.util.LogUtil;
+ import org.apache.phoenix.util.MetaDataUtil;
+ import org.apache.phoenix.util.PhoenixContextExecutor;
+ import org.apache.phoenix.util.PhoenixRuntime;
+ import org.apache.phoenix.util.PhoenixStopWatch;
+ import org.apache.phoenix.util.PropertiesUtil;
+ import org.apache.phoenix.util.QueryUtil;
+ import org.apache.phoenix.util.ReadOnlyProps;
+ import org.apache.phoenix.util.SchemaUtil;
+ import org.apache.phoenix.util.StringUtil;
+ import org.apache.phoenix.util.UpgradeUtil;
+ import org.slf4j.Logger;
+ import org.slf4j.LoggerFactory;
+ 
+ import org.apache.phoenix.thirdparty.com.google.common.annotations.VisibleForTesting;
+ import org.apache.phoenix.thirdparty.com.google.common.base.Joiner;
+ import org.apache.phoenix.thirdparty.com.google.common.base.Preconditions;
+ import org.apache.phoenix.thirdparty.com.google.common.base.Strings;
+ import org.apache.phoenix.thirdparty.com.google.common.base.Throwables;
+ import org.apache.phoenix.thirdparty.com.google.common.collect.ImmutableList;
+ import org.apache.phoenix.thirdparty.com.google.common.collect.ImmutableMap;
+ import org.apache.phoenix.thirdparty.com.google.common.collect.Iterables;
+ import org.apache.phoenix.thirdparty.com.google.common.collect.Lists;
+ import org.apache.phoenix.thirdparty.com.google.common.collect.Maps;
+ import org.apache.phoenix.thirdparty.com.google.common.collect.Sets;
+ 
+ public class ConnectionQueryServicesImpl extends DelegateQueryServices implements ConnectionQueryServices {
+     private static final Logger LOGGER =
+             LoggerFactory.getLogger(ConnectionQueryServicesImpl.class);
+     private static final int INITIAL_CHILD_SERVICES_CAPACITY = 100;
+     private static final int DEFAULT_OUT_OF_ORDER_MUTATIONS_WAIT_TIME_MS = 1000;
+     private static final String ALTER_TABLE_SET_PROPS =
+         "ALTER TABLE %s SET %s=%s";
+     private final GuidePostsCacheProvider
+             GUIDE_POSTS_CACHE_PROVIDER = new GuidePostsCacheProvider();
+     protected final Configuration config;
+ 
+     public ConnectionInfo getConnectionInfo() {
+         return connectionInfo;
+     }
+ 
+     protected final ConnectionInfo connectionInfo;
+     // Copy of config.getProps(), but read-only to prevent synchronization that we
+     // don't need.
+     private final ReadOnlyProps props;
+     private final String userName;
+     private final User user;
+     private final ConcurrentHashMap<ImmutableBytesWritable,ConnectionQueryServices> childServices;
+     private final GuidePostsCacheWrapper tableStatsCache;
+ 
+     // Cache the latest meta data here for future connections
+     // writes guarded by "latestMetaDataLock"
+     private volatile PMetaData latestMetaData;
+     private final Object latestMetaDataLock = new Object();
+ 
+     // Lowest HBase version on the cluster.
+     private int lowestClusterHBaseVersion = Integer.MAX_VALUE;
+     private boolean hasIndexWALCodec = true;
+ 
+     @GuardedBy("connectionCountLock")
+     private int connectionCount = 0;
+ 
+     @GuardedBy("connectionCountLock")
+     private int internalConnectionCount = 0;
+ 
+     private final Object connectionCountLock = new Object();
+     private final boolean returnSequenceValues ;
+ 
+     private Connection connection;
+     private volatile boolean initialized;
+     private volatile int nSequenceSaltBuckets;
+ 
+     // writes guarded by "this"
+     private volatile boolean closed;
+ 
+     private volatile SQLException initializationException;
+     // setting this member variable guarded by "connectionCountLock"
+     private volatile ConcurrentMap<SequenceKey,Sequence> sequenceMap = Maps.newConcurrentMap();
+     private KeyValueBuilder kvBuilder;
+ 
+     private final int renewLeaseTaskFrequency;
+     private final int renewLeasePoolSize;
+     private final int renewLeaseThreshold;
+     // List of queues instead of a single queue to provide reduced contention via lock striping
+     private final List<LinkedBlockingQueue<WeakReference<PhoenixConnection>>> connectionQueues;
+     private ScheduledExecutorService renewLeaseExecutor;
+     // Use TransactionFactory.Provider.values() here not TransactionFactory.Provider.available()
+     // because the array will be indexed by ordinal.
+     private PhoenixTransactionClient[] txClients = new PhoenixTransactionClient[Provider.values().length];
+     /*
+      * We can have multiple instances of ConnectionQueryServices. By making the thread factory
+      * static, renew lease thread names will be unique across them.
+      */
+     private static final ThreadFactory renewLeaseThreadFactory = new RenewLeaseThreadFactory();
+     private final boolean renewLeaseEnabled;
+     private final boolean isAutoUpgradeEnabled;
+     private final AtomicBoolean upgradeRequired = new AtomicBoolean(false);
+     private final int maxConnectionsAllowed;
+     private final int maxInternalConnectionsAllowed;
+     private final boolean shouldThrottleNumConnections;
+     public static final byte[] MUTEX_LOCKED = "MUTEX_LOCKED".getBytes(StandardCharsets.UTF_8);
+     private ServerSideRPCControllerFactory serverSideRPCControllerFactory;
+     private boolean localIndexUpgradeRequired;
+ 
+     private final boolean enableConnectionActivityLogging;
+     private final int loggingIntervalInMins;
+ 
+     private final ConnectionLimiter connectionLimiter;
+ 
++    // writes guarded by "liveRegionServersLock"
++    private volatile List<ServerName> liveRegionServers;
++    private final Object liveRegionServersLock = new Object();
++    // Writes guarded by invalidateMetadataCacheConnLock
++    private Connection invalidateMetadataCacheConnection = null;
++    private final Object invalidateMetadataCacheConnLock = new Object();
++    private MetricsMetadataCachingSource metricsMetadataCachingSource;
++    public static final String INVALIDATE_SERVER_METADATA_CACHE_EX_MESSAGE =
++            "Cannot invalidate server metadata cache on a non-server connection";
++
+     private static interface FeatureSupported {
+         boolean isSupported(ConnectionQueryServices services);
+     }
+ 
+     private final Map<Feature, FeatureSupported> featureMap = ImmutableMap.<Feature, FeatureSupported>of(
+             Feature.LOCAL_INDEX, new FeatureSupported() {
+                 @Override
+                 public boolean isSupported(ConnectionQueryServices services) {
+                     int hbaseVersion = services.getLowestClusterHBaseVersion();
+                     return hbaseVersion < MetaDataProtocol.MIN_LOCAL_SI_VERSION_DISALLOW || hbaseVersion > MetaDataProtocol.MAX_LOCAL_SI_VERSION_DISALLOW;
+                 }
+             },
+             Feature.RENEW_LEASE, new FeatureSupported() {
+                 @Override
+                 public boolean isSupported(ConnectionQueryServices services) {
+                     int hbaseVersion = services.getLowestClusterHBaseVersion();
+                     return hbaseVersion >= MetaDataProtocol.MIN_RENEW_LEASE_VERSION;
+                 }
+             });
+     private QueryLoggerDisruptor queryDisruptor;
+ 
+     private PMetaData newEmptyMetaData() {
+         return new PMetaDataImpl(INITIAL_META_DATA_TABLE_CAPACITY,
+                 (Long) ConnectionProperty.UPDATE_CACHE_FREQUENCY.getValue(
+                 getProps().get(QueryServices.DEFAULT_UPDATE_CACHE_FREQUENCY_ATRRIB)),
+                         getProps());
+     }
+ 
+     /**
+      * Construct a ConnectionQueryServicesImpl that represents a connection to an HBase
+      * cluster.
+      * @param services base services from where we derive our default configuration
+      * @param connectionInfo to provide connection information
+      * @param info hbase configuration properties
+      */
+     public ConnectionQueryServicesImpl(QueryServices services, ConnectionInfo connectionInfo, Properties info) {
+         super(services);
+         Configuration config = HBaseFactoryProvider.getConfigurationFactory().getConfiguration();
+         for (Entry<String,String> entry : services.getProps()) {
+             config.set(entry.getKey(), entry.getValue());
+         }
+         if (info != null) {
+             for (Object key : info.keySet()) {
+                 config.set((String) key, info.getProperty((String) key));
+             }
+         }
+         for (Entry<String,String> entry : connectionInfo.asProps()) {
+             config.set(entry.getKey(), entry.getValue());
+         }
+         if (connectionInfo.getPrincipal() != null) {
+             config.set(QUERY_SERVICES_NAME, connectionInfo.getPrincipal());
+         }
+         LOGGER.info(String.format("CQS initialized with connection query service : %s",
+                 config.get(QUERY_SERVICES_NAME)));
+         this.connectionInfo = connectionInfo;
+ 
+         // Without making a copy of the configuration we cons up, we lose some of our properties
+         // on the server side during testing.
+         this.config = HBaseFactoryProvider.getConfigurationFactory().getConfiguration(config);
+         //Set the rpcControllerFactory if it is a server side connnection.
+         boolean isServerSideConnection = config.getBoolean(QueryUtil.IS_SERVER_CONNECTION, false);
+         if (isServerSideConnection) {
+             this.serverSideRPCControllerFactory = new ServerSideRPCControllerFactory(config);
+         }
+         // set replication required parameter
+         ConfigUtil.setReplicationConfigIfAbsent(this.config);
+         this.props = new ReadOnlyProps(this.config.iterator());
+         this.userName = connectionInfo.getPrincipal();
+         this.user = connectionInfo.getUser();
+         this.latestMetaData = newEmptyMetaData();
+         // TODO: should we track connection wide memory usage or just org-wide usage?
+         // If connection-wide, create a MemoryManager here, otherwise just use the one from the delegate
+         this.childServices = new ConcurrentHashMap<ImmutableBytesWritable,ConnectionQueryServices>(INITIAL_CHILD_SERVICES_CAPACITY);
+         // find the HBase version and use that to determine the KeyValueBuilder that should be used
+         String hbaseVersion = VersionInfo.getVersion();
+         this.kvBuilder = KeyValueBuilder.get(hbaseVersion);
+         this.returnSequenceValues = props.getBoolean(QueryServices.RETURN_SEQUENCE_VALUES_ATTRIB, QueryServicesOptions.DEFAULT_RETURN_SEQUENCE_VALUES);
+         this.renewLeaseEnabled = config.getBoolean(RENEW_LEASE_ENABLED, DEFAULT_RENEW_LEASE_ENABLED);
+         this.renewLeasePoolSize = config.getInt(RENEW_LEASE_THREAD_POOL_SIZE, DEFAULT_RENEW_LEASE_THREAD_POOL_SIZE);
+         this.renewLeaseThreshold = config.getInt(RENEW_LEASE_THRESHOLD_MILLISECONDS, DEFAULT_RENEW_LEASE_THRESHOLD_MILLISECONDS);
+         this.renewLeaseTaskFrequency = config.getInt(RUN_RENEW_LEASE_FREQUENCY_INTERVAL_MILLISECONDS, DEFAULT_RUN_RENEW_LEASE_FREQUENCY_INTERVAL_MILLISECONDS);
+         List<LinkedBlockingQueue<WeakReference<PhoenixConnection>>> list = Lists.newArrayListWithCapacity(renewLeasePoolSize);
+         for (int i = 0; i < renewLeasePoolSize; i++) {
+             LinkedBlockingQueue<WeakReference<PhoenixConnection>> queue = new LinkedBlockingQueue<WeakReference<PhoenixConnection>>();
+             list.add(queue);
+         }
+         connectionQueues = ImmutableList.copyOf(list);
+ 
+         // A little bit of a smell to leak `this` here, but should not be a problem
+         this.tableStatsCache = GUIDE_POSTS_CACHE_PROVIDER.getGuidePostsCache(props.get(GUIDE_POSTS_CACHE_FACTORY_CLASS,
+                 QueryServicesOptions.DEFAULT_GUIDE_POSTS_CACHE_FACTORY_CLASS), this, config);
+ 
+         this.isAutoUpgradeEnabled = config.getBoolean(AUTO_UPGRADE_ENABLED, QueryServicesOptions.DEFAULT_AUTO_UPGRADE_ENABLED);
+         this.maxConnectionsAllowed = config.getInt(QueryServices.CLIENT_CONNECTION_MAX_ALLOWED_CONNECTIONS,
+             QueryServicesOptions.DEFAULT_CLIENT_CONNECTION_MAX_ALLOWED_CONNECTIONS);
+         this.maxInternalConnectionsAllowed = config.getInt(QueryServices.INTERNAL_CONNECTION_MAX_ALLOWED_CONNECTIONS,
+                 QueryServicesOptions.DEFAULT_INTERNAL_CONNECTION_MAX_ALLOWED_CONNECTIONS);
+         this.shouldThrottleNumConnections = (maxConnectionsAllowed > 0) || (maxInternalConnectionsAllowed > 0);
+         this.enableConnectionActivityLogging =
+                 config.getBoolean(CONNECTION_ACTIVITY_LOGGING_ENABLED,
+                         QueryServicesOptions.DEFAULT_CONNECTION_ACTIVITY_LOGGING_ENABLED);
+         this.loggingIntervalInMins =
+                 config.getInt(CONNECTION_ACTIVITY_LOGGING_INTERVAL,
+                         QueryServicesOptions.DEFAULT_CONNECTION_ACTIVITY_LOGGING_INTERVAL_IN_MINS);
+ 
+         if (enableConnectionActivityLogging) {
+             LoggingConnectionLimiter.Builder builder = new LoggingConnectionLimiter.Builder(shouldThrottleNumConnections);
+             connectionLimiter = builder
+                     .withLoggingIntervalInMins(loggingIntervalInMins)
+                     .withLogging(true)
+                     .withMaxAllowed(this.maxConnectionsAllowed)
+                     .withMaxInternalAllowed(this.maxInternalConnectionsAllowed)
+                     .build();
+         } else {
+             DefaultConnectionLimiter.Builder builder = new DefaultConnectionLimiter.Builder(shouldThrottleNumConnections);
+             connectionLimiter = builder
+                     .withMaxAllowed(this.maxConnectionsAllowed)
+                     .withMaxInternalAllowed(this.maxInternalConnectionsAllowed)
+                     .build();
+         }
+ 
+ 
+         if (!QueryUtil.isServerConnection(props)) {
+             //Start queryDistruptor everytime as log level can be change at connection level as well, but we can avoid starting for server connections.
+             try {
+                 this.queryDisruptor = new QueryLoggerDisruptor(this.config);
+             } catch (SQLException e) {
+                 LOGGER.warn("Unable to initiate query logging service !!");
+                 e.printStackTrace();
+             }
+         }
 -
++        nSequenceSaltBuckets = config.getInt(QueryServices.SEQUENCE_SALT_BUCKETS_ATTRIB,
++                QueryServicesOptions.DEFAULT_SEQUENCE_TABLE_SALT_BUCKETS);
++        this.metricsMetadataCachingSource = MetricsPhoenixCoprocessorSourceFactory.getInstance()
++                .getMetadataCachingSource();
+     }
+ 
 -    private void openConnection() throws SQLException {
++    private Connection openConnection(Configuration conf) throws SQLException {
++        Connection localConnection;
+         try {
 -            this.connection = HBaseFactoryProvider.getHConnectionFactory().createConnection(this.config);
++            localConnection = HBaseFactoryProvider.getHConnectionFactory().createConnection(conf);
+             GLOBAL_HCONNECTIONS_COUNTER.increment();
+             LOGGER.info("HConnection established. Stacktrace for informational purposes: "
 -                    + connection + " " +  LogUtil.getCallerStackTrace());
++                    + localConnection + " " +  LogUtil.getCallerStackTrace());
+         } catch (IOException e) {
+             throw new SQLExceptionInfo.Builder(SQLExceptionCode.CANNOT_ESTABLISH_CONNECTION)
+             .setRootCause(e).build().buildException();
+         }
 -        if (this.connection.isClosed()) { // TODO: why the heck doesn't this throw above?
++        if (localConnection.isClosed()) { // TODO: why the heck doesn't this throw above?
+             throw new SQLExceptionInfo.Builder(SQLExceptionCode.CANNOT_ESTABLISH_CONNECTION).build().buildException();
+         }
++        return localConnection;
++    }
++
++    /**
++     *  We create a long-lived hbase connection to run invalidate cache RPCs. We override
++     *  CUSTOM_CONTROLLER_CONF_KEY to instantiate InvalidateMetadataCacheController which has
++     *  a special priority for invalidate metadata cache operations.
++     * @return hbase connection
++     * @throws SQLException SQLException
++     */
++    public Connection getInvalidateMetadataCacheConnection() throws SQLException {
++        if (invalidateMetadataCacheConnection != null) {
++            return invalidateMetadataCacheConnection;
++        }
++
++        synchronized (invalidateMetadataCacheConnLock) {
++            Configuration clonedConfiguration = PropertiesUtil.cloneConfig(this.config);
++            clonedConfiguration.setClass(CUSTOM_CONTROLLER_CONF_KEY,
++                    InvalidateMetadataCacheControllerFactory.class, RpcControllerFactory.class);
++            invalidateMetadataCacheConnection = openConnection(clonedConfiguration);
++        }
++        return invalidateMetadataCacheConnection;
+     }
+ 
+     /**
+      * Close the HBase connection and decrement the counter.
+      * @throws IOException throws IOException
+      */
 -    private void closeConnection() throws IOException {
++    private void closeConnection(Connection connection) throws IOException {
+         if (connection != null) {
+             connection.close();
+             LOGGER.info("{} HConnection closed. Stacktrace for informational"
+                 + " purposes: {}", connection, LogUtil.getCallerStackTrace());
++            GLOBAL_HCONNECTIONS_COUNTER.decrement();
+         }
 -        GLOBAL_HCONNECTIONS_COUNTER.decrement();
+     }
+ 
+     @Override
+     public Table getTable(byte[] tableName) throws SQLException {
+         try {
+             return HBaseFactoryProvider.getHTableFactory().getTable(tableName,
+                 connection, null);
+         } catch (IOException e) {
+             throw new SQLException(e);
+         }
+     }
+ 
+     @Override
+     public Table getTableIfExists(byte[] tableName) throws SQLException {
+         try (Admin admin = getAdmin()) {
+             if (!AdminUtilWithFallback.tableExists(admin, TableName.valueOf(tableName))) {
+                 throw new TableNotFoundException(
+                     SchemaUtil.getSchemaNameFromFullName(tableName),
+                     SchemaUtil.getTableNameFromFullName(tableName));
+             }
+         } catch (IOException | InterruptedException e) {
+             throw new SQLException(e);
+         }
+         return getTable(tableName);
+     }
+ 
+     @Override
+     public TableDescriptor getTableDescriptor(byte[] tableName) throws SQLException {
+         Table htable = getTable(tableName);
+         try {
+             return htable.getDescriptor();
+         } catch (IOException e) {
+             if (e instanceof org.apache.hadoop.hbase.TableNotFoundException
+                     || e.getCause() instanceof org.apache.hadoop.hbase.TableNotFoundException) {
+                 byte[][] schemaAndTableName = new byte[2][];
+                 SchemaUtil.getVarChars(tableName, schemaAndTableName);
+                 throw new TableNotFoundException(Bytes.toString(schemaAndTableName[0]), Bytes.toString(schemaAndTableName[1]));
+             }
+             throw new RuntimeException(e);
+         } finally {
+             Closeables.closeQuietly(htable);
+         }
+     }
+ 
+     @Override
+     public ReadOnlyProps getProps() {
+         return props;
+     }
+ 
+     /**
+      * Closes all the connections it has in its connectionQueues.
+      */
+     @Override
+     public void closeAllConnections(SQLExceptionInfo.Builder reasonBuilder) {
+         for (LinkedBlockingQueue<WeakReference<PhoenixConnection>> queue : connectionQueues) {
+             for (WeakReference<PhoenixConnection> connectionReference : queue) {
+                 PhoenixConnection connection = connectionReference.get();
+                 try {
+                     if (connection != null && !connection.isClosed()) {
+                         connection.close(reasonBuilder.build().buildException());
+                     }
+                 } catch (SQLException e) {
+                     LOGGER.warn("Exception while closing phoenix connection {}", connection, e);
+                 }
+             }
+         }
+     }
+ 
+ 
+     /**
+      * Closes the underlying connection to zookeeper. The QueryServices
+      * may not be used after that point. When a Connection is closed,
+      * this is not called, since these instances are pooled by the
+      * Driver. Instead, the Driver should call this if the QueryServices
+      * is ever removed from the pool
+      */
+     @Override
+     public void close() throws SQLException {
+         if (closed) {
+             return;
+         }
+         synchronized (this) {
+             if (closed) {
+                 return;
+             }
+             closed = true;
+             GLOBAL_QUERY_SERVICES_COUNTER.decrement();
+             try {
+                 if (this.queryDisruptor != null) {
+                     this.queryDisruptor.close();
+                 }
+             } catch (Exception e) {
+                 // Ignore
+             }
+             SQLException sqlE = null;
+             try {
+                 // Attempt to return any unused sequences.
+                 if (connection != null) returnAllSequences(this.sequenceMap);
+             } catch (SQLException e) {
+                 sqlE = e;
+             } finally {
+                 try {
+                     childServices.clear();
+                     synchronized (latestMetaDataLock) {
+                         latestMetaData = null;
+                         latestMetaDataLock.notifyAll();
+                     }
+                     try {
 -                        // close the HBase connection
 -                        closeConnection();
++                        // close HBase connections.
++                        closeConnection(this.connection);
++                        closeConnection(this.invalidateMetadataCacheConnection);
+                     } finally {
+                         if (renewLeaseExecutor != null) {
+                             renewLeaseExecutor.shutdownNow();
+                         }
+                         // shut down the tx client service if we created one to support transactions
+                         for (PhoenixTransactionClient client : txClients) {
+                             if (client != null) {
+                                 client.close();
+                             }
+                         }
+                     }
+                 } catch (IOException e) {
+                     if (sqlE == null) {
+                         sqlE = ClientUtil.parseServerException(e);
+                     } else {
+                         sqlE.setNextException(ClientUtil.parseServerException(e));
+                     }
+                 } finally {
+                     try {
+                         tableStatsCache.invalidateAll();
+                         super.close();
+                     } catch (SQLException e) {
+                         if (sqlE == null) {
+                             sqlE = e;
+                         } else {
+                             sqlE.setNextException(e);
+                         }
+                     } finally {
+                         if (sqlE != null) { throw sqlE; }
+                     }
+                 }
+             }
+         }
+     }
+ 
+     protected ConnectionQueryServices newChildQueryService() {
+         return new ChildQueryServices(this);
+     }
+ 
+     /**
+      * Get (and create if necessary) a child QueryService for a given tenantId.
+      * The QueryService will be cached for the lifetime of the parent QueryService
+      * @param tenantId the tenant ID
+      * @return the child QueryService
+      */
+     @Override
+     public ConnectionQueryServices getChildQueryServices(ImmutableBytesWritable tenantId) {
+         ConnectionQueryServices childQueryService = childServices.get(tenantId);
+         if (childQueryService == null) {
+             childQueryService = newChildQueryService();
+             ConnectionQueryServices prevQueryService = childServices.putIfAbsent(tenantId, childQueryService);
+             return prevQueryService == null ? childQueryService : prevQueryService;
+         }
+         return childQueryService;
+     }
+ 
+     @Override
+     public void clearTableRegionCache(TableName tableName) throws SQLException {
+         ((ClusterConnection)connection).clearRegionCache(tableName);
+     }
+ 
+     public byte[] getNextRegionStartKey(HRegionLocation regionLocation, byte[] currentKey) throws IOException {
+         // in order to check the overlap/inconsistencies bad region info, we have to make sure
+         // the current endKey always increasing(compare the previous endKey)
+         // note :- currentKey is the previous regions endKey
+         if ((Bytes.compareTo(regionLocation.getRegion().getStartKey(), currentKey) != 0
+                 || Bytes.compareTo(regionLocation.getRegion().getEndKey(), currentKey) <= 0)
+                 && !Bytes.equals(currentKey, HConstants.EMPTY_START_ROW)
+                 && !Bytes.equals(regionLocation.getRegion().getEndKey(), HConstants.EMPTY_END_ROW)) {
+             GLOBAL_HBASE_COUNTER_METADATA_INCONSISTENCY.increment();
+             String regionNameString =
+                     new String(regionLocation.getRegion().getRegionName(), StandardCharsets.UTF_8);
+             throw new IOException(String.format(
+                     "HBase region information overlap/inconsistencies on region %s", regionNameString));
+         }
+         return regionLocation.getRegion().getEndKey();
+     }
+ 
+     @Override
+     public List<HRegionLocation> getAllTableRegions(byte[] tableName) throws SQLException {
+         /*
+          * Use HConnection.getRegionLocation as it uses the cache in HConnection, while getting
+          * all region locations from the HTable doesn't.
+          */
+         int retryCount = 0, maxRetryCount = 1;
+         TableName table = TableName.valueOf(tableName);
+         while (true) {
+             try {
+                 // We could surface the package projected HConnectionImplementation.getNumberOfCachedRegionLocations
+                 // to get the sizing info we need, but this would require a new class in the same package and a cast
+                 // to this implementation class, so it's probably not worth it.
+                 List<HRegionLocation> locations = Lists.newArrayList();
+                 byte[] currentKey = HConstants.EMPTY_START_ROW;
+                 do {
+                     HRegionLocation regionLocation = ((ClusterConnection)connection).getRegionLocation(
+                             table, currentKey, false);
+                     currentKey = getNextRegionStartKey(regionLocation, currentKey);
+                     locations.add(regionLocation);
+                 } while (!Bytes.equals(currentKey, HConstants.EMPTY_END_ROW));
+                 return locations;
+             } catch (org.apache.hadoop.hbase.TableNotFoundException e) {
+                 throw new TableNotFoundException(table.getNameAsString());
+             } catch (IOException e) {
+                 LOGGER.error("Exception encountered in getAllTableRegions for "
+                         + "table: {}, retryCount: {}", table.getNameAsString(), retryCount, e);
+                 if (retryCount++ < maxRetryCount) { // One retry, in case split occurs while navigating
+                     continue;
+                 }
+                 throw new SQLExceptionInfo.Builder(SQLExceptionCode.GET_TABLE_REGIONS_FAIL)
+                 .setRootCause(e).build().buildException();
+             }
+         }
+     }
+ 
+     public PMetaData getMetaDataCache() {
+         return latestMetaData;
+     }
+ 
+     @Override
+     public int getConnectionCount(boolean isInternal) {
+         if (isInternal) {
+             return connectionLimiter.getInternalConnectionCount();
+         } else {
+             return connectionLimiter.getConnectionCount();
+         }
+     }
+ 
+     @Override
+     public void addTable(PTable table, long resolvedTime) throws SQLException {
+         synchronized (latestMetaDataLock) {
+             try {
+                 throwConnectionClosedIfNullMetaData();
+                 // If existing table isn't older than new table, don't replace
+                 // If a client opens a connection at an earlier timestamp, this can happen
+                 PTableRef existingTableRef = latestMetaData.getTableRef(new PTableKey(
+                         table.getTenantId(), table.getName().getString()));
+                 PTable existingTable = existingTableRef.getTable();
+                 if (existingTable.getTimeStamp() > table.getTimeStamp()) {
+                     return;
+                 }
+             } catch (TableNotFoundException e) {}
+             latestMetaData.addTable(table, resolvedTime);
+             latestMetaDataLock.notifyAll();
+         }
+     }
+     @Override
+     public void updateResolvedTimestamp(PTable table, long resolvedTime) throws SQLException {
+         synchronized (latestMetaDataLock) {
+             throwConnectionClosedIfNullMetaData();
+             latestMetaData.updateResolvedTimestamp(table, resolvedTime);
+             latestMetaDataLock.notifyAll();
+         }
+     }
+ 
+     private static interface Mutator {
+         void mutate(PMetaData metaData) throws SQLException;
+     }
+ 
+     /**
+      * Ensures that metaData mutations are handled in the correct order
+      */
+     private PMetaData metaDataMutated(PName tenantId, String tableName, long tableSeqNum, Mutator mutator) throws SQLException {
+         synchronized (latestMetaDataLock) {
+             throwConnectionClosedIfNullMetaData();
+             PMetaData metaData = latestMetaData;
+             PTable table;
+             long endTime = EnvironmentEdgeManager.currentTimeMillis() +
+                 DEFAULT_OUT_OF_ORDER_MUTATIONS_WAIT_TIME_MS;
+             while (true) {
+                 try {
+                     try {
+                         table = metaData.getTableRef(new PTableKey(tenantId, tableName)).getTable();
+                         /* If the table is at the prior sequence number, then we're good to go.
+                          * We know if we've got this far, that the server validated the mutations,
+                          * so we'd just need to wait until the other connection that mutated the same
+                          * table is processed.
+                          */
+                         if (table.getSequenceNumber() + 1 == tableSeqNum) {
+                             // TODO: assert that timeStamp is bigger that table timeStamp?
+                             mutator.mutate(metaData);
+                             break;
+                         } else if (table.getSequenceNumber() >= tableSeqNum) {
+                             LOGGER.warn("Attempt to cache older version of " + tableName +
+                                     ": current= " + table.getSequenceNumber() +
+                                     ", new=" + tableSeqNum);
+                             break;
+                         }
+                     } catch (TableNotFoundException e) {
+                     }
+                     long waitTime = endTime - EnvironmentEdgeManager.currentTimeMillis();
+                     // We waited long enough - just remove the table from the cache
+                     // and the next time it's used it'll be pulled over from the server.
+                     if (waitTime <= 0) {
+                         LOGGER.warn("Unable to update meta data repo within " +
+                                 (DEFAULT_OUT_OF_ORDER_MUTATIONS_WAIT_TIME_MS/1000) +
+                                 " seconds for " + tableName);
+                         // There will never be a parentTableName here, as that would only
+                         // be non null for an index an we never add/remove columns from an index.
+                         metaData.removeTable(tenantId, tableName, null, HConstants.LATEST_TIMESTAMP);
+                         break;
+                     }
+                     latestMetaDataLock.wait(waitTime);
+                 } catch (InterruptedException e) {
+                     // restore the interrupt status
+                     Thread.currentThread().interrupt();
+                     throw new SQLExceptionInfo.Builder(SQLExceptionCode.INTERRUPTED_EXCEPTION)
+                     .setRootCause(e).build().buildException(); // FIXME
+                 }
+             }
+             latestMetaData = metaData;
+             latestMetaDataLock.notifyAll();
+             return metaData;
+         }
+     }
+ 
+     @Override
+     public void removeTable(PName tenantId, final String tableName, String parentTableName, long tableTimeStamp) throws SQLException {
+         synchronized (latestMetaDataLock) {
+             throwConnectionClosedIfNullMetaData();
+             latestMetaData.removeTable(tenantId, tableName, parentTableName, tableTimeStamp);
+             latestMetaDataLock.notifyAll();
+         }
+     }
+ 
+     @Override
+     public void removeColumn(final PName tenantId, final String tableName, final List<PColumn> columnsToRemove, final long tableTimeStamp, final long tableSeqNum, final long resolvedTime) throws SQLException {
+         metaDataMutated(tenantId, tableName, tableSeqNum, new Mutator() {
+             @Override
+             public void mutate(PMetaData metaData) throws SQLException {
+                 try {
+                     metaData.removeColumn(tenantId, tableName, columnsToRemove, tableTimeStamp, tableSeqNum, resolvedTime);
+                 } catch (TableNotFoundException e) {
+                     // The DROP TABLE may have been processed first, so just ignore.
+                 }
+             }
+         });
+     }
+ 
+     /**
+      * Check that the supplied connection properties are set to valid values.
+      * @param info The properties to be validated.
+      * @throws IllegalArgumentException when a property is not set to a valid value.
+      */
+     private void validateConnectionProperties(Properties info) {
+         if (info.get(DEFAULT_UPDATE_CACHE_FREQUENCY_ATRRIB) != null) {
+             if (LOGGER.isInfoEnabled()) {
+                 LOGGER.info("Connection's " + DEFAULT_UPDATE_CACHE_FREQUENCY_ATRRIB + " set to " +
+                         info.get(DEFAULT_UPDATE_CACHE_FREQUENCY_ATRRIB));
+             }
+             ConnectionProperty.UPDATE_CACHE_FREQUENCY.getValue(
+                     info.getProperty(DEFAULT_UPDATE_CACHE_FREQUENCY_ATRRIB));
+         }
+     }
+ 
+     @Override
+     public PhoenixConnection connect(String url, Properties info) throws SQLException {
+         checkClosed();
+         throwConnectionClosedIfNullMetaData();
+         validateConnectionProperties(info);
+ 
+         return new PhoenixConnection(this, url, info);
+     }
+ 
+     private ColumnFamilyDescriptor generateColumnFamilyDescriptor(Pair<byte[],Map<String,Object>> family, PTableType tableType) throws SQLException {
+         ColumnFamilyDescriptorBuilder columnDescBuilder = ColumnFamilyDescriptorBuilder.newBuilder(family.getFirst());
+         if (tableType != PTableType.VIEW) {
+             columnDescBuilder.setDataBlockEncoding(SchemaUtil.DEFAULT_DATA_BLOCK_ENCODING);
+             for (Entry<String,Object> entry : family.getSecond().entrySet()) {
+                 String key = entry.getKey();
+                 Object value = entry.getValue();
+                 setHColumnDescriptorValue(columnDescBuilder, key, value);
+             }
+         }
+         return columnDescBuilder.build();
+     }
+ 
+     // Workaround HBASE-14737
+     private static void setHColumnDescriptorValue(ColumnFamilyDescriptorBuilder columnDescBuilder, String key, Object value) {
+         if (HConstants.VERSIONS.equals(key)) {
+             columnDescBuilder.setMaxVersions(getMaxVersion(value));
+         } else {
+             columnDescBuilder.setValue(key, value == null ? null : value.toString());
+         }
+     }
+ 
+     private static int getMaxVersion(Object value) {
+         if (value == null) {
+             return -1;  // HColumnDescriptor.UNINITIALIZED is private
+         }
+         if (value instanceof Number) {
+             return ((Number)value).intValue();
+         }
+         String stringValue = value.toString();
+         if (stringValue.isEmpty()) {
+             return -1;
+         }
+         return Integer.parseInt(stringValue);
+     }
+ 
+     private void modifyColumnFamilyDescriptor(ColumnFamilyDescriptorBuilder hcd, Map<String,Object> props) throws SQLException {
+         for (Entry<String, Object> entry : props.entrySet()) {
+             String propName = entry.getKey();
+             Object value = entry.getValue();
+             setHColumnDescriptorValue(hcd, propName, value);
+         }
+     }
+ 
+     private TableDescriptorBuilder generateTableDescriptor(byte[] physicalTableName,  byte[] parentPhysicalTableName, TableDescriptor existingDesc,
+             PTableType tableType, Map<String, Object> tableProps, List<Pair<byte[], Map<String, Object>>> families,
+             byte[][] splits, boolean isNamespaceMapped) throws SQLException {
+         String defaultFamilyName = (String)tableProps.remove(PhoenixDatabaseMetaData.DEFAULT_COLUMN_FAMILY_NAME);
+         TableDescriptorBuilder tableDescriptorBuilder = (existingDesc != null) ?TableDescriptorBuilder.newBuilder(existingDesc)
+         : TableDescriptorBuilder.newBuilder(TableName.valueOf(physicalTableName));
+ 
+         ColumnFamilyDescriptor dataTableColDescForIndexTablePropSyncing = null;
+         boolean doNotAddGlobalIndexChecker = false;
+         if (tableType == PTableType.INDEX || MetaDataUtil.isViewIndex(Bytes.toString(physicalTableName))) {
+             byte[] defaultFamilyBytes =
+                     defaultFamilyName == null ? QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES : Bytes.toBytes(defaultFamilyName);
+ 
+             final TableDescriptor baseTableDesc;
+             if (MetaDataUtil.isViewIndex(Bytes.toString(physicalTableName))) {
+                 // Handles indexes created on views for single-tenant tables and
+                 // global indexes created on views of multi-tenant tables
+                 baseTableDesc = this.getTableDescriptor(parentPhysicalTableName);
+             } else if (existingDesc == null) {
+                 // Global/local index creation on top of a physical base table
+                 baseTableDesc = this.getTableDescriptor(SchemaUtil.getPhysicalTableName(
+                         Bytes.toBytes((String) tableProps.get(PhoenixDatabaseMetaData.DATA_TABLE_NAME)), isNamespaceMapped)
+                         .getName());
+             } else {
+                 // In case this a local index created on a view of a multi-tenant table, the
+                 // PHYSICAL_DATA_TABLE_NAME points to the name of the view instead of the physical base table
+                 baseTableDesc = existingDesc;
+             }
+             dataTableColDescForIndexTablePropSyncing = baseTableDesc.getColumnFamily(defaultFamilyBytes);
+             // It's possible that the table has specific column families and none of them are declared
+             // to be the DEFAULT_COLUMN_FAMILY, so we choose the first column family for syncing properties
+             if (dataTableColDescForIndexTablePropSyncing == null) {
+                 dataTableColDescForIndexTablePropSyncing = baseTableDesc.getColumnFamilies()[0];
+             }
+             if (baseTableDesc.hasCoprocessor(QueryConstants.INDEXER_CLASSNAME)) {
+                 // The base table still uses the old indexing
+                 doNotAddGlobalIndexChecker = true;
+             }
+         }
+         // By default, do not automatically rebuild/catch up an index on a write failure
+         // Add table-specific properties to the table descriptor
+         for (Entry<String,Object> entry : tableProps.entrySet()) {
+             String key = entry.getKey();
+             if (!TableProperty.isPhoenixTableProperty(key)) {
+                 Object value = entry.getValue();
+                 tableDescriptorBuilder.setValue(key, value == null ? null : value.toString());
+             }
+         }
+ 
+         Map<String, Object> syncedProps = MetaDataUtil.getSyncedProps(dataTableColDescForIndexTablePropSyncing);
+         // Add column family-specific properties to the table descriptor
+         for (Pair<byte[],Map<String,Object>> family : families) {
+             // If family is only in phoenix description, add it. otherwise, modify its property accordingly.
+             byte[] familyByte = family.getFirst();
+             if (tableDescriptorBuilder.build().getColumnFamily(familyByte) == null) {
+                 if (tableType == PTableType.VIEW) {
+                     String fullTableName = Bytes.toString(physicalTableName);
+                     throw new ReadOnlyTableException(
+                             "The HBase column families for a read-only table must already exist",
+                             SchemaUtil.getSchemaNameFromFullName(fullTableName),
+                             SchemaUtil.getTableNameFromFullName(fullTableName),
+                             Bytes.toString(familyByte));
+                 }
+ 
+                 ColumnFamilyDescriptor columnDescriptor = generateColumnFamilyDescriptor(family, tableType);
+                 // Keep certain index column family properties in sync with the base table
+                 if ((tableType == PTableType.INDEX || MetaDataUtil.isViewIndex(Bytes.toString(physicalTableName))) &&
+                         (syncedProps != null && !syncedProps.isEmpty())) {
+                     ColumnFamilyDescriptorBuilder colFamDescBuilder = ColumnFamilyDescriptorBuilder.newBuilder(columnDescriptor);
+                     modifyColumnFamilyDescriptor(colFamDescBuilder, syncedProps);
+                     columnDescriptor = colFamDescBuilder.build();
+                 }
+                 tableDescriptorBuilder.setColumnFamily(columnDescriptor);
+             } else {
+                 if (tableType != PTableType.VIEW) {
+                     ColumnFamilyDescriptor columnDescriptor = tableDescriptorBuilder.build().getColumnFamily(familyByte);
+                     if (columnDescriptor == null) {
+                         throw new IllegalArgumentException("Unable to find column descriptor with family name " + Bytes.toString(family.getFirst()));
+                     }
+                     ColumnFamilyDescriptorBuilder columnDescriptorBuilder = ColumnFamilyDescriptorBuilder.newBuilder(columnDescriptor);
+                     modifyColumnFamilyDescriptor(columnDescriptorBuilder, family.getSecond());
+                     tableDescriptorBuilder.modifyColumnFamily(columnDescriptorBuilder.build());
+                 }
+             }
+         }
+         addCoprocessors(physicalTableName, tableDescriptorBuilder,
+             tableType, tableProps, existingDesc, doNotAddGlobalIndexChecker);
+ 
+         // PHOENIX-3072: Set index priority if this is a system table or index table
+         if (tableType == PTableType.SYSTEM) {
+             tableDescriptorBuilder.setValue(QueryConstants.PRIORITY,
+                     String.valueOf(IndexUtil.getMetadataPriority(config)));
+         } else if (tableType == PTableType.INDEX // Global, mutable index
+                 && !isLocalIndexTable(tableDescriptorBuilder.build().getColumnFamilyNames())
+                 && !Boolean.TRUE.equals(tableProps.get(PhoenixDatabaseMetaData.IMMUTABLE_ROWS))) {
+             tableDescriptorBuilder.setValue(QueryConstants.PRIORITY,
+                     String.valueOf(IndexUtil.getIndexPriority(config)));
+         }
+         return tableDescriptorBuilder;
+     }
+ 
+     private boolean isLocalIndexTable(Collection<byte[]> families) {
+         // no easier way to know local index table?
+         for (byte[] family: families) {
+             if (Bytes.toString(family).startsWith(QueryConstants.LOCAL_INDEX_COLUMN_FAMILY_PREFIX)) {
+                 return true;
+             }
+         }
+         return false;
+     }
+ 
+ 
+     private void addCoprocessors(byte[] tableName, TableDescriptorBuilder builder,
+             PTableType tableType, Map<String, Object> tableProps, TableDescriptor existingDesc,
+             boolean doNotAddGlobalIndexChecker) throws SQLException {
+         // The phoenix jar must be available on HBase classpath
+         int priority = props.getInt(QueryServices.COPROCESSOR_PRIORITY_ATTRIB, QueryServicesOptions.DEFAULT_COPROCESSOR_PRIORITY);
+         try {
+             TableDescriptor newDesc = builder.build();
+             TransactionFactory.Provider provider = getTransactionProvider(tableProps);
+             boolean isTransactional = (provider != null);
+ 
+             boolean indexRegionObserverEnabled = config.getBoolean(
+                     QueryServices.INDEX_REGION_OBSERVER_ENABLED_ATTRIB,
+                     QueryServicesOptions.DEFAULT_INDEX_REGION_OBSERVER_ENABLED);
+             boolean isViewIndex = TRUE_BYTES_AS_STRING
+                     .equals(tableProps.get(MetaDataUtil.IS_VIEW_INDEX_TABLE_PROP_NAME));
+             boolean isServerSideMaskingEnabled = config.getBoolean(
+                     QueryServices.PHOENIX_TTL_SERVER_SIDE_MASKING_ENABLED,
+                     QueryServicesOptions.DEFAULT_SERVER_SIDE_MASKING_ENABLED);
+ 
+             boolean isViewBaseTransactional = false;
+             if (!isTransactional && isViewIndex) {
+                 if (tableProps.containsKey(TRANSACTIONAL) &&
+                         Boolean.TRUE.equals(tableProps.get(TRANSACTIONAL))) {
+                     isViewBaseTransactional = true;
+                 }
+             }
+ 
+             if (!isTransactional && !isViewBaseTransactional
+                     && (tableType == PTableType.INDEX || isViewIndex)) {
+                 if (!indexRegionObserverEnabled && newDesc.hasCoprocessor(QueryConstants.GLOBAL_INDEX_CHECKER_CLASSNAME)) {
+                     builder.removeCoprocessor(QueryConstants.GLOBAL_INDEX_CHECKER_CLASSNAME);
+                 } else if (indexRegionObserverEnabled && !newDesc.hasCoprocessor(QueryConstants.GLOBAL_INDEX_CHECKER_CLASSNAME) &&
+                         !isLocalIndexTable(newDesc.getColumnFamilyNames())) {
+                     if (newDesc.hasCoprocessor(QueryConstants.INDEX_REGION_OBSERVER_CLASSNAME)) {
+                         builder.removeCoprocessor(QueryConstants.INDEX_REGION_OBSERVER_CLASSNAME);
+                     }
+                     if (!doNotAddGlobalIndexChecker) {
+                         builder.setCoprocessor(CoprocessorDescriptorBuilder
+                                 .newBuilder(QueryConstants.GLOBAL_INDEX_CHECKER_CLASSNAME)
+                                 .setPriority(priority - 1).build());
+                     }
+                 }
+             }
+ 
+             if (!newDesc.hasCoprocessor(QueryConstants.SCAN_REGION_OBSERVER_CLASSNAME)) {
+                 builder.setCoprocessor(CoprocessorDescriptorBuilder.newBuilder(QueryConstants.SCAN_REGION_OBSERVER_CLASSNAME)
+                         .setPriority(priority).build());
+             }
+             if (!newDesc.hasCoprocessor(QueryConstants.UNGROUPED_AGGREGATE_REGION_OBSERVER_CLASSNAME)) {
+                 builder.setCoprocessor(
+                         CoprocessorDescriptorBuilder.newBuilder(QueryConstants.UNGROUPED_AGGREGATE_REGION_OBSERVER_CLASSNAME)
+                                 .setPriority(priority).build());
+             }
+             if (!newDesc.hasCoprocessor(QueryConstants.GROUPED_AGGREGATE_REGION_OBSERVER_CLASSNAME)) {
+                 builder.setCoprocessor(
+                         CoprocessorDescriptorBuilder.newBuilder(QueryConstants.GROUPED_AGGREGATE_REGION_OBSERVER_CLASSNAME)
+                                 .setPriority(priority).build());
+             }
+             if (!newDesc.hasCoprocessor(QueryConstants.SERVER_CACHING_ENDPOINT_IMPL_CLASSNAME)) {
+                 builder.setCoprocessor(
+                         CoprocessorDescriptorBuilder.newBuilder(QueryConstants.SERVER_CACHING_ENDPOINT_IMPL_CLASSNAME)
+                                 .setPriority(priority).build());
+             }
+ 
+             // TODO: better encapsulation for this
+             // Since indexes can't have indexes, don't install our indexing coprocessor for indexes.
+             // Also don't install on the SYSTEM.CATALOG and SYSTEM.STATS table because we use
+             // all-or-none mutate class which break when this coprocessor is installed (PHOENIX-1318).
+             if ((tableType != PTableType.INDEX && tableType != PTableType.VIEW && !isViewIndex)
+                     && !SchemaUtil.isMetaTable(tableName)
+                     && !SchemaUtil.isStatsTable(tableName)) {
+                 if (isTransactional) {
+                     if (!newDesc.hasCoprocessor(QueryConstants.PHOENIX_TRANSACTIONAL_INDEXER_CLASSNAME)) {
+                         builder.setCoprocessor(
+                                 CoprocessorDescriptorBuilder.newBuilder(QueryConstants.PHOENIX_TRANSACTIONAL_INDEXER_CLASSNAME)
+                                         .setPriority(priority).build());
+                     }
+                     // For alter table, remove non transactional index coprocessor
+                     if (newDesc.hasCoprocessor(QueryConstants.INDEXER_CLASSNAME)) {
+                         builder.removeCoprocessor(QueryConstants.INDEXER_CLASSNAME);
+                     }
+                     if (newDesc.hasCoprocessor(QueryConstants.INDEX_REGION_OBSERVER_CLASSNAME)) {
+                         builder.removeCoprocessor(QueryConstants.INDEX_REGION_OBSERVER_CLASSNAME);
+                     }
+                 } else {
+                     // If exception on alter table to transition back to non transactional
+                     if (newDesc.hasCoprocessor(QueryConstants.PHOENIX_TRANSACTIONAL_INDEXER_CLASSNAME)) {
+                         builder.removeCoprocessor(QueryConstants.PHOENIX_TRANSACTIONAL_INDEXER_CLASSNAME);
+                     }
+                     // we only want to mess with the indexing coprocs if we're on the original
+                     // CREATE statement. Otherwise, if we're on an ALTER or CREATE TABLE
+                     // IF NOT EXISTS of an existing table, we should leave them unaltered,
+                     // because they should be upgraded or downgraded using the IndexUpgradeTool
+                     if (!doesPhoenixTableAlreadyExist(existingDesc)) {
+                         if (indexRegionObserverEnabled) {
+                             if (newDesc.hasCoprocessor(QueryConstants.INDEXER_CLASSNAME)) {
+                                 builder.removeCoprocessor(QueryConstants.INDEXER_CLASSNAME);
+                             }
+                             if (!newDesc.hasCoprocessor(QueryConstants.INDEX_REGION_OBSERVER_CLASSNAME)) {
+                                 Map<String, String> opts = Maps.newHashMapWithExpectedSize(1);
+                                 opts.put(IndexUtil.CODEC_CLASS_NAME_KEY,  PhoenixIndexCodec.class.getName());
+                                 IndexUtil.enableIndexing(builder, IndexUtil.PHOENIX_INDEX_BUILDER_CLASSNAME,
+                                         opts, priority, QueryConstants.INDEX_REGION_OBSERVER_CLASSNAME);
+                             }
+                         } else {
+                             if (newDesc.hasCoprocessor(QueryConstants.INDEX_REGION_OBSERVER_CLASSNAME)) {
+                                 builder.removeCoprocessor(QueryConstants.INDEX_REGION_OBSERVER_CLASSNAME);
+                             }
+                             if (!newDesc.hasCoprocessor(QueryConstants.INDEXER_CLASSNAME)) {
+                                 Map<String, String> opts = Maps.newHashMapWithExpectedSize(1);
+                                 opts.put(IndexUtil.CODEC_CLASS_NAME_KEY, PhoenixIndexCodec.class.getName());
+                                 IndexUtil.enableIndexing(builder, IndexUtil.PHOENIX_INDEX_BUILDER_CLASSNAME,
+                                         opts, priority, QueryConstants.INDEXER_CLASSNAME);
+                             }
+                         }
+                     }
+                 }
+             }
+ 
+             if ((SchemaUtil.isStatsTable(tableName) || SchemaUtil.isMetaTable(tableName))
+                     && !newDesc.hasCoprocessor(QueryConstants.MULTI_ROW_MUTATION_ENDPOINT_CLASSNAME)) {
+                 builder.setCoprocessor(
+                         CoprocessorDescriptorBuilder
+                                 .newBuilder(QueryConstants.MULTI_ROW_MUTATION_ENDPOINT_CLASSNAME)
+                                 .setPriority(priority)
+                                 .setProperties(Collections.emptyMap())
+                                 .build());
+             }
+ 
+             Set<byte[]> familiesKeys = builder.build().getColumnFamilyNames();
+             for (byte[] family: familiesKeys) {
+                 if (Bytes.toString(family).startsWith(QueryConstants.LOCAL_INDEX_COLUMN_FAMILY_PREFIX)) {
+                     if (!newDesc.hasCoprocessor(QueryConstants.INDEX_HALF_STORE_FILE_READER_GENERATOR_CLASSNAME)) {
+                         builder.setCoprocessor(
+                                 CoprocessorDescriptorBuilder
+                                         .newBuilder(QueryConstants.INDEX_HALF_STORE_FILE_READER_GENERATOR_CLASSNAME)
+                                         .setPriority(priority)
+                                         .setProperties(Collections.emptyMap())
+                                         .build());
+                         break;
+                     }
+                 }
+             }
+ 
+             // Setup split policy on Phoenix metadata table to ensure that the key values of a Phoenix table
+             // stay on the same region.
+             if (SchemaUtil.isMetaTable(tableName) || SchemaUtil.isFunctionTable(tableName)) {
+                 if (!newDesc.hasCoprocessor(QueryConstants.META_DATA_ENDPOINT_IMPL_CLASSNAME)) {
+                     builder.setCoprocessor(
+                             CoprocessorDescriptorBuilder
+                                     .newBuilder(QueryConstants.META_DATA_ENDPOINT_IMPL_CLASSNAME)
+                                     .setPriority(priority)
+                                     .setProperties(Collections.emptyMap())
+                                     .build());
+                 }
+                 if (SchemaUtil.isMetaTable(tableName) ) {
+                     if (!newDesc.hasCoprocessor(QueryConstants.META_DATA_REGION_OBSERVER_CLASSNAME)) {
+                         builder.setCoprocessor(
+                                 CoprocessorDescriptorBuilder
+                                         .newBuilder(QueryConstants.META_DATA_REGION_OBSERVER_CLASSNAME)
+                                         .setPriority(priority + 1)
+                                         .setProperties(Collections.emptyMap())
+                                         .build());
+                     }
+                 }
+             } else if (SchemaUtil.isSequenceTable(tableName)) {
+                 if (!newDesc.hasCoprocessor(QueryConstants.SEQUENCE_REGION_OBSERVER_CLASSNAME)) {
+                     builder.setCoprocessor(
+                             CoprocessorDescriptorBuilder
+                                     .newBuilder(QueryConstants.SEQUENCE_REGION_OBSERVER_CLASSNAME)
+                                     .setPriority(priority)
+                                     .setProperties(Collections.emptyMap())
+                                     .build());
+                 }
+             } else if (SchemaUtil.isTaskTable(tableName)) {
+                 if (!newDesc.hasCoprocessor(QueryConstants.TASK_REGION_OBSERVER_CLASSNAME)) {
+                     builder.setCoprocessor(
+                             CoprocessorDescriptorBuilder
+                                     .newBuilder(QueryConstants.TASK_REGION_OBSERVER_CLASSNAME)
+                                     .setPriority(priority)
+                                     .setProperties(Collections.emptyMap())
+                                     .build());
+                 }
+                 if (!newDesc.hasCoprocessor(QueryConstants.TASK_META_DATA_ENDPOINT_CLASSNAME)) {
+                     builder.setCoprocessor(
+                             CoprocessorDescriptorBuilder
+                                     .newBuilder(QueryConstants.TASK_META_DATA_ENDPOINT_CLASSNAME)
+                                     .setPriority(priority)
+                                     .setProperties(Collections.emptyMap())
+                                     .build());
+                 }
+             } else if (SchemaUtil.isChildLinkTable(tableName)) {
+                 if (!newDesc.hasCoprocessor(QueryConstants.CHILD_LINK_META_DATA_ENDPOINT_CLASSNAME)) {
+                     builder.setCoprocessor(
+                             CoprocessorDescriptorBuilder
+                                     .newBuilder(QueryConstants.CHILD_LINK_META_DATA_ENDPOINT_CLASSNAME)
+                                     .setPriority(priority)
+                                     .setProperties(Collections.emptyMap())
+                                     .build());
+                 }
+             }
+ 
+             if (isTransactional) {
+                 String coprocessorClassName = provider.getTransactionProvider().getCoprocessorClassName();
+                 if (!newDesc.hasCoprocessor(coprocessorClassName)) {
+                     builder.setCoprocessor(
+                             CoprocessorDescriptorBuilder
+                                     .newBuilder(coprocessorClassName)
+                                     .setPriority(priority - 10)
+                                     .setProperties(Collections.emptyMap())
+                                     .build());
+                 }
+                 String coprocessorGCClassName = provider.getTransactionProvider().getGCCoprocessorClassName();
+                 if (coprocessorGCClassName != null) {
+                     if (!newDesc.hasCoprocessor(coprocessorGCClassName)) {
+                         builder.setCoprocessor(
+                                 CoprocessorDescriptorBuilder
+                                         .newBuilder(coprocessorGCClassName)
+                                         .setPriority(priority - 10)
+                                         .setProperties(Collections.emptyMap())
+                                         .build());
+                     }
+                 }
+             } else {
+                 // Remove all potential transactional coprocessors
+                 for (TransactionFactory.Provider aprovider : TransactionFactory.Provider.available()) {
+                     String coprocessorClassName = aprovider.getTransactionProvider().getCoprocessorClassName();
+                     String coprocessorGCClassName = aprovider.getTransactionProvider().getGCCoprocessorClassName();
+                     if (coprocessorClassName != null && newDesc.hasCoprocessor(coprocessorClassName)) {
+                         builder.removeCoprocessor(coprocessorClassName);
+                     }
+                     if (coprocessorGCClassName != null && newDesc.hasCoprocessor(coprocessorGCClassName)) {
+                         builder.removeCoprocessor(coprocessorGCClassName);
+                     }
+                 }
+             }
+ 
+             // The priority for this co-processor should be set higher than the GlobalIndexChecker so that the read repair scans
+             // are intercepted by the TTLAwareRegionObserver and only the rows that are not ttl-expired are returned.
+             if (!SchemaUtil.isSystemTable(tableName)) {
+                 if (!newDesc.hasCoprocessor(QueryConstants.PHOENIX_TTL_REGION_OBSERVER_CLASSNAME) &&
+                         isServerSideMaskingEnabled) {
+                         builder.setCoprocessor(
+                             CoprocessorDescriptorBuilder
+                                     .newBuilder(QueryConstants.PHOENIX_TTL_REGION_OBSERVER_CLASSNAME)
+                                     .setPriority(priority - 2)
+                                     .setProperties(Collections.emptyMap())
+                                     .build());
+                 }
+             }
+             if (Arrays.equals(tableName, SchemaUtil.getPhysicalName(SYSTEM_CATALOG_NAME_BYTES, props).getName())) {
+                 if (!newDesc.hasCoprocessor(QueryConstants.SYSTEM_CATALOG_REGION_OBSERVER_CLASSNAME)) {
+                     builder.setCoprocessor(
+                             CoprocessorDescriptorBuilder
+                                     .newBuilder(QueryConstants.SYSTEM_CATALOG_REGION_OBSERVER_CLASSNAME)
+                                     .setPriority(priority)
+                                     .setProperties(Collections.emptyMap())
+                                     .build());
+                 }
+             }
+ 
+         } catch (IOException e) {
+             throw ClientUtil.parseServerException(e);
+         }
+     }
+ 
+     private TransactionFactory.Provider getTransactionProvider(Map<String,Object> tableProps) {
+         TransactionFactory.Provider provider = (TransactionFactory.Provider)TableProperty.TRANSACTION_PROVIDER.getValue(tableProps);
+         return provider;
+     }
+ 
+     private boolean doesPhoenixTableAlreadyExist(TableDescriptor existingDesc) {
+         //if the table descriptor already has Phoenix coprocs, we assume it's
+         //already gone through a Phoenix create statement once
+         if (existingDesc == null){
+             return false;
+         }
+         boolean hasScanObserver = existingDesc.hasCoprocessor(QueryConstants.SCAN_REGION_OBSERVER_CLASSNAME);
+         boolean hasUnAggObserver = existingDesc.hasCoprocessor(
+                 QueryConstants.UNGROUPED_AGGREGATE_REGION_OBSERVER_CLASSNAME);
+         boolean hasGroupedObserver = existingDesc.hasCoprocessor(
+             QueryConstants.GROUPED_AGGREGATE_REGION_OBSERVER_CLASSNAME);
+         boolean hasIndexObserver = existingDesc.hasCoprocessor(QueryConstants.INDEXER_CLASSNAME)
+             || existingDesc.hasCoprocessor(QueryConstants.INDEX_REGION_OBSERVER_CLASSNAME)
+             || existingDesc.hasCoprocessor(QueryConstants.GLOBAL_INDEX_CHECKER_CLASSNAME);
+         return hasScanObserver && hasUnAggObserver && hasGroupedObserver && hasIndexObserver;
+     }
+ 
+     private static interface RetriableOperation {
+         boolean checkForCompletion() throws TimeoutException, IOException;
+         String getOperationName();
+     }
+ 
+     private void pollForUpdatedTableDescriptor(final Admin admin, final TableDescriptor newTableDescriptor,
+             final byte[] tableName) throws InterruptedException, TimeoutException {
+         checkAndRetry(new RetriableOperation() {
+ 
+             @Override
+             public String getOperationName() {
+                 return "UpdateOrNewTableDescriptor";
+             }
+ 
+             @Override
+             public boolean checkForCompletion() throws TimeoutException, IOException {
+                 TableDescriptor tableDesc = admin.getDescriptor(TableName.valueOf(tableName));
+                 return newTableDescriptor.equals(tableDesc);
+             }
+         });
+     }
+ 
+     private void checkAndRetry(RetriableOperation op) throws InterruptedException, TimeoutException {
+         int maxRetries = ConnectionQueryServicesImpl.this.props.getInt(
+                 QueryServices.NUM_RETRIES_FOR_SCHEMA_UPDATE_CHECK,
+                 QueryServicesOptions.DEFAULT_RETRIES_FOR_SCHEMA_UPDATE_CHECK);
+         long sleepInterval = ConnectionQueryServicesImpl.this.props
+                 .getLong(QueryServices.DELAY_FOR_SCHEMA_UPDATE_CHECK,
+                         QueryServicesOptions.DEFAULT_DELAY_FOR_SCHEMA_UPDATE_CHECK);
+         boolean success = false;
+         int numTries = 1;
+         PhoenixStopWatch watch = new PhoenixStopWatch();
+         watch.start();
+         do {
+             try {
+                 success = op.checkForCompletion();
+             } catch (Exception ex) {
+                 // If we encounter any exception on the first or last try, propagate the exception and fail.
+                 // Else, we swallow the exception and retry till we reach maxRetries.
+                 if (numTries == 1 || numTries == maxRetries) {
+                     watch.stop();
+                     TimeoutException toThrow = new TimeoutException("Operation " + op.getOperationName()
+                             + " didn't complete because of exception. Time elapsed: " + watch.elapsedMillis());
+                     toThrow.initCause(ex);
+                     throw toThrow;
+                 }
+             }
+             numTries++;
+             Thread.sleep(sleepInterval);
+         } while (numTries < maxRetries && !success);
+ 
+         watch.stop();
+ 
+         if (!success) {
+             throw new TimeoutException("Operation  " + op.getOperationName() + " didn't complete within "
+                     + watch.elapsedMillis() + " ms "
+                     + "after trying " + numTries + "times.");
+         } else {
+             if (LOGGER.isDebugEnabled()) {
+                 LOGGER.debug("Operation "
+                         + op.getOperationName()
+                         + " completed within "
+                         + watch.elapsedMillis()
+                         + "ms "
+                         + "after trying " + numTries +  " times." );
+             }
+         }
+     }
+ 
+     private boolean allowOnlineTableSchemaUpdate() {
+         return props.getBoolean(
+                 QueryServices.ALLOW_ONLINE_TABLE_SCHEMA_UPDATE,
+                 QueryServicesOptions.DEFAULT_ALLOW_ONLINE_TABLE_SCHEMA_UPDATE);
+     }
+ 
+     /**
+      * Ensure that the HBase namespace is created/exists already
+      * @param schemaName Phoenix schema name for which we ensure existence of the HBase namespace
+      * @return true if we created the HBase namespace because it didn't already exist
+      * @throws SQLException If there is an exception creating the HBase namespace
+      */
+     boolean ensureNamespaceCreated(String schemaName) throws SQLException {
+         SQLException sqlE = null;
+         boolean createdNamespace = false;
+         try (Admin admin = getAdmin()) {
+             if (!ClientUtil.isHBaseNamespaceAvailable(admin, schemaName)) {
+                 NamespaceDescriptor namespaceDescriptor =
+                     NamespaceDescriptor.create(schemaName).build();
+                 admin.createNamespace(namespaceDescriptor);
+                 createdNamespace = true;
+             }
+         } catch (IOException e) {
+             sqlE = ClientUtil.parseServerException(e);
+         } finally {
+             if (sqlE != null) { throw sqlE; }
+         }
+         return createdNamespace;
+     }
+ 
+     /**
+      *
+      * @param physicalTableName
+      * @param tableType
+      * @param props
+      * @param families
+      * @param splits
+      * @param modifyExistingMetaData
+      * @param isNamespaceMapped
+      * @param isDoNotUpgradePropSet
+      * @return true if table was created and false if it already exists
+      * @throws SQLException
+      */
+ 
+     private TableDescriptor ensureTableCreated(byte[] physicalTableName, byte[] parentPhysicalTableName, PTableType tableType, Map<String, Object> props,
+             List<Pair<byte[], Map<String, Object>>> families, byte[][] splits, boolean modifyExistingMetaData,
+             boolean isNamespaceMapped, boolean isDoNotUpgradePropSet) throws SQLException {
+         SQLException sqlE = null;
+         TableDescriptor existingDesc = null;
+         boolean isMetaTable = SchemaUtil.isMetaTable(physicalTableName);
+         boolean tableExist = true;
+         try (Admin admin = getAdmin()) {
+             final String quorum = ZKConfig.getZKQuorumServersString(config);
+             final String znode = this.getProps().get(HConstants.ZOOKEEPER_ZNODE_PARENT);
+             boolean createdNamespace = false;
+             LOGGER.debug("Found quorum: " + quorum + ":" + znode);
+ 
+             if (isMetaTable) {
+                 if (SchemaUtil.isNamespaceMappingEnabled(PTableType.SYSTEM, this.getProps())) {
+                     try {
+                         // SYSTEM namespace needs to be created via HBase APIs because "CREATE SCHEMA" statement tries to write
+                         // its metadata in SYSTEM:CATALOG table. Without SYSTEM namespace, SYSTEM:CATALOG table cannot be created
+                         createdNamespace = ensureNamespaceCreated(QueryConstants.SYSTEM_SCHEMA_NAME);
+                     } catch (PhoenixIOException e) {
+                         // We could either:
+                         // 1) Not access the NS descriptor. The NS may or may not exist at this point
+                         // 2) We could not create the NS
+                         // Regardless of the case 1 or 2, if we eventually try to migrate SYSTEM tables to the SYSTEM
+                         // namespace using the {@link ensureSystemTablesMigratedToSystemNamespace(ReadOnlyProps)} method,
+                         // if the NS does not exist, we will error as expected, or
+                         // if the NS does exist and tables are already mapped, the check will exit gracefully
+                     }
+                     if (AdminUtilWithFallback.tableExists(admin,
+                         SchemaUtil.getPhysicalTableName(SYSTEM_CATALOG_NAME_BYTES, false))) {
+                         // SYSTEM.CATALOG exists, so at this point, we have 3 cases:
+                         // 1) If server-side namespace mapping is disabled, drop the SYSTEM namespace if it was created
+                         //    above and throw Inconsistent namespace mapping exception
+                         // 2) If server-side namespace mapping is enabled and SYSTEM.CATALOG needs to be upgraded,
+                         //    upgrade SYSTEM.CATALOG and also migrate SYSTEM tables to the SYSTEM namespace
+                         // 3. If server-side namespace mapping is enabled and SYSTEM.CATALOG doesn't need to be
+                         //    upgraded, we still need to migrate SYSTEM tables to the SYSTEM namespace using the
+                         //    {@link ensureSystemTablesMigratedToSystemNamespace(ReadOnlyProps)} method (as part of
+                         //    {@link upgradeSystemTables(String, Properties)})
+                         try {
+                             checkClientServerCompatibility(SYSTEM_CATALOG_NAME_BYTES);
+                         } catch (SQLException possibleCompatException) {
+                             // Handles Case 1: Drop the SYSTEM namespace in case it was created above
+                             if (createdNamespace && possibleCompatException.getErrorCode() ==
+                                     SQLExceptionCode.INCONSISTENT_NAMESPACE_MAPPING_PROPERTIES.getErrorCode()) {
+                                 ensureNamespaceDropped(QueryConstants.SYSTEM_SCHEMA_NAME);
+                             }
+                             // rethrow the SQLException
+                             throw possibleCompatException;
+                         }
+                         // Thrown so we can force an upgrade which will just migrate SYSTEM tables to the SYSTEM namespace
+                         throw new UpgradeRequiredException(MIN_SYSTEM_TABLE_TIMESTAMP);
+                     }
+                 } else if (AdminUtilWithFallback.tableExists(admin,
+                     SchemaUtil.getPhysicalTableName(SYSTEM_CATALOG_NAME_BYTES, true))) {
+                     // If SYSTEM:CATALOG exists, but client-side namespace mapping for SYSTEM tables is disabled, throw an exception
+                     throw new SQLExceptionInfo.Builder(
+                       SQLExceptionCode.INCONSISTENT_NAMESPACE_MAPPING_PROPERTIES)
+                       .setMessage("Cannot initiate connection as "
+                         + SchemaUtil.getPhysicalTableName(SYSTEM_CATALOG_NAME_BYTES, true)
+                         + " is found but client does not have "
+                         + IS_NAMESPACE_MAPPING_ENABLED + " enabled")
+                       .build().buildException();
+                 }
+                 // If DoNotUpgrade config is set only check namespace mapping and
+                 // Client-server compatibility for system tables.
+                 if (isDoNotUpgradePropSet) {
+                     try {
+                         checkClientServerCompatibility(SchemaUtil.getPhysicalName(
+                                 SYSTEM_CATALOG_NAME_BYTES, this.getProps()).getName());
+                     } catch (SQLException possibleCompatException) {
+                         if (possibleCompatException.getCause()
+                                 instanceof org.apache.hadoop.hbase.TableNotFoundException) {
+                             throw new UpgradeRequiredException(MIN_SYSTEM_TABLE_TIMESTAMP);
+                         }
+                         throw possibleCompatException;
+                     }
+                     return null;
+                 }
+             }
+ 
+             try {
+                 existingDesc = admin.getDescriptor(TableName.valueOf(physicalTableName));
+             } catch (org.apache.hadoop.hbase.TableNotFoundException e) {
+                 tableExist = false;
+                 if (tableType == PTableType.VIEW) {
+                     String fullTableName = Bytes.toString(physicalTableName);
+                     throw new ReadOnlyTableException(
+                             "An HBase table for a VIEW must already exist",
+                             SchemaUtil.getSchemaNameFromFullName(fullTableName),
+                             SchemaUtil.getTableNameFromFullName(fullTableName));
+                 }
+             }
+ 
+             TableDescriptorBuilder newDesc = generateTableDescriptor(physicalTableName, parentPhysicalTableName, existingDesc, tableType, props, families,
+                     splits, isNamespaceMapped);
+ 
+             if (!tableExist) {
+                 if (SchemaUtil.isSystemTable(physicalTableName) && !isUpgradeRequired() && (!isAutoUpgradeEnabled || isDoNotUpgradePropSet)) {
+                     // Disallow creating the SYSTEM.CATALOG or SYSTEM:CATALOG HBase table
+                     throw new UpgradeRequiredException();
+                 }
+                 if (newDesc.build().getValue(MetaDataUtil.IS_LOCAL_INDEX_TABLE_PROP_BYTES) != null && Boolean.TRUE.equals(
+                         PBoolean.INSTANCE.toObject(newDesc.build().getValue(MetaDataUtil.IS_LOCAL_INDEX_TABLE_PROP_BYTES)))) {
+                     newDesc.setRegionSplitPolicyClassName(QueryConstants.INDEX_REGION_SPLIT_POLICY_CLASSNAME);
+                 }
+                 try {
+                     if (splits == null) {
+                         admin.createTable(newDesc.build());
+                     } else {
+                         admin.createTable(newDesc.build(), splits);
+                     }
+                 } catch (TableExistsException e) {
+                     // We can ignore this, as it just means that another client beat us
+                     // to creating the HBase metadata.
+                     if (isMetaTable && !isUpgradeRequired()) {
+                         checkClientServerCompatibility(SchemaUtil.getPhysicalName(SYSTEM_CATALOG_NAME_BYTES, this.getProps()).getName());
+                     }
+                     return null;
+                 }
+                 if (isMetaTable && !isUpgradeRequired()) {
+                     try {
+                         checkClientServerCompatibility(SchemaUtil.getPhysicalName(SYSTEM_CATALOG_NAME_BYTES,
+                                 this.getProps()).getName());
+                     } catch (SQLException possibleCompatException) {
+                         if (possibleCompatException.getErrorCode() ==
+                                 SQLExceptionCode.INCONSISTENT_NAMESPACE_MAPPING_PROPERTIES.getErrorCode()) {
+                             try {
+                                 // In case we wrongly created SYSTEM.CATALOG or SYSTEM:CATALOG, we should drop it
+                                 admin.disableTable(TableName.valueOf(physicalTableName));
... 22110 lines suppressed ...