Search in sources :

Example 6 with GridSqlQuery

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

the class UpdatePlanBuilder method planForInsert.

/**
     * Prepare update plan for INSERT or MERGE.
     *
     * @param stmt INSERT or MERGE statement.
     * @return Update plan.
     * @throws IgniteCheckedException if failed.
     */
@SuppressWarnings("ConstantConditions")
private static UpdatePlan planForInsert(GridSqlStatement stmt) throws IgniteCheckedException {
    GridSqlQuery sel;
    GridSqlElement target;
    GridSqlColumn[] cols;
    boolean isTwoStepSubqry;
    int rowsNum;
    GridSqlTable tbl;
    GridH2RowDescriptor desc;
    if (stmt instanceof GridSqlInsert) {
        GridSqlInsert ins = (GridSqlInsert) stmt;
        target = ins.into();
        tbl = gridTableForElement(target);
        desc = tbl.dataTable().rowDescriptor();
        cols = ins.columns();
        sel = DmlAstUtils.selectForInsertOrMerge(cols, ins.rows(), ins.query(), desc);
        isTwoStepSubqry = (ins.query() != null);
        rowsNum = isTwoStepSubqry ? 0 : ins.rows().size();
    } else if (stmt instanceof GridSqlMerge) {
        GridSqlMerge merge = (GridSqlMerge) stmt;
        target = merge.into();
        tbl = gridTableForElement(target);
        desc = tbl.dataTable().rowDescriptor();
        // This check also protects us from attempts to update key or its fields directly -
        // when no key except cache key can be used, it will serve only for uniqueness checks,
        // not for updates, and hence will allow putting new pairs only.
        // We don't quote _key and _val column names on CREATE TABLE, so they are always uppercase here.
        GridSqlColumn[] keys = merge.keys();
        if (keys.length != 1 || !desc.isKeyColumn(tbl.dataTable().getColumn(keys[0].columnName()).getColumnId()))
            throw new CacheException("SQL MERGE does not support arbitrary keys");
        cols = merge.columns();
        sel = DmlAstUtils.selectForInsertOrMerge(cols, merge.rows(), merge.query(), desc);
        isTwoStepSubqry = (merge.query() != null);
        rowsNum = isTwoStepSubqry ? 0 : merge.rows().size();
    } else
        throw new IgniteSQLException("Unexpected DML operation [cls=" + stmt.getClass().getName() + ']', IgniteQueryErrorCode.UNEXPECTED_OPERATION);
    // Let's set the flag only for subqueries that have their FROM specified.
    isTwoStepSubqry = (isTwoStepSubqry && (sel instanceof GridSqlUnion || (sel instanceof GridSqlSelect && ((GridSqlSelect) sel).from() != null)));
    int keyColIdx = -1;
    int valColIdx = -1;
    boolean hasKeyProps = false;
    boolean hasValProps = false;
    if (desc == null)
        throw new IgniteSQLException("Row descriptor undefined for table '" + tbl.dataTable().getName() + "'", IgniteQueryErrorCode.NULL_TABLE_DESCRIPTOR);
    GridCacheContext<?, ?> cctx = desc.context();
    String[] colNames = new String[cols.length];
    int[] colTypes = new int[cols.length];
    for (int i = 0; i < cols.length; i++) {
        GridSqlColumn col = cols[i];
        String colName = col.columnName();
        colNames[i] = colName;
        colTypes[i] = col.resultType().type();
        int colId = col.column().getColumnId();
        if (desc.isKeyColumn(colId)) {
            keyColIdx = i;
            continue;
        }
        if (desc.isValueColumn(colId)) {
            valColIdx = i;
            continue;
        }
        GridQueryProperty prop = desc.type().property(colName);
        assert prop != null : "Property '" + colName + "' not found.";
        if (prop.key())
            hasKeyProps = true;
        else
            hasValProps = true;
    }
    KeyValueSupplier keySupplier = createSupplier(cctx, desc.type(), keyColIdx, hasKeyProps, true, false);
    KeyValueSupplier valSupplier = createSupplier(cctx, desc.type(), valColIdx, hasValProps, false, false);
    if (stmt instanceof GridSqlMerge)
        return UpdatePlan.forMerge(tbl.dataTable(), colNames, colTypes, keySupplier, valSupplier, keyColIdx, valColIdx, sel.getSQL(), !isTwoStepSubqry, rowsNum);
    else
        return UpdatePlan.forInsert(tbl.dataTable(), colNames, colTypes, keySupplier, valSupplier, keyColIdx, valColIdx, sel.getSQL(), !isTwoStepSubqry, rowsNum);
}
Also used : GridSqlMerge(org.apache.ignite.internal.processors.query.h2.sql.GridSqlMerge) GridSqlUnion(org.apache.ignite.internal.processors.query.h2.sql.GridSqlUnion) CacheException(javax.cache.CacheException) GridSqlSelect(org.apache.ignite.internal.processors.query.h2.sql.GridSqlSelect) GridSqlQuery(org.apache.ignite.internal.processors.query.h2.sql.GridSqlQuery) GridQueryProperty(org.apache.ignite.internal.processors.query.GridQueryProperty) GridH2RowDescriptor(org.apache.ignite.internal.processors.query.h2.opt.GridH2RowDescriptor) GridSqlColumn(org.apache.ignite.internal.processors.query.h2.sql.GridSqlColumn) GridSqlTable(org.apache.ignite.internal.processors.query.h2.sql.GridSqlTable) IgniteSQLException(org.apache.ignite.internal.processors.query.IgniteSQLException) GridSqlElement(org.apache.ignite.internal.processors.query.h2.sql.GridSqlElement) GridSqlInsert(org.apache.ignite.internal.processors.query.h2.sql.GridSqlInsert)

