Search in sources :

Example 1 with JoinType

use of org.voltdb.types.JoinType in project voltdb by VoltDB.

the class SelectSubPlanAssembler method generateJoinOrdersForTree.

private static List<JoinNode> generateJoinOrdersForTree(JoinNode subTree) {
    if (subTree instanceof BranchNode) {
        BranchNode branchSubTree = (BranchNode) subTree;
        JoinType joinType = branchSubTree.getJoinType();
        if (joinType == JoinType.INNER) {
            return generateInnerJoinOrdersForTree(subTree);
        } else if (joinType == JoinType.LEFT) {
            return generateOuterJoinOrdersForTree(subTree);
        } else if (joinType == JoinType.FULL) {
            return generateFullJoinOrdersForTree(subTree);
        } else {
            // Shouldn't get there
            assert (false);
            return null;
        }
    } else {
        // Single tables and subqueries
        return generateInnerJoinOrdersForTree(subTree);
    }
}
Also used : BranchNode(org.voltdb.planner.parseinfo.BranchNode) JoinType(org.voltdb.types.JoinType)

Example 2 with JoinType

use of org.voltdb.types.JoinType in project voltdb by VoltDB.

the class SelectSubPlanAssembler method generateOuterAccessPaths.

/**
     * Generate all possible access paths for an outer node in a join.
     * The outer table and/or join can have the naive access path and possible index path(s)
     * Optimizations - outer-table-only where expressions can be pushed down to the child node
     * to pre-qualify the outer tuples before they enter the join.
     * For inner joins outer-table-only join expressions can be pushed down as well
     *
     * @param parentNode A parent node to the node to generate paths to.
     */
private void generateOuterAccessPaths(BranchNode parentNode) {
    JoinNode outerChildNode = parentNode.getLeftNode();
    assert (outerChildNode != null);
    JoinType joinType = parentNode.getJoinType();
    // For LEFT and FULL join types, the outer join expressions are kept as a pre-join predicate
    // at the join node to pre-qualify the outer rows
    List<AbstractExpression> joinOuterList = (joinType == JoinType.INNER) ? parentNode.m_joinOuterList : null;
    if (outerChildNode instanceof BranchNode) {
        generateOuterAccessPaths((BranchNode) outerChildNode);
        generateInnerAccessPaths((BranchNode) outerChildNode);
        // The join node can have only sequential scan access
        outerChildNode.m_accessPaths.add(getRelevantNaivePath(joinOuterList, parentNode.m_whereOuterList));
        assert (outerChildNode.m_accessPaths.size() > 0);
        return;
    }
    // WHERE Outer expressions must stay at the join node for the FULL joins
    // They will be added later as part of the WHERE predicate of the join node
    List<AbstractExpression> parentWhereList = null;
    if (joinType != JoinType.FULL) {
        parentWhereList = parentNode.m_whereOuterList;
    }
    outerChildNode.m_accessPaths.addAll(getRelevantAccessPathsForTable(outerChildNode.getTableScan(), joinOuterList, parentWhereList, null));
}
Also used : BranchNode(org.voltdb.planner.parseinfo.BranchNode) AbstractExpression(org.voltdb.expressions.AbstractExpression) JoinNode(org.voltdb.planner.parseinfo.JoinNode) JoinType(org.voltdb.types.JoinType)

Example 3 with JoinType

use of org.voltdb.types.JoinType in project voltdb by VoltDB.

the class BranchNode method pushDownExpressions.

/**
     * Push down each WHERE expression on a given join node to the most specific child join
     * or table the expression applies to.
     *  1. The OUTER WHERE expressions can be pushed down to the outer (left) child for all joins
     *    (INNER and LEFT).
     *  2. The INNER WHERE expressions can be pushed down to the inner (right) child for the INNER joins.
     *  3. The WHERE expressions must be preserved for the FULL join type.
     * @param joinNode JoinNode
     */
protected void pushDownExpressions(List<AbstractExpression> noneList) {
    JoinType joinType = getJoinType();
    if (joinType == JoinType.FULL) {
        return;
    }
    JoinNode outerNode = getLeftNode();
    if (outerNode instanceof BranchNode) {
        ((BranchNode) outerNode).pushDownExpressionsRecursively(m_whereOuterList, noneList);
    }
    JoinNode innerNode = getRightNode();
    if (innerNode instanceof BranchNode && joinType == JoinType.INNER) {
        ((BranchNode) innerNode).pushDownExpressionsRecursively(m_whereInnerList, noneList);
    }
}
Also used : JoinType(org.voltdb.types.JoinType)

Example 4 with JoinType

use of org.voltdb.types.JoinType in project voltdb by VoltDB.

the class AbstractParsedStmt method parseTable.

/**
     *
     * @param tableNode
     */
