Search in sources :

Example 6 with GridSqlAlias

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

the class DmlAstUtils method selectForUpdate.

/**
 * Generate SQL SELECT based on UPDATE's WHERE, LIMIT, etc.
 *
 * @param update Update statement.
 * @return SELECT statement.
 */
public static GridSqlSelect selectForUpdate(GridSqlUpdate update) {
    GridSqlSelect mapQry = new GridSqlSelect();
    mapQry.from(update.target());
    Set<GridSqlTable> tbls = new HashSet<>();
    collectAllGridTablesInTarget(update.target(), tbls);
    assert tbls.size() == 1 : "Failed to determine target table for UPDATE";
    GridSqlTable tbl = tbls.iterator().next();
    GridH2Table gridTbl = tbl.dataTable();
    assert gridTbl != null : "Failed to determine target grid table for UPDATE";
    Column h2KeyCol = gridTbl.getColumn(QueryUtils.KEY_COL);
    Column h2ValCol = gridTbl.getColumn(QueryUtils.VAL_COL);
    GridSqlColumn keyCol = new GridSqlColumn(h2KeyCol, tbl, h2KeyCol.getName());
    keyCol.resultType(GridSqlType.fromColumn(h2KeyCol));
    GridSqlColumn valCol = new GridSqlColumn(h2ValCol, tbl, h2ValCol.getName());
    valCol.resultType(GridSqlType.fromColumn(h2ValCol));
    mapQry.addColumn(keyCol, true);
    mapQry.addColumn(valCol, true);
    for (GridSqlColumn c : update.cols()) {
        String newColName = Parser.quoteIdentifier("_upd_" + c.columnName());
        // We have to use aliases to cover cases when the user
        // wants to update _val field directly (if it's a literal)
        GridSqlAlias alias = new GridSqlAlias(newColName, elementOrDefault(update.set().get(c.columnName()), c), true);
        alias.resultType(c.resultType());
        mapQry.addColumn(alias, true);
    }
    GridSqlElement where = update.where();
    // On no MVCC mode we cannot use lazy mode when UPDATE query contains index with updated columns
    // and that index may be chosen to scan by WHERE condition
    // because in this case any rows update may be updated several times.
    // e.g. in the cases below we cannot use lazy mode:
    // 
    // 1. CREATE INDEX idx on test(val)
    // UPDATE test SET val = val + 1 WHERE val >= ?
    // 
    // 2. CREATE INDEX idx on test(val0, val1)
    // UPDATE test SET val1 = val1 + 1 WHERE val0 >= ?
    mapQry.canBeLazy(!isIndexWithUpdateColumnsMayBeUsed(gridTbl, update.cols().stream().map(GridSqlColumn::column).collect(Collectors.toSet()), extractColumns(gridTbl, where)));
    mapQry.where(where);
    mapQry.limit(update.limit());
    return mapQry;
}
Also used : GridSqlAlias(org.apache.ignite.internal.processors.query.h2.sql.GridSqlAlias) GridSqlColumn(org.apache.ignite.internal.processors.query.h2.sql.GridSqlColumn) Column(org.h2.table.Column) GridSqlTable(org.apache.ignite.internal.processors.query.h2.sql.GridSqlTable) GridH2Table(org.apache.ignite.internal.processors.query.h2.opt.GridH2Table) GridSqlColumn(org.apache.ignite.internal.processors.query.h2.sql.GridSqlColumn) GridSqlElement(org.apache.ignite.internal.processors.query.h2.sql.GridSqlElement) ValueString(org.h2.value.ValueString) GridSqlSelect(org.apache.ignite.internal.processors.query.h2.sql.GridSqlSelect) HashSet(java.util.HashSet)

Example 7 with GridSqlAlias

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

the class DmlAstUtils method selectForInsertOrMerge.

/**
 * Create SELECT on which subsequent INSERT or MERGE will be based.
 *
 * @param cols Columns to insert values into.
 * @param rows Rows to create pseudo-SELECT upon.
 * @param subQry Subquery to use rather than rows.
 * @return Subquery or pseudo-SELECT to evaluate inserted expressions, or {@code null} no query needs to be run.
 */