Example 7 with GridSqlQuery

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

the class UpdatePlanBuilder method planForInsert.

/**
 * Prepare update plan for INSERT or MERGE.
 *
 * @param stmt INSERT or MERGE statement.
 * @param loc Local query flag.
 * @param idx Indexing.
 * @param conn Connection.
 * @param fieldsQuery Original query.
 * @return Update plan.
 * @throws IgniteCheckedException if failed.
 */
@SuppressWarnings("ConstantConditions")
private static UpdatePlan planForInsert(GridSqlStatement stmt, boolean loc, IgniteH2Indexing idx, @Nullable Connection conn, @Nullable SqlFieldsQuery fieldsQuery) throws IgniteCheckedException {
    GridSqlQuery sel;
    GridSqlElement target;
    GridSqlColumn[] cols;
    boolean isTwoStepSubqry;
    int rowsNum;
    GridSqlTable tbl;
    GridH2RowDescriptor desc;
    List<GridSqlElement[]> elRows = null;
    if (stmt instanceof GridSqlInsert) {
        GridSqlInsert ins = (GridSqlInsert) stmt;
        target = ins.into();
        tbl = DmlAstUtils.gridTableForElement(target);
        desc = tbl.dataTable().rowDescriptor();
        cols = ins.columns();
        sel = DmlAstUtils.selectForInsertOrMerge(cols, ins.rows(), ins.query());
        if (sel == null)
            elRows = ins.rows();
        isTwoStepSubqry = (ins.query() != null);
        rowsNum = isTwoStepSubqry ? 0 : ins.rows().size();
    } else if (stmt instanceof GridSqlMerge) {
        GridSqlMerge merge = (GridSqlMerge) stmt;
        target = merge.into();
        tbl = DmlAstUtils.gridTableForElement(target);
        desc = tbl.dataTable().rowDescriptor();
        cols = merge.columns();
        sel = DmlAstUtils.selectForInsertOrMerge(cols, merge.rows(), merge.query());
        if (sel == null)
            elRows = merge.rows();
        isTwoStepSubqry = (merge.query() != null);
        rowsNum = isTwoStepSubqry ? 0 : merge.rows().size();
    } else {
        throw new IgniteSQLException("Unexpected DML operation [cls=" + stmt.getClass().getName() + ']', IgniteQueryErrorCode.UNEXPECTED_OPERATION);
    }
    // Let's set the flag only for subqueries that have their FROM specified.
    isTwoStepSubqry &= (sel != null && (sel instanceof GridSqlUnion || (sel instanceof GridSqlSelect && ((GridSqlSelect) sel).from() != null)));
    int keyColIdx = -1;
    int valColIdx = -1;
    boolean hasKeyProps = false;
    boolean hasValProps = false;
    if (desc == null)
        throw new IgniteSQLException("Row descriptor undefined for table '" + tbl.dataTable().getName() + "'", IgniteQueryErrorCode.NULL_TABLE_DESCRIPTOR);
    GridCacheContext<?, ?> cctx = desc.context();
    String[] colNames = new String[cols.length];
    int[] colTypes = new int[cols.length];
    for (int i = 0; i < cols.length; i++) {
        GridSqlColumn col = cols[i];
        String colName = col.columnName();
        colNames[i] = colName;
        colTypes[i] = col.resultType().type();
        int colId = col.column().getColumnId();
        if (desc.isKeyColumn(colId)) {
            keyColIdx = i;
            continue;
        }
        if (desc.isValueColumn(colId)) {
            valColIdx = i;
            continue;
        }
        GridQueryProperty prop = desc.type().property(colName);
        assert prop != null : "Property '" + colName + "' not found.";
        if (prop.key())
            hasKeyProps = true;
        else
            hasValProps = true;
    }
    KeyValueSupplier keySupplier = createSupplier(cctx, desc.type(), keyColIdx, hasKeyProps, true, false);
    KeyValueSupplier valSupplier = createSupplier(cctx, desc.type(), valColIdx, hasValProps, false, false);
    String selectSql = sel != null ? sel.getSQL() : null;
    DmlDistributedPlanInfo distributed = (rowsNum == 0 && !F.isEmpty(selectSql)) ? checkPlanCanBeDistributed(idx, conn, fieldsQuery, loc, selectSql, tbl.dataTable().cacheName()) : null;
    UpdateMode mode = stmt instanceof GridSqlMerge ? UpdateMode.MERGE : UpdateMode.INSERT;
    List<List<DmlArgument>> rows = null;
    if (elRows != null) {
        assert sel == null;
        rows = new ArrayList<>(elRows.size());
        for (GridSqlElement[] elRow : elRows) {
            List<DmlArgument> row = new ArrayList<>(cols.length);
            for (GridSqlElement el : elRow) {
                DmlArgument arg = DmlArguments.create(el);
                row.add(arg);
            }
            rows.add(row);
        }
    }
    return new UpdatePlan(mode, tbl.dataTable(), colNames, colTypes, keySupplier, valSupplier, keyColIdx, valColIdx, selectSql, !isTwoStepSubqry, rows, rowsNum, null, distributed);
}
Also used : GridSqlMerge(org.apache.ignite.internal.processors.query.h2.sql.GridSqlMerge) ArrayList(java.util.ArrayList) GridH2RowDescriptor(org.apache.ignite.internal.processors.query.h2.opt.GridH2RowDescriptor) GridSqlTable(org.apache.ignite.internal.processors.query.h2.sql.GridSqlTable) GridSqlInsert(org.apache.ignite.internal.processors.query.h2.sql.GridSqlInsert) ArrayList(java.util.ArrayList) List(java.util.List) GridSqlUnion(org.apache.ignite.internal.processors.query.h2.sql.GridSqlUnion) GridSqlSelect(org.apache.ignite.internal.processors.query.h2.sql.GridSqlSelect) GridSqlQuery(org.apache.ignite.internal.processors.query.h2.sql.GridSqlQuery) GridQueryProperty(org.apache.ignite.internal.processors.query.GridQueryProperty) GridSqlColumn(org.apache.ignite.internal.processors.query.h2.sql.GridSqlColumn) IgniteSQLException(org.apache.ignite.internal.processors.query.IgniteSQLException) GridSqlElement(org.apache.ignite.internal.processors.query.h2.sql.GridSqlElement)

