Search in sources :

Example 11 with SelectStatement

use of org.apache.phoenix.parse.SelectStatement in project phoenix by apache.

the class QueryCompiler method compileJoinQuery.

/**
 * Call compileJoinQuery() for join queries recursively down to the leaf JoinTable nodes.
 * If it is a leaf node, call compileSingleFlatQuery() or compileSubquery(), otherwise:
 *      1) If option COST_BASED_OPTIMIZER_ENABLED is on and stats are available, return the
 *         join plan with the best cost. Note that the "best" plan is only locally optimal,
 *         and might or might not be globally optimal.
 *      2) Otherwise, return the join plan compiled with the default strategy.
 * @see JoinCompiler.JoinTable#getApplicableJoinStrategies()
 */
protected QueryPlan compileJoinQuery(StatementContext context, List<Object> binds, JoinTable joinTable, boolean asSubquery, boolean projectPKColumns, List<OrderByNode> orderBy) throws SQLException {
    if (joinTable.getJoinSpecs().isEmpty()) {
        Table table = joinTable.getTable();
        SelectStatement subquery = table.getAsSubquery(orderBy);
        if (!table.isSubselect()) {
            context.setCurrentTable(table.getTableRef());
            PTable projectedTable = table.createProjectedTable(!projectPKColumns, context);
            TupleProjector projector = new TupleProjector(projectedTable);
            TupleProjector.serializeProjectorIntoScan(context.getScan(), projector);
            context.setResolver(FromCompiler.getResolverForProjectedTable(projectedTable, context.getConnection(), subquery.getUdfParseNodes()));
            table.projectColumns(context.getScan());
            return compileSingleFlatQuery(context, subquery, binds, asSubquery, !asSubquery, null, projectPKColumns ? projector : null, true);
        }
        QueryPlan plan = compileSubquery(subquery, false);
        PTable projectedTable = table.createProjectedTable(plan.getProjector());
        context.setResolver(FromCompiler.getResolverForProjectedTable(projectedTable, context.getConnection(), subquery.getUdfParseNodes()));
        return new TupleProjectionPlan(plan, new TupleProjector(plan.getProjector()), table.compilePostFilterExpression(context));
    }
    List<JoinCompiler.Strategy> strategies = joinTable.getApplicableJoinStrategies();
    assert strategies.size() > 0;
    if (!costBased || strategies.size() == 1) {
        return compileJoinQuery(strategies.get(0), context, binds, joinTable, asSubquery, projectPKColumns, orderBy);
    }
    QueryPlan bestPlan = null;
    Cost bestCost = null;
    for (JoinCompiler.Strategy strategy : strategies) {
        StatementContext newContext = new StatementContext(context.getStatement(), context.getResolver(), new Scan(), context.getSequenceManager());
        QueryPlan plan = compileJoinQuery(strategy, newContext, binds, joinTable, asSubquery, projectPKColumns, orderBy);
        Cost cost = plan.getCost();
        if (bestPlan == null || cost.compareTo(bestCost) < 0) {
            bestPlan = plan;
            bestCost = cost;
        }
    }
    context.setResolver(bestPlan.getContext().getResolver());
    context.setCurrentTable(bestPlan.getContext().getCurrentTable());
    return bestPlan;
}
Also used : Table(org.apache.phoenix.compile.JoinCompiler.Table) JoinTable(org.apache.phoenix.compile.JoinCompiler.JoinTable) PTable(org.apache.phoenix.schema.PTable) TupleProjector(org.apache.phoenix.execute.TupleProjector) TupleProjectionPlan(org.apache.phoenix.execute.TupleProjectionPlan) Cost(org.apache.phoenix.optimize.Cost) PTable(org.apache.phoenix.schema.PTable) SelectStatement(org.apache.phoenix.parse.SelectStatement) Scan(org.apache.hadoop.hbase.client.Scan)

Example 12 with SelectStatement

use of org.apache.phoenix.parse.SelectStatement in project phoenix by apache.

the class MetaDataClient method getParentOfView.

private PTable getParentOfView(PTable view) throws SQLException {
    // TODO just use view.getParentName().getString() after implementing https://issues.apache.org/jira/browse/PHOENIX-2114
    SelectStatement select = new SQLParser(view.getViewStatement()).parseQuery();
    String parentName = SchemaUtil.normalizeFullTableName(select.getFrom().toString().trim());
    return connection.getTable(new PTableKey(view.getTenantId(), parentName));
}
Also used : SelectStatement(org.apache.phoenix.parse.SelectStatement) SQLParser(org.apache.phoenix.parse.SQLParser)

