Search in sources :

Example 1 with GridSqlJoin

use of org.apache.ignite.internal.processors.query.h2.sql.GridSqlJoin in project ignite by apache.

the class PartitionExtractor method prepareTableModel0.

/**
 * Prepare tables which will be used in join model.
 *
 * @param from From flag.
 * @param model Table model.
 * @return {@code True} if extracted tables successfully, {@code false} if failed to extract.
 */
private List<PartitionTable> prepareTableModel0(GridSqlAst from, PartitionTableModel model) {
    if (from instanceof GridSqlJoin) {
        // Process JOIN recursively.
        GridSqlJoin join = (GridSqlJoin) from;
        List<PartitionTable> leftTbls = prepareTableModel0(join.leftTable(), model);
        List<PartitionTable> rightTbls = prepareTableModel0(join.rightTable(), model);
        if (join.isLeftOuter()) {
            // If a condition is met on "b" afterwards, we will ignore it.
            for (PartitionTable rightTbl : rightTbls) model.addExcludedTable(rightTbl.alias());
            return leftTbls;
        }
        // Extract equi-join or cross-join from condition. For normal INNER JOINs most likely we will have "1=1"
        // cross join here, real join condition will be found in WHERE clause later.
        PartitionJoinCondition cond = parseJoinCondition(join.on());
        if (cond != null && !cond.cross())
            model.addJoin(cond);
        ArrayList<PartitionTable> res = new ArrayList<>(leftTbls.size() + rightTbls.size());
        res.addAll(leftTbls);
        res.addAll(rightTbls);
        return res;
    }
    PartitionTable tbl = prepareTable(from, model);
    return tbl != null ? Collections.singletonList(tbl) : Collections.emptyList();
}
Also used : PartitionTable(org.apache.ignite.internal.sql.optimizer.affinity.PartitionTable) PartitionJoinCondition(org.apache.ignite.internal.sql.optimizer.affinity.PartitionJoinCondition) GridSqlJoin(org.apache.ignite.internal.processors.query.h2.sql.GridSqlJoin) ArrayList(java.util.ArrayList)

Example 2 with GridSqlJoin

use of org.apache.ignite.internal.processors.query.h2.sql.GridSqlJoin in project ignite by apache.

the class GridSubqueryJoinOptimizer method pullOutSubQryFromSelectExpr.

/**
 * Pull out sub-select from SELECT clause to the parent select level.
 * <p>
 * Example:
 * <pre>
 *   Before:
 *     SELECT name,
 *            (SELECT name FROM dep d WHERE d.id = e.dep_id) as dep_name
 *       FROM emp e
 *      WHERE sal > 2000
 *
 *   After:
 *     SELECT name,
 *            d.name as dep_name
 *       FROM emp e
 *       LEFT JOIN dep d
 *         ON d.id = e.dep_id
 *      WHERE sal > 2000
 * </pre>
 *
 * @param parent Parent select.
 * @param targetEl Target sql element. Can be {@code null}.
 * @param childInd Column ind.
 */
private static boolean pullOutSubQryFromSelectExpr(GridSqlSelect parent, @Nullable GridSqlAst targetEl, int childInd) {
    GridSqlSubquery subQry = targetEl != null ? targetEl.child(childInd) : (GridSqlSubquery) parent.columns(false).get(childInd);
    if (!subQueryCanBePulledOut(subQry))
        return false;
    GridSqlSelect subS = subQry.subquery();
    if (subS.allColumns() != 1)
        return false;
    GridSqlAst subCol = GridSqlAlias.unwrap(subS.columns(false).get(0));
    if (subCol instanceof GridSqlConst)
        return false;
    if (targetEl != null)
        targetEl.child(childInd, subCol);
    else
        parent.setColumn(childInd, subCol);
    GridSqlElement parentFrom = parent.from() instanceof GridSqlElement ? (GridSqlElement) parent.from() : new GridSqlSubquery((GridSqlQuery) parent.from());
    parent.from(new GridSqlJoin(parentFrom, GridSqlAlias.unwrap(subS.from()), true, (GridSqlElement) subS.where())).child();
    return true;
}
Also used : GridSqlQuery(org.apache.ignite.internal.processors.query.h2.sql.GridSqlQuery) GridSqlConst(org.apache.ignite.internal.processors.query.h2.sql.GridSqlConst) GridSqlSubquery(org.apache.ignite.internal.processors.query.h2.sql.GridSqlSubquery) GridSqlAst(org.apache.ignite.internal.processors.query.h2.sql.GridSqlAst) GridSqlJoin(org.apache.ignite.internal.processors.query.h2.sql.GridSqlJoin) GridSqlElement(org.apache.ignite.internal.processors.query.h2.sql.GridSqlElement) GridSqlSelect(org.apache.ignite.internal.processors.query.h2.sql.GridSqlSelect)

Example 3 with GridSqlJoin

use of org.apache.ignite.internal.processors.query.h2.sql.GridSqlJoin in project ignite by apache.

the class GridSubqueryJoinOptimizer method pullOutSubQryFromExistsClause.

