Search in sources :

Example 41 with ParseNode

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

the class WhereCompiler method compile.

/**
     * Optimize scan ranges by applying dynamically generated filter expressions.
     * @param context the shared context during query compilation
     * @param statement TODO
     * @throws SQLException if mismatched types are found, bind value do not match binds,
     * or invalid function arguments are encountered.
     * @throws SQLFeatureNotSupportedException if an unsupported expression is encountered.
     * @throws ColumnNotFoundException if column name could not be resolved
     * @throws AmbiguousColumnException if an unaliased column name is ambiguous across multiple tables
     */
public static Expression compile(StatementContext context, FilterableStatement statement, ParseNode viewWhere, List<Expression> dynamicFilters, boolean hashJoinOptimization, Set<SubqueryParseNode> subqueryNodes) throws SQLException {
    ParseNode where = statement.getWhere();
    if (subqueryNodes != null) {
        // if the subqueryNodes passed in is null, we assume there will be no sub-queries in the WHERE clause.
        SubqueryParseNodeVisitor subqueryVisitor = new SubqueryParseNodeVisitor(context, subqueryNodes);
        if (where != null) {
            where.accept(subqueryVisitor);
        }
        if (viewWhere != null) {
            viewWhere.accept(subqueryVisitor);
        }
        if (!subqueryNodes.isEmpty()) {
            return null;
        }
    }
    Set<Expression> extractedNodes = Sets.<Expression>newHashSet();
    WhereExpressionCompiler whereCompiler = new WhereExpressionCompiler(context);
    Expression expression = where == null ? LiteralExpression.newConstant(true, PBoolean.INSTANCE, Determinism.ALWAYS) : where.accept(whereCompiler);
    if (whereCompiler.isAggregate()) {
        throw new SQLExceptionInfo.Builder(SQLExceptionCode.AGGREGATE_IN_WHERE).build().buildException();
    }
    if (expression.getDataType() != PBoolean.INSTANCE) {
        throw TypeMismatchException.newException(PBoolean.INSTANCE, expression.getDataType(), expression.toString());
    }
    if (viewWhere != null) {
        WhereExpressionCompiler viewWhereCompiler = new WhereExpressionCompiler(context, true);
        Expression viewExpression = viewWhere.accept(viewWhereCompiler);
        expression = AndExpression.create(Lists.newArrayList(expression, viewExpression));
    }
    if (!dynamicFilters.isEmpty()) {
        List<Expression> filters = Lists.newArrayList(expression);
        filters.addAll(dynamicFilters);
        expression = AndExpression.create(filters);
    }
    if (context.getCurrentTable().getTable().getType() != PTableType.PROJECTED && context.getCurrentTable().getTable().getType() != PTableType.SUBQUERY) {
        expression = WhereOptimizer.pushKeyExpressionsToScan(context, statement, expression, extractedNodes);
    }
    setScanFilter(context, statement, expression, whereCompiler.disambiguateWithFamily, hashJoinOptimization);
    return expression;
}
Also used : KeyValueColumnExpression(org.apache.phoenix.expression.KeyValueColumnExpression) Expression(org.apache.phoenix.expression.Expression) LiteralExpression(org.apache.phoenix.expression.LiteralExpression) AndExpression(org.apache.phoenix.expression.AndExpression) ColumnParseNode(org.apache.phoenix.parse.ColumnParseNode) SubqueryParseNode(org.apache.phoenix.parse.SubqueryParseNode) ParseNode(org.apache.phoenix.parse.ParseNode)

Example 42 with ParseNode

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

the class QueryCompiler method compileSingleFlatQuery.