Example 8 with GridSqlQuery

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

the class GridSubqueryJoinOptimizer method subQueryCanBePulledOut.

/**
 * Whether sub-query can be pulled out or not.
 *
 * @param subQry Sub-query.
 * @return {@code true} if sub-query cound be pulled out, {@code false} otherwise.
 */
private static boolean subQueryCanBePulledOut(GridSqlSubquery subQry) {
    GridSqlQuery subQ = subQry.subquery();
    if (!isSimpleSelect(subQ))
        return false;
    assert subQ instanceof GridSqlSelect;
    GridSqlSelect subS = (GridSqlSelect) subQ;
    if (subS.where() == null)
        return false;
    Predicate<GridSqlAst> andOrEqPre = ELEMENT_IS_AND_OPERATION.or(ELEMENT_IS_EQ);
    if (!andOrEqPre.test(subS.where()))
        return false;
    ASTNodeFinder opEqFinder = new ASTNodeFinder(subS.where(), (parent, child) -> ELEMENT_IS_EQ.test(parent), andOrEqPre);
    List<GridSqlColumn> sqlCols = new ArrayList<>();
    ASTNodeFinder.Result res;
    while ((res = opEqFinder.findNext()) != null) {
        GridSqlOperation op = (GridSqlOperation) res.getEl();
        assert op.size() == 2;
        GridSqlColumn[] colArr = new GridSqlColumn[2];
        for (int i = 0; i < 2; i++) {
            if (op.child(i) instanceof GridSqlColumn)
                colArr[i] = op.child(i);
            else if (op.child(i) instanceof GridSqlOperation && ((GridSqlOperation) op.child(i)).operationType() == NEGATE && op.child() instanceof GridSqlColumn)
                colArr[i] = op.child(i).child();
        }
        if (colArr[0] == null || colArr[1] == null || // whether the column refers to exactly the same table
        colArr[0].expressionInFrom() != colArr[1].expressionInFrom()) {
            if (colArr[0] != null && colArr[0].expressionInFrom() == subS.from())
                sqlCols.add(colArr[0]);
            if (colArr[1] != null && colArr[1].expressionInFrom() == subS.from())
                sqlCols.add(colArr[1]);
        }
    }
    GridSqlAst subTbl = GridSqlAlias.unwrap(subS.from());
    return subTbl instanceof GridSqlTable && isUniqueIndexExists(sqlCols, (GridSqlTable) subTbl);
}
Also used : ArrayList(java.util.ArrayList) GridSqlSelect(org.apache.ignite.internal.processors.query.h2.sql.GridSqlSelect) GridSqlQuery(org.apache.ignite.internal.processors.query.h2.sql.GridSqlQuery) GridSqlAst(org.apache.ignite.internal.processors.query.h2.sql.GridSqlAst) GridSqlColumn(org.apache.ignite.internal.processors.query.h2.sql.GridSqlColumn) GridSqlTable(org.apache.ignite.internal.processors.query.h2.sql.GridSqlTable) GridSqlOperation(org.apache.ignite.internal.processors.query.h2.sql.GridSqlOperation)