private void parseTable(VoltXMLElement tableNode) {
    String tableName = tableNode.attributes.get("table");
    assert (tableName != null);
    String tableAlias = tableNode.attributes.get("tablealias");
    if (tableAlias == null) {
        tableAlias = tableName;
    }
    // Hsql rejects name conflicts in a single query
    m_tableAliasListAsJoinOrder.add(tableAlias);
    VoltXMLElement subqueryElement = null;
    // Possible sub-query
    for (VoltXMLElement childNode : tableNode.children) {
        if (!childNode.name.equals("tablesubquery")) {
            continue;
        }
        if (childNode.children.isEmpty()) {
            continue;
        }
        // sub-query FROM (SELECT ...)
        subqueryElement = childNode.children.get(0);
        break;
    }
    // add table to the query cache before processing the JOIN/WHERE expressions
    // The order is important because processing sub-query expressions assumes that
    // the sub-query is already registered
    StmtTableScan tableScan = null;
    Table table = null;
    // In case of a subquery we need to preserve its filter expressions
    AbstractExpression simplifiedSubqueryFilter = null;
    if (subqueryElement == null) {
        table = getTableFromDB(tableName);
        assert (table != null);
        tableScan = addTableToStmtCache(table, tableAlias);
        m_tableList.add(table);
    } else {
        AbstractParsedStmt subquery = parseFromSubQuery(subqueryElement);
        StmtSubqueryScan subqueryScan = addSubqueryToStmtCache(subquery, tableAlias);
        tableScan = subqueryScan;
        StmtTargetTableScan simpler = simplifierForSubquery(subquery);
        if (simpler != null) {
            tableScan = addSimplifiedSubqueryToStmtCache(subqueryScan, simpler);
            table = simpler.getTargetTable();
            // Extract subquery's filters
            assert (subquery.m_joinTree != null);
            // Adjust the table alias in all TVEs from the eliminated
            // subquery expressions. Example:
            // SELECT TA2.CA FROM (SELECT C CA FROM T TA1 WHERE C > 0) TA2
            // The table alias TA1 from the original TVE (T)TA1.C from the
            // subquery WHERE condition needs to be replaced with the alias
            // TA2. The new TVE will be (T)TA2.C.
            // The column alias does not require an adjustment.
            simplifiedSubqueryFilter = subquery.m_joinTree.getAllFilters();
            List<TupleValueExpression> tves = ExpressionUtil.getTupleValueExpressions(simplifiedSubqueryFilter);
            for (TupleValueExpression tve : tves) {
                tve.setTableAlias(tableScan.getTableAlias());
                tve.setOrigStmtId(m_stmtId);
            }
        }
    }
    AbstractExpression joinExpr = parseJoinCondition(tableNode);
    AbstractExpression whereExpr = parseWhereCondition(tableNode);
    if (simplifiedSubqueryFilter != null) {
        // Add subqueruy's expressions as JOIN filters to make sure they will
        // stay at the node level in case of an OUTER joins and won't affect
        // the join simplification process:
        // select * from T LEFT JOIN (select C FROM T1 WHERE C > 2) S ON T.C = S.C;
        joinExpr = (joinExpr != null) ? ExpressionUtil.combine(joinExpr, simplifiedSubqueryFilter) : simplifiedSubqueryFilter;
    }
    // The join type of the leaf node is always INNER
    // For a new tree its node's ids start with 0 and keep incrementing by 1
    int nodeId = (m_joinTree == null) ? 0 : m_joinTree.getId() + 1;
    JoinNode leafNode;
    if (table != null) {
        assert (tableScan instanceof StmtTargetTableScan);
        leafNode = new TableLeafNode(nodeId, joinExpr, whereExpr, (StmtTargetTableScan) tableScan);
    } else {
        assert (tableScan instanceof StmtSubqueryScan);
        leafNode = new SubqueryLeafNode(nodeId, joinExpr, whereExpr, (StmtSubqueryScan) tableScan);
        leafNode.updateContentDeterminismMessage(((StmtSubqueryScan) tableScan).calculateContentDeterminismMessage());
    }
    if (m_joinTree == null) {
        // this is the first table
        m_joinTree = leafNode;
    } else {
        // Build the tree by attaching the next table always to the right
        // The node's join type is determined by the type of its right node
        JoinType joinType = JoinType.get(tableNode.attributes.get("jointype"));
        assert (joinType != JoinType.INVALID);
        JoinNode joinNode = new BranchNode(nodeId + 1, joinType, m_joinTree, leafNode);
        m_joinTree = joinNode;
    }
}
Also used : StmtSubqueryScan(org.voltdb.planner.parseinfo.StmtSubqueryScan) TupleValueExpression(org.voltdb.expressions.TupleValueExpression) Table(org.voltdb.catalog.Table) TableLeafNode(org.voltdb.planner.parseinfo.TableLeafNode) JoinNode(org.voltdb.planner.parseinfo.JoinNode) JoinType(org.voltdb.types.JoinType) VoltXMLElement(org.hsqldb_voltpatches.VoltXMLElement) Constraint(org.voltdb.catalog.Constraint) StmtTableScan(org.voltdb.planner.parseinfo.StmtTableScan) BranchNode(org.voltdb.planner.parseinfo.BranchNode) AbstractExpression(org.voltdb.expressions.AbstractExpression) SubqueryLeafNode(org.voltdb.planner.parseinfo.SubqueryLeafNode) StmtTargetTableScan(org.voltdb.planner.parseinfo.StmtTargetTableScan)

Aggregations

JoinType (org.voltdb.types.JoinType)4 BranchNode (org.voltdb.planner.parseinfo.BranchNode)3 AbstractExpression (org.voltdb.expressions.AbstractExpression)2 JoinNode (org.voltdb.planner.parseinfo.JoinNode)2 VoltXMLElement (org.hsqldb_voltpatches.VoltXMLElement)1 Constraint (org.voltdb.catalog.Constraint)1 Table (org.voltdb.catalog.Table)1 TupleValueExpression (org.voltdb.expressions.TupleValueExpression)1 StmtSubqueryScan (org.voltdb.planner.parseinfo.StmtSubqueryScan)1 StmtTableScan (org.voltdb.planner.parseinfo.StmtTableScan)1 StmtTargetTableScan (org.voltdb.planner.parseinfo.StmtTargetTableScan)1 SubqueryLeafNode (org.voltdb.planner.parseinfo.SubqueryLeafNode)1 TableLeafNode (org.voltdb.planner.parseinfo.TableLeafNode)1