Search in sources :

Example 1 with TupleProjector

use of org.apache.phoenix.execute.TupleProjector in project phoenix by apache.

the class QueryCompiler method compileJoinQuery.

/*
     * Call compileJoinQuery() for join queries recursively down to the leaf JoinTable nodes.
     * This matches the input JoinTable node against patterns in the following order:
     * 1. A (leaf JoinTable node, which can be a named table reference or a subquery of any kind.)
     *    Returns the compilation result of a single table scan or of an independent subquery.
     * 2. Matching either of (when hint USE_SORT_MERGE_JOIN not specified):
     *        1) A LEFT/INNER JOIN B
     *        2) A LEFT/INNER JOIN B (LEFT/INNER JOIN C)+, if hint NO_STAR_JOIN not specified
     *        where A can be a named table reference or a flat subquery, and B, C, ... can be a named
     *        table reference, a sub-join or a subquery of any kind.
     *    Returns a HashJoinPlan{scan: A, hash: B, C, ...}.
     * 3. Matching pattern:
     *        A RIGHT/INNER JOIN B (when hint USE_SORT_MERGE_JOIN not specified)
     *        where B can be a named table reference or a flat subquery, and A can be a named table
     *        reference, a sub-join or a subquery of any kind.
     *    Returns a HashJoinPlan{scan: B, hash: A}.
     *    NOTE that "A LEFT/RIGHT/INNER/FULL JOIN B RIGHT/INNER JOIN C" is viewed as
     *    "(A LEFT/RIGHT/INNER/FULL JOIN B) RIGHT/INNER JOIN C" here, which means the left part in the
     *    parenthesis is considered a sub-join.
     *    viewed as a sub-join.
     * 4. All the rest that do not qualify for previous patterns or conditions, including FULL joins.
     *    Returns a SortMergeJoinPlan, the sorting part of which is pushed down to the JoinTable nodes
     *    of both sides as order-by clauses.
     * NOTE that SEMI or ANTI joins are treated the same way as LEFT joins in JoinTable pattern matching.
     *    
     * If no join algorithm hint is provided, according to the above compilation process, a join query 
     * plan can probably consist of both HashJoinPlan and SortMergeJoinPlan which may enclose each other.
     * TODO 1) Use table statistics to guide the choice of join plans.
     *      2) Make it possible to hint a certain join algorithm for a specific join step.
     */