Example 9 with GridSqlQuery

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

the class PartitionExtractor method extract.

/**
 * Extract partitions.
 *
 * @param qry Query.
 * @return Partitions.
 */
public PartitionResult extract(GridSqlQuery qry) throws IgniteCheckedException {
    // No unions support yet.
    if (!(qry instanceof GridSqlSelect))
        return null;
    GridSqlSelect select = (GridSqlSelect) qry;
    // Prepare table model.
    PartitionTableModel tblModel = prepareTableModel(select.from());
    // Do extract.
    PartitionNode tree = extractFromExpression(select.where(), tblModel, false);
    assert tree != null;
    // Reduce tree if possible.
    tree = tree.optimize();
    if (tree instanceof PartitionAllNode)
        return null;
    // Done.
    return new PartitionResult(tree, tblModel.joinGroupAffinity(tree.joinGroup()), ctx.cache().context().exchange().readyAffinityVersion());
}
Also used : PartitionAllNode(org.apache.ignite.internal.sql.optimizer.affinity.PartitionAllNode) PartitionNode(org.apache.ignite.internal.sql.optimizer.affinity.PartitionNode) PartitionTableModel(org.apache.ignite.internal.sql.optimizer.affinity.PartitionTableModel) PartitionResult(org.apache.ignite.internal.sql.optimizer.affinity.PartitionResult) GridSqlSelect(org.apache.ignite.internal.processors.query.h2.sql.GridSqlSelect)