protected QueryPlan compileSingleFlatQuery(StatementContext context, SelectStatement select, List<Object> binds, boolean asSubquery, boolean allowPageFilter, QueryPlan innerPlan, TupleProjector innerPlanTupleProjector, boolean isInRowKeyOrder) throws SQLException {
    PTable projectedTable = null;
    if (this.projectTuples) {
        projectedTable = TupleProjectionCompiler.createProjectedTable(select, context);
        if (projectedTable != null) {
            context.setResolver(FromCompiler.getResolverForProjectedTable(projectedTable, context.getConnection(), select.getUdfParseNodes()));
        }
    }
    ColumnResolver resolver = context.getResolver();
    TableRef tableRef = context.getCurrentTable();
    PTable table = tableRef.getTable();
    ParseNode viewWhere = null;
    if (table.getViewStatement() != null) {
        viewWhere = new SQLParser(table.getViewStatement()).parseQuery().getWhere();
    }
    Integer limit = LimitCompiler.compile(context, select);
    Integer offset = OffsetCompiler.compile(context, select);
    GroupBy groupBy = GroupByCompiler.compile(context, select, isInRowKeyOrder);
    // Optimize the HAVING clause by finding any group by expressions that can be moved
    // to the WHERE clause
    select = HavingCompiler.rewrite(context, select, groupBy);
    Expression having = HavingCompiler.compile(context, select, groupBy);
    // expressions as group by key expressions since they're pre, not post filtered.
    if (innerPlan == null && !tableRef.equals(resolver.getTables().get(0))) {
        context.setResolver(FromCompiler.getResolver(context.getConnection(), tableRef, select.getUdfParseNodes()));
    }
    Set<SubqueryParseNode> subqueries = Sets.<SubqueryParseNode>newHashSet();
    Expression where = WhereCompiler.compile(context, select, viewWhere, subqueries);
    // Recompile GROUP BY now that we've figured out our ScanRanges so we know
    // definitively whether or not we'll traverse in row key order.
    groupBy = groupBy.compile(context, innerPlanTupleProjector);
    // recover resolver
    context.setResolver(resolver);
    RowProjector projector = ProjectionCompiler.compile(context, select, groupBy, asSubquery ? Collections.<PDatum>emptyList() : targetColumns, where);
    OrderBy orderBy = OrderByCompiler.compile(context, select, groupBy, limit, offset, projector, groupBy == GroupBy.EMPTY_GROUP_BY ? innerPlanTupleProjector : null, isInRowKeyOrder);
    context.getAggregationManager().compile(context, groupBy);
    // Final step is to build the query plan
    if (!asSubquery) {
        int maxRows = statement.getMaxRows();
        if (maxRows > 0) {
            if (limit != null) {
                limit = Math.min(limit, maxRows);
            } else {
                limit = maxRows;
            }
        }
    }
    if (projectedTable != null) {
        TupleProjector.serializeProjectorIntoScan(context.getScan(), new TupleProjector(projectedTable));
    }
    QueryPlan plan = innerPlan;
    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) : new ScanPlan(context, select, tableRef, projector, limit, offset, orderBy, parallelIteratorFactory, allowPageFilter));
    }
    if (!subqueries.isEmpty()) {
        int count = subqueries.size();
        WhereClauseSubPlan[] subPlans = new WhereClauseSubPlan[count];
        int i = 0;
        for (SubqueryParseNode subqueryNode : subqueries) {
            SelectStatement stmt = subqueryNode.getSelectNode();
            subPlans[i++] = new WhereClauseSubPlan(compileSubquery(stmt, false), stmt, subqueryNode.expectSingleRow());
        }
        plan = HashJoinPlan.create(select, plan, null, subPlans);
    }
    if (innerPlan != null) {
        if (LiteralExpression.isTrue(where)) {
            // we do not pass "true" as filter
            where = null;
        }
        plan = select.isAggregate() || select.isDistinct() ? new ClientAggregatePlan(context, select, tableRef, projector, limit, offset, where, orderBy, groupBy, having, plan) : new ClientScanPlan(context, select, tableRef, projector, limit, offset, where, orderBy, plan);
    }
    return plan;
}
Also used : TupleProjector(org.apache.phoenix.execute.TupleProjector) ClientAggregatePlan(org.apache.phoenix.execute.ClientAggregatePlan) PTable(org.apache.phoenix.schema.PTable) PDatum(org.apache.phoenix.schema.PDatum) SelectStatement(org.apache.phoenix.parse.SelectStatement) SubqueryParseNode(org.apache.phoenix.parse.SubqueryParseNode) SubqueryParseNode(org.apache.phoenix.parse.SubqueryParseNode) EqualParseNode(org.apache.phoenix.parse.EqualParseNode) ParseNode(org.apache.phoenix.parse.ParseNode) ClientAggregatePlan(org.apache.phoenix.execute.ClientAggregatePlan) AggregatePlan(org.apache.phoenix.execute.AggregatePlan) OrderBy(org.apache.phoenix.compile.OrderByCompiler.OrderBy) LiteralResultIterationPlan(org.apache.phoenix.execute.LiteralResultIterationPlan) ClientScanPlan(org.apache.phoenix.execute.ClientScanPlan) ScanPlan(org.apache.phoenix.execute.ScanPlan) GroupBy(org.apache.phoenix.compile.GroupByCompiler.GroupBy) WhereClauseSubPlan(org.apache.phoenix.execute.HashJoinPlan.WhereClauseSubPlan) ParallelIteratorFactory(org.apache.phoenix.iterate.ParallelIteratorFactory) Hint(org.apache.phoenix.parse.HintNode.Hint) ClientScanPlan(org.apache.phoenix.execute.ClientScanPlan) SQLParser(org.apache.phoenix.parse.SQLParser) Expression(org.apache.phoenix.expression.Expression) LiteralExpression(org.apache.phoenix.expression.LiteralExpression) RowValueConstructorExpression(org.apache.phoenix.expression.RowValueConstructorExpression) TableRef(org.apache.phoenix.schema.TableRef)

