public static SelectStatement create(SelectStatement select, List<AliasedNode> selects) { return new SelectStatement(select.getFrom(), select.getHint(), select.isDistinct(), selects, select.getWhere(), select.getGroupBy(), select.getHaving(), select.getOrderBy(), select.getLimit(), select.getOffset(), select.getBindCount(), select.isAggregate(), select.hasSequence(), select.getSelects(), select.getUdfParseNodes()); }
@Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; DerivedTableNode other = (DerivedTableNode)obj; if (select == null) { if (other.select != null) return false; } else if (!select.equals(other.select)) return false; return true; } }
private static boolean isFlat(SelectStatement select) { return !select.isJoin() && !select.isAggregate() && !select.isDistinct() && !(select.getFrom() instanceof DerivedTableNode) && select.getLimit() == null && select.getOffset() == null; }
public String getQuerySQL(){ //Check if there are parameters to bind. if(select.getBindCount() > 0){ } //TODO: Test if this works return select.toString(); }
public SelectStatement select(SelectStatement statement, List<AliasedNode> select, ParseNode where, List<ParseNode> groupBy, ParseNode having, List<OrderByNode> orderBy) { return select(statement.getFrom(), statement.getHint(), statement.isDistinct(), select, where, groupBy, having, orderBy, statement.getLimit(), statement.getOffset(), statement.getBindCount(), statement.isAggregate(), statement.hasSequence(), statement.getSelects(), statement.getUdfParseNodes()); }
select = StatementNormalizer.normalize(transformedSelect, selectResolver); sameTable = !select.isJoin() && tableRefToBe.equals(selectResolver.getTables().get(0)); if (! (select.isAggregate() || select.isDistinct() || select.getLimit() != null || select.hasSequence()) ) { boolean hasWhereSubquery = select.getWhere() != null && select.getWhere().hasSubquery(); runOnServer = (sameTable || (serverUpsertSelectEnabled && !hasGlobalMutableIndexes)) && isAutoCommit && !select.isJoin() && !hasWhereSubquery && table.getRowTimestampColPos() == -1; hint = HintNode.create(hint, Hint.USE_DATA_OVER_INDEX_TABLE); select = SelectStatement.create(select, hint); .build(); SelectStatement select = SelectStatement.create(SelectStatement.COUNT_ONE, upsert.getHint()); StatementContext statementContext = queryPlan.getContext(); RowProjector aggProjectorToBe = ProjectionCompiler.compile(statementContext, select, GroupBy
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; 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); 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); 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());
TableNode table = FACTORY.namedTable(alias, FACTORY.table(schemaName, tableName),select.getTableSamplingRate()); SelectStatement indexSelect = FACTORY.select(select, table); ColumnResolver resolver = FromCompiler.getResolverForQuery(indexSelect, statement.getConnection()); try { indexSelect = ParseNodeRewriter.rewrite(indexSelect, new IndexExpressionParseNodeRewriter(index, null, statement.getConnection(), indexSelect.getUdfParseNodes())); QueryCompiler compiler = new QueryCompiler(statement, indexSelect, resolver, targetColumns, parallelIteratorFactory, dataPlan.getContext().getSequenceManager(), isProjected, true, dataPlans); && (indexSelect.getWhere() == null || plan.getContext().getScanRanges().getBoundRanges().size() == 1) && !plan.getContext().getDataColumns().isEmpty() && !optimizedSort) { ParseNode where = dataSelect.getWhere(); if (isHinted && where != null) { StatementContext context = new StatementContext(statement, resolver); nodes.add(new ColumnParseNode(null, '"' + column.getName().getString() + '"')); SelectStatement innerSelect = FACTORY.select(indexSelect.getFrom(), indexSelect.getHint(), false, aliasedNodes, where, null, null, null, null, null, indexSelect.getBindCount(), false, indexSelect.hasSequence(), Collections.<SelectStatement>emptyList(), indexSelect.getUdfParseNodes()); ParseNode outerWhere = FACTORY.in(nodes.size() == 1 ? nodes.get(0) : FACTORY.rowValueConstructor(nodes), FACTORY.subquery(innerSelect, false), false, true); ParseNode extractedCondition = whereRewriter.getExtractedCondition(); outerWhere = FACTORY.and(Lists.newArrayList(outerWhere, extractedCondition)); HintNode hint = HintNode.combine(HintNode.subtract(indexSelect.getHint(), new Hint[] {Hint.INDEX, Hint.NO_CHILD_PARENT_JOIN_OPTIMIZATION}), FACTORY.hint("NO_INDEX")); SelectStatement query = FACTORY.select(dataSelect, hint, outerWhere); ColumnResolver queryResolver = FromCompiler.getResolverForQuery(query, statement.getConnection());
public static PTable createProjectedTable(SelectStatement select, StatementContext context) throws SQLException { Preconditions.checkArgument(!select.isJoin()); 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)) PTable table = tableRef.getTable(); for (AliasedNode aliasedNode : select.getSelect()) { ParseNode node = aliasedNode.getNode(); if (node instanceof WildcardParseNode) { for (OrderByNode orderBy : select.getOrderBy()) { orderBy.getNode().accept(visitor);
List<ParseNode> groupByNodes = statement.getGroupBy(); if (statement.isAggregate()) { if (statement.getHint().hasHint(Hint.RANGE_SCAN) || statement.getHaving() != null) { return GroupBy.UNGROUPED_GROUP_BY; groupByNodes = Lists.newArrayListWithExpectedSize(statement.getSelect().size()); for (AliasedNode aliasedNode : statement.getSelect()) { if (aliasedNode.getNode() instanceof DistinctCountParseNode) { } else if (statement.isDistinct()) { groupByNodes = Lists.newArrayListWithExpectedSize(statement.getSelect().size()); for (AliasedNode aliasedNode : statement.getSelect()) {
public static JoinTable compile(PhoenixStatement statement, SelectStatement select, ColumnResolver resolver) throws SQLException { JoinCompiler compiler = new JoinCompiler(statement, select, resolver); JoinTableConstructor constructor = compiler.new JoinTableConstructor(); Pair<Table, List<JoinSpec>> res = select.getFrom().accept(constructor); JoinTable joinTable = res.getSecond() == null ? compiler.new JoinTable(res.getFirst()) : compiler.new JoinTable(res.getFirst(), res.getSecond()); if (select.getWhere() != null) { joinTable.addFilter(select.getWhere()); for (AliasedNode node : select.getSelect()) { node.getNode().accept(generalRefVisitor); if (select.getGroupBy() != null) { for (ParseNode node : select.getGroupBy()) { node.accept(generalRefVisitor); if (select.getHaving() != null) { select.getHaving().accept(generalRefVisitor); if (select.getOrderBy() != null) { for (OrderByNode node : select.getOrderBy()) { node.getNode().accept(generalRefVisitor);
context.setResolver(FromCompiler.getResolverForProjectedTable(projectedTable, context.getConnection(), query.getUdfParseNodes())); joinIds[i] = new ImmutableBytesPtr(emptyByteArray); // place-holder Pair<List<Expression>, List<Expression>> joinConditions = joinSpec.compileJoinConditions(context, subContexts[i], strategy); Integer limit = null; Integer offset = null; if (!query.isAggregate() && !query.isDistinct() && query.getOrderBy().isEmpty()) { limit = plan.getLimit(); offset = plan.getOffset(); context.setResolver(FromCompiler.getResolverForProjectedTable(rhsProjTable, context.getConnection(), rhs.getUdfParseNodes())); ImmutableBytesPtr[] joinIds = new ImmutableBytesPtr[]{new ImmutableBytesPtr(emptyByteArray)}; Pair<List<Expression>, List<Expression>> joinConditions = lastJoinSpec.compileJoinConditions(lhsCtx, context, strategy); PTable projectedTable = needsMerge ? JoinCompiler.joinProjectedTables(rhsProjTable, lhsTable, type == JoinType.Right ? JoinType.Left : type) : rhsProjTable; TupleProjector.serializeProjectorIntoScan(context.getScan(), tupleProjector); context.setResolver(FromCompiler.getResolverForProjectedTable(projectedTable, context.getConnection(), rhs.getUdfParseNodes())); QueryPlan rhsPlan = compileSingleFlatQuery(context, rhs, binds, asSubquery, !asSubquery && type == JoinType.Right, null, !rhsTable.isSubselect() && projectPKColumns ? tupleProjector : null, true); Expression postJoinFilterExpression = joinTable.compilePostFilterExpression(context, rhsTable); Integer limit = null; Integer offset = null; if (!rhs.isAggregate() && !rhs.isDistinct() && rhs.getOrderBy().isEmpty()) { limit = rhsPlan.getLimit(); offset = rhsPlan.getOffset(); new JoinType[]{type == JoinType.Right ? JoinType.Left : type}, new boolean[]{true}, new PTable[]{lhsTable}, new int[]{fieldPosition}, postJoinFilterExpression, QueryUtil.getOffsetLimit(limit, offset)); boolean usePersistentCache = joinTable.getStatement().getHint().hasHint(Hint.USE_PERSISTENT_CACHE); Pair<Expression, Expression> keyRangeExpressions = new Pair<Expression, Expression>(null, null);
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); boolean isGroupby = !subquery.getGroupBy().isEmpty(); boolean isAggregate = subquery.isAggregate(); List<AliasedNode> aliasedNodes = subquery.getSelect(); if (aliasedNodes.size() == 1) { rhsNode = aliasedNodes.get(0).getNode(); 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);
projectedTable = TupleProjectionCompiler.createProjectedTable(select, context); if (projectedTable != null) { context.setResolver(FromCompiler.getResolverForProjectedTable(projectedTable, context.getConnection(), select.getUdfParseNodes())); viewWhere = new SQLParser(table.getViewStatement()).parseQuery().getWhere(); context.setResolver(FromCompiler.getResolver(context.getConnection(), tableRef, select.getUdfParseNodes())); if (plan == null) { ParallelIteratorFactory parallelIteratorFactory = asSubquery ? null : this.parallelIteratorFactory; plan = select.getFrom() == null ? new LiteralResultIterationPlan(context, select, tableRef, projector, limit, offset, orderBy, parallelIteratorFactory) : (select.isAggregate() || select.isDistinct() ? new AggregatePlan(context, select, tableRef, projector, limit, offset, orderBy, parallelIteratorFactory, groupBy, having, dataPlan) plan = select.isAggregate() || select.isDistinct() ? new ClientAggregatePlan(context, planSelect, tableRef, projector, limit, offset, where, orderBy, groupBy, having, plan)
private SelectStatement fixSubqueryStatement(SelectStatement select) { if (!select.isUnion()) return select; // Wrap as a derived table. return NODE_FACTORY.select(NODE_FACTORY.derivedTable(ParseNodeFactory.createTempAlias(), select), HintNode.EMPTY_HINT_NODE, false, select.getSelect(), null, null, null, null, null, null, select.getBindCount(), false, false, Collections.<SelectStatement> emptyList(), select.getUdfParseNodes()); }
boolean isInRowKeyOrder, Expression whereExpression) throws SQLException { List<OrderByNode> orderByNodes = statement.getOrderBy(); if (orderByNodes.isEmpty()) { return OrderBy.EMPTY_ORDER_BY; if (statement.isAggregate() || statement.isDistinct()) { if (statement.isDistinct()) { throw new SQLExceptionInfo.Builder(SQLExceptionCode.ORDER_BY_NOT_IN_SELECT_DISTINCT) .setMessage(expression.toString()).build().buildException(); && context.getCurrentTable().getTable().getType() != PTableType.PROJECTED && context.getCurrentTable().getTable().getType() != PTableType.SUBQUERY && !statement.getHint().hasHint(Hint.FORWARD_SCAN)) { return OrderBy.REV_ROW_KEY_ORDER_BY;
public static boolean isPostFilterConvertible(SelectStatement statement) throws SQLException { return statement.getLimit() == null && (!statement.isAggregate() || !statement.getGroupBy().isEmpty()); }
private SelectStatement applyPostFilters(SelectStatement statement, List<ParseNode> postFilters) throws SQLException { List<ParseNode> postFiltersRewrite = Lists.<ParseNode>newArrayListWithExpectedSize(postFilters.size()); for (ParseNode node : postFilters) { postFiltersRewrite.add(node.accept(this)); } if (statement.getGroupBy().isEmpty()) { ParseNode where = statement.getWhere(); if (where != null) { postFiltersRewrite.add(where); } return NODE_FACTORY.select(statement, combine(postFiltersRewrite)); } ParseNode having = statement.getHaving(); if (having != null) { postFiltersRewrite.add(having); } return NODE_FACTORY.select(statement, statement.getWhere(), combine(postFiltersRewrite)); }
public static SelectStatement flatten(SelectStatement select, PhoenixConnection connection) throws SQLException { TableNode from = select.getFrom(); while (from != null && from instanceof DerivedTableNode) { DerivedTableNode derivedTable = (DerivedTableNode) from; SelectStatement subselect = derivedTable.getSelect(); if (subselect.isUnion()) break; ColumnResolver resolver = FromCompiler.getResolverForQuery(subselect, connection); SubselectRewriter rewriter = new SubselectRewriter(resolver, subselect.getSelect(), derivedTable.getAlias()); SelectStatement ret = rewriter.flatten(select, subselect); if (ret == select) break; select = ret; from = select.getFrom(); } return select; }
private static SelectStatement prependTenantAndViewConstants(PTable table, SelectStatement select, String tenantId, Set<PColumn> addViewColumns, boolean useServerTimestamp) { if ((!table.isMultiTenant() || tenantId == null) && table.getViewIndexId() == null && addViewColumns.isEmpty() && !useServerTimestamp) { return select; } List<AliasedNode> selectNodes = newArrayListWithCapacity(select.getSelect().size() + 1 + addViewColumns.size()); if (table.getViewIndexId() != null) { selectNodes.add(new AliasedNode(null, new LiteralParseNode(table.getViewIndexId()))); } if (table.isMultiTenant() && tenantId != null) { selectNodes.add(new AliasedNode(null, new LiteralParseNode(tenantId))); } selectNodes.addAll(select.getSelect()); for (PColumn column : addViewColumns) { byte[] byteValue = column.getViewConstant(); Object value = column.getDataType().toObject(byteValue, 0, byteValue.length-1); selectNodes.add(new AliasedNode(null, new LiteralParseNode(value))); } if (useServerTimestamp) { PColumn rowTimestampCol = table.getPKColumns().get(table.getRowTimestampColPos()); selectNodes.add(new AliasedNode(null, getNodeForRowTimestampColumn(rowTimestampCol))); } return SelectStatement.create(select, selectNodes); }