Example 10 with GridSqlQuery

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

the class DmlAstUtils method findParams.

/**
 * @param qry Select.
 * @param params Parameters.
 * @param target Extracted parameters.
 * @param paramIdxs Parameter indexes.
 * @return Extracted parameters list.
 */
@SuppressWarnings("unused")
private static List<Object> findParams(GridSqlQuery qry, Object[] params, ArrayList<Object> target, IntArray paramIdxs) {
    if (qry instanceof GridSqlSelect)
        return findParams((GridSqlSelect) qry, params, target, paramIdxs);
    GridSqlUnion union = (GridSqlUnion) qry;
    findParams(union.left(), params, target, paramIdxs);
    findParams(union.right(), params, target, paramIdxs);
    findParams((GridSqlElement) qry.limit(), params, target, paramIdxs);
    findParams((GridSqlElement) qry.offset(), params, target, paramIdxs);
    return target;
}
Also used : GridSqlUnion(org.apache.ignite.internal.processors.query.h2.sql.GridSqlUnion) GridSqlSelect(org.apache.ignite.internal.processors.query.h2.sql.GridSqlSelect)

Aggregations

GridSqlSelect (org.apache.ignite.internal.processors.query.h2.sql.GridSqlSelect)12 GridSqlQuery (org.apache.ignite.internal.processors.query.h2.sql.GridSqlQuery)9 GridSqlElement (org.apache.ignite.internal.processors.query.h2.sql.GridSqlElement)7 IgniteSQLException (org.apache.ignite.internal.processors.query.IgniteSQLException)6 GridSqlUnion (org.apache.ignite.internal.processors.query.h2.sql.GridSqlUnion)6 GridSqlColumn (org.apache.ignite.internal.processors.query.h2.sql.GridSqlColumn)5 GridSqlTable (org.apache.ignite.internal.processors.query.h2.sql.GridSqlTable)4 PreparedStatement (java.sql.PreparedStatement)3 SQLException (java.sql.SQLException)3 ArrayList (java.util.ArrayList)3 IgniteCheckedException (org.apache.ignite.IgniteCheckedException)3 GridCacheTwoStepQuery (org.apache.ignite.internal.processors.cache.query.GridCacheTwoStepQuery)3 GridQueryProperty (org.apache.ignite.internal.processors.query.GridQueryProperty)3 GridH2RowDescriptor (org.apache.ignite.internal.processors.query.h2.opt.GridH2RowDescriptor)3 GridSqlAst (org.apache.ignite.internal.processors.query.h2.sql.GridSqlAst)3 GridSqlInsert (org.apache.ignite.internal.processors.query.h2.sql.GridSqlInsert)3 GridSqlMerge (org.apache.ignite.internal.processors.query.h2.sql.GridSqlMerge)3 GridSqlQueryParser (org.apache.ignite.internal.processors.query.h2.sql.GridSqlQueryParser)3 Prepared (org.h2.command.Prepared)3 List (java.util.List)2