public static GridSqlQuery selectForInsertOrMerge(GridSqlColumn[] cols, List<GridSqlElement[]> rows, GridSqlQuery subQry) {
    if (!F.isEmpty(rows)) {
        assert !F.isEmpty(cols);
        GridSqlSelect sel = new GridSqlSelect();
        GridSqlFunction from = new GridSqlFunction(GridSqlFunctionType.TABLE);
        sel.from(from);
        GridSqlArray[] args = new GridSqlArray[cols.length];
        for (int i = 0; i < cols.length; i++) {
            GridSqlArray arr = new GridSqlArray(rows.size());
            String colName = cols[i].columnName();
            GridSqlAlias alias = new GridSqlAlias(colName, arr);
            alias.resultType(cols[i].resultType());
            from.addChild(alias);
            args[i] = arr;
            GridSqlColumn newCol = new GridSqlColumn(null, from, null, "TABLE", colName);
            newCol.resultType(cols[i].resultType());
            sel.addColumn(newCol, true);
        }
        for (GridSqlElement[] row : rows) {
            assert cols.length == row.length;
            for (int i = 0; i < row.length; i++) args[i].addChild(row[i]);
        }
        return sel;
    } else {
        assert subQry != null;
        return subQry;
    }
}
Also used : GridSqlAlias(org.apache.ignite.internal.processors.query.h2.sql.GridSqlAlias) GridSqlColumn(org.apache.ignite.internal.processors.query.h2.sql.GridSqlColumn) GridSqlElement(org.apache.ignite.internal.processors.query.h2.sql.GridSqlElement) GridSqlFunction(org.apache.ignite.internal.processors.query.h2.sql.GridSqlFunction) ValueString(org.h2.value.ValueString) GridSqlArray(org.apache.ignite.internal.processors.query.h2.sql.GridSqlArray) GridSqlSelect(org.apache.ignite.internal.processors.query.h2.sql.GridSqlSelect)

Example 8 with GridSqlAlias

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

the class GridSqlQuerySplitter method keyColumn.

/**
 * Retrieves _KEY column from SELECT. This column is used for SELECT FOR UPDATE statements.
 *
 * @param sel Select statement.
 * @return Key column alias.
 */
public static GridSqlAlias keyColumn(GridSqlSelect sel) {
    GridSqlAst from = sel.from();
    GridSqlTable tbl = from instanceof GridSqlTable ? (GridSqlTable) from : ((GridSqlElement) from).child();
    GridH2Table gridTbl = tbl.dataTable();
    Column h2KeyCol = gridTbl.getColumn(QueryUtils.KEY_COL);
    GridSqlColumn keyCol = new GridSqlColumn(h2KeyCol, tbl, h2KeyCol.getName());
    keyCol.resultType(GridSqlType.fromColumn(h2KeyCol));
    GridSqlAlias al = SplitterUtils.alias(QueryUtils.KEY_FIELD_NAME, keyCol);
    return al;
}
Also used : Column(org.h2.table.Column) GridSqlSelect.childIndexForColumn(org.apache.ignite.internal.processors.query.h2.sql.GridSqlSelect.childIndexForColumn) GridH2Table(org.apache.ignite.internal.processors.query.h2.opt.GridH2Table)

Example 9 with GridSqlAlias

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

the class DmlAstUtils method selectForUpdate.

/**
 * Generate SQL SELECT based on UPDATE's WHERE, LIMIT, etc.
 *
 * @param update Update statement.
 * @param keysParamIdx Index of new param for the array of keys.
 * @return SELECT statement.
 */
public static GridSqlSelect selectForUpdate(GridSqlUpdate update, @Nullable Integer keysParamIdx) {
    GridSqlSelect mapQry = new GridSqlSelect();
    mapQry.from(update.target());
    Set<GridSqlTable> tbls = new HashSet<>();
    collectAllGridTablesInTarget(update.target(), tbls);
    assert tbls.size() == 1 : "Failed to determine target table for UPDATE";
    GridSqlTable tbl = tbls.iterator().next();
    GridH2Table gridTbl = tbl.dataTable();
    assert gridTbl != null : "Failed to determine target grid table for UPDATE";
    Column h2KeyCol = gridTbl.getColumn(GridH2KeyValueRowOnheap.KEY_COL);
    Column h2ValCol = gridTbl.getColumn(GridH2KeyValueRowOnheap.VAL_COL);
    GridSqlColumn keyCol = new GridSqlColumn(h2KeyCol, tbl, h2KeyCol.getName());
    keyCol.resultType(GridSqlType.fromColumn(h2KeyCol));
    GridSqlColumn valCol = new GridSqlColumn(h2ValCol, tbl, h2ValCol.getName());
    valCol.resultType(GridSqlType.fromColumn(h2ValCol));
    mapQry.addColumn(keyCol, true);
    mapQry.addColumn(valCol, true);
    for (GridSqlColumn c : update.cols()) {
        String newColName = Parser.quoteIdentifier("_upd_" + c.columnName());
        // We have to use aliases to cover cases when the user
        // wants to update _val field directly (if it's a literal)
        GridSqlAlias alias = new GridSqlAlias(newColName, elementOrDefault(update.set().get(c.columnName()), c), true);
        alias.resultType(c.resultType());
        mapQry.addColumn(alias, true);
    }
    GridSqlElement where = update.where();
    if (keysParamIdx != null)
        where = injectKeysFilterParam(where, keyCol, keysParamIdx);
    mapQry.where(where);
    mapQry.limit(update.limit());
    return mapQry;
}
Also used : GridSqlAlias(org.apache.ignite.internal.processors.query.h2.sql.GridSqlAlias) Column(org.h2.table.Column) GridSqlColumn(org.apache.ignite.internal.processors.query.h2.sql.GridSqlColumn) GridSqlTable(org.apache.ignite.internal.processors.query.h2.sql.GridSqlTable) GridH2Table(org.apache.ignite.internal.processors.query.h2.opt.GridH2Table) GridSqlColumn(org.apache.ignite.internal.processors.query.h2.sql.GridSqlColumn) GridSqlElement(org.apache.ignite.internal.processors.query.h2.sql.GridSqlElement) ValueString(org.h2.value.ValueString) GridSqlSelect(org.apache.ignite.internal.processors.query.h2.sql.GridSqlSelect) HashSet(java.util.HashSet)