Example 13 with SelectStatement

use of org.apache.phoenix.parse.SelectStatement in project phoenix by apache.

the class JoinCompiler method optimize.

public static SelectStatement optimize(PhoenixStatement statement, SelectStatement select, final ColumnResolver resolver) throws SQLException {
    TableRef groupByTableRef = null;
    TableRef orderByTableRef = null;
    if (select.getGroupBy() != null && !select.getGroupBy().isEmpty()) {
        ColumnRefParseNodeVisitor groupByVisitor = new ColumnRefParseNodeVisitor(resolver, statement.getConnection());
        for (ParseNode node : select.getGroupBy()) {
            node.accept(groupByVisitor);
        }
        Set<TableRef> set = groupByVisitor.getTableRefSet();
        if (set.size() == 1) {
            groupByTableRef = set.iterator().next();
        }
    } else if (select.getOrderBy() != null && !select.getOrderBy().isEmpty()) {
        ColumnRefParseNodeVisitor orderByVisitor = new ColumnRefParseNodeVisitor(resolver, statement.getConnection());
        for (OrderByNode node : select.getOrderBy()) {
            node.getNode().accept(orderByVisitor);
        }
        Set<TableRef> set = orderByVisitor.getTableRefSet();
        if (set.size() == 1) {
            orderByTableRef = set.iterator().next();
        }
    }
    JoinTable join = compile(statement, select, resolver);
    if (groupByTableRef != null || orderByTableRef != null) {
        QueryCompiler compiler = new QueryCompiler(statement, select, resolver, false);
        List<Object> binds = statement.getParameters();
        StatementContext ctx = new StatementContext(statement, resolver, new Scan(), new SequenceManager(statement));
        QueryPlan plan = compiler.compileJoinQuery(ctx, binds, join, false, false, null);
        TableRef table = plan.getTableRef();
        if (groupByTableRef != null && !groupByTableRef.equals(table)) {
            groupByTableRef = null;
        }
        if (orderByTableRef != null && !orderByTableRef.equals(table)) {
            orderByTableRef = null;
        }
    }
    final Map<TableRef, TableRef> replacement = new HashMap<TableRef, TableRef>();
    for (Table table : join.getTables()) {
        if (table.isSubselect())
            continue;
        TableRef tableRef = table.getTableRef();
        List<ParseNode> groupBy = tableRef.equals(groupByTableRef) ? select.getGroupBy() : null;
        List<OrderByNode> orderBy = tableRef.equals(orderByTableRef) ? select.getOrderBy() : null;
        SelectStatement stmt = getSubqueryForOptimizedPlan(select.getHint(), table.getDynamicColumns(), tableRef, join.getColumnRefs(), table.getPreFiltersCombined(), groupBy, orderBy, table.isWildCardSelect(), select.hasSequence(), select.getUdfParseNodes());
        QueryPlan plan = statement.getConnection().getQueryServices().getOptimizer().optimize(statement, stmt);
        if (!plan.getTableRef().equals(tableRef)) {
            replacement.put(tableRef, plan.getTableRef());
        }
    }
    if (replacement.isEmpty())
        return select;
    TableNode from = select.getFrom();
    TableNode newFrom = from.accept(new TableNodeVisitor<TableNode>() {

        private TableRef resolveTable(String alias, TableName name) throws SQLException {
            if (alias != null)
                return resolver.resolveTable(null, alias);
            return resolver.resolveTable(name.getSchemaName(), name.getTableName());
        }

        private TableName getReplacedTableName(TableRef tableRef) {
            String schemaName = tableRef.getTable().getSchemaName().getString();
            return TableName.create(schemaName.length() == 0 ? null : schemaName, tableRef.getTable().getTableName().getString());
        }

        @Override
        public TableNode visit(BindTableNode boundTableNode) throws SQLException {
            TableRef tableRef = resolveTable(boundTableNode.getAlias(), boundTableNode.getName());
            TableRef replaceRef = replacement.get(tableRef);
            if (replaceRef == null)
                return boundTableNode;
            String alias = boundTableNode.getAlias();
            return NODE_FACTORY.bindTable(alias == null ? null : '"' + alias + '"', getReplacedTableName(replaceRef));
        }

        @Override
        public TableNode visit(JoinTableNode joinNode) throws SQLException {
            TableNode lhs = joinNode.getLHS();
            TableNode rhs = joinNode.getRHS();
            TableNode lhsReplace = lhs.accept(this);
            TableNode rhsReplace = rhs.accept(this);
            if (lhs == lhsReplace && rhs == rhsReplace)
                return joinNode;
            return NODE_FACTORY.join(joinNode.getType(), lhsReplace, rhsReplace, joinNode.getOnNode(), joinNode.isSingleValueOnly());
        }

        @Override
        public TableNode visit(NamedTableNode namedTableNode) throws SQLException {
            TableRef tableRef = resolveTable(namedTableNode.getAlias(), namedTableNode.getName());
            TableRef replaceRef = replacement.get(tableRef);
            if (replaceRef == null)
                return namedTableNode;
            String alias = namedTableNode.getAlias();
            return NODE_FACTORY.namedTable(alias == null ? null : '"' + alias + '"', getReplacedTableName(replaceRef), namedTableNode.getDynamicColumns());
        }

        @Override
        public TableNode visit(DerivedTableNode subselectNode) throws SQLException {
            return subselectNode;
        }
    });
    SelectStatement indexSelect = IndexStatementRewriter.translate(NODE_FACTORY.select(select, newFrom), resolver, replacement);
    for (TableRef indexTableRef : replacement.values()) {
        // replace expressions with corresponding matching columns for functional indexes
        indexSelect = ParseNodeRewriter.rewrite(indexSelect, new IndexExpressionParseNodeRewriter(indexTableRef.getTable(), indexTableRef.getTableAlias(), statement.getConnection(), indexSelect.getUdfParseNodes()));
    }
    return indexSelect;
}
Also used : Set(java.util.Set) HashSet(java.util.HashSet) HashMap(java.util.HashMap) SQLException(java.sql.SQLException) OrderByNode(org.apache.phoenix.parse.OrderByNode) SelectStatement(org.apache.phoenix.parse.SelectStatement) BindTableNode(org.apache.phoenix.parse.BindTableNode) UDFParseNode(org.apache.phoenix.parse.UDFParseNode) ComparisonParseNode(org.apache.phoenix.parse.ComparisonParseNode) ColumnParseNode(org.apache.phoenix.parse.ColumnParseNode) AndParseNode(org.apache.phoenix.parse.AndParseNode) WildcardParseNode(org.apache.phoenix.parse.WildcardParseNode) TableWildcardParseNode(org.apache.phoenix.parse.TableWildcardParseNode) EqualParseNode(org.apache.phoenix.parse.EqualParseNode) ParseNode(org.apache.phoenix.parse.ParseNode) PTable(org.apache.phoenix.schema.PTable) JoinTableNode(org.apache.phoenix.parse.JoinTableNode) TableName(org.apache.phoenix.parse.TableName) DerivedTableNode(org.apache.phoenix.parse.DerivedTableNode) TableNode(org.apache.phoenix.parse.TableNode) JoinTableNode(org.apache.phoenix.parse.JoinTableNode) NamedTableNode(org.apache.phoenix.parse.NamedTableNode) BindTableNode(org.apache.phoenix.parse.BindTableNode) DerivedTableNode(org.apache.phoenix.parse.DerivedTableNode) NamedTableNode(org.apache.phoenix.parse.NamedTableNode) Scan(org.apache.hadoop.hbase.client.Scan) IndexExpressionParseNodeRewriter(org.apache.phoenix.parse.IndexExpressionParseNodeRewriter) TableRef(org.apache.phoenix.schema.TableRef)