@SuppressWarnings("unchecked")
protected QueryPlan compileJoinQuery(StatementContext context, List<Object> binds, JoinTable joinTable, boolean asSubquery, boolean projectPKColumns, List<OrderByNode> orderBy) throws SQLException {
    byte[] emptyByteArray = new byte[0];
    List<JoinSpec> joinSpecs = joinTable.getJoinSpecs();
    if (joinSpecs.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));
    }
    boolean[] starJoinVector;
    if (!this.useSortMergeJoin && (starJoinVector = joinTable.getStarJoinVector()) != null) {
        Table table = joinTable.getTable();
        PTable initialProjectedTable;
        TableRef tableRef;
        SelectStatement query;
        TupleProjector tupleProjector;
        if (!table.isSubselect()) {
            context.setCurrentTable(table.getTableRef());
            initialProjectedTable = table.createProjectedTable(!projectPKColumns, context);
            tableRef = table.getTableRef();
            table.projectColumns(context.getScan());
            query = joinTable.getAsSingleSubquery(table.getAsSubquery(orderBy), asSubquery);
            tupleProjector = new TupleProjector(initialProjectedTable);
        } else {
            SelectStatement subquery = table.getAsSubquery(orderBy);
            QueryPlan plan = compileSubquery(subquery, false);
            initialProjectedTable = table.createProjectedTable(plan.getProjector());
            tableRef = plan.getTableRef();
            context.getScan().setFamilyMap(plan.getContext().getScan().getFamilyMap());
            query = joinTable.getAsSingleSubquery((SelectStatement) plan.getStatement(), asSubquery);
            tupleProjector = new TupleProjector(plan.getProjector());
        }
        context.setCurrentTable(tableRef);
        PTable projectedTable = initialProjectedTable;
        int count = joinSpecs.size();
        ImmutableBytesPtr[] joinIds = new ImmutableBytesPtr[count];
        List<Expression>[] joinExpressions = new List[count];
        JoinType[] joinTypes = new JoinType[count];
        PTable[] tables = new PTable[count];
        int[] fieldPositions = new int[count];
        StatementContext[] subContexts = new StatementContext[count];
        QueryPlan[] subPlans = new QueryPlan[count];
        HashSubPlan[] hashPlans = new HashSubPlan[count];
        fieldPositions[0] = projectedTable.getColumns().size() - projectedTable.getPKColumns().size();
        for (int i = 0; i < count; i++) {
            JoinSpec joinSpec = joinSpecs.get(i);
            Scan subScan = ScanUtil.newScan(originalScan);
            subContexts[i] = new StatementContext(statement, context.getResolver(), subScan, new SequenceManager(statement));
            subPlans[i] = compileJoinQuery(subContexts[i], binds, joinSpec.getJoinTable(), true, true, null);
            boolean hasPostReference = joinSpec.getJoinTable().hasPostReference();
            if (hasPostReference) {
                tables[i] = subContexts[i].getResolver().getTables().get(0).getTable();
                projectedTable = JoinCompiler.joinProjectedTables(projectedTable, tables[i], joinSpec.getType());
            } else {
                tables[i] = null;
            }
        }
        for (int i = 0; i < count; i++) {
            JoinSpec joinSpec = joinSpecs.get(i);
            context.setResolver(FromCompiler.getResolverForProjectedTable(projectedTable, context.getConnection(), query.getUdfParseNodes()));
            // place-holder
            joinIds[i] = new ImmutableBytesPtr(emptyByteArray);
            Pair<List<Expression>, List<Expression>> joinConditions = joinSpec.compileJoinConditions(context, subContexts[i], true);
            joinExpressions[i] = joinConditions.getFirst();
            List<Expression> hashExpressions = joinConditions.getSecond();
            Pair<Expression, Expression> keyRangeExpressions = new Pair<Expression, Expression>(null, null);
            boolean optimized = getKeyExpressionCombinations(keyRangeExpressions, context, joinTable.getStatement(), tableRef, joinSpec.getType(), joinExpressions[i], hashExpressions);
            Expression keyRangeLhsExpression = keyRangeExpressions.getFirst();
            Expression keyRangeRhsExpression = keyRangeExpressions.getSecond();
            joinTypes[i] = joinSpec.getType();
            if (i < count - 1) {
                fieldPositions[i + 1] = fieldPositions[i] + (tables[i] == null ? 0 : (tables[i].getColumns().size() - tables[i].getPKColumns().size()));
            }
            hashPlans[i] = new HashSubPlan(i, subPlans[i], optimized ? null : hashExpressions, joinSpec.isSingleValueOnly(), keyRangeLhsExpression, keyRangeRhsExpression);
        }
        TupleProjector.serializeProjectorIntoScan(context.getScan(), tupleProjector);
        QueryPlan plan = compileSingleFlatQuery(context, query, binds, asSubquery, !asSubquery && joinTable.isAllLeftJoin(), null, !table.isSubselect() && projectPKColumns ? tupleProjector : null, true);
        Expression postJoinFilterExpression = joinTable.compilePostFilterExpression(context, table);
        Integer limit = null;
        Integer offset = null;
        if (!query.isAggregate() && !query.isDistinct() && query.getOrderBy().isEmpty()) {
            limit = plan.getLimit();
            offset = plan.getOffset();
        }
        HashJoinInfo joinInfo = new HashJoinInfo(projectedTable, joinIds, joinExpressions, joinTypes, starJoinVector, tables, fieldPositions, postJoinFilterExpression, QueryUtil.getOffsetLimit(limit, offset));
        return HashJoinPlan.create(joinTable.getStatement(), plan, joinInfo, hashPlans);
    }
    JoinSpec lastJoinSpec = joinSpecs.get(joinSpecs.size() - 1);
    JoinType type = lastJoinSpec.getType();
    if (!this.useSortMergeJoin && (type == JoinType.Right || type == JoinType.Inner) && lastJoinSpec.getJoinTable().getJoinSpecs().isEmpty() && lastJoinSpec.getJoinTable().getTable().isFlat()) {
        JoinTable rhsJoinTable = lastJoinSpec.getJoinTable();
        Table rhsTable = rhsJoinTable.getTable();
        JoinTable lhsJoin = joinTable.getSubJoinTableWithoutPostFilters();
        Scan subScan = ScanUtil.newScan(originalScan);
        StatementContext lhsCtx = new StatementContext(statement, context.getResolver(), subScan, new SequenceManager(statement));
        QueryPlan lhsPlan = compileJoinQuery(lhsCtx, binds, lhsJoin, true, true, null);
        PTable rhsProjTable;
        TableRef rhsTableRef;
        SelectStatement rhs;
        TupleProjector tupleProjector;
        if (!rhsTable.isSubselect()) {
            context.setCurrentTable(rhsTable.getTableRef());
            rhsProjTable = rhsTable.createProjectedTable(!projectPKColumns, context);
            rhsTableRef = rhsTable.getTableRef();
            rhsTable.projectColumns(context.getScan());
            rhs = rhsJoinTable.getAsSingleSubquery(rhsTable.getAsSubquery(orderBy), asSubquery);
            tupleProjector = new TupleProjector(rhsProjTable);
        } else {
            SelectStatement subquery = rhsTable.getAsSubquery(orderBy);
            QueryPlan plan = compileSubquery(subquery, false);
            rhsProjTable = rhsTable.createProjectedTable(plan.getProjector());
            rhsTableRef = plan.getTableRef();
            context.getScan().setFamilyMap(plan.getContext().getScan().getFamilyMap());
            rhs = rhsJoinTable.getAsSingleSubquery((SelectStatement) plan.getStatement(), asSubquery);
            tupleProjector = new TupleProjector(plan.getProjector());
        }
        context.setCurrentTable(rhsTableRef);
        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, true);
        List<Expression> joinExpressions = joinConditions.getSecond();
        List<Expression> hashExpressions = joinConditions.getFirst();
        boolean needsMerge = lhsJoin.hasPostReference();
        PTable lhsTable = needsMerge ? lhsCtx.getResolver().getTables().get(0).getTable() : null;
        int fieldPosition = needsMerge ? rhsProjTable.getColumns().size() - rhsProjTable.getPKColumns().size() : 0;
        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();
        }
        HashJoinInfo joinInfo = new HashJoinInfo(projectedTable, joinIds, new List[] { joinExpressions }, new JoinType[] { type == JoinType.Right ? JoinType.Left : type }, new boolean[] { true }, new PTable[] { lhsTable }, new int[] { fieldPosition }, postJoinFilterExpression, QueryUtil.getOffsetLimit(limit, offset));
        Pair<Expression, Expression> keyRangeExpressions = new Pair<Expression, Expression>(null, null);
        getKeyExpressionCombinations(keyRangeExpressions, context, joinTable.getStatement(), rhsTableRef, type, joinExpressions, hashExpressions);
        return HashJoinPlan.create(joinTable.getStatement(), rhsPlan, joinInfo, new HashSubPlan[] { new HashSubPlan(0, lhsPlan, hashExpressions, false, keyRangeExpressions.getFirst(), keyRangeExpressions.getSecond()) });
    }
    JoinTable lhsJoin = joinTable.getSubJoinTableWithoutPostFilters();
    JoinTable rhsJoin = lastJoinSpec.getJoinTable();
    if (type == JoinType.Right) {
        JoinTable temp = lhsJoin;
        lhsJoin = rhsJoin;
        rhsJoin = temp;
    }
    List<EqualParseNode> joinConditionNodes = lastJoinSpec.getOnConditions();
    List<OrderByNode> lhsOrderBy = Lists.<OrderByNode>newArrayListWithExpectedSize(joinConditionNodes.size());
    List<OrderByNode> rhsOrderBy = Lists.<OrderByNode>newArrayListWithExpectedSize(joinConditionNodes.size());
    for (EqualParseNode condition : joinConditionNodes) {
        lhsOrderBy.add(NODE_FACTORY.orderBy(type == JoinType.Right ? condition.getRHS() : condition.getLHS(), false, true));
        rhsOrderBy.add(NODE_FACTORY.orderBy(type == JoinType.Right ? condition.getLHS() : condition.getRHS(), false, true));
    }
    Scan lhsScan = ScanUtil.newScan(originalScan);
    StatementContext lhsCtx = new StatementContext(statement, context.getResolver(), lhsScan, new SequenceManager(statement));
    boolean preserveRowkey = !projectPKColumns && type != JoinType.Full;
    QueryPlan lhsPlan = compileJoinQuery(lhsCtx, binds, lhsJoin, true, !preserveRowkey, lhsOrderBy);
    PTable lhsProjTable = lhsCtx.getResolver().getTables().get(0).getTable();
    boolean isInRowKeyOrder = preserveRowkey && lhsPlan.getOrderBy().getOrderByExpressions().isEmpty();
    Scan rhsScan = ScanUtil.newScan(originalScan);
    StatementContext rhsCtx = new StatementContext(statement, context.getResolver(), rhsScan, new SequenceManager(statement));
    QueryPlan rhsPlan = compileJoinQuery(rhsCtx, binds, rhsJoin, true, true, rhsOrderBy);
    PTable rhsProjTable = rhsCtx.getResolver().getTables().get(0).getTable();
    Pair<List<Expression>, List<Expression>> joinConditions = lastJoinSpec.compileJoinConditions(type == JoinType.Right ? rhsCtx : lhsCtx, type == JoinType.Right ? lhsCtx : rhsCtx, false);
    List<Expression> lhsKeyExpressions = type == JoinType.Right ? joinConditions.getSecond() : joinConditions.getFirst();
    List<Expression> rhsKeyExpressions = type == JoinType.Right ? joinConditions.getFirst() : joinConditions.getSecond();
    boolean needsMerge = rhsJoin.hasPostReference();
    int fieldPosition = needsMerge ? lhsProjTable.getColumns().size() - lhsProjTable.getPKColumns().size() : 0;
    PTable projectedTable = needsMerge ? JoinCompiler.joinProjectedTables(lhsProjTable, rhsProjTable, type == JoinType.Right ? JoinType.Left : type) : lhsProjTable;
    ColumnResolver resolver = FromCompiler.getResolverForProjectedTable(projectedTable, context.getConnection(), joinTable.getStatement().getUdfParseNodes());
    TableRef tableRef = resolver.getTables().get(0);
    StatementContext subCtx = new StatementContext(statement, resolver, ScanUtil.newScan(originalScan), new SequenceManager(statement));
    subCtx.setCurrentTable(tableRef);
    QueryPlan innerPlan = new SortMergeJoinPlan(subCtx, joinTable.getStatement(), tableRef, type == JoinType.Right ? JoinType.Left : type, lhsPlan, rhsPlan, lhsKeyExpressions, rhsKeyExpressions, projectedTable, lhsProjTable, needsMerge ? rhsProjTable : null, fieldPosition, lastJoinSpec.isSingleValueOnly());
    context.setCurrentTable(tableRef);
    context.setResolver(resolver);
    TableNode from = NODE_FACTORY.namedTable(tableRef.getTableAlias(), NODE_FACTORY.table(tableRef.getTable().getSchemaName().getString(), tableRef.getTable().getTableName().getString()));
    ParseNode where = joinTable.getPostFiltersCombined();
    SelectStatement select = asSubquery ? NODE_FACTORY.select(from, joinTable.getStatement().getHint(), false, Collections.<AliasedNode>emptyList(), where, null, null, orderBy, null, null, 0, false, joinTable.getStatement().hasSequence(), Collections.<SelectStatement>emptyList(), joinTable.getStatement().getUdfParseNodes()) : NODE_FACTORY.select(joinTable.getStatement(), from, where);
    return compileSingleFlatQuery(context, select, binds, asSubquery, false, innerPlan, null, isInRowKeyOrder);
}
Also used : TupleProjector(org.apache.phoenix.execute.TupleProjector) TupleProjectionPlan(org.apache.phoenix.execute.TupleProjectionPlan) OrderByNode(org.apache.phoenix.parse.OrderByNode) PTable(org.apache.phoenix.schema.PTable) HashSubPlan(org.apache.phoenix.execute.HashJoinPlan.HashSubPlan) SelectStatement(org.apache.phoenix.parse.SelectStatement) SortMergeJoinPlan(org.apache.phoenix.execute.SortMergeJoinPlan) SubqueryParseNode(org.apache.phoenix.parse.SubqueryParseNode) EqualParseNode(org.apache.phoenix.parse.EqualParseNode) ParseNode(org.apache.phoenix.parse.ParseNode) List(java.util.List) ArrayList(java.util.ArrayList) Pair(org.apache.hadoop.hbase.util.Pair) Table(org.apache.phoenix.compile.JoinCompiler.Table) JoinTable(org.apache.phoenix.compile.JoinCompiler.JoinTable) PTable(org.apache.phoenix.schema.PTable) ImmutableBytesPtr(org.apache.phoenix.hbase.index.util.ImmutableBytesPtr) JoinSpec(org.apache.phoenix.compile.JoinCompiler.JoinSpec) JoinType(org.apache.phoenix.parse.JoinTableNode.JoinType) AliasedNode(org.apache.phoenix.parse.AliasedNode) Hint(org.apache.phoenix.parse.HintNode.Hint) Expression(org.apache.phoenix.expression.Expression) LiteralExpression(org.apache.phoenix.expression.LiteralExpression) RowValueConstructorExpression(org.apache.phoenix.expression.RowValueConstructorExpression) HashJoinInfo(org.apache.phoenix.join.HashJoinInfo) TableNode(org.apache.phoenix.parse.TableNode) Scan(org.apache.hadoop.hbase.client.Scan) TableRef(org.apache.phoenix.schema.TableRef) JoinTable(org.apache.phoenix.compile.JoinCompiler.JoinTable) EqualParseNode(org.apache.phoenix.parse.EqualParseNode)