Example 10 with GridSqlAlias

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

the class GridSqlQueryParser method isLocalQuery.

/**
 * Check if query may be run locally on all caches mentioned in the query.
 * @param replicatedOnlyQry replicated-only query flag from original {@link SqlFieldsQuery}.
 * @return {@code true} if query may be run locally on all caches mentioned in the query, i.e. there's no need
 *     to run distributed query.
 * @see SqlFieldsQuery#isReplicatedOnly()
 */
public boolean isLocalQuery(boolean replicatedOnlyQry) {
    boolean hasCaches = false;
    for (Object o : h2ObjToGridObj.values()) {
        if (o instanceof GridSqlAlias)
            o = GridSqlAlias.unwrap((GridSqlAst) o);
        if (o instanceof GridSqlTable) {
            GridH2Table tbl = ((GridSqlTable) o).dataTable();
            if (tbl != null) {
                hasCaches = true;
                GridCacheContext cctx = tbl.cache();
                if (!cctx.isLocal() && !(replicatedOnlyQry && cctx.isReplicatedAffinityNode()))
                    return false;
            }
        }
    }
    // if there are no caches, original SqlFieldsQuery's isLocal flag will be used.
    return hasCaches;
}
Also used : GridCacheContext(org.apache.ignite.internal.processors.cache.GridCacheContext) GridH2Table(org.apache.ignite.internal.processors.query.h2.opt.GridH2Table)

Aggregations

GridSqlAlias (org.apache.ignite.internal.processors.query.h2.sql.GridSqlAlias)9 GridH2Table (org.apache.ignite.internal.processors.query.h2.opt.GridH2Table)8 GridSqlSelect (org.apache.ignite.internal.processors.query.h2.sql.GridSqlSelect)7 Column (org.h2.table.Column)7 GridSqlColumn (org.apache.ignite.internal.processors.query.h2.sql.GridSqlColumn)6 GridSqlTable (org.apache.ignite.internal.processors.query.h2.sql.GridSqlTable)6 GridSqlElement (org.apache.ignite.internal.processors.query.h2.sql.GridSqlElement)5 ArrayList (java.util.ArrayList)3 HashSet (java.util.HashSet)3 IgniteSQLException (org.apache.ignite.internal.processors.query.IgniteSQLException)3 GridSqlFunction (org.apache.ignite.internal.processors.query.h2.sql.GridSqlFunction)3 GridSqlOperation (org.apache.ignite.internal.processors.query.h2.sql.GridSqlOperation)3 GridSqlSubquery (org.apache.ignite.internal.processors.query.h2.sql.GridSqlSubquery)3 ValueString (org.h2.value.ValueString)3 GridCacheContext (org.apache.ignite.internal.processors.cache.GridCacheContext)2 GridSqlArray (org.apache.ignite.internal.processors.query.h2.sql.GridSqlArray)2 GridSqlAst (org.apache.ignite.internal.processors.query.h2.sql.GridSqlAst)2 GridSqlJoin (org.apache.ignite.internal.processors.query.h2.sql.GridSqlJoin)2 GridSqlQuery (org.apache.ignite.internal.processors.query.h2.sql.GridSqlQuery)2 GridSqlType.fromExpression (org.apache.ignite.internal.processors.query.h2.sql.GridSqlType.fromExpression)2