Example 14 with SelectStatement

use of org.apache.phoenix.parse.SelectStatement in project phoenix by apache.

the class QueryCompiler method compileSingleQuery.

protected QueryPlan compileSingleQuery(StatementContext context, SelectStatement select, List<Object> binds, boolean asSubquery, boolean allowPageFilter) throws SQLException {
    SelectStatement innerSelect = select.getInnerSelectStatement();
    if (innerSelect == null) {
        return compileSingleFlatQuery(context, select, binds, asSubquery, allowPageFilter, null, null, true);
    }
    QueryPlan innerPlan = compileSubquery(innerSelect, false);
    TupleProjector tupleProjector = new TupleProjector(innerPlan.getProjector());
    innerPlan = new TupleProjectionPlan(innerPlan, tupleProjector, null);
    // Replace the original resolver and table with those having compiled type info.
    TableRef tableRef = context.getResolver().getTables().get(0);
    ColumnResolver resolver = FromCompiler.getResolverForCompiledDerivedTable(statement.getConnection(), tableRef, innerPlan.getProjector());
    context.setResolver(resolver);
    tableRef = resolver.getTables().get(0);
    context.setCurrentTable(tableRef);
    boolean isInRowKeyOrder = innerPlan.getGroupBy() == GroupBy.EMPTY_GROUP_BY && innerPlan.getOrderBy() == OrderBy.EMPTY_ORDER_BY;
    return compileSingleFlatQuery(context, select, binds, asSubquery, allowPageFilter, innerPlan, tupleProjector, isInRowKeyOrder);
}
Also used : SelectStatement(org.apache.phoenix.parse.SelectStatement) TupleProjector(org.apache.phoenix.execute.TupleProjector) TupleProjectionPlan(org.apache.phoenix.execute.TupleProjectionPlan) TableRef(org.apache.phoenix.schema.TableRef)

