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 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;
}
use of org.apache.phoenix.parse.AliasedNode in project phoenix by apache.
the class SubqueryRewriter method visitLeave.
@Override
public ParseNode visitLeave(ExistsParseNode node, List<ParseNode> l) throws SQLException {
boolean isTopNode = topNode == node;
if (isTopNode) {
topNode = null;
}
SubqueryParseNode subqueryNode = (SubqueryParseNode) l.get(0);
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 EXISTS subquery, add LIMIT 1
subquery = NODE_FACTORY.select(subquery, NODE_FACTORY.limit(NODE_FACTORY.literal(1)));
subqueryNode = NODE_FACTORY.subquery(subquery, false);
node = NODE_FACTORY.exists(subqueryNode, node.isNegate());
return super.visitLeave(node, Collections.<ParseNode>singletonList(subqueryNode));
}
List<AliasedNode> additionalSelectNodes = conditionExtractor.getAdditionalSelectNodes();
List<AliasedNode> selectNodes = Lists.newArrayListWithExpectedSize(additionalSelectNodes.size() + 1);
selectNodes.add(NODE_FACTORY.aliasedNode(ParseNodeFactory.createTempAlias(), LiteralParseNode.ONE));
selectNodes.addAll(additionalSelectNodes);
subquery = NODE_FACTORY.select(subquery, true, selectNodes, where);
ParseNode onNode = conditionExtractor.getJoinCondition();
TableNode rhsTable = NODE_FACTORY.derivedTable(rhsTableAlias, subquery);
JoinType joinType = isTopNode ? (node.isNegate() ? JoinType.Anti : JoinType.Semi) : JoinType.Left;
ParseNode ret = isTopNode ? null : NODE_FACTORY.isNull(NODE_FACTORY.column(NODE_FACTORY.table(null, rhsTableAlias), selectNodes.get(0).getAlias(), null), !node.isNegate());
tableNode = NODE_FACTORY.join(joinType, tableNode, rhsTable, onNode, false);
return ret;
}
use of org.apache.phoenix.parse.AliasedNode 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.AliasedNode 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;
}
Aggregations