Search in sources :

Example 1 with TupleProjectionPlan

use of org.apache.phoenix.execute.TupleProjectionPlan 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 2 with TupleProjectionPlan

use of org.apache.phoenix.execute.TupleProjectionPlan 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 3 with TupleProjectionPlan

use of org.apache.phoenix.execute.TupleProjectionPlan 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 4 with TupleProjectionPlan

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

the class QueryCompilerTest method testSortMergeJoinSubQueryOrderByOverrideBug3745.

@Test
public void testSortMergeJoinSubQueryOrderByOverrideBug3745() throws Exception {
    Connection conn = null;
    try {
        conn = DriverManager.getConnection(getUrl());
        String tableName1 = "MERGE1";
        String tableName2 = "MERGE2";
        conn.createStatement().execute("DROP TABLE if exists " + tableName1);
        String sql = "CREATE TABLE IF NOT EXISTS " + tableName1 + " ( " + "AID INTEGER PRIMARY KEY," + "AGE INTEGER" + ")";
        conn.createStatement().execute(sql);
        conn.createStatement().execute("DROP TABLE if exists " + tableName2);
        sql = "CREATE TABLE IF NOT EXISTS " + tableName2 + " ( " + "BID INTEGER PRIMARY KEY," + "CODE INTEGER" + ")";
        conn.createStatement().execute(sql);
        // test for simple scan
        sql = "select /*+ USE_SORT_MERGE_JOIN */ a.aid,b.code from (select aid,age from " + tableName1 + " where age >=11 and age<=33 order by age limit 3) a inner join " + "(select bid,code from " + tableName2 + " order by code limit 1) b on a.aid=b.bid ";
        QueryPlan queryPlan = getQueryPlan(conn, sql);
        SortMergeJoinPlan sortMergeJoinPlan = (SortMergeJoinPlan) ((ClientScanPlan) queryPlan).getDelegate();
        ClientScanPlan lhsOuterPlan = (ClientScanPlan) ((TupleProjectionPlan) (sortMergeJoinPlan.getLhsPlan())).getDelegate();
        OrderBy orderBy = lhsOuterPlan.getOrderBy();
        assertTrue(orderBy.getOrderByExpressions().size() == 1);
        assertTrue(orderBy.getOrderByExpressions().get(0).toString().equals("AID"));
        ScanPlan innerScanPlan = (ScanPlan) ((TupleProjectionPlan) lhsOuterPlan.getDelegate()).getDelegate();
        orderBy = innerScanPlan.getOrderBy();
        assertTrue(orderBy.getOrderByExpressions().size() == 1);
        assertTrue(orderBy.getOrderByExpressions().get(0).toString().equals("AGE"));
        assertTrue(innerScanPlan.getLimit().intValue() == 3);
        ClientScanPlan rhsOuterPlan = (ClientScanPlan) ((TupleProjectionPlan) (sortMergeJoinPlan.getRhsPlan())).getDelegate();
        orderBy = rhsOuterPlan.getOrderBy();
        assertTrue(orderBy.getOrderByExpressions().size() == 1);
        assertTrue(orderBy.getOrderByExpressions().get(0).toString().equals("BID"));
        innerScanPlan = (ScanPlan) ((TupleProjectionPlan) rhsOuterPlan.getDelegate()).getDelegate();
        orderBy = innerScanPlan.getOrderBy();
        assertTrue(orderBy.getOrderByExpressions().size() == 1);
        assertTrue(orderBy.getOrderByExpressions().get(0).toString().equals("CODE"));
        assertTrue(innerScanPlan.getLimit().intValue() == 1);
        // test for aggregate
        sql = "select /*+ USE_SORT_MERGE_JOIN */ a.aid,b.codesum from (select aid,sum(age) agesum from " + tableName1 + " where age >=11 and age<=33 group by aid order by agesum limit 3) a inner join " + "(select bid,sum(code) codesum from " + tableName2 + " group by bid order by codesum limit 1) b on a.aid=b.bid ";
        queryPlan = getQueryPlan(conn, sql);
        sortMergeJoinPlan = (SortMergeJoinPlan) ((ClientScanPlan) queryPlan).getDelegate();
        lhsOuterPlan = (ClientScanPlan) ((TupleProjectionPlan) (sortMergeJoinPlan.getLhsPlan())).getDelegate();
        orderBy = lhsOuterPlan.getOrderBy();
        assertTrue(orderBy.getOrderByExpressions().size() == 1);
        assertTrue(orderBy.getOrderByExpressions().get(0).toString().equals("AID"));
        AggregatePlan innerAggregatePlan = (AggregatePlan) ((TupleProjectionPlan) lhsOuterPlan.getDelegate()).getDelegate();
        orderBy = innerAggregatePlan.getOrderBy();
        assertTrue(orderBy.getOrderByExpressions().size() == 1);
        assertTrue(orderBy.getOrderByExpressions().get(0).toString().equals("SUM(AGE)"));
        assertTrue(innerAggregatePlan.getLimit().intValue() == 3);
        rhsOuterPlan = (ClientScanPlan) ((TupleProjectionPlan) (sortMergeJoinPlan.getRhsPlan())).getDelegate();
        orderBy = rhsOuterPlan.getOrderBy();
        assertTrue(orderBy.getOrderByExpressions().size() == 1);
        assertTrue(orderBy.getOrderByExpressions().get(0).toString().equals("BID"));
        innerAggregatePlan = (AggregatePlan) ((TupleProjectionPlan) rhsOuterPlan.getDelegate()).getDelegate();
        orderBy = innerAggregatePlan.getOrderBy();
        assertTrue(orderBy.getOrderByExpressions().size() == 1);
        assertTrue(orderBy.getOrderByExpressions().get(0).toString().equals("SUM(CODE)"));
        assertTrue(innerAggregatePlan.getLimit().intValue() == 1);
        String tableName3 = "merge3";
        conn.createStatement().execute("DROP TABLE if exists " + tableName3);
        sql = "CREATE TABLE IF NOT EXISTS " + tableName3 + " ( " + "CID INTEGER PRIMARY KEY," + "REGION INTEGER" + ")";
        conn.createStatement().execute(sql);
        // test for join
        sql = "select t1.aid,t1.code,t2.region from " + "(select a.aid,b.code from " + tableName1 + " a inner join " + tableName2 + " b on a.aid=b.bid where b.code >=44 and b.code<=66 order by b.code limit 3) t1 inner join " + "(select a.aid,c.region from " + tableName1 + " a inner join " + tableName3 + " c on a.aid=c.cid where c.region>=77 and c.region<=99 order by c.region desc limit 1) t2 on t1.aid=t2.aid";
        PhoenixPreparedStatement phoenixPreparedStatement = conn.prepareStatement(sql).unwrap(PhoenixPreparedStatement.class);
        queryPlan = phoenixPreparedStatement.optimizeQuery(sql);
        sortMergeJoinPlan = (SortMergeJoinPlan) ((ClientScanPlan) queryPlan).getDelegate();
        lhsOuterPlan = (ClientScanPlan) ((TupleProjectionPlan) (sortMergeJoinPlan.getLhsPlan())).getDelegate();
        orderBy = lhsOuterPlan.getOrderBy();
        assertTrue(orderBy.getOrderByExpressions().size() == 1);
        assertTrue(orderBy.getOrderByExpressions().get(0).toString().equals("AID"));
        innerScanPlan = (ScanPlan) ((HashJoinPlan) ((TupleProjectionPlan) lhsOuterPlan.getDelegate()).getDelegate()).getDelegate();
        orderBy = innerScanPlan.getOrderBy();
        assertTrue(orderBy.getOrderByExpressions().size() == 1);
        assertTrue(orderBy.getOrderByExpressions().get(0).toString().equals("B.CODE"));
        assertTrue(innerScanPlan.getLimit().intValue() == 3);
        rhsOuterPlan = (ClientScanPlan) ((TupleProjectionPlan) (sortMergeJoinPlan.getRhsPlan())).getDelegate();
        orderBy = rhsOuterPlan.getOrderBy();
        assertTrue(orderBy.getOrderByExpressions().size() == 1);
        assertTrue(orderBy.getOrderByExpressions().get(0).toString().equals("AID"));
        innerScanPlan = (ScanPlan) ((HashJoinPlan) ((TupleProjectionPlan) rhsOuterPlan.getDelegate()).getDelegate()).getDelegate();
        orderBy = innerScanPlan.getOrderBy();
        assertTrue(orderBy.getOrderByExpressions().size() == 1);
        assertTrue(orderBy.getOrderByExpressions().get(0).toString().equals("C.REGION DESC"));
        assertTrue(innerScanPlan.getLimit().intValue() == 1);
        // test for join and aggregate
        sql = "select t1.aid,t1.codesum,t2.regionsum from " + "(select a.aid,sum(b.code) codesum from " + tableName1 + " a inner join " + tableName2 + " b on a.aid=b.bid where b.code >=44 and b.code<=66 group by a.aid order by codesum limit 3) t1 inner join " + "(select a.aid,sum(c.region) regionsum from " + tableName1 + " a inner join " + tableName3 + " c on a.aid=c.cid where c.region>=77 and c.region<=99 group by a.aid order by regionsum desc limit 2) t2 on t1.aid=t2.aid";
        phoenixPreparedStatement = conn.prepareStatement(sql).unwrap(PhoenixPreparedStatement.class);
        queryPlan = phoenixPreparedStatement.optimizeQuery(sql);
        sortMergeJoinPlan = (SortMergeJoinPlan) ((ClientScanPlan) queryPlan).getDelegate();
        lhsOuterPlan = (ClientScanPlan) ((TupleProjectionPlan) (sortMergeJoinPlan.getLhsPlan())).getDelegate();
        orderBy = lhsOuterPlan.getOrderBy();
        assertTrue(orderBy.getOrderByExpressions().size() == 1);
        assertTrue(orderBy.getOrderByExpressions().get(0).toString().equals("AID"));
        innerAggregatePlan = (AggregatePlan) ((HashJoinPlan) ((TupleProjectionPlan) lhsOuterPlan.getDelegate()).getDelegate()).getDelegate();
        orderBy = innerAggregatePlan.getOrderBy();
        assertTrue(orderBy.getOrderByExpressions().size() == 1);
        assertTrue(orderBy.getOrderByExpressions().get(0).toString().equals("SUM(B.CODE)"));
        assertTrue(innerAggregatePlan.getLimit().intValue() == 3);
        rhsOuterPlan = (ClientScanPlan) ((TupleProjectionPlan) (sortMergeJoinPlan.getRhsPlan())).getDelegate();
        orderBy = rhsOuterPlan.getOrderBy();
        assertTrue(orderBy.getOrderByExpressions().size() == 1);
        assertTrue(orderBy.getOrderByExpressions().get(0).toString().equals("AID"));
        innerAggregatePlan = (AggregatePlan) ((HashJoinPlan) ((TupleProjectionPlan) rhsOuterPlan.getDelegate()).getDelegate()).getDelegate();
        orderBy = innerAggregatePlan.getOrderBy();
        assertTrue(orderBy.getOrderByExpressions().size() == 1);
        assertTrue(orderBy.getOrderByExpressions().get(0).toString().equals("SUM(C.REGION) DESC"));
        assertTrue(innerAggregatePlan.getLimit().intValue() == 2);
        // test for if SubselectRewriter.isOrderByPrefix had take effect
        sql = "select t1.aid,t1.codesum,t2.regionsum from " + "(select a.aid,sum(b.code) codesum from " + tableName1 + " a inner join " + tableName2 + " b on a.aid=b.bid where b.code >=44 and b.code<=66 group by a.aid order by a.aid,codesum limit 3) t1 inner join " + "(select a.aid,sum(c.region) regionsum from " + tableName1 + " a inner join " + tableName3 + " c on a.aid=c.cid where c.region>=77 and c.region<=99 group by a.aid order by a.aid desc,regionsum desc limit 2) t2 on t1.aid=t2.aid " + "order by t1.aid desc";
        phoenixPreparedStatement = conn.prepareStatement(sql).unwrap(PhoenixPreparedStatement.class);
        queryPlan = phoenixPreparedStatement.optimizeQuery(sql);
        orderBy = queryPlan.getOrderBy();
        assertTrue(orderBy.getOrderByExpressions().size() == 1);
        assertTrue(orderBy.getOrderByExpressions().get(0).toString().equals("T1.AID DESC"));
        sortMergeJoinPlan = (SortMergeJoinPlan) ((ClientScanPlan) queryPlan).getDelegate();
        innerAggregatePlan = (AggregatePlan) ((HashJoinPlan) (((TupleProjectionPlan) sortMergeJoinPlan.getLhsPlan()).getDelegate())).getDelegate();
        orderBy = innerAggregatePlan.getOrderBy();
        assertTrue(orderBy.getOrderByExpressions().size() == 2);
        assertTrue(orderBy.getOrderByExpressions().get(0).toString().equals("A.AID"));
        assertTrue(orderBy.getOrderByExpressions().get(1).toString().equals("SUM(B.CODE)"));
        assertTrue(innerAggregatePlan.getLimit().intValue() == 3);
        rhsOuterPlan = (ClientScanPlan) ((TupleProjectionPlan) (sortMergeJoinPlan.getRhsPlan())).getDelegate();
        orderBy = rhsOuterPlan.getOrderBy();
        assertTrue(orderBy.getOrderByExpressions().size() == 1);
        assertTrue(orderBy.getOrderByExpressions().get(0).toString().equals("AID"));
        innerAggregatePlan = (AggregatePlan) ((HashJoinPlan) ((TupleProjectionPlan) rhsOuterPlan.getDelegate()).getDelegate()).getDelegate();
        orderBy = innerAggregatePlan.getOrderBy();
        assertTrue(orderBy.getOrderByExpressions().size() == 2);
        assertTrue(orderBy.getOrderByExpressions().get(0).toString().equals("A.AID DESC"));
        assertTrue(orderBy.getOrderByExpressions().get(1).toString().equals("SUM(C.REGION) DESC"));
        assertTrue(innerAggregatePlan.getLimit().intValue() == 2);
    } finally {
        if (conn != null) {
            conn.close();
        }
    }
}
Also used : OrderBy(org.apache.phoenix.compile.OrderByCompiler.OrderBy) ClientScanPlan(org.apache.phoenix.execute.ClientScanPlan) ScanPlan(org.apache.phoenix.execute.ScanPlan) TupleProjectionPlan(org.apache.phoenix.execute.TupleProjectionPlan) HashJoinPlan(org.apache.phoenix.execute.HashJoinPlan) Connection(java.sql.Connection) PhoenixConnection(org.apache.phoenix.jdbc.PhoenixConnection) SortMergeJoinPlan(org.apache.phoenix.execute.SortMergeJoinPlan) ClientAggregatePlan(org.apache.phoenix.execute.ClientAggregatePlan) AggregatePlan(org.apache.phoenix.execute.AggregatePlan) PhoenixPreparedStatement(org.apache.phoenix.jdbc.PhoenixPreparedStatement) ClientScanPlan(org.apache.phoenix.execute.ClientScanPlan) Test(org.junit.Test) BaseConnectionlessQueryTest(org.apache.phoenix.query.BaseConnectionlessQueryTest)