Example 43 with ParseNode

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

the class SequenceManager method newSequenceReference.

public SequenceValueExpression newSequenceReference(SequenceValueParseNode node) throws SQLException {
    PName tenantName = statement.getConnection().getTenantId();
    String tenantId = tenantName == null ? null : tenantName.getString();
    TableName tableName = node.getTableName();
    if (tableName.getSchemaName() == null && statement.getConnection().getSchema() != null) {
        tableName = TableName.create(statement.getConnection().getSchema(), tableName.getTableName());
    }
    int nSaltBuckets = statement.getConnection().getQueryServices().getSequenceSaltBuckets();
    ParseNode numToAllocateNode = node.getNumToAllocateNode();
    long numToAllocate = determineNumToAllocate(tableName, numToAllocateNode);
    SequenceKey key = new SequenceKey(tenantId, tableName.getSchemaName(), tableName.getTableName(), nSaltBuckets);
    SequenceValueExpression expression = sequenceMap.get(key);
    if (expression == null) {
        int index = sequenceMap.size();
        expression = new SequenceValueExpression(key, node.getOp(), index, numToAllocate);
        sequenceMap.put(key, expression);
    } else if (expression.op != node.getOp() || expression.getNumToAllocate() < numToAllocate) {
        // Keep the maximum allocation size we see in a statement
        SequenceValueExpression oldExpression = expression;
        expression = new SequenceValueExpression(key, node.getOp(), expression.getIndex(), Math.max(expression.getNumToAllocate(), numToAllocate));
        if (oldExpression.getNumToAllocate() < numToAllocate) {
            // If we found a NEXT VALUE expression with a higher number to allocate
            // We override the original expression
            sequenceMap.put(key, expression);
        }
    }
    // If we see a NEXT and a CURRENT, treat the CURRENT just like a NEXT
    if (node.getOp() == Op.NEXT_VALUE) {
        isNextSequence.set(expression.getIndex());
    }
    return expression;
}
Also used : TableName(org.apache.phoenix.parse.TableName) SequenceKey(org.apache.phoenix.schema.SequenceKey) PName(org.apache.phoenix.schema.PName) ParseNode(org.apache.phoenix.parse.ParseNode) SequenceValueParseNode(org.apache.phoenix.parse.SequenceValueParseNode)

Example 44 with ParseNode

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

the class StatementNormalizer method visitLeave.

@Override
public ParseNode visitLeave(final BetweenParseNode node, List<ParseNode> nodes) throws SQLException {
    LessThanOrEqualParseNode lhsNode = NODE_FACTORY.lte(node.getChildren().get(1), node.getChildren().get(0));
    LessThanOrEqualParseNode rhsNode = NODE_FACTORY.lte(node.getChildren().get(0), node.getChildren().get(2));
    List<ParseNode> parseNodes = Lists.newArrayListWithExpectedSize(2);
    parseNodes.add(this.visitLeave(lhsNode, lhsNode.getChildren()));
    parseNodes.add(this.visitLeave(rhsNode, rhsNode.getChildren()));
    return super.visitLeave(node, parseNodes);
}
Also used : LessThanOrEqualParseNode(org.apache.phoenix.parse.LessThanOrEqualParseNode) BetweenParseNode(org.apache.phoenix.parse.BetweenParseNode) FamilyWildcardParseNode(org.apache.phoenix.parse.FamilyWildcardParseNode) WildcardParseNode(org.apache.phoenix.parse.WildcardParseNode) LessThanOrEqualParseNode(org.apache.phoenix.parse.LessThanOrEqualParseNode) ComparisonParseNode(org.apache.phoenix.parse.ComparisonParseNode) ColumnParseNode(org.apache.phoenix.parse.ColumnParseNode) TableWildcardParseNode(org.apache.phoenix.parse.TableWildcardParseNode) ParseNode(org.apache.phoenix.parse.ParseNode)

Example 45 with ParseNode

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