Example 2 with TupleProjector

use of org.apache.phoenix.execute.TupleProjector in project phoenix by apache.

the class IndexUtil method getTupleProjector.

public static TupleProjector getTupleProjector(Scan scan, ColumnReference[] dataColumns) {
    if (dataColumns != null && dataColumns.length != 0) {
        KeyValueSchema keyValueSchema = deserializeLocalIndexJoinSchemaFromScan(scan);
        boolean storeColsInSingleCell = scan.getAttribute(BaseScannerRegionObserver.COLUMNS_STORED_IN_SINGLE_CELL) != null;
        QualifierEncodingScheme encodingScheme = EncodedColumnsUtil.getQualifierEncodingScheme(scan);
        Expression[] colExpressions = storeColsInSingleCell ? new SingleCellColumnExpression[dataColumns.length] : new KeyValueColumnExpression[dataColumns.length];
        for (int i = 0; i < dataColumns.length; i++) {
            byte[] family = dataColumns[i].getFamily();
            byte[] qualifier = dataColumns[i].getQualifier();
            Field field = keyValueSchema.getField(i);
            Expression dataColumnExpr = storeColsInSingleCell ? new SingleCellColumnExpression(field, family, qualifier, encodingScheme) : new KeyValueColumnExpression(field, family, qualifier);
            colExpressions[i] = dataColumnExpr;
        }
        return new TupleProjector(keyValueSchema, colExpressions);
    }
    return null;
}
Also used : Field(org.apache.phoenix.schema.ValueSchema.Field) SingleCellColumnExpression(org.apache.phoenix.expression.SingleCellColumnExpression) QualifierEncodingScheme(org.apache.phoenix.schema.PTable.QualifierEncodingScheme) KeyValueColumnExpression(org.apache.phoenix.expression.KeyValueColumnExpression) Expression(org.apache.phoenix.expression.Expression) SingleCellColumnExpression(org.apache.phoenix.expression.SingleCellColumnExpression) RowKeyColumnExpression(org.apache.phoenix.expression.RowKeyColumnExpression) TupleProjector(org.apache.phoenix.execute.TupleProjector) KeyValueColumnExpression(org.apache.phoenix.expression.KeyValueColumnExpression) KeyValueSchema(org.apache.phoenix.schema.KeyValueSchema)

