use of org.apache.phoenix.parse.TableName in project phoenix by apache.
the class JoinCompiler method getSubqueryForOptimizedPlan.
private static SelectStatement getSubqueryForOptimizedPlan(HintNode hintNode, List<ColumnDef> dynamicCols, TableRef tableRef, Map<ColumnRef, ColumnRefType> columnRefs, ParseNode where, List<ParseNode> groupBy, List<OrderByNode> orderBy, boolean isWildCardSelect, boolean hasSequence, Map<String, UDFParseNode> udfParseNodes) {
String schemaName = tableRef.getTable().getSchemaName().getString();
TableName tName = TableName.create(schemaName.length() == 0 ? null : schemaName, tableRef.getTable().getTableName().getString());
List<AliasedNode> selectList = new ArrayList<AliasedNode>();
if (isWildCardSelect) {
selectList.add(NODE_FACTORY.aliasedNode(null, WildcardParseNode.INSTANCE));
} else {
for (ColumnRef colRef : columnRefs.keySet()) {
if (colRef.getTableRef().equals(tableRef)) {
ParseNode node = NODE_FACTORY.column(tName, '"' + colRef.getColumn().getName().getString() + '"', null);
if (groupBy != null) {
node = NODE_FACTORY.function(CountAggregateFunction.NAME, Collections.singletonList(node));
}
selectList.add(NODE_FACTORY.aliasedNode(null, node));
}
}
}
String tableAlias = tableRef.getTableAlias();
TableNode from = NODE_FACTORY.namedTable(tableAlias == null ? null : '"' + tableAlias + '"', tName, dynamicCols);
return NODE_FACTORY.select(from, hintNode, false, selectList, where, groupBy, null, orderBy, null, null, 0, groupBy != null, hasSequence, Collections.<SelectStatement>emptyList(), udfParseNodes);
}
use of org.apache.phoenix.parse.TableName in project phoenix by apache.
the class JoinCompiler method extractFromSelect.
private List<AliasedNode> extractFromSelect(List<AliasedNode> select, TableRef tableRef, ColumnResolver resolver) throws SQLException {
List<AliasedNode> ret = new ArrayList<AliasedNode>();
ColumnRefParseNodeVisitor visitor = new ColumnRefParseNodeVisitor(resolver, statement.getConnection());
for (AliasedNode aliasedNode : select) {
ParseNode node = aliasedNode.getNode();
if (node instanceof TableWildcardParseNode) {
TableName tableName = ((TableWildcardParseNode) node).getTableName();
if (tableRef.equals(resolver.resolveTable(tableName.getSchemaName(), tableName.getTableName()))) {
ret.clear();
ret.add(aliasedNode);
return ret;
}
continue;
}
node.accept(visitor);
ColumnRefParseNodeVisitor.ColumnRefType type = visitor.getContentType(Collections.singletonList(tableRef));
if (type == ColumnRefParseNodeVisitor.ColumnRefType.SELF_ONLY) {
ret.add(aliasedNode);
} else if (type == ColumnRefParseNodeVisitor.ColumnRefType.COMPLEX) {
for (Map.Entry<ColumnRef, ColumnParseNode> entry : visitor.getColumnRefMap().entrySet()) {
if (entry.getKey().getTableRef().equals(tableRef)) {
ret.add(NODE_FACTORY.aliasedNode(null, entry.getValue()));
}
}
}
visitor.reset();
}
return ret;
}
use of org.apache.phoenix.parse.TableName in project phoenix by apache.
the class CreateSequenceCompiler method compile.
public MutationPlan compile(final CreateSequenceStatement sequence) throws SQLException {
ParseNode startsWithNode = sequence.getStartWith();
ParseNode incrementByNode = sequence.getIncrementBy();
ParseNode maxValueNode = sequence.getMaxValue();
ParseNode minValueNode = sequence.getMinValue();
ParseNode cacheNode = sequence.getCacheSize();
// validate parse nodes
if (startsWithNode != null) {
validateNodeIsStateless(sequence, startsWithNode, SQLExceptionCode.START_WITH_MUST_BE_CONSTANT);
}
validateNodeIsStateless(sequence, incrementByNode, SQLExceptionCode.INCREMENT_BY_MUST_BE_CONSTANT);
validateNodeIsStateless(sequence, maxValueNode, SQLExceptionCode.MAXVALUE_MUST_BE_CONSTANT);
validateNodeIsStateless(sequence, minValueNode, SQLExceptionCode.MINVALUE_MUST_BE_CONSTANT);
if (cacheNode != null) {
validateNodeIsStateless(sequence, cacheNode, SQLExceptionCode.CACHE_MUST_BE_NON_NEGATIVE_CONSTANT);
}
final PhoenixConnection connection = statement.getConnection();
final StatementContext context = new StatementContext(statement);
// add param meta data if required
if (startsWithNode instanceof BindParseNode) {
context.getBindManager().addParamMetaData((BindParseNode) startsWithNode, LONG_DATUM);
}
if (incrementByNode instanceof BindParseNode) {
context.getBindManager().addParamMetaData((BindParseNode) incrementByNode, LONG_DATUM);
}
if (maxValueNode instanceof BindParseNode) {
context.getBindManager().addParamMetaData((BindParseNode) maxValueNode, LONG_DATUM);
}
if (minValueNode instanceof BindParseNode) {
context.getBindManager().addParamMetaData((BindParseNode) minValueNode, LONG_DATUM);
}
if (cacheNode instanceof BindParseNode) {
context.getBindManager().addParamMetaData((BindParseNode) cacheNode, INTEGER_DATUM);
}
ExpressionCompiler expressionCompiler = new ExpressionCompiler(context);
final long incrementBy = evalExpression(sequence, context, incrementByNode.accept(expressionCompiler), SQLExceptionCode.INCREMENT_BY_MUST_BE_CONSTANT);
if (incrementBy == 0) {
throw SequenceUtil.getException(sequence.getSequenceName().getSchemaName(), sequence.getSequenceName().getTableName(), SQLExceptionCode.INCREMENT_BY_MUST_NOT_BE_ZERO);
}
final long maxValue = evalExpression(sequence, context, maxValueNode.accept(expressionCompiler), SQLExceptionCode.MAXVALUE_MUST_BE_CONSTANT);
final long minValue = evalExpression(sequence, context, minValueNode.accept(expressionCompiler), SQLExceptionCode.MINVALUE_MUST_BE_CONSTANT);
if (minValue > maxValue) {
TableName sequenceName = sequence.getSequenceName();
throw SequenceUtil.getException(sequenceName.getSchemaName(), sequenceName.getTableName(), SQLExceptionCode.MINVALUE_MUST_BE_LESS_THAN_OR_EQUAL_TO_MAXVALUE);
}
long startsWithValue;
if (startsWithNode == null) {
startsWithValue = incrementBy > 0 ? minValue : maxValue;
} else {
startsWithValue = evalExpression(sequence, context, startsWithNode.accept(expressionCompiler), SQLExceptionCode.START_WITH_MUST_BE_CONSTANT);
if (startsWithValue < minValue || startsWithValue > maxValue) {
TableName sequenceName = sequence.getSequenceName();
throw SequenceUtil.getException(sequenceName.getSchemaName(), sequenceName.getTableName(), SQLExceptionCode.STARTS_WITH_MUST_BE_BETWEEN_MIN_MAX_VALUE);
}
}
final long startsWith = startsWithValue;
long cacheSizeValue;
if (cacheNode == null) {
cacheSizeValue = connection.getQueryServices().getProps().getLong(QueryServices.SEQUENCE_CACHE_SIZE_ATTRIB, QueryServicesOptions.DEFAULT_SEQUENCE_CACHE_SIZE);
} else {
cacheSizeValue = evalExpression(sequence, context, cacheNode.accept(expressionCompiler), SQLExceptionCode.CACHE_MUST_BE_NON_NEGATIVE_CONSTANT);
if (cacheSizeValue < 0) {
TableName sequenceName = sequence.getSequenceName();
throw SequenceUtil.getException(sequenceName.getSchemaName(), sequenceName.getTableName(), SQLExceptionCode.CACHE_MUST_BE_NON_NEGATIVE_CONSTANT);
}
}
final long cacheSize = Math.max(1L, cacheSizeValue);
final MetaDataClient client = new MetaDataClient(connection);
return new BaseMutationPlan(context, operation) {
@Override
public MutationState execute() throws SQLException {
return client.createSequence(sequence, startsWith, incrementBy, cacheSize, minValue, maxValue);
}
@Override
public ExplainPlan getExplainPlan() throws SQLException {
return new ExplainPlan(Collections.singletonList("CREATE SEQUENCE"));
}
};
}
use of org.apache.phoenix.parse.TableName in project phoenix by apache.
the class BaseIndexIT method createIndexOnTableWithSpecifiedDefaultCF.
@Test
public void createIndexOnTableWithSpecifiedDefaultCF() throws Exception {
Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
String tableName = "TBL_" + generateUniqueName();
String indexName = "IND_" + generateUniqueName();
String fullTableName = SchemaUtil.getTableName(TestUtil.DEFAULT_SCHEMA_NAME, tableName);
String fullIndexName = SchemaUtil.getTableName(TestUtil.DEFAULT_SCHEMA_NAME, indexName);
try (Connection conn = DriverManager.getConnection(getUrl(), props)) {
conn.setAutoCommit(false);
String query;
ResultSet rs;
String ddl = "CREATE TABLE " + fullTableName + " (k VARCHAR NOT NULL PRIMARY KEY, v1 VARCHAR, v2 VARCHAR) DEFAULT_COLUMN_FAMILY='A'" + (!tableDDLOptions.isEmpty() ? "," + tableDDLOptions : "");
Statement stmt = conn.createStatement();
stmt.execute(ddl);
query = "SELECT * FROM " + tableName;
rs = conn.createStatement().executeQuery(query);
assertFalse(rs.next());
String options = localIndex ? "SALT_BUCKETS=10, MULTI_TENANT=true, IMMUTABLE_ROWS=true, DISABLE_WAL=true" : "";
conn.createStatement().execute("CREATE INDEX " + indexName + " ON " + fullTableName + " (v1) INCLUDE (v2) " + options);
query = "SELECT * FROM " + fullIndexName;
rs = conn.createStatement().executeQuery(query);
assertFalse(rs.next());
// check options set correctly on index
TableName indexTableName = TableName.create(TestUtil.DEFAULT_SCHEMA_NAME, indexName);
NamedTableNode indexNode = NamedTableNode.create(null, indexTableName, null);
ColumnResolver resolver = FromCompiler.getResolver(indexNode, conn.unwrap(PhoenixConnection.class));
PTable indexTable = resolver.getTables().get(0).getTable();
// Can't set IMMUTABLE_ROWS, MULTI_TENANT or DEFAULT_COLUMN_FAMILY_NAME on an index
assertNull(indexTable.getDefaultFamilyName());
assertFalse(indexTable.isMultiTenant());
// Should match table
assertEquals(mutable, !indexTable.isImmutableRows());
if (localIndex) {
assertEquals(10, indexTable.getBucketNum().intValue());
assertTrue(indexTable.isWALDisabled());
}
}
}
use of org.apache.phoenix.parse.TableName in project phoenix by apache.
the class ProjectionCompiler method compile.
/**
* Builds the projection for the scan
* @param context query context kept between compilation of different query clauses
* @param statement TODO
* @param groupBy compiled GROUP BY clause
* @param targetColumns list of columns, parallel to aliasedNodes, that are being set for an
* UPSERT SELECT statement. Used to coerce expression types to the expected target type.
* @return projector used to access row values during scan
* @throws SQLException
*/
public static RowProjector compile(StatementContext context, SelectStatement statement, GroupBy groupBy, List<? extends PDatum> targetColumns, Expression where) throws SQLException {
List<KeyValueColumnExpression> arrayKVRefs = new ArrayList<KeyValueColumnExpression>();
List<ProjectedColumnExpression> arrayProjectedColumnRefs = new ArrayList<ProjectedColumnExpression>();
List<Expression> arrayKVFuncs = new ArrayList<Expression>();
List<Expression> arrayOldFuncs = new ArrayList<Expression>();
Map<Expression, Integer> arrayExpressionCounts = new HashMap<>();
List<AliasedNode> aliasedNodes = statement.getSelect();
// Setup projected columns in Scan
SelectClauseVisitor selectVisitor = new SelectClauseVisitor(context, groupBy, arrayKVRefs, arrayKVFuncs, arrayExpressionCounts, arrayProjectedColumnRefs, arrayOldFuncs, statement);
List<ExpressionProjector> projectedColumns = new ArrayList<ExpressionProjector>();
ColumnResolver resolver = context.getResolver();
TableRef tableRef = context.getCurrentTable();
PTable table = tableRef.getTable();
boolean resolveColumn = !tableRef.equals(resolver.getTables().get(0));
boolean isWildcard = false;
Scan scan = context.getScan();
int index = 0;
List<Expression> projectedExpressions = Lists.newArrayListWithExpectedSize(aliasedNodes.size());
List<byte[]> projectedFamilies = Lists.newArrayListWithExpectedSize(aliasedNodes.size());
for (AliasedNode aliasedNode : aliasedNodes) {
ParseNode node = aliasedNode.getNode();
// TODO: visitor?
if (node instanceof WildcardParseNode) {
if (statement.isAggregate()) {
ExpressionCompiler.throwNonAggExpressionInAggException(node.toString());
}
if (tableRef == TableRef.EMPTY_TABLE_REF) {
throw new SQLExceptionInfo.Builder(SQLExceptionCode.NO_TABLE_SPECIFIED_FOR_WILDCARD_SELECT).build().buildException();
}
isWildcard = true;
if (tableRef.getTable().getType() == PTableType.INDEX && ((WildcardParseNode) node).isRewrite()) {
projectAllIndexColumns(context, tableRef, resolveColumn, projectedExpressions, projectedColumns, targetColumns);
} else {
projectAllTableColumns(context, tableRef, resolveColumn, projectedExpressions, projectedColumns, targetColumns);
}
} else if (node instanceof TableWildcardParseNode) {
TableName tName = ((TableWildcardParseNode) node).getTableName();
TableRef tRef = resolver.resolveTable(tName.getSchemaName(), tName.getTableName());
if (tRef.equals(tableRef)) {
isWildcard = true;
}
if (tRef.getTable().getType() == PTableType.INDEX && ((TableWildcardParseNode) node).isRewrite()) {
projectAllIndexColumns(context, tRef, true, projectedExpressions, projectedColumns, targetColumns);
} else {
projectAllTableColumns(context, tRef, true, projectedExpressions, projectedColumns, targetColumns);
}
} else if (node instanceof FamilyWildcardParseNode) {
if (tableRef == TableRef.EMPTY_TABLE_REF) {
throw new SQLExceptionInfo.Builder(SQLExceptionCode.NO_TABLE_SPECIFIED_FOR_WILDCARD_SELECT).build().buildException();
}
// Project everything for SELECT cf.*
String cfName = ((FamilyWildcardParseNode) node).getName();
// Delay projecting to scan, as when any other column in the column family gets
// added to the scan, it overwrites that we want to project the entire column
// family. Instead, we do the projection at the end.
// TODO: consider having a ScanUtil.addColumn and ScanUtil.addFamily to work
// around this, as this code depends on this function being the last place where
// columns are projected (which is currently true, but could change).
projectedFamilies.add(Bytes.toBytes(cfName));
if (tableRef.getTable().getType() == PTableType.INDEX && ((FamilyWildcardParseNode) node).isRewrite()) {
projectIndexColumnFamily(context, cfName, tableRef, resolveColumn, projectedExpressions, projectedColumns);
} else {
projectTableColumnFamily(context, cfName, tableRef, resolveColumn, projectedExpressions, projectedColumns);
}
} else {
Expression expression = node.accept(selectVisitor);
projectedExpressions.add(expression);
expression = coerceIfNecessary(index, targetColumns, expression);
if (node instanceof BindParseNode) {
context.getBindManager().addParamMetaData((BindParseNode) node, expression);
}
if (!node.isStateless()) {
if (!selectVisitor.isAggregate() && statement.isAggregate()) {
ExpressionCompiler.throwNonAggExpressionInAggException(expression.toString());
}
}
String columnAlias = aliasedNode.getAlias() != null ? aliasedNode.getAlias() : SchemaUtil.normalizeIdentifier(aliasedNode.getNode().getAlias());
boolean isCaseSensitive = aliasedNode.getAlias() != null ? aliasedNode.isCaseSensitve() : (columnAlias != null ? SchemaUtil.isCaseSensitive(aliasedNode.getNode().getAlias()) : selectVisitor.isCaseSensitive);
String name = columnAlias == null ? expression.toString() : columnAlias;
projectedColumns.add(new ExpressionProjector(name, tableRef.getTableAlias() == null ? (table.getName() == null ? "" : table.getName().getString()) : tableRef.getTableAlias(), expression, isCaseSensitive));
}
selectVisitor.reset();
index++;
}
for (int i = arrayProjectedColumnRefs.size() - 1; i >= 0; i--) {
Expression expression = arrayProjectedColumnRefs.get(i);
Integer count = arrayExpressionCounts.get(expression);
if (count != 0) {
arrayKVRefs.remove(i);
arrayKVFuncs.remove(i);
arrayOldFuncs.remove(i);
}
}
if (arrayKVFuncs.size() > 0 && arrayKVRefs.size() > 0) {
serailizeArrayIndexInformationAndSetInScan(context, arrayKVFuncs, arrayKVRefs);
KeyValueSchemaBuilder builder = new KeyValueSchemaBuilder(0);
for (Expression expression : arrayKVRefs) {
builder.addField(expression);
}
KeyValueSchema kvSchema = builder.build();
ValueBitSet arrayIndexesBitSet = ValueBitSet.newInstance(kvSchema);
builder = new KeyValueSchemaBuilder(0);
for (Expression expression : arrayKVFuncs) {
builder.addField(expression);
}
KeyValueSchema arrayIndexesSchema = builder.build();
Map<Expression, Expression> replacementMap = new HashMap<>();
for (int i = 0; i < arrayOldFuncs.size(); i++) {
Expression function = arrayKVFuncs.get(i);
replacementMap.put(arrayOldFuncs.get(i), new ArrayIndexExpression(i, function.getDataType(), arrayIndexesBitSet, arrayIndexesSchema));
}
ReplaceArrayFunctionExpressionVisitor visitor = new ReplaceArrayFunctionExpressionVisitor(replacementMap);
for (int i = 0; i < projectedColumns.size(); i++) {
ExpressionProjector projector = projectedColumns.get(i);
projectedColumns.set(i, new ExpressionProjector(projector.getName(), tableRef.getTableAlias() == null ? (table.getName() == null ? "" : table.getName().getString()) : tableRef.getTableAlias(), projector.getExpression().accept(visitor), projector.isCaseSensitive()));
}
}
boolean isProjectEmptyKeyValue = false;
if (isWildcard) {
projectAllColumnFamilies(table, scan);
} else {
isProjectEmptyKeyValue = where == null || LiteralExpression.isTrue(where) || where.requiresFinalEvaluation();
for (byte[] family : projectedFamilies) {
projectColumnFamily(table, scan, family);
}
}
// TODO make estimatedByteSize more accurate by counting the joined columns.
int estimatedKeySize = table.getRowKeySchema().getEstimatedValueLength();
int estimatedByteSize = 0;
for (Map.Entry<byte[], NavigableSet<byte[]>> entry : scan.getFamilyMap().entrySet()) {
try {
PColumnFamily family = table.getColumnFamily(entry.getKey());
if (entry.getValue() == null) {
for (PColumn column : family.getColumns()) {
Integer maxLength = column.getMaxLength();
int byteSize = column.getDataType().isFixedWidth() ? maxLength == null ? column.getDataType().getByteSize() : maxLength : RowKeySchema.ESTIMATED_VARIABLE_LENGTH_SIZE;
estimatedByteSize += SizedUtil.KEY_VALUE_SIZE + estimatedKeySize + byteSize;
}
} else {
for (byte[] cq : entry.getValue()) {
PColumn column = family.getPColumnForColumnQualifier(cq);
Integer maxLength = column.getMaxLength();
int byteSize = column.getDataType().isFixedWidth() ? maxLength == null ? column.getDataType().getByteSize() : maxLength : RowKeySchema.ESTIMATED_VARIABLE_LENGTH_SIZE;
estimatedByteSize += SizedUtil.KEY_VALUE_SIZE + estimatedKeySize + byteSize;
}
}
} catch (ColumnFamilyNotFoundException e) {
// Ignore as this can happen for local indexes when the data table has a column family, but there are no covered columns in the family
}
}
return new RowProjector(projectedColumns, Math.max(estimatedKeySize, estimatedByteSize), isProjectEmptyKeyValue, resolver.hasUDFs(), isWildcard);
}
Aggregations