use of org.apache.phoenix.parse.SubqueryParseNode 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.SubqueryParseNode 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.SubqueryParseNode in project phoenix by apache.
the class GenSubqueryParamValuesRewriter method visitLeave.
@Override
public ParseNode visitLeave(ComparisonParseNode node, List<ParseNode> l) throws SQLException {
if (!(l.get(1) instanceof SubqueryParseNode)) {
super.visitLeave(node, l);
}
ParseNode lhs = l.get(0);
List<ParseNode> rhs = generateDummyValues(lhs, false);
List<ParseNode> children = new ArrayList<ParseNode>();
children.add(lhs);
children.add(rhs.get(0));
return super.visitLeave(node, children);
}
use of org.apache.phoenix.parse.SubqueryParseNode in project phoenix by apache.
the class SubqueryRewriter method visitLeave.
@Override
public ParseNode visitLeave(InParseNode node, List<ParseNode> l) throws SQLException {
boolean isTopNode = topNode == node;
if (isTopNode) {
topNode = null;
}
SubqueryParseNode subqueryNode = (SubqueryParseNode) l.get(1);
SelectStatement subquery = fixSubqueryStatement(subqueryNode.getSelectNode());
String rhsTableAlias = ParseNodeFactory.createTempAlias();
List<AliasedNode> selectNodes = fixAliasedNodes(subquery.getSelect(), true);
subquery = NODE_FACTORY.select(subquery, !node.isSubqueryDistinct(), selectNodes);
ParseNode onNode = getJoinConditionNode(l.get(0), selectNodes, rhsTableAlias);
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.SubqueryParseNode in project phoenix by apache.
the class SubqueryRewriter method leaveArrayComparisonNode.
protected List<ParseNode> leaveArrayComparisonNode(ParseNode node, List<ParseNode> l) throws SQLException {
boolean isTopNode = topNode == node;
if (isTopNode) {
topNode = null;
}
ParseNode firstChild = l.get(0);
if (!(firstChild instanceof SubqueryParseNode)) {
return l;
}
SubqueryParseNode subqueryNode = (SubqueryParseNode) firstChild;
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 any/all comparison subquery
return l;
}
ParseNode rhsNode = null;
boolean isNonGroupByAggregate = subquery.getGroupBy().isEmpty() && subquery.isAggregate();
List<AliasedNode> aliasedNodes = subquery.getSelect();
String derivedTableAlias = null;
if (!subquery.getGroupBy().isEmpty()) {
derivedTableAlias = ParseNodeFactory.createTempAlias();
aliasedNodes = fixAliasedNodes(aliasedNodes, false);
}
if (aliasedNodes.size() == 1) {
rhsNode = derivedTableAlias == null ? aliasedNodes.get(0).getNode() : NODE_FACTORY.column(NODE_FACTORY.table(null, derivedTableAlias), aliasedNodes.get(0).getAlias(), null);
} else {
List<ParseNode> nodes = Lists.<ParseNode>newArrayListWithExpectedSize(aliasedNodes.size());
for (AliasedNode aliasedNode : aliasedNodes) {
nodes.add(derivedTableAlias == null ? aliasedNode.getNode() : NODE_FACTORY.column(NODE_FACTORY.table(null, derivedTableAlias), aliasedNode.getAlias(), null));
}
rhsNode = NODE_FACTORY.rowValueConstructor(nodes);
}
if (!isNonGroupByAggregate) {
rhsNode = NODE_FACTORY.function(DistinctValueAggregateFunction.NAME, Collections.singletonList(rhsNode));
}
List<AliasedNode> additionalSelectNodes = conditionExtractor.getAdditionalSelectNodes();
List<AliasedNode> selectNodes = Lists.newArrayListWithExpectedSize(additionalSelectNodes.size() + 1);
selectNodes.add(NODE_FACTORY.aliasedNode(ParseNodeFactory.createTempAlias(), rhsNode));
selectNodes.addAll(additionalSelectNodes);
List<ParseNode> groupbyNodes = Lists.newArrayListWithExpectedSize(additionalSelectNodes.size());
for (AliasedNode aliasedNode : additionalSelectNodes) {
groupbyNodes.add(aliasedNode.getNode());
}
if (derivedTableAlias == null) {
subquery = NODE_FACTORY.select(subquery, false, selectNodes, where, groupbyNodes, true);
} else {
List<ParseNode> derivedTableGroupBy = Lists.newArrayListWithExpectedSize(subquery.getGroupBy().size() + groupbyNodes.size());
derivedTableGroupBy.addAll(groupbyNodes);
derivedTableGroupBy.addAll(subquery.getGroupBy());
List<AliasedNode> derivedTableSelect = Lists.newArrayListWithExpectedSize(aliasedNodes.size() + selectNodes.size() - 1);
derivedTableSelect.addAll(aliasedNodes);
for (int i = 1; i < selectNodes.size(); i++) {
AliasedNode aliasedNode = selectNodes.get(i);
String alias = ParseNodeFactory.createTempAlias();
derivedTableSelect.add(NODE_FACTORY.aliasedNode(alias, aliasedNode.getNode()));
aliasedNode = NODE_FACTORY.aliasedNode(aliasedNode.getAlias(), NODE_FACTORY.column(NODE_FACTORY.table(null, derivedTableAlias), alias, null));
selectNodes.set(i, aliasedNode);
groupbyNodes.set(i - 1, aliasedNode.getNode());
}
SelectStatement derivedTableStmt = NODE_FACTORY.select(subquery, subquery.isDistinct(), derivedTableSelect, where, derivedTableGroupBy, true);
subquery = NODE_FACTORY.select(NODE_FACTORY.derivedTable(derivedTableAlias, derivedTableStmt), subquery.getHint(), false, selectNodes, null, groupbyNodes, null, Collections.<OrderByNode>emptyList(), null, null, subquery.getBindCount(), true, false, Collections.<SelectStatement>emptyList(), subquery.getUdfParseNodes());
}
ParseNode onNode = conditionExtractor.getJoinCondition();
TableNode rhsTable = NODE_FACTORY.derivedTable(rhsTableAlias, subquery);
JoinType joinType = isTopNode ? JoinType.Inner : JoinType.Left;
tableNode = NODE_FACTORY.join(joinType, tableNode, rhsTable, onNode, false);
firstChild = NODE_FACTORY.column(NODE_FACTORY.table(null, rhsTableAlias), selectNodes.get(0).getAlias(), null);
if (isNonGroupByAggregate) {
firstChild = NODE_FACTORY.upsertStmtArrayNode(Collections.singletonList(firstChild));
}
ComparisonParseNode secondChild = (ComparisonParseNode) l.get(1);
secondChild = NODE_FACTORY.comparison(secondChild.getFilterOp(), secondChild.getLHS(), NODE_FACTORY.elementRef(Lists.newArrayList(firstChild, NODE_FACTORY.literal(1))));
return Lists.newArrayList(firstChild, secondChild);
}
Aggregations