Example 3 with TupleProjector

use of org.apache.phoenix.execute.TupleProjector in project phoenix by apache.

the class UnionCompiler method contructSchemaTable.

public static TableRef contructSchemaTable(PhoenixStatement statement, List<QueryPlan> plans, List<AliasedNode> selectNodes) throws SQLException {
    List<TargetDataExpression> targetTypes = checkProjectionNumAndExpressions(plans);
    for (int i = 0; i < plans.size(); i++) {
        QueryPlan subPlan = plans.get(i);
        TupleProjector projector = getTupleProjector(subPlan.getProjector(), targetTypes);
        subPlan = new TupleProjectionPlan(subPlan, projector, null);
        plans.set(i, subPlan);
    }
    QueryPlan plan = plans.get(0);
    List<PColumn> projectedColumns = new ArrayList<PColumn>();
    for (int i = 0; i < plan.getProjector().getColumnCount(); i++) {
        ColumnProjector colProj = plan.getProjector().getColumnProjector(i);
        String name = selectNodes == null ? colProj.getName() : selectNodes.get(i).getAlias();
        PName colName = PNameFactory.newName(name);
        PColumnImpl projectedColumn = new PColumnImpl(PNameFactory.newName(name), UNION_FAMILY_NAME, targetTypes.get(i).getType(), targetTypes.get(i).getMaxLength(), targetTypes.get(i).getScale(), colProj.getExpression().isNullable(), i, targetTypes.get(i).getSortOrder(), 500, null, false, colProj.getExpression().toString(), false, false, colName.getBytes());
        projectedColumns.add(projectedColumn);
    }
    Long scn = statement.getConnection().getSCN();
    PTable tempTable = PTableImpl.makePTable(statement.getConnection().getTenantId(), UNION_SCHEMA_NAME, UNION_TABLE_NAME, PTableType.SUBQUERY, null, HConstants.LATEST_TIMESTAMP, scn == null ? HConstants.LATEST_TIMESTAMP : scn, null, null, projectedColumns, null, null, null, true, null, null, null, true, true, true, null, null, null, false, false, 0, 0L, SchemaUtil.isNamespaceMappingEnabled(PTableType.SUBQUERY, statement.getConnection().getQueryServices().getProps()), null, false, ImmutableStorageScheme.ONE_CELL_PER_COLUMN, QualifierEncodingScheme.NON_ENCODED_QUALIFIERS, PTable.EncodedCQCounter.NULL_COUNTER, true);
    TableRef tableRef = new TableRef(null, tempTable, 0, false);
    return tableRef;
}
Also used : PColumnImpl(org.apache.phoenix.schema.PColumnImpl) TupleProjector(org.apache.phoenix.execute.TupleProjector) TupleProjectionPlan(org.apache.phoenix.execute.TupleProjectionPlan) ArrayList(java.util.ArrayList) PTable(org.apache.phoenix.schema.PTable) PColumn(org.apache.phoenix.schema.PColumn) PName(org.apache.phoenix.schema.PName) TableRef(org.apache.phoenix.schema.TableRef)