/**
 * Pull out sub-select from EXISTS clause to the parent select level.
 * <p>
 * Example:
 * <pre>
 *   Before:
 *     SELECT name
 *       FROM emp e
 *      WHERE EXISTS (SELECT 1 FROM dep d WHERE d.id = e.dep_id and d.name = 'dep1')
 *        AND sal > 2000
 *
 *   After:
 *     SELECT name
 *       FROM emp e
 *       JOIN dep d
 *      WHERE sal > 2000 AND d.id = e.dep_id and d.name = 'dep1
 * </pre>
 *
 * @param parent Parent select.
 * @param targetEl Target sql element. Can be null.
 * @param childInd Column ind.
 */
private static boolean pullOutSubQryFromExistsClause(GridSqlSelect parent, @Nullable GridSqlAst targetEl, int childInd) {
    // extract sub-query
    GridSqlSubquery subQry = targetEl != null ? targetEl.child(childInd).child() : parent.where().child();
    if (!subQueryCanBePulledOut(subQry))
        return false;
    GridSqlSelect subS = subQry.subquery();
    if (targetEl != null)
        targetEl.child(childInd, subS.where());
    else
        parent.where(subS.where());
    GridSqlElement parentFrom = parent.from() instanceof GridSqlElement ? (GridSqlElement) parent.from() : new GridSqlSubquery((GridSqlQuery) parent.from());
    parent.from(new GridSqlJoin(parentFrom, GridSqlAlias.unwrap(subS.from()), false, null)).child();
    return true;
}
Also used : GridSqlQuery(org.apache.ignite.internal.processors.query.h2.sql.GridSqlQuery) GridSqlSubquery(org.apache.ignite.internal.processors.query.h2.sql.GridSqlSubquery) GridSqlJoin(org.apache.ignite.internal.processors.query.h2.sql.GridSqlJoin) GridSqlElement(org.apache.ignite.internal.processors.query.h2.sql.GridSqlElement) GridSqlSelect(org.apache.ignite.internal.processors.query.h2.sql.GridSqlSelect)

Example 4 with GridSqlJoin

use of org.apache.ignite.internal.processors.query.h2.sql.GridSqlJoin in project ignite by apache.

the class SqlAstTraverser method lookForPartitionedJoin.

/**
 * Traverse AST while join operation isn't found. Check it if found.
 *
 * @param ast AST item to check recursively.
 * @param upWhere Where condition that applies to this ast.
 */
private void lookForPartitionedJoin(GridSqlAst ast, GridSqlAst upWhere) {
    if (ast == null)
        return;
    GridSqlJoin join = null;
    GridSqlAst where = null;
    if (ast instanceof GridSqlJoin) {
        join = (GridSqlJoin) ast;
        where = upWhere;
    } else if (ast instanceof GridSqlSelect) {
        GridSqlSelect select = (GridSqlSelect) ast;
        if (select.from() instanceof GridSqlJoin) {
            join = (GridSqlJoin) select.from();
            where = select.where();
        }
    } else if (ast instanceof GridSqlSubquery)
        hasSubQueries = true;
    else if (ast instanceof GridSqlTable)
        hasPartitionedTables |= ((GridSqlTable) ast).dataTable().isPartitioned();
    // No joins on this level. Traverse AST deeper.
    if (join == null) {
        for (int i = 0; i < ast.size(); i++) lookForPartitionedJoin(ast.child(i), null);
        return;
    }
    // Check WHERE clause first.
    lookForPartitionedJoin(where, null);
    // Check left side of join.
    GridSqlTable leftTable = getTable(join.leftTable());
    GridH2Table left = null;
    // Left side of join is a subquery.
    if (leftTable == null) {
        hasSubQueries = true;
        // Check subquery on left side.
        lookForPartitionedJoin(join.leftTable(), where);
    } else {
        left = leftTable.dataTable();
        // Data table is NULL for views.
        if (left != null && left.isPartitioned())
            hasPartitionedTables = true;
    }
    // Check right side of join.
    GridSqlTable rightTable = getTable(join.rightTable());
    // Right side of join is a subquery.
    if (rightTable == null) {
        hasSubQueries = true;
        // Check subquery and return (can't exctract more info there).
        lookForPartitionedJoin(join.rightTable(), where);
        return;
    }
    GridH2Table right = rightTable.dataTable();
    if (right != null && right.isPartitioned())
        hasPartitionedTables = true;
    // Skip check of views.
    if (left == null || right == null)
        return;
    if (join.isLeftOuter() && !left.isPartitioned() && right.isPartitioned())
        hasOuterJoinReplicatedPartitioned = true;
    // Skip check if at least one of tables isn't partitioned.
    if (!(left.isPartitioned() && right.isPartitioned()))
        return;
    if (!distributedJoins)
        checkPartitionedJoin(join, where, left, right, log);
}
Also used : GridH2Table(org.apache.ignite.internal.processors.query.h2.opt.GridH2Table)

Example 5 with GridSqlJoin