Example 15 with SelectStatement

use of org.apache.phoenix.parse.SelectStatement in project phoenix by apache.

the class QueryCompiler method compileUnionAll.

public QueryPlan compileUnionAll(SelectStatement select) throws SQLException {
    List<SelectStatement> unionAllSelects = select.getSelects();
    List<QueryPlan> plans = new ArrayList<QueryPlan>();
    for (int i = 0; i < unionAllSelects.size(); i++) {
        SelectStatement subSelect = unionAllSelects.get(i);
        // Push down order-by and limit into sub-selects.
        if (!select.getOrderBy().isEmpty() || select.getLimit() != null) {
            if (select.getOffset() == null) {
                subSelect = NODE_FACTORY.select(subSelect, select.getOrderBy(), select.getLimit(), null);
            } else {
                subSelect = NODE_FACTORY.select(subSelect, select.getOrderBy(), null, null);
            }
        }
        QueryPlan subPlan = compileSubquery(subSelect, true);
        plans.add(subPlan);
    }
    TableRef tableRef = UnionCompiler.contructSchemaTable(statement, plans, select.hasWildcard() ? null : select.getSelect());
    ColumnResolver resolver = FromCompiler.getResolver(tableRef);
    StatementContext context = new StatementContext(statement, resolver, scan, sequenceManager);
    QueryPlan plan = compileSingleFlatQuery(context, select, statement.getParameters(), false, false, null, null, false);
    plan = new UnionPlan(context, select, tableRef, plan.getProjector(), plan.getLimit(), plan.getOffset(), plan.getOrderBy(), GroupBy.EMPTY_GROUP_BY, plans, context.getBindManager().getParameterMetaData());
    return plan;
}
Also used : SelectStatement(org.apache.phoenix.parse.SelectStatement) ArrayList(java.util.ArrayList) Hint(org.apache.phoenix.parse.HintNode.Hint) TableRef(org.apache.phoenix.schema.TableRef) UnionPlan(org.apache.phoenix.execute.UnionPlan)

Aggregations

SelectStatement (org.apache.phoenix.parse.SelectStatement)24 ParseNode (org.apache.phoenix.parse.ParseNode)14 TableRef (org.apache.phoenix.schema.TableRef)13 ColumnParseNode (org.apache.phoenix.parse.ColumnParseNode)9 TableNode (org.apache.phoenix.parse.TableNode)9 PTable (org.apache.phoenix.schema.PTable)9 Scan (org.apache.hadoop.hbase.client.Scan)8 AndParseNode (org.apache.phoenix.parse.AndParseNode)7 AliasedNode (org.apache.phoenix.parse.AliasedNode)6 SubqueryParseNode (org.apache.phoenix.parse.SubqueryParseNode)6 ComparisonParseNode (org.apache.phoenix.parse.ComparisonParseNode)5 Hint (org.apache.phoenix.parse.HintNode.Hint)5 JoinType (org.apache.phoenix.parse.JoinTableNode.JoinType)5 LiteralParseNode (org.apache.phoenix.parse.LiteralParseNode)5 SQLParser (org.apache.phoenix.parse.SQLParser)5 List (java.util.List)4 AggregatePlan (org.apache.phoenix.execute.AggregatePlan)4 CompoundParseNode (org.apache.phoenix.parse.CompoundParseNode)4 ExistsParseNode (org.apache.phoenix.parse.ExistsParseNode)4 HintNode (org.apache.phoenix.parse.HintNode)4