Example 4 with TupleProjector

use of org.apache.phoenix.execute.TupleProjector in project phoenix by apache.

the class GroupedAggregateRegionObserver method doPostScannerOpen.

/**
     * Replaces the RegionScanner s with a RegionScanner that groups by the key formed by the list
     * of expressions from the scan and returns the aggregated rows of each group. For example,
     * given the following original rows in the RegionScanner: KEY COL1 row1 a row2 b row3 a row4 a
     * the following rows will be returned for COUNT(*): KEY COUNT a 3 b 1 The client is required to
     * do a sort and a final aggregation, since multiple rows with the same key may be returned from
     * different regions.
     */
@Override
protected RegionScanner doPostScannerOpen(ObserverContext<RegionCoprocessorEnvironment> c, Scan scan, RegionScanner s) throws IOException {
    boolean keyOrdered = false;
    byte[] expressionBytes = scan.getAttribute(BaseScannerRegionObserver.UNORDERED_GROUP_BY_EXPRESSIONS);
    if (expressionBytes == null) {
        expressionBytes = scan.getAttribute(BaseScannerRegionObserver.KEY_ORDERED_GROUP_BY_EXPRESSIONS);
        keyOrdered = true;
    }
    int offset = 0;
    if (ScanUtil.isLocalIndex(scan)) {
        /*
             * For local indexes, we need to set an offset on row key expressions to skip
             * the region start key.
             */
        Region region = c.getEnvironment().getRegion();
        offset = region.getRegionInfo().getStartKey().length != 0 ? region.getRegionInfo().getStartKey().length : region.getRegionInfo().getEndKey().length;
        ScanUtil.setRowKeyOffset(scan, offset);
    }
    List<Expression> expressions = deserializeGroupByExpressions(expressionBytes, 0);
    ServerAggregators aggregators = ServerAggregators.deserialize(scan.getAttribute(BaseScannerRegionObserver.AGGREGATORS), c.getEnvironment().getConfiguration());
    RegionScanner innerScanner = s;
    boolean useProto = false;
    byte[] localIndexBytes = scan.getAttribute(LOCAL_INDEX_BUILD_PROTO);
    useProto = localIndexBytes != null;
    if (localIndexBytes == null) {
        localIndexBytes = scan.getAttribute(LOCAL_INDEX_BUILD);
    }
    List<IndexMaintainer> indexMaintainers = localIndexBytes == null ? null : IndexMaintainer.deserialize(localIndexBytes, useProto);
    TupleProjector tupleProjector = null;
    byte[][] viewConstants = null;
    ColumnReference[] dataColumns = IndexUtil.deserializeDataTableColumnsToJoin(scan);
    final TupleProjector p = TupleProjector.deserializeProjectorFromScan(scan);
    final HashJoinInfo j = HashJoinInfo.deserializeHashJoinFromScan(scan);
    boolean useQualifierAsIndex = EncodedColumnsUtil.useQualifierAsIndex(EncodedColumnsUtil.getMinMaxQualifiersFromScan(scan));
    if (ScanUtil.isLocalIndex(scan) || (j == null && p != null)) {
        if (dataColumns != null) {
            tupleProjector = IndexUtil.getTupleProjector(scan, dataColumns);
            viewConstants = IndexUtil.deserializeViewConstantsFromScan(scan);
        }
        ImmutableBytesPtr tempPtr = new ImmutableBytesPtr();
        innerScanner = getWrappedScanner(c, innerScanner, offset, scan, dataColumns, tupleProjector, c.getEnvironment().getRegion(), indexMaintainers == null ? null : indexMaintainers.get(0), viewConstants, p, tempPtr, useQualifierAsIndex);
    }
    if (j != null) {
        innerScanner = new HashJoinRegionScanner(innerScanner, p, j, ScanUtil.getTenantId(scan), c.getEnvironment(), useQualifierAsIndex, useNewValueColumnQualifier);
    }
    long limit = Long.MAX_VALUE;
    byte[] limitBytes = scan.getAttribute(GROUP_BY_LIMIT);
    if (limitBytes != null) {
        limit = PInteger.INSTANCE.getCodec().decodeInt(limitBytes, 0, SortOrder.getDefault());
    }
    if (keyOrdered) {
        // already in the required group by key order
        return scanOrdered(c, scan, innerScanner, expressions, aggregators, limit);
    } else {
        // Otherwse, collect them all up in an in memory map
        return scanUnordered(c, scan, innerScanner, expressions, aggregators, limit);
    }
}
Also used : TupleProjector(org.apache.phoenix.execute.TupleProjector) ImmutableBytesPtr(org.apache.phoenix.hbase.index.util.ImmutableBytesPtr) ServerAggregators(org.apache.phoenix.expression.aggregator.ServerAggregators) RegionScanner(org.apache.hadoop.hbase.regionserver.RegionScanner) IndexMaintainer(org.apache.phoenix.index.IndexMaintainer) Expression(org.apache.phoenix.expression.Expression) HashJoinInfo(org.apache.phoenix.join.HashJoinInfo) Region(org.apache.hadoop.hbase.regionserver.Region) ColumnReference(org.apache.phoenix.hbase.index.covered.update.ColumnReference)