use of org.apache.ignite.internal.processors.query.h2.sql.GridSqlJoin in project ignite by apache.

the class GridSubqueryJoinOptimizer method pullOutSubQryFromTableList.

/**
 * Pull out sub-select from table list.
 * <p>
 * Example:
 * <pre>
 *   Before:
 *     SELECT d.name
 *       FROM emp e,
 *            (select * from dep) d
 *      WHERE e.dep_id = d.id
 *        AND e.sal > 2000
 *
 *   After:
 *     SELECT d.name
 *       FROM emp e
 *       JOIN dep d
 *      WHERE sal > 2000 AND d.id = e.dep_id
 * </pre>
 *
 * @param parent Parent select.
 * @param target Target sql element. Can be {@code null}.
 * @param childInd Column index.
 */
private static boolean pullOutSubQryFromTableList(GridSqlSelect parent, @Nullable GridSqlAst target, int childInd) {
    if (target != null && !ELEMENT_IS_JOIN.test(target))
        return false;
    GridSqlAlias wrappedSubQry = target != null ? target.child(childInd) : (GridSqlAlias) parent.from();
    GridSqlSubquery subQry = GridSqlAlias.unwrap(wrappedSubQry);
    if (!isSimpleSelect(subQry.subquery()))
        return false;
    GridSqlSelect subSel = subQry.subquery();
    if (!(subSel.from() instanceof GridSqlAlias) && !(subSel.from() instanceof GridSqlTable))
        // we can't deal with joins and others right now
        return false;
    GridSqlAlias subTbl = new GridSqlAlias(wrappedSubQry.alias(), GridSqlAlias.unwrap(subSel.from()));
    if (target == null)
        // it's true only when the subquery is only table in the table list
        // so we can safely replace entire FROM expression of the parent
        parent.from(subTbl);
    else
        target.child(childInd, subTbl);
    GridSqlAst where = subSel.where();
    if (where != null) {
        if (target != null) {
            GridSqlJoin join = (GridSqlJoin) target;
            join.child(GridSqlJoin.ON_CHILD, new GridSqlOperation(AND, join.on(), where));
        } else
            parent.where(parent.where() == null ? where : new GridSqlOperation(AND, parent.where(), where));
    }
    remapColumns(parent, subSel, // reference equality used intentionally here
    col -> wrappedSubQry == col.expressionInFrom(), subTbl);
    return true;
}
Also used : GridSqlAlias(org.apache.ignite.internal.processors.query.h2.sql.GridSqlAlias) GridSqlSubquery(org.apache.ignite.internal.processors.query.h2.sql.GridSqlSubquery) GridSqlAst(org.apache.ignite.internal.processors.query.h2.sql.GridSqlAst) GridSqlJoin(org.apache.ignite.internal.processors.query.h2.sql.GridSqlJoin) GridSqlTable(org.apache.ignite.internal.processors.query.h2.sql.GridSqlTable) GridSqlOperation(org.apache.ignite.internal.processors.query.h2.sql.GridSqlOperation) GridSqlSelect(org.apache.ignite.internal.processors.query.h2.sql.GridSqlSelect)

Aggregations

GridSqlJoin (org.apache.ignite.internal.processors.query.h2.sql.GridSqlJoin)4 GridSqlSelect (org.apache.ignite.internal.processors.query.h2.sql.GridSqlSelect)3 GridSqlSubquery (org.apache.ignite.internal.processors.query.h2.sql.GridSqlSubquery)3 ArrayList (java.util.ArrayList)2 GridH2Table (org.apache.ignite.internal.processors.query.h2.opt.GridH2Table)2 GridSqlAst (org.apache.ignite.internal.processors.query.h2.sql.GridSqlAst)2 GridSqlElement (org.apache.ignite.internal.processors.query.h2.sql.GridSqlElement)2 GridSqlQuery (org.apache.ignite.internal.processors.query.h2.sql.GridSqlQuery)2 IgniteSQLException (org.apache.ignite.internal.processors.query.IgniteSQLException)1 GridSqlAlias (org.apache.ignite.internal.processors.query.h2.sql.GridSqlAlias)1 GridSqlConst (org.apache.ignite.internal.processors.query.h2.sql.GridSqlConst)1 GridSqlOperation (org.apache.ignite.internal.processors.query.h2.sql.GridSqlOperation)1 GridSqlTable (org.apache.ignite.internal.processors.query.h2.sql.GridSqlTable)1 GridSqlType.fromExpression (org.apache.ignite.internal.processors.query.h2.sql.GridSqlType.fromExpression)1 PartitionJoinCondition (org.apache.ignite.internal.sql.optimizer.affinity.PartitionJoinCondition)1 PartitionTable (org.apache.ignite.internal.sql.optimizer.affinity.PartitionTable)1 AlterTableAddConstraint (org.h2.command.ddl.AlterTableAddConstraint)1 Expression (org.h2.expression.Expression)1 ValueExpression (org.h2.expression.ValueExpression)1 TableFilter (org.h2.table.TableFilter)1