use of org.apache.phoenix.parse.AliasedNode in project phoenix by apache.
the class SubselectRewriter method applyOrderBy.
private SelectStatement applyOrderBy(SelectStatement subselectStatement, List<OrderByNode> newOrderByNodes, TableNode subselectAsTableNode) throws SQLException {
ArrayList<OrderByNode> rewrittenNewOrderByNodes = Lists.<OrderByNode>newArrayListWithExpectedSize(newOrderByNodes.size());
for (OrderByNode newOrderByNode : newOrderByNodes) {
ParseNode parseNode = newOrderByNode.getNode();
rewrittenNewOrderByNodes.add(NODE_FACTORY.orderBy(parseNode.accept(this), newOrderByNode.isNullsLast(), newOrderByNode.isAscending()));
}
// in these case,we can safely override subselect's orderBy
if (subselectStatement.getLimit() == null || subselectStatement.getOrderBy() == null || subselectStatement.getOrderBy().isEmpty()) {
return NODE_FACTORY.select(subselectStatement, rewrittenNewOrderByNodes);
}
//then subselectStatement no need to modify
if (this.isOrderByPrefix(subselectStatement, rewrittenNewOrderByNodes)) {
return subselectStatement;
}
//modify the subselect "(select id,code from tableName order by code limit 3) as a" to
//"(select id,code from (select id,code from tableName order by code limit 3) order by id) as a"
List<AliasedNode> newSelectAliasedNodes = createAliasedNodesFromSubselect(subselectStatement, rewrittenNewOrderByNodes);
assert subselectAsTableNode instanceof DerivedTableNode;
//set the subselect alias to null.
subselectAsTableNode = NODE_FACTORY.derivedTable(null, ((DerivedTableNode) subselectAsTableNode).getSelect());
return NODE_FACTORY.select(subselectAsTableNode, HintNode.EMPTY_HINT_NODE, false, newSelectAliasedNodes, null, null, null, rewrittenNewOrderByNodes, null, null, 0, false, subselectStatement.hasSequence(), Collections.<SelectStatement>emptyList(), subselectStatement.getUdfParseNodes());
}
use of org.apache.phoenix.parse.AliasedNode in project phoenix by apache.
the class SubselectRewriter method flatten.
private SelectStatement flatten(SelectStatement select, SelectStatement subselect) throws SQLException {
// Replace aliases in sub-select first.
subselect = ParseNodeRewriter.rewrite(subselect, this);
ParseNode whereRewrite = subselect.getWhere();
List<ParseNode> groupByRewrite = subselect.getGroupBy();
ParseNode havingRewrite = subselect.getHaving();
List<OrderByNode> orderByRewrite = subselect.getOrderBy();
LimitNode limitRewrite = subselect.getLimit();
OffsetNode offsetRewrite = subselect.getOffset();
HintNode hintRewrite = subselect.getHint();
boolean isDistinctRewrite = subselect.isDistinct();
boolean isAggregateRewrite = subselect.isAggregate();
ParseNode where = select.getWhere();
if (where != null) {
if (subselect.getLimit() != null || (subselect.isAggregate() && subselect.getGroupBy().isEmpty())) {
return select;
}
ParseNode postFilter = where.accept(this);
if (subselect.getGroupBy().isEmpty()) {
whereRewrite = whereRewrite == null ? postFilter : NODE_FACTORY.and(Arrays.<ParseNode>asList(whereRewrite, postFilter));
} else {
havingRewrite = havingRewrite == null ? postFilter : NODE_FACTORY.and(Arrays.<ParseNode>asList(havingRewrite, postFilter));
}
}
if (select.isDistinct()) {
if (subselect.getLimit() != null || subselect.isAggregate() || subselect.isDistinct()) {
return select;
}
isDistinctRewrite = true;
orderByRewrite = null;
}
if (select.isAggregate()) {
if (subselect.getLimit() != null || subselect.isAggregate() || subselect.isDistinct()) {
return select;
}
isAggregateRewrite = true;
orderByRewrite = null;
}
List<ParseNode> groupBy = select.getGroupBy();
if (!groupBy.isEmpty()) {
if (subselect.getLimit() != null || subselect.isAggregate() || subselect.isDistinct()) {
return select;
}
groupByRewrite = Lists.<ParseNode>newArrayListWithExpectedSize(groupBy.size());
for (ParseNode node : groupBy) {
groupByRewrite.add(node.accept(this));
}
if (select.getHaving() != null) {
havingRewrite = select.getHaving().accept(this);
}
orderByRewrite = null;
}
List<AliasedNode> selectNodes = select.getSelect();
List<AliasedNode> selectNodesRewrite = Lists.newArrayListWithExpectedSize(selectNodes.size());
for (AliasedNode aliasedNode : selectNodes) {
ParseNode node = aliasedNode.getNode();
if (node instanceof WildcardParseNode || (node instanceof TableWildcardParseNode && ((TableWildcardParseNode) node).getTableName().equals(tableAlias))) {
for (AliasedNode aNode : subselect.getSelect()) {
String alias = aNode.getAlias();
String aliasRewrite = alias == null ? null : SchemaUtil.getColumnName(tableAlias, alias);
selectNodesRewrite.add(NODE_FACTORY.aliasedNode(aliasRewrite, aNode.getNode()));
}
} else {
selectNodesRewrite.add(NODE_FACTORY.aliasedNode(aliasedNode.getAlias(), node.accept(this)));
}
}
List<OrderByNode> orderBy = select.getOrderBy();
if (!orderBy.isEmpty()) {
if (subselect.getLimit() != null) {
return select;
}
orderByRewrite = Lists.newArrayListWithExpectedSize(orderBy.size());
for (OrderByNode orderByNode : orderBy) {
ParseNode node = orderByNode.getNode();
orderByRewrite.add(NODE_FACTORY.orderBy(node.accept(this), orderByNode.isNullsLast(), orderByNode.isAscending()));
}
}
OffsetNode offset = select.getOffset();
if (offsetRewrite != null || (limitRewrite != null && offset != null)) {
return select;
} else {
offsetRewrite = offset;
}
LimitNode limit = select.getLimit();
if (limit != null) {
if (limitRewrite == null) {
limitRewrite = limit;
} else {
Integer limitValue = LimitCompiler.compile(null, select);
Integer limitValueSubselect = LimitCompiler.compile(null, subselect);
if (limitValue != null && limitValueSubselect != null) {
limitRewrite = limitValue < limitValueSubselect ? limit : limitRewrite;
} else {
return select;
}
}
}
HintNode hint = select.getHint();
if (hint != null) {
hintRewrite = hintRewrite == null ? hint : HintNode.combine(hint, hintRewrite);
}
SelectStatement stmt = NODE_FACTORY.select(subselect.getFrom(), hintRewrite, isDistinctRewrite, selectNodesRewrite, whereRewrite, groupByRewrite, havingRewrite, orderByRewrite, limitRewrite, offsetRewrite, select.getBindCount(), isAggregateRewrite, select.hasSequence(), select.getSelects(), select.getUdfParseNodes());
if (tableAlias != null) {
this.removeAlias = true;
stmt = ParseNodeRewriter.rewrite(stmt, this);
}
return stmt;
}
use of org.apache.phoenix.parse.AliasedNode in project phoenix by apache.
the class SubselectRewriter method createAliasedNodesFromSubselect.
/**
* create new aliasedNodes from subSelectStatement's select alias.
* @param subSelectStatement
* @param rewrittenOrderByNodes
* @return
*/
private List<AliasedNode> createAliasedNodesFromSubselect(SelectStatement subSelectStatement, ArrayList<OrderByNode> rewrittenOrderByNodes) throws SQLException {
List<AliasedNode> selectAliasedNodes = subSelectStatement.getSelect();
List<AliasedNode> newSelectAliasedNodes = new ArrayList<AliasedNode>(selectAliasedNodes.size());
Map<ParseNode, Integer> rewrittenOrderByParseNodeToIndex = new HashMap<ParseNode, Integer>(rewrittenOrderByNodes.size());
for (int index = 0; index < rewrittenOrderByNodes.size(); index++) {
OrderByNode rewrittenOrderByNode = rewrittenOrderByNodes.get(index);
rewrittenOrderByParseNodeToIndex.put(rewrittenOrderByNode.getNode(), Integer.valueOf(index));
}
for (AliasedNode selectAliasedNode : selectAliasedNodes) {
String selectAliasName = selectAliasedNode.getAlias();
ParseNode oldSelectAliasParseNode = selectAliasedNode.getNode();
if (selectAliasName == null) {
selectAliasName = SchemaUtil.normalizeIdentifier(oldSelectAliasParseNode.getAlias());
}
//we must has alias for sum(code)
if (selectAliasName == null) {
throw new SQLExceptionInfo.Builder(SQLExceptionCode.SUBQUERY_SELECT_LIST_COLUMN_MUST_HAS_ALIAS).setMessage("the subquery is:" + subSelectStatement).build().buildException();
}
ColumnParseNode newColumnParseNode = NODE_FACTORY.column(null, selectAliasName, selectAliasName);
Integer index = rewrittenOrderByParseNodeToIndex.get(oldSelectAliasParseNode);
if (index != null) {
//replace the rewrittenOrderByNode's child to newColumnParseNode
OrderByNode oldOrderByNode = rewrittenOrderByNodes.get(index);
rewrittenOrderByNodes.set(index, NODE_FACTORY.orderBy(newColumnParseNode, oldOrderByNode.isNullsLast(), oldOrderByNode.isAscending()));
}
AliasedNode newSelectAliasNode = NODE_FACTORY.aliasedNode(null, newColumnParseNode);
newSelectAliasedNodes.add(newSelectAliasNode);
}
return newSelectAliasedNodes;
}
use of org.apache.phoenix.parse.AliasedNode in project phoenix by apache.
the class TupleProjectionCompiler method createProjectedTable.
public static PTable createProjectedTable(SelectStatement select, StatementContext context) throws SQLException {
Preconditions.checkArgument(!select.isJoin());
// Non-group-by or group-by aggregations will create its own projected result.
if (select.getInnerSelectStatement() != null || select.getFrom() == null || select.isAggregate() || select.isDistinct() || (context.getResolver().getTables().get(0).getTable().getType() != PTableType.TABLE && context.getResolver().getTables().get(0).getTable().getType() != PTableType.INDEX && context.getResolver().getTables().get(0).getTable().getType() != PTableType.VIEW))
return null;
List<PColumn> projectedColumns = new ArrayList<PColumn>();
boolean isWildcard = false;
Set<String> families = new HashSet<String>();
ColumnRefVisitor visitor = new ColumnRefVisitor(context);
TableRef tableRef = context.getCurrentTable();
PTable table = tableRef.getTable();
for (AliasedNode aliasedNode : select.getSelect()) {
ParseNode node = aliasedNode.getNode();
if (node instanceof WildcardParseNode) {
if (((WildcardParseNode) node).isRewrite()) {
TableRef parentTableRef = FromCompiler.getResolver(NODE_FACTORY.namedTable(null, TableName.create(table.getSchemaName().getString(), table.getParentTableName().getString())), context.getConnection()).resolveTable(table.getSchemaName().getString(), table.getParentTableName().getString());
for (PColumn column : parentTableRef.getTable().getColumns()) {
NODE_FACTORY.column(null, '"' + IndexUtil.getIndexColumnName(column) + '"', null).accept(visitor);
}
}
isWildcard = true;
} else if (node instanceof FamilyWildcardParseNode) {
FamilyWildcardParseNode familyWildcardNode = (FamilyWildcardParseNode) node;
String familyName = familyWildcardNode.getName();
if (familyWildcardNode.isRewrite()) {
TableRef parentTableRef = FromCompiler.getResolver(NODE_FACTORY.namedTable(null, TableName.create(table.getSchemaName().getString(), table.getParentTableName().getString())), context.getConnection()).resolveTable(table.getSchemaName().getString(), table.getParentTableName().getString());
for (PColumn column : parentTableRef.getTable().getColumnFamily(familyName).getColumns()) {
NODE_FACTORY.column(null, '"' + IndexUtil.getIndexColumnName(column) + '"', null).accept(visitor);
}
}
families.add(familyName);
} else {
node.accept(visitor);
}
}
if (!isWildcard) {
for (OrderByNode orderBy : select.getOrderBy()) {
orderBy.getNode().accept(visitor);
}
}
boolean hasSaltingColumn = table.getBucketNum() != null;
int position = hasSaltingColumn ? 1 : 0;
// Always project PK columns first in case there are some PK columns added by alter table.
for (int i = position; i < table.getPKColumns().size(); i++) {
PColumn sourceColumn = table.getPKColumns().get(i);
ColumnRef sourceColumnRef = new ColumnRef(tableRef, sourceColumn.getPosition());
PColumn column = new ProjectedColumn(sourceColumn.getName(), sourceColumn.getFamilyName(), position++, sourceColumn.isNullable(), sourceColumnRef, null);
projectedColumns.add(column);
}
for (PColumn sourceColumn : table.getColumns()) {
if (SchemaUtil.isPKColumn(sourceColumn))
continue;
ColumnRef sourceColumnRef = new ColumnRef(tableRef, sourceColumn.getPosition());
if (!isWildcard && !visitor.columnRefSet.contains(sourceColumnRef) && !families.contains(sourceColumn.getFamilyName().getString()))
continue;
PColumn column = new ProjectedColumn(sourceColumn.getName(), sourceColumn.getFamilyName(), position++, sourceColumn.isNullable(), sourceColumnRef, sourceColumn.getColumnQualifierBytes());
projectedColumns.add(column);
// Wildcard or FamilyWildcard will be handled by ProjectionCompiler.
if (!isWildcard && !families.contains(sourceColumn.getFamilyName())) {
EncodedColumnsUtil.setColumns(column, table, context.getScan());
}
}
// add LocalIndexDataColumnRef
for (LocalIndexDataColumnRef sourceColumnRef : visitor.localIndexColumnRefSet) {
PColumn column = new ProjectedColumn(sourceColumnRef.getColumn().getName(), sourceColumnRef.getColumn().getFamilyName(), position++, sourceColumnRef.getColumn().isNullable(), sourceColumnRef, sourceColumnRef.getColumn().getColumnQualifierBytes());
projectedColumns.add(column);
}
return PTableImpl.makePTable(table.getTenantId(), table.getSchemaName(), table.getTableName(), PTableType.PROJECTED, table.getIndexState(), table.getTimeStamp(), table.getSequenceNumber(), table.getPKName(), table.getBucketNum(), projectedColumns, table.getParentSchemaName(), table.getParentName(), table.getIndexes(), table.isImmutableRows(), Collections.<PName>emptyList(), null, null, table.isWALDisabled(), table.isMultiTenant(), table.getStoreNulls(), table.getViewType(), table.getViewIndexId(), table.getIndexType(), table.rowKeyOrderOptimizable(), table.isTransactional(), table.getUpdateCacheFrequency(), table.getIndexDisableTimestamp(), table.isNamespaceMapped(), table.getAutoPartitionSeqName(), table.isAppendOnlySchema(), table.getImmutableStorageScheme(), table.getEncodingScheme(), table.getEncodedCQCounter(), table.useStatsForParallelization());
}
use of org.apache.phoenix.parse.AliasedNode in project phoenix by apache.
the class SubqueryRewriter method visitLeave.
@Override
public ParseNode visitLeave(ComparisonParseNode node, List<ParseNode> l) throws SQLException {
boolean isTopNode = topNode == node;
if (isTopNode) {
topNode = null;
}
ParseNode secondChild = l.get(1);
if (!(secondChild instanceof SubqueryParseNode)) {
return super.visitLeave(node, l);
}
SubqueryParseNode subqueryNode = (SubqueryParseNode) secondChild;
SelectStatement subquery = fixSubqueryStatement(subqueryNode.getSelectNode());
String rhsTableAlias = ParseNodeFactory.createTempAlias();
JoinConditionExtractor conditionExtractor = new JoinConditionExtractor(subquery, resolver, connection, rhsTableAlias);
ParseNode where = subquery.getWhere() == null ? null : subquery.getWhere().accept(conditionExtractor);
if (where == subquery.getWhere()) {
// non-correlated comparison subquery, add LIMIT 2, expectSingleRow = true
subquery = NODE_FACTORY.select(subquery, NODE_FACTORY.limit(NODE_FACTORY.literal(2)));
subqueryNode = NODE_FACTORY.subquery(subquery, true);
l = Lists.newArrayList(l.get(0), subqueryNode);
node = NODE_FACTORY.comparison(node.getFilterOp(), l.get(0), l.get(1));
return super.visitLeave(node, l);
}
ParseNode rhsNode = null;
boolean isGroupby = !subquery.getGroupBy().isEmpty();
boolean isAggregate = subquery.isAggregate();
List<AliasedNode> aliasedNodes = subquery.getSelect();
if (aliasedNodes.size() == 1) {
rhsNode = aliasedNodes.get(0).getNode();
} else {
List<ParseNode> nodes = Lists.<ParseNode>newArrayListWithExpectedSize(aliasedNodes.size());
for (AliasedNode aliasedNode : aliasedNodes) {
nodes.add(aliasedNode.getNode());
}
rhsNode = NODE_FACTORY.rowValueConstructor(nodes);
}
List<AliasedNode> additionalSelectNodes = conditionExtractor.getAdditionalSelectNodes();
List<AliasedNode> selectNodes = Lists.newArrayListWithExpectedSize(additionalSelectNodes.size() + 1);
selectNodes.add(NODE_FACTORY.aliasedNode(ParseNodeFactory.createTempAlias(), rhsNode));
selectNodes.addAll(additionalSelectNodes);
if (!isAggregate) {
subquery = NODE_FACTORY.select(subquery, subquery.isDistinct(), selectNodes, where);
} else {
List<ParseNode> groupbyNodes = Lists.newArrayListWithExpectedSize(additionalSelectNodes.size() + subquery.getGroupBy().size());
for (AliasedNode aliasedNode : additionalSelectNodes) {
groupbyNodes.add(aliasedNode.getNode());
}
groupbyNodes.addAll(subquery.getGroupBy());
subquery = NODE_FACTORY.select(subquery, subquery.isDistinct(), selectNodes, where, groupbyNodes, true);
}
ParseNode onNode = conditionExtractor.getJoinCondition();
TableNode rhsTable = NODE_FACTORY.derivedTable(rhsTableAlias, subquery);
JoinType joinType = isTopNode ? JoinType.Inner : JoinType.Left;
ParseNode ret = NODE_FACTORY.comparison(node.getFilterOp(), l.get(0), NODE_FACTORY.column(NODE_FACTORY.table(null, rhsTableAlias), selectNodes.get(0).getAlias(), null));
tableNode = NODE_FACTORY.join(joinType, tableNode, rhsTable, onNode, !isAggregate || isGroupby);
return ret;
}
Aggregations