Example 5 with TupleProjector

use of org.apache.phoenix.execute.TupleProjector 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)

Aggregations

TupleProjector (org.apache.phoenix.execute.TupleProjector)8 Expression (org.apache.phoenix.expression.Expression)6 TableRef (org.apache.phoenix.schema.TableRef)5 HashJoinInfo (org.apache.phoenix.join.HashJoinInfo)4 PTable (org.apache.phoenix.schema.PTable)4 ArrayList (java.util.ArrayList)3 Region (org.apache.hadoop.hbase.regionserver.Region)3 RegionScanner (org.apache.hadoop.hbase.regionserver.RegionScanner)3 TupleProjectionPlan (org.apache.phoenix.execute.TupleProjectionPlan)3 ColumnReference (org.apache.phoenix.hbase.index.covered.update.ColumnReference)3 IndexMaintainer (org.apache.phoenix.index.IndexMaintainer)3 SelectStatement (org.apache.phoenix.parse.SelectStatement)3 List (java.util.List)2 KeyValueColumnExpression (org.apache.phoenix.expression.KeyValueColumnExpression)2 LiteralExpression (org.apache.phoenix.expression.LiteralExpression)2 RowValueConstructorExpression (org.apache.phoenix.expression.RowValueConstructorExpression)2 SingleCellColumnExpression (org.apache.phoenix.expression.SingleCellColumnExpression)2 ImmutableBytesPtr (org.apache.phoenix.hbase.index.util.ImmutableBytesPtr)2 SQLException (java.sql.SQLException)1 Configuration (org.apache.hadoop.conf.Configuration)1