the class StatementNormalizer method normalize.

/**
     * Rewrite the select statement by switching any constants to the right hand side
     * of the expression.
     * @param statement the select statement
     * @param resolver 
     * @return new select statement
     * @throws SQLException 
     */
public static SelectStatement normalize(SelectStatement statement, ColumnResolver resolver) throws SQLException {
    boolean multiTable = statement.isJoin();
    // Replace WildcardParse with a list of TableWildcardParseNode for multi-table queries
    if (multiTable) {
        List<AliasedNode> selectNodes = statement.getSelect();
        List<AliasedNode> normSelectNodes = selectNodes;
        for (int i = 0; i < selectNodes.size(); i++) {
            AliasedNode aliasedNode = selectNodes.get(i);
            ParseNode selectNode = aliasedNode.getNode();
            if (selectNode == WildcardParseNode.INSTANCE) {
                if (selectNodes == normSelectNodes) {
                    normSelectNodes = Lists.newArrayList(selectNodes.subList(0, i));
                }
                List<TableName> tableNames = statement.getFrom().accept(new TableNameVisitor());
                for (TableName tableName : tableNames) {
                    TableWildcardParseNode node = NODE_FACTORY.tableWildcard(tableName);
                    normSelectNodes.add(NODE_FACTORY.aliasedNode(null, node));
                }
            } else if (selectNodes != normSelectNodes) {
                normSelectNodes.add(aliasedNode);
            }
        }
        if (selectNodes != normSelectNodes) {
            statement = NODE_FACTORY.select(statement.getFrom(), statement.getHint(), statement.isDistinct(), normSelectNodes, statement.getWhere(), statement.getGroupBy(), statement.getHaving(), statement.getOrderBy(), statement.getLimit(), statement.getOffset(), statement.getBindCount(), statement.isAggregate(), statement.hasSequence(), statement.getSelects(), statement.getUdfParseNodes());
        }
    }
    return rewrite(statement, new StatementNormalizer(resolver, statement.getSelect().size(), multiTable));
}
Also used : TableName(org.apache.phoenix.parse.TableName) TableWildcardParseNode(org.apache.phoenix.parse.TableWildcardParseNode) BetweenParseNode(org.apache.phoenix.parse.BetweenParseNode) FamilyWildcardParseNode(org.apache.phoenix.parse.FamilyWildcardParseNode) WildcardParseNode(org.apache.phoenix.parse.WildcardParseNode) LessThanOrEqualParseNode(org.apache.phoenix.parse.LessThanOrEqualParseNode) ComparisonParseNode(org.apache.phoenix.parse.ComparisonParseNode) ColumnParseNode(org.apache.phoenix.parse.ColumnParseNode) TableWildcardParseNode(org.apache.phoenix.parse.TableWildcardParseNode) ParseNode(org.apache.phoenix.parse.ParseNode) AliasedNode(org.apache.phoenix.parse.AliasedNode)

Aggregations

ParseNode (org.apache.phoenix.parse.ParseNode)49 ColumnParseNode (org.apache.phoenix.parse.ColumnParseNode)34 Expression (org.apache.phoenix.expression.Expression)23 AndParseNode (org.apache.phoenix.parse.AndParseNode)23 ComparisonParseNode (org.apache.phoenix.parse.ComparisonParseNode)22 LiteralExpression (org.apache.phoenix.expression.LiteralExpression)20 LiteralParseNode (org.apache.phoenix.parse.LiteralParseNode)19 SubqueryParseNode (org.apache.phoenix.parse.SubqueryParseNode)18 AliasedNode (org.apache.phoenix.parse.AliasedNode)16 ExistsParseNode (org.apache.phoenix.parse.ExistsParseNode)15 RowValueConstructorParseNode (org.apache.phoenix.parse.RowValueConstructorParseNode)15 SelectStatement (org.apache.phoenix.parse.SelectStatement)14 UDFParseNode (org.apache.phoenix.parse.UDFParseNode)14 BindParseNode (org.apache.phoenix.parse.BindParseNode)13 RowKeyColumnExpression (org.apache.phoenix.expression.RowKeyColumnExpression)12 FunctionParseNode (org.apache.phoenix.parse.FunctionParseNode)12 SequenceValueParseNode (org.apache.phoenix.parse.SequenceValueParseNode)12 AndExpression (org.apache.phoenix.expression.AndExpression)11 CoerceExpression (org.apache.phoenix.expression.CoerceExpression)11 RowValueConstructorExpression (org.apache.phoenix.expression.RowValueConstructorExpression)11