http://git-wip-us.apache.org/repos/asf/phoenix/blob/7d3b544a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java ---------------------------------------------------------------------- diff --cc phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java index b78a904,b591281..c215da6 --- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java @@@ -193,7 -201,8 +202,8 @@@ public class PTableImpl implements PTab table.getTenantId(), table.getSchemaName(), table.getTableName(), table.getType(), table.getIndexState(), timeStamp, table.getSequenceNumber(), table.getPKName(), table.getBucketNum(), getColumnsToClone(table), parentSchemaName, table.getParentTableName(), indexes, table.isImmutableRows(), table.getPhysicalNames(), table.getDefaultFamilyName(), viewStatement, - table.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(), table.getIndexType(), table.isTransactional(), table.getTableStats()); + table.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(), table.getIndexType(), - table.getTableStats(), table.getBaseColumnCount(), table.rowKeyOrderOptimizable()); ++ table.getTableStats(), table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional()); } public static PTableImpl makePTable(PTable table, List<PColumn> columns) throws SQLException { @@@ -201,7 -210,8 +211,8 @@@ table.getTenantId(), table.getSchemaName(), table.getTableName(), table.getType(), table.getIndexState(), table.getTimeStamp(), table.getSequenceNumber(), table.getPKName(), table.getBucketNum(), columns, table.getParentSchemaName(), table.getParentTableName(), table.getIndexes(), table.isImmutableRows(), table.getPhysicalNames(), table.getDefaultFamilyName(), table.getViewStatement(), - table.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(), table.getIndexType(), table.isTransactional(), table.getTableStats()); + table.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(), table.getIndexType(), - table.getTableStats(), table.getBaseColumnCount(), table.rowKeyOrderOptimizable()); ++ table.getTableStats(), table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional()); } public static PTableImpl makePTable(PTable table, long timeStamp, long sequenceNumber, List<PColumn> columns) throws SQLException { @@@ -209,7 -219,8 +220,8 @@@ table.getTenantId(), table.getSchemaName(), table.getTableName(), table.getType(), table.getIndexState(), timeStamp, sequenceNumber, table.getPKName(), table.getBucketNum(), columns, table.getParentSchemaName(), table.getParentTableName(), table.getIndexes(), table.isImmutableRows(), table.getPhysicalNames(), table.getDefaultFamilyName(), table.getViewStatement(), table.isWALDisabled(), - table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(), table.getIndexType(), table.isTransactional(), table.getTableStats()); + table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(), table.getIndexType(), table.getTableStats(), - table.getBaseColumnCount(), table.rowKeyOrderOptimizable()); ++ table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional()); } public static PTableImpl makePTable(PTable table, long timeStamp, long sequenceNumber, List<PColumn> columns, boolean isImmutableRows) throws SQLException { @@@ -217,7 -228,8 +229,8 @@@ table.getTenantId(), table.getSchemaName(), table.getTableName(), table.getType(), table.getIndexState(), timeStamp, sequenceNumber, table.getPKName(), table.getBucketNum(), columns, table.getParentSchemaName(), table.getParentTableName(), table.getIndexes(), isImmutableRows, table.getPhysicalNames(), table.getDefaultFamilyName(), table.getViewStatement(), - table.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(), table.getIndexType(), table.isTransactional(), table.getTableStats()); + table.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(), - table.getIndexType(), table.getTableStats(), table.getBaseColumnCount(), table.rowKeyOrderOptimizable()); ++ table.getIndexType(), table.getTableStats(), table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional()); } public static PTableImpl makePTable(PTable table, long timeStamp, long sequenceNumber, List<PColumn> columns, boolean isImmutableRows, boolean isWalDisabled, boolean isMultitenant, boolean storeNulls) throws SQLException { @@@ -225,7 -237,8 +238,8 @@@ table.getTenantId(), table.getSchemaName(), table.getTableName(), table.getType(), table.getIndexState(), timeStamp, sequenceNumber, table.getPKName(), table.getBucketNum(), columns, table.getParentSchemaName(), table.getParentTableName(), table.getIndexes(), isImmutableRows, table.getPhysicalNames(), table.getDefaultFamilyName(), table.getViewStatement(), - isWalDisabled, isMultitenant, storeNulls, table.getViewType(), table.getViewIndexId(), table.getIndexType(), table.isTransactional(), table.getTableStats()); + isWalDisabled, isMultitenant, storeNulls, table.getViewType(), table.getViewIndexId(), table.getIndexType(), table.getTableStats(), - table.getBaseColumnCount(), table.rowKeyOrderOptimizable()); ++ table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional()); } public static PTableImpl makePTable(PTable table, PIndexState state) throws SQLException { @@@ -234,7 -247,18 +248,18 @@@ table.getSequenceNumber(), table.getPKName(), table.getBucketNum(), getColumnsToClone(table), table.getParentSchemaName(), table.getParentTableName(), table.getIndexes(), table.isImmutableRows(), table.getPhysicalNames(), table.getDefaultFamilyName(), table.getViewStatement(), - table.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(), table.getIndexType(), table.isTransactional(), table.getTableStats()); + table.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(), table.getIndexType(), - table.getTableStats(), table.getBaseColumnCount(), table.rowKeyOrderOptimizable()); ++ table.getTableStats(), table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional()); + } + + public static PTableImpl makePTable(PTable table, boolean rowKeyOrderOptimizable) throws SQLException { + return new PTableImpl( + table.getTenantId(), table.getSchemaName(), table.getTableName(), table.getType(), table.getIndexState(), table.getTimeStamp(), + table.getSequenceNumber(), table.getPKName(), table.getBucketNum(), getColumnsToClone(table), + table.getParentSchemaName(), table.getParentTableName(), table.getIndexes(), + table.isImmutableRows(), table.getPhysicalNames(), table.getDefaultFamilyName(), table.getViewStatement(), + table.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(), table.getIndexType(), table.getTableStats(), - table.getBaseColumnCount(), rowKeyOrderOptimizable); ++ table.getBaseColumnCount(), rowKeyOrderOptimizable, table.isTransactional()); } public static PTableImpl makePTable(PTable table, PTableStats stats) throws SQLException { @@@ -243,28 -267,29 +268,29 @@@ table.getSequenceNumber(), table.getPKName(), table.getBucketNum(), getColumnsToClone(table), table.getParentSchemaName(), table.getParentTableName(), table.getIndexes(), table.isImmutableRows(), table.getPhysicalNames(), table.getDefaultFamilyName(), table.getViewStatement(), - table.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(), table.getIndexType(), table.isTransactional(), stats); + table.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(), table.getIndexType(), stats, - table.getBaseColumnCount(), table.rowKeyOrderOptimizable()); ++ table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), table.isTransactional()); } public static PTableImpl makePTable(PName tenantId, PName schemaName, PName tableName, PTableType type, PIndexState state, long timeStamp, long sequenceNumber, PName pkName, Integer bucketNum, List<PColumn> columns, PName dataSchemaName, PName dataTableName, List<PTable> indexes, boolean isImmutableRows, List<PName> physicalNames, PName defaultFamilyName, String viewExpression, boolean disableWAL, boolean multiTenant, - boolean storeNulls, ViewType viewType, Short viewIndexId, IndexType indexType, boolean isTransactional) throws SQLException { - boolean storeNulls, ViewType viewType, Short viewIndexId, IndexType indexType, boolean rowKeyOrderOptimizable) throws SQLException { ++ boolean storeNulls, ViewType viewType, Short viewIndexId, IndexType indexType, boolean rowKeyOrderOptimizable, boolean isTransactional) throws SQLException { return new PTableImpl(tenantId, schemaName, tableName, type, state, timeStamp, sequenceNumber, pkName, bucketNum, columns, dataSchemaName, dataTableName, indexes, isImmutableRows, physicalNames, defaultFamilyName, viewExpression, disableWAL, multiTenant, storeNulls, viewType, viewIndexId, - indexType, isTransactional, PTableStats.EMPTY_STATS); - indexType, PTableStats.EMPTY_STATS, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, rowKeyOrderOptimizable); ++ indexType, PTableStats.EMPTY_STATS, QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, rowKeyOrderOptimizable, isTransactional); } public static PTableImpl makePTable(PName tenantId, PName schemaName, PName tableName, PTableType type, PIndexState state, long timeStamp, long sequenceNumber, PName pkName, Integer bucketNum, List<PColumn> columns, PName dataSchemaName, PName dataTableName, List<PTable> indexes, boolean isImmutableRows, List<PName> physicalNames, PName defaultFamilyName, String viewExpression, - boolean disableWAL, boolean multiTenant, boolean storeNulls, ViewType viewType, Short viewIndexId, IndexType indexType, boolean isTransactional, @NotNull PTableStats stats) - boolean disableWAL, boolean multiTenant, boolean storeNulls, ViewType viewType, Short viewIndexId, IndexType indexType, @NotNull PTableStats stats, int baseColumnCount, boolean rowKeyOrderOptimizable) ++ boolean disableWAL, boolean multiTenant, boolean storeNulls, ViewType viewType, Short viewIndexId, IndexType indexType, @NotNull PTableStats stats, int baseColumnCount, boolean rowKeyOrderOptimizable, boolean isTransactional) throws SQLException { return new PTableImpl(tenantId, schemaName, tableName, type, state, timeStamp, sequenceNumber, pkName, bucketNum, columns, dataSchemaName, dataTableName, indexes, isImmutableRows, physicalNames, - defaultFamilyName, viewExpression, disableWAL, multiTenant, storeNulls, viewType, viewIndexId, indexType, isTransactional, stats); - defaultFamilyName, viewExpression, disableWAL, multiTenant, storeNulls, viewType, viewIndexId, indexType, stats, baseColumnCount, rowKeyOrderOptimizable); ++ defaultFamilyName, viewExpression, disableWAL, multiTenant, storeNulls, viewType, viewIndexId, indexType, stats, baseColumnCount, rowKeyOrderOptimizable, isTransactional); } private PTableImpl(PName tenantId, PName schemaName, PName tableName, PTableType type, PIndexState state, @@@ -272,10 -297,10 +298,10 @@@ PName parentSchemaName, PName parentTableName, List<PTable> indexes, boolean isImmutableRows, List<PName> physicalNames, PName defaultFamilyName, String viewExpression, boolean disableWAL, boolean multiTenant, boolean storeNulls, ViewType viewType, Short viewIndexId, IndexType indexType, - boolean isTransactional, PTableStats stats) throws SQLException { - PTableStats stats, int baseColumnCount, boolean rowKeyOrderOptimizable) throws SQLException { ++ PTableStats stats, int baseColumnCount, boolean rowKeyOrderOptimizable, boolean isTransactional) throws SQLException { init(tenantId, schemaName, tableName, type, state, timeStamp, sequenceNumber, pkName, bucketNum, columns, stats, schemaName, parentTableName, indexes, isImmutableRows, physicalNames, defaultFamilyName, - viewExpression, disableWAL, multiTenant, storeNulls, viewType, viewIndexId, indexType, isTransactional); - viewExpression, disableWAL, multiTenant, storeNulls, viewType, viewIndexId, indexType, baseColumnCount, rowKeyOrderOptimizable); ++ viewExpression, disableWAL, multiTenant, storeNulls, viewType, viewIndexId, indexType, baseColumnCount, rowKeyOrderOptimizable, isTransactional); } @Override @@@ -303,7 -328,7 +329,7 @@@ PName pkName, Integer bucketNum, List<PColumn> columns, PTableStats stats, PName parentSchemaName, PName parentTableName, List<PTable> indexes, boolean isImmutableRows, List<PName> physicalNames, PName defaultFamilyName, String viewExpression, boolean disableWAL, boolean multiTenant, boolean storeNulls, ViewType viewType, Short viewIndexId, - IndexType indexType, boolean isTransactional ) throws SQLException { - IndexType indexType , int baseColumnCount, boolean rowKeyOrderOptimizable) throws SQLException { ++ IndexType indexType , int baseColumnCount, boolean rowKeyOrderOptimizable, boolean isTransactional) throws SQLException { Preconditions.checkNotNull(schemaName); Preconditions.checkArgument(tenantId==null || tenantId.getBytes().length > 0); // tenantId should be null or not empty int estimatedSize = SizedUtil.OBJECT_SIZE * 2 + 23 * SizedUtil.POINTER_SIZE + 4 * SizedUtil.INT_SIZE + 2 * SizedUtil.LONG_SIZE + 2 * SizedUtil.INT_OBJECT_SIZE + @@@ -332,8 -357,8 +358,9 @@@ this.viewType = viewType; this.viewIndexId = viewIndexId; this.indexType = indexType; + this.isTransactional = isTransactional; this.tableStats = stats; + this.rowKeyOrderOptimizable = rowKeyOrderOptimizable; List<PColumn> pkColumns; PColumn[] allColumns; @@@ -977,7 -1044,7 +1050,7 @@@ result.init(tenantId, schemaName, tableName, tableType, indexState, timeStamp, sequenceNumber, pkName, (bucketNum == NO_SALTING) ? null : bucketNum, columns, stats, schemaName,dataTableName, indexes, isImmutableRows, physicalNames, defaultFamilyName, viewStatement, disableWAL, - multiTenant, storeNulls, viewType, viewIndexId, indexType, isTransactional); - multiTenant, storeNulls, viewType, viewIndexId, indexType, baseColumnCount, rowKeyOrderOptimizable); ++ multiTenant, storeNulls, viewType, viewIndexId, indexType, baseColumnCount, rowKeyOrderOptimizable, isTransactional); return result; } catch (SQLException e) { throw new RuntimeException(e); // Impossible @@@ -1057,10 -1124,9 +1130,10 @@@ builder.setDisableWAL(table.isWALDisabled()); builder.setMultiTenant(table.isMultiTenant()); builder.setStoreNulls(table.getStoreNulls()); + builder.setTransactional(table.isTransactional()); if(table.getType() == PTableType.VIEW){ - builder.setViewType(HBaseZeroCopyByteString.wrap(new byte[]{table.getViewType().getSerializedValue()})); - builder.setViewStatement(HBaseZeroCopyByteString.wrap(PVarchar.INSTANCE.toBytes(table.getViewStatement()))); + builder.setViewType(ByteStringer.wrap(new byte[]{table.getViewType().getSerializedValue()})); + builder.setViewStatement(ByteStringer.wrap(PVarchar.INSTANCE.toBytes(table.getViewStatement()))); } if(table.getType() == PTableType.VIEW || table.getViewIndexId() != null){ for (int i = 0; i < table.getPhysicalNames().size(); i++) { @@@ -1087,8 -1155,17 +1162,21 @@@ } @Override + public boolean isTransactional() { + return isTransactional; + } + + public int getBaseColumnCount() { + return baseColumnCount; + } + + @Override + public boolean rowKeyOrderOptimizable() { + return rowKeyOrderOptimizable || !hasColumnsRequiringUpgrade; + } + + @Override + public int getRowTimestampColPos() { + return rowTimestampColPos; + } }
http://git-wip-us.apache.org/repos/asf/phoenix/blob/7d3b544a/phoenix-core/src/main/java/org/apache/phoenix/schema/TableRef.java ---------------------------------------------------------------------- diff --cc phoenix-core/src/main/java/org/apache/phoenix/schema/TableRef.java index 316b6ae,78b00fa..f1ef456 --- a/phoenix-core/src/main/java/org/apache/phoenix/schema/TableRef.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/TableRef.java @@@ -103,7 -101,7 +105,7 @@@ public class TableRef public int hashCode() { final int prime = 31; int result = alias == null ? 0 : alias.hashCode(); -- result = prime * result + this.table.getName().getString().hashCode(); ++ result = prime * result + ( this.table!=null && this.table.getName()!=null ? this.table.getName().getString().hashCode() : 0); return result; } http://git-wip-us.apache.org/repos/asf/phoenix/blob/7d3b544a/phoenix-core/src/main/java/org/apache/phoenix/util/IndexUtil.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/phoenix/blob/7d3b544a/phoenix-core/src/main/java/org/apache/phoenix/util/MetaDataUtil.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/phoenix/blob/7d3b544a/phoenix-core/src/main/java/org/apache/phoenix/util/PhoenixRuntime.java ---------------------------------------------------------------------- diff --cc phoenix-core/src/main/java/org/apache/phoenix/util/PhoenixRuntime.java index 4fdd597,4f87765..4df2971 --- a/phoenix-core/src/main/java/org/apache/phoenix/util/PhoenixRuntime.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/util/PhoenixRuntime.java @@@ -303,8 -355,7 +355,7 @@@ public class PhoenixRuntime PTable table = null; PhoenixConnection pconn = conn.unwrap(PhoenixConnection.class); try { - name = SchemaUtil.normalizeIdentifier(name); - table = pconn.getTable(new PTableKey(pconn.getTenantId(), name)); - table = pconn.getMetaDataCache().getTable(new PTableKey(pconn.getTenantId(), name)); ++ table = pconn.getMetaDataCache().getTableRef(new PTableKey(pconn.getTenantId(), name)).getTable(); } catch (TableNotFoundException e) { String schemaName = SchemaUtil.getSchemaNameFromFullName(name); String tableName = SchemaUtil.getTableNameFromFullName(name); http://git-wip-us.apache.org/repos/asf/phoenix/blob/7d3b544a/phoenix-core/src/main/java/org/apache/phoenix/util/ScanUtil.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/phoenix/blob/7d3b544a/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java ---------------------------------------------------------------------- diff --cc phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java index 4dc792f,5414d4f..84860f4 --- a/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/util/SchemaUtil.java @@@ -675,14 -711,37 +708,47 @@@ public class SchemaUtil checkArgument(!isNullOrEmpty(columnName), "Column name cannot be null or empty"); return columnFamilyName == null ? ("\"" + columnName + "\"") : ("\"" + columnFamilyName + "\"" + QueryConstants.NAME_SEPARATOR + "\"" + columnName + "\""); } + + public static boolean hasHTableDescriptorProps(Map<String, Object> tableProps) { + int pTablePropCount = 0; + for (String prop : tableProps.keySet()) { + if (TableProperty.isPhoenixTableProperty(prop)) { + pTablePropCount++; + } + } + return tableProps.size() - pTablePropCount > 0; + } + + /** + * Replaces all occurrences of {@link #ESCAPE_CHARACTER} with an empty character. + * @param fullColumnName + * @return + */ + public static String getUnEscapedFullColumnName(String fullColumnName) { + checkArgument(!isNullOrEmpty(fullColumnName), "Column name cannot be null or empty"); + fullColumnName = fullColumnName.replaceAll(ESCAPE_CHARACTER, ""); + return fullColumnName.trim(); + } + + /** + * Return the separator byte to use based on: + * @param rowKeyOrderOptimizable whether or not the table may optimize descending row keys. If the + * table has no descending row keys, this will be true. Also, if the table has been upgraded (using + * a new -u option for psql.py), then it'll be true + * @param isNullValue whether or not the value is null. We use a null byte still if the value is null + * regardless of sort order since nulls will always sort first this way. + * @param sortOrder whether the value sorts ascending or descending. + * @return the byte to use as the separator + */ + public static byte getSeparatorByte(boolean rowKeyOrderOptimizable, boolean isNullValue, SortOrder sortOrder) { + return !rowKeyOrderOptimizable || isNullValue || sortOrder == SortOrder.ASC ? QueryConstants.SEPARATOR_BYTE : QueryConstants.DESC_SEPARATOR_BYTE; + } + + public static byte getSeparatorByte(boolean rowKeyOrderOptimizable, boolean isNullValue, Field f) { + return getSeparatorByte(rowKeyOrderOptimizable, isNullValue, f.getSortOrder()); + } + + public static byte getSeparatorByte(boolean rowKeyOrderOptimizable, boolean isNullValue, Expression e) { + return getSeparatorByte(rowKeyOrderOptimizable, isNullValue, e.getSortOrder()); + } } http://git-wip-us.apache.org/repos/asf/phoenix/blob/7d3b544a/phoenix-core/src/test/java/org/apache/phoenix/compile/QueryCompilerTest.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/phoenix/blob/7d3b544a/phoenix-core/src/test/java/org/apache/phoenix/compile/ViewCompilerTest.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/phoenix/blob/7d3b544a/phoenix-core/src/test/java/org/apache/phoenix/execute/CorrelatePlanTest.java ---------------------------------------------------------------------- diff --cc phoenix-core/src/test/java/org/apache/phoenix/execute/CorrelatePlanTest.java index 0000000,334ce8c..9d5e17c mode 000000,100644..100644 --- a/phoenix-core/src/test/java/org/apache/phoenix/execute/CorrelatePlanTest.java +++ b/phoenix-core/src/test/java/org/apache/phoenix/execute/CorrelatePlanTest.java @@@ -1,0 -1,248 +1,248 @@@ + /* + * 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.util.PhoenixRuntime.CONNECTIONLESS; + import static org.apache.phoenix.util.PhoenixRuntime.JDBC_PROTOCOL; + import static org.apache.phoenix.util.PhoenixRuntime.JDBC_PROTOCOL_SEPARATOR; + import static org.junit.Assert.assertEquals; + import static org.junit.Assert.assertNotNull; + + import java.sql.DriverManager; + import java.sql.SQLException; + import java.util.Arrays; + import java.util.Collections; + import java.util.List; + + import org.apache.hadoop.hbase.KeyValue; + import org.apache.hadoop.hbase.client.Scan; + import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp; + import org.apache.hadoop.hbase.io.ImmutableBytesWritable; + import org.apache.phoenix.compile.ColumnResolver; + import org.apache.phoenix.compile.FromCompiler; + import org.apache.phoenix.compile.JoinCompiler; + 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.TupleProjectionCompiler; + import org.apache.phoenix.compile.OrderByCompiler.OrderBy; + import org.apache.phoenix.coprocessor.MetaDataProtocol; + import org.apache.phoenix.exception.SQLExceptionCode; + import org.apache.phoenix.expression.ComparisonExpression; + import org.apache.phoenix.expression.CorrelateVariableFieldAccessExpression; + import org.apache.phoenix.expression.Expression; + import org.apache.phoenix.expression.LiteralExpression; + import org.apache.phoenix.expression.ProjectedColumnExpression; + import org.apache.phoenix.iterate.ResultIterator; + import org.apache.phoenix.jdbc.PhoenixConnection; + import org.apache.phoenix.jdbc.PhoenixStatement; + import org.apache.phoenix.parse.JoinTableNode.JoinType; + import org.apache.phoenix.parse.ParseNodeFactory; + import org.apache.phoenix.parse.SelectStatement; + import org.apache.phoenix.schema.ColumnRef; + import org.apache.phoenix.schema.PColumn; + import org.apache.phoenix.schema.PColumnImpl; + 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.PTableType; + import org.apache.phoenix.schema.TableRef; + import org.apache.phoenix.schema.tuple.SingleKeyValueTuple; + import org.apache.phoenix.schema.tuple.Tuple; + import org.junit.Test; + + import com.google.common.collect.Lists; + + public class CorrelatePlanTest { + + private static final StatementContext CONTEXT; + static { + try { + PhoenixConnection connection = DriverManager.getConnection(JDBC_PROTOCOL + JDBC_PROTOCOL_SEPARATOR + CONNECTIONLESS).unwrap(PhoenixConnection.class); + PhoenixStatement stmt = new PhoenixStatement(connection); + ColumnResolver resolver = FromCompiler.getResolverForQuery(SelectStatement.SELECT_ONE, connection); + CONTEXT = new StatementContext(stmt, resolver, new Scan(), new SequenceManager(stmt)); + } catch (SQLException e) { + throw new RuntimeException(e); + } + } + + private static final Object[][] LEFT_RELATION = new Object[][] { + {1, "1"}, + {2, "2"}, + {3, "3"}, + {4, "4"}, + {5, "5"}, + }; + + private static final Object[][] RIGHT_RELATION = new Object[][] { + {"2", 20}, + {"2", 40}, + {"5", 50}, + {"6", 60}, + {"5", 100}, + {"1", 10}, + {"3", 30}, + }; + + @Test + public void testCorrelatePlanWithInnerJoinType() throws SQLException { + Object[][] expected = new Object[][] { + {1, "1", "1", 10}, + {2, "2", "2", 20}, + {2, "2", "2", 40}, + {3, "3", "3", 30}, + {5, "5", "5", 50}, + {5, "5", "5", 100}, + }; + testCorrelatePlan(LEFT_RELATION, RIGHT_RELATION, 1, 0, JoinType.Inner, expected); + } + + @Test + public void testCorrelatePlanWithLeftJoinType() throws SQLException { + Object[][] expected = new Object[][] { + {1, "1", "1", 10}, + {2, "2", "2", 20}, + {2, "2", "2", 40}, + {3, "3", "3", 30}, + {4, "4", null, null}, + {5, "5", "5", 50}, + {5, "5", "5", 100}, + }; + testCorrelatePlan(LEFT_RELATION, RIGHT_RELATION, 1, 0, JoinType.Left, expected); + } + + @Test + public void testCorrelatePlanWithSemiJoinType() throws SQLException { + Object[][] expected = new Object[][] { + {1, "1"}, + {2, "2"}, + {3, "3"}, + {5, "5"}, + }; + testCorrelatePlan(LEFT_RELATION, RIGHT_RELATION, 1, 0, JoinType.Semi, expected); + } + + @Test + public void testCorrelatePlanWithAntiJoinType() throws SQLException { + Object[][] expected = new Object[][] { + {4, "4"}, + }; + testCorrelatePlan(LEFT_RELATION, RIGHT_RELATION, 1, 0, JoinType.Anti, expected); + } + + @Test + public void testCorrelatePlanWithSingleValueOnly() throws SQLException { + Object[][] expected = new Object[][] { + {1, "1", "1", 10}, + {2, "2", "2", 20}, + {2, "2", "2", 40}, + }; + try { + testCorrelatePlan(LEFT_RELATION, RIGHT_RELATION, 1, 0, JoinType.Inner, expected); + } catch (SQLException e) { + assertEquals(SQLExceptionCode.SINGLE_ROW_SUBQUERY_RETURNS_MULTIPLE_ROWS.getErrorCode(), e.getErrorCode()); + } + + Object[][] rightRelation = new Object[][] { + {"2", 20}, + {"6", 60}, + {"5", 100}, + {"1", 10}, + }; + expected = new Object[][] { + {1, "1", "1", 10}, + {2, "2", "2", 20}, + {5, "5", "5", 100}, + }; + testCorrelatePlan(LEFT_RELATION, rightRelation, 1, 0, JoinType.Inner, expected); + } + + private void testCorrelatePlan(Object[][] leftRelation, Object[][] rightRelation, int leftCorrelColumn, int rightCorrelColumn, JoinType type, Object[][] expectedResult) throws SQLException { + TableRef leftTable = createProjectedTableFromLiterals(leftRelation[0]); + TableRef rightTable = createProjectedTableFromLiterals(rightRelation[0]); + String varName = "$cor0"; + RuntimeContext runtimeContext = new RuntimeContextImpl(); + runtimeContext.defineCorrelateVariable(varName, leftTable); + QueryPlan leftPlan = newLiteralResultIterationPlan(leftRelation); + QueryPlan rightPlan = newLiteralResultIterationPlan(rightRelation); + Expression columnExpr = new ColumnRef(rightTable, rightCorrelColumn).newColumnExpression(); + Expression fieldAccess = new CorrelateVariableFieldAccessExpression(runtimeContext, varName, new ColumnRef(leftTable, leftCorrelColumn).newColumnExpression()); + Expression filter = ComparisonExpression.create(CompareOp.EQUAL, Arrays.asList(columnExpr, fieldAccess), CONTEXT.getTempPtr(), false); + rightPlan = new ClientScanPlan(CONTEXT, SelectStatement.SELECT_ONE, rightTable, RowProjector.EMPTY_PROJECTOR, null, filter, OrderBy.EMPTY_ORDER_BY, rightPlan); + PTable joinedTable = JoinCompiler.joinProjectedTables(leftTable.getTable(), rightTable.getTable(), type); + CorrelatePlan correlatePlan = new CorrelatePlan(leftPlan, rightPlan, varName, type, false, runtimeContext, joinedTable, leftTable.getTable(), rightTable.getTable(), leftTable.getTable().getColumns().size()); + ResultIterator iter = correlatePlan.iterator(); + ImmutableBytesWritable ptr = new ImmutableBytesWritable(); + for (Object[] row : expectedResult) { + Tuple next = iter.next(); + assertNotNull(next); + for (int i = 0; i < row.length; i++) { + PColumn column = joinedTable.getColumns().get(i); + boolean eval = new ProjectedColumnExpression(column, joinedTable, column.getName().getString()).evaluate(next, ptr); + Object o = eval ? column.getDataType().toObject(ptr) : null; + assertEquals(row[i], o); + } + } + } + + private QueryPlan newLiteralResultIterationPlan(Object[][] rows) { + List<Tuple> tuples = Lists.newArrayList(); + Tuple baseTuple = new SingleKeyValueTuple(KeyValue.LOWESTKEY); + for (Object[] row : rows) { + Expression[] exprs = new Expression[row.length]; + for (int i = 0; i < row.length; i++) { + exprs[i] = LiteralExpression.newConstant(row[i]); + } + TupleProjector projector = new TupleProjector(exprs); + tuples.add(projector.projectResults(baseTuple)); + } + + return new LiteralResultIterationPlan(tuples, CONTEXT, SelectStatement.SELECT_ONE, TableRef.EMPTY_TABLE_REF, RowProjector.EMPTY_PROJECTOR, null, OrderBy.EMPTY_ORDER_BY, null); + } + + + private TableRef createProjectedTableFromLiterals(Object[] row) { + List<PColumn> columns = Lists.<PColumn>newArrayList(); + for (int i = 0; i < row.length; i++) { + String name = ParseNodeFactory.createTempAlias(); + Expression expr = LiteralExpression.newConstant(row[i]); + columns.add(new PColumnImpl(PNameFactory.newName(name), PNameFactory.newName(TupleProjector.VALUE_COLUMN_FAMILY), + expr.getDataType(), expr.getMaxLength(), expr.getScale(), expr.isNullable(), + i, expr.getSortOrder(), null, null, false, name, false)); + } + try { + PTable pTable = PTableImpl.makePTable(null, PName.EMPTY_NAME, PName.EMPTY_NAME, + PTableType.SUBQUERY, null, MetaDataProtocol.MIN_TABLE_TIMESTAMP, PTable.INITIAL_SEQ_NUM, + null, null, columns, null, null, Collections.<PTable>emptyList(), + false, Collections.<PName>emptyList(), null, null, false, false, false, null, - null, null, true); ++ null, null, true, false); + TableRef sourceTable = new TableRef(pTable); + List<ColumnRef> sourceColumnRefs = Lists.<ColumnRef> newArrayList(); + for (PColumn column : sourceTable.getTable().getColumns()) { + sourceColumnRefs.add(new ColumnRef(sourceTable, column.getPosition())); + } + + return new TableRef(TupleProjectionCompiler.createProjectedTable(sourceTable, sourceColumnRefs, false)); + } catch (SQLException e) { + throw new RuntimeException(e); + } + } + } http://git-wip-us.apache.org/repos/asf/phoenix/blob/7d3b544a/phoenix-core/src/test/java/org/apache/phoenix/filter/SkipScanBigFilterTest.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/phoenix/blob/7d3b544a/phoenix-core/src/test/java/org/apache/phoenix/hbase/index/covered/TestLocalTableState.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/phoenix/blob/7d3b544a/phoenix-core/src/test/java/org/apache/phoenix/hbase/index/covered/example/TestCoveredColumnIndexCodec.java ---------------------------------------------------------------------- diff --cc phoenix-core/src/test/java/org/apache/phoenix/hbase/index/covered/example/TestCoveredColumnIndexCodec.java index e4654ea,1b61ef0..fc3a976 --- a/phoenix-core/src/test/java/org/apache/phoenix/hbase/index/covered/example/TestCoveredColumnIndexCodec.java +++ b/phoenix-core/src/test/java/org/apache/phoenix/hbase/index/covered/example/TestCoveredColumnIndexCodec.java @@@ -169,7 -172,7 +169,7 @@@ public class TestCoveredColumnIndexCode // start with a basic put that has some keyvalues Put p = new Put(PK); // setup the kvs to add -- List<Cell> kvs = new ArrayList<Cell>(); ++ List<KeyValue> kvs = new ArrayList<KeyValue>(); byte[] v1 = Bytes.toBytes("v1"); KeyValue kv = new KeyValue(PK, FAMILY, QUAL, 1, v1); kvs.add(kv); @@@ -207,7 -210,7 +207,7 @@@ d.deleteFamily(FAMILY, 2); // setup the next batch of 'current state', basically just ripping out the current state from // the last round -- table = new SimpleTableState(Result.create(kvs)); ++ table = new SimpleTableState(new Result(kvs)); state = new LocalTableState(env, table, d); state.setCurrentTimestamp(2); // check the cleanup of the current table, after the puts (mocking a 'next' update) @@@ -234,14 -237,14 +234,14 @@@ ensureNoUpdatesWhenCoveredByDelete(env, codec, kvs, d); } -- private void ensureNoUpdatesWhenCoveredByDelete(RegionCoprocessorEnvironment env, IndexCodec codec, List<Cell> currentState, ++ private void ensureNoUpdatesWhenCoveredByDelete(RegionCoprocessorEnvironment env, IndexCodec codec, List<KeyValue> currentState, Delete d) throws IOException { -- LocalHBaseState table = new SimpleTableState(Result.create(currentState)); ++ LocalHBaseState table = new SimpleTableState(new Result(currentState)); LocalTableState state = new LocalTableState(env, table, d); state.setCurrentTimestamp(d.getTimeStamp()); // now we shouldn't see anything when getting the index update - state.addPendingUpdates(d.getFamilyCellMap().get(FAMILY)); - state.addPendingUpdates(KeyValueUtil.ensureKeyValues(d.getFamilyCellMap().get(FAMILY))); - Iterable<IndexUpdate> updates = codec.getIndexUpserts(state); ++ state.addPendingUpdates(d.getFamilyMap().get(FAMILY)); + Iterable<IndexUpdate> updates = codec.getIndexUpserts(state, IndexMetaData.NULL_INDEX_META_DATA); for (IndexUpdate update : updates) { assertFalse("Had some index updates, though it should have been covered by the delete", update.isValid()); http://git-wip-us.apache.org/repos/asf/phoenix/blob/7d3b544a/phoenix-core/src/test/java/org/apache/phoenix/jdbc/PhoenixTestDriver.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/phoenix/blob/7d3b544a/phoenix-core/src/test/java/org/apache/phoenix/query/BaseTest.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/phoenix/blob/7d3b544a/phoenix-core/src/test/java/org/apache/phoenix/query/ConnectionlessTest.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/phoenix/blob/7d3b544a/phoenix-core/src/test/java/org/apache/phoenix/query/ParallelIteratorsSplitTest.java ---------------------------------------------------------------------- diff --cc phoenix-core/src/test/java/org/apache/phoenix/query/ParallelIteratorsSplitTest.java index 98fcd73,ed1f3e4..666cb2a --- a/phoenix-core/src/test/java/org/apache/phoenix/query/ParallelIteratorsSplitTest.java +++ b/phoenix-core/src/test/java/org/apache/phoenix/query/ParallelIteratorsSplitTest.java @@@ -50,10 -50,12 +51,11 @@@ import org.apache.phoenix.iterate.Spool import org.apache.phoenix.jdbc.PhoenixConnection; import org.apache.phoenix.jdbc.PhoenixParameterMetaData; import org.apache.phoenix.jdbc.PhoenixStatement; +import org.apache.phoenix.jdbc.PhoenixStatement.Operation; import org.apache.phoenix.parse.FilterableStatement; + import org.apache.phoenix.parse.PFunction; import org.apache.phoenix.parse.SelectStatement; -import org.apache.phoenix.schema.types.PChar; import org.apache.phoenix.schema.ColumnRef; -import org.apache.phoenix.schema.types.PDataType; import org.apache.phoenix.schema.PDatum; import org.apache.phoenix.schema.PTable; import org.apache.phoenix.schema.PTableKey; @@@ -61,11 -63,8 +63,10 @@@ import org.apache.phoenix.schema.RowKey import org.apache.phoenix.schema.RowKeySchema.RowKeySchemaBuilder; import org.apache.phoenix.schema.SortOrder; import org.apache.phoenix.schema.TableRef; +import org.apache.phoenix.schema.types.PChar; +import org.apache.phoenix.schema.types.PDataType; import org.apache.phoenix.util.ByteUtil; import org.apache.phoenix.util.PropertiesUtil; - import org.apache.phoenix.util.ScanUtil; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@@ -422,10 -433,10 +442,15 @@@ public class ParallelIteratorsSplitTes } @Override + public Operation getOperation() { + return Operation.QUERY; + } + ++ @Override + public boolean useRoundRobinIterator() { + return false; + } + }, null, new SpoolingResultIterator.SpoolingResultIteratorFactory(context.getConnection().getQueryServices())); List<KeyRange> keyRanges = parallelIterators.getSplits(); return keyRanges; http://git-wip-us.apache.org/repos/asf/phoenix/blob/7d3b544a/phoenix-core/src/test/java/org/apache/phoenix/schema/PMetaDataImplTest.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/phoenix/blob/7d3b544a/phoenix-core/src/test/java/org/apache/phoenix/util/TestUtil.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/phoenix/blob/7d3b544a/phoenix-flume/pom.xml ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/phoenix/blob/7d3b544a/phoenix-pig/pom.xml ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/phoenix/blob/7d3b544a/phoenix-protocol/src/main/PTable.proto ---------------------------------------------------------------------- diff --cc phoenix-protocol/src/main/PTable.proto index ababd23,3257a70..3048a40 --- a/phoenix-protocol/src/main/PTable.proto +++ b/phoenix-protocol/src/main/PTable.proto @@@ -83,5 -84,6 +84,7 @@@ message PTable optional bytes indexType = 22; optional int64 statsTimeStamp = 23; optional bool storeNulls = 24; - optional bool transactional = 25; + optional int32 baseColumnCount = 25; + optional bool rowKeyOrderOptimizable = 26; ++ optional bool transactional = 27; } http://git-wip-us.apache.org/repos/asf/phoenix/blob/7d3b544a/pom.xml ---------------------------------------------------------------------- diff --cc pom.xml index 1d10116,ada83af..7d95158 --- a/pom.xml +++ b/pom.xml @@@ -89,21 -95,23 +95,25 @@@ <commons-configuration.version>1.6</commons-configuration.version> <commons-io.version>2.1</commons-io.version> <commons-lang.version>2.5</commons-lang.version> - <commons-logging.version>1.1.1</commons-logging.version> + <commons-logging.version>1.2</commons-logging.version> <commons-csv.version>1.0</commons-csv.version> <sqlline.version>1.1.8</sqlline.version> - <guava.version>12.0.1</guava.version> + <guava.version>13.0.1</guava.version> <jackson.version>1.8.8</jackson.version> <flume.version>1.4.0</flume.version> <findbugs.version>1.3.2</findbugs.version> <jline.version>2.11</jline.version> <snappy.version>0.3</snappy.version> - <netty.version>3.6.6.Final</netty.version> + <netty.version>4.0.23.Final</netty.version> <commons-codec.version>1.7</commons-codec.version> - <htrace.version>2.04</htrace.version> + <htrace.version>3.1.0-incubating</htrace.version> <collections.version>3.2.1</collections.version> + <jodatime.version>2.3</jodatime.version> + <jodatime.version>2.7</jodatime.version> + <joni.version>2.1.2</joni.version> + <calcite.version>1.3.0-incubating</calcite.version> + <jettyVersion>8.1.7.v20120910</jettyVersion> + <tephra.version>0.6.3-SNAPSHOT</tephra.version> <!-- Test Dependencies --> <mockito-all.version>1.8.5</mockito-all.version> @@@ -117,7 -125,8 +127,8 @@@ <maven-dependency-plugin.version>2.1</maven-dependency-plugin.version> <maven.assembly.version>2.5.2</maven.assembly.version> - + <maven.rat.version>0.8</maven.rat.version> - ++ <!-- Plugin options --> <numForkedUT>3</numForkedUT> <numForkedIT>5</numForkedIT> @@@ -290,6 -335,28 +337,29 @@@ <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-checkstyle-plugin</artifactId> + <version>2.13</version> + <executions> + <execution> + <id>validate</id> + <phase>validate</phase> + <configuration> + <configLocation>${top.dir}/src/main/config/checkstyle/checker.xml</configLocation> + <suppressionsLocation>${top.dir}/src/main/config/checkstyle/suppressions.xml</suppressionsLocation> + <consoleOutput>true</consoleOutput> + <headerLocation>${top.dir}/src/main/config/checkstyle/header.txt</headerLocation> + <failOnViolation><!--true-->false</failOnViolation> + <includeTestSourceDirectory><!--true-->false</includeTestSourceDirectory> ++ <skip>true</skip> + </configuration> + <goals> + <goal>check</goal> + </goals> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-source-plugin</artifactId> <version>2.2.1</version> <executions>