Aggregations

TupleProjectionPlan (org.apache.phoenix.execute.TupleProjectionPlan)4 TupleProjector (org.apache.phoenix.execute.TupleProjector)3 SelectStatement (org.apache.phoenix.parse.SelectStatement)2 PTable (org.apache.phoenix.schema.PTable)2 TableRef (org.apache.phoenix.schema.TableRef)2 Connection (java.sql.Connection)1 ArrayList (java.util.ArrayList)1 Scan (org.apache.hadoop.hbase.client.Scan)1 JoinTable (org.apache.phoenix.compile.JoinCompiler.JoinTable)1 Table (org.apache.phoenix.compile.JoinCompiler.Table)1 OrderBy (org.apache.phoenix.compile.OrderByCompiler.OrderBy)1 AggregatePlan (org.apache.phoenix.execute.AggregatePlan)1 ClientAggregatePlan (org.apache.phoenix.execute.ClientAggregatePlan)1 ClientScanPlan (org.apache.phoenix.execute.ClientScanPlan)1 HashJoinPlan (org.apache.phoenix.execute.HashJoinPlan)1 ScanPlan (org.apache.phoenix.execute.ScanPlan)1 SortMergeJoinPlan (org.apache.phoenix.execute.SortMergeJoinPlan)1 PhoenixConnection (org.apache.phoenix.jdbc.PhoenixConnection)1 PhoenixPreparedStatement (org.apache.phoenix.jdbc.PhoenixPreparedStatement)1 Cost (org.apache.phoenix.optimize.Cost)1