Search in sources :

Example 31 with Alias

use of org.h2.expression.Alias in project ignite by apache.

the class GridReduceQueryExecutor method createMergeTable.

/**
 * @param conn Connection.
 * @param qry Query.
 * @param explain Explain.
 * @return Table.
 * @throws IgniteCheckedException If failed.
 */
@SuppressWarnings("unchecked")
private ReduceTable createMergeTable(H2PooledConnection conn, GridCacheSqlQuery qry, boolean explain) throws IgniteCheckedException {
    try {
        Session ses = H2Utils.session(conn);
        CreateTableData data = new CreateTableData();
        data.tableName = "T___";
        data.schema = ses.getDatabase().getSchema(ses.getCurrentSchemaName());
        data.create = true;
        if (!explain) {
            LinkedHashMap<String, ?> colsMap = qry.columns();
            assert colsMap != null;
            ArrayList<Column> cols = new ArrayList<>(colsMap.size());
            for (Map.Entry<String, ?> e : colsMap.entrySet()) {
                String alias = e.getKey();
                GridSqlType type = (GridSqlType) e.getValue();
                assert !F.isEmpty(alias);
                Column col0;
                if (type == GridSqlType.UNKNOWN) {
                    // Special case for parameter being set at the top of the query (e.g. SELECT ? FROM ...).
                    // Re-map it to STRING in the same way it is done in H2, because any argument can be cast
                    // to string.
                    col0 = new Column(alias, Value.STRING);
                } else {
                    col0 = new Column(alias, type.type(), type.precision(), type.scale(), type.displaySize());
                }
                cols.add(col0);
            }
            data.columns = cols;
        } else
            data.columns = planColumns();
        boolean sortedIndex = !F.isEmpty(qry.sortColumns());
        ReduceTable tbl = new ReduceTable(data);
        ArrayList<Index> idxs = new ArrayList<>(2);
        if (explain) {
            idxs.add(new UnsortedReduceIndexAdapter(ctx, tbl, sortedIndex ? MERGE_INDEX_SORTED : MERGE_INDEX_UNSORTED));
        } else if (sortedIndex) {
            List<GridSqlSortColumn> sortCols = (List<GridSqlSortColumn>) qry.sortColumns();
            SortedReduceIndexAdapter sortedMergeIdx = new SortedReduceIndexAdapter(ctx, tbl, MERGE_INDEX_SORTED, GridSqlSortColumn.toIndexColumns(tbl, sortCols));
            idxs.add(ReduceTable.createScanIndex(sortedMergeIdx));
            idxs.add(sortedMergeIdx);
        } else
            idxs.add(new UnsortedReduceIndexAdapter(ctx, tbl, MERGE_INDEX_UNSORTED));
        tbl.indexes(idxs);
        return tbl;
    } catch (Exception e) {
        throw new IgniteCheckedException(e);
    }
}
Also used : ArrayList(java.util.ArrayList) Index(org.h2.index.Index) CreateTableData(org.h2.command.ddl.CreateTableData) QueryCancelledException(org.apache.ignite.cache.query.QueryCancelledException) IgniteClientDisconnectedException(org.apache.ignite.IgniteClientDisconnectedException) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) IgniteException(org.apache.ignite.IgniteException) TransactionAlreadyCompletedException(org.apache.ignite.transactions.TransactionAlreadyCompletedException) IgniteTxAlreadyCompletedCheckedException(org.apache.ignite.internal.transactions.IgniteTxAlreadyCompletedCheckedException) QueryRetryException(org.apache.ignite.cache.query.QueryRetryException) SQLException(java.sql.SQLException) IgniteInterruptedCheckedException(org.apache.ignite.internal.IgniteInterruptedCheckedException) CacheException(javax.cache.CacheException) TransactionException(org.apache.ignite.transactions.TransactionException) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) GridSqlSortColumn(org.apache.ignite.internal.processors.query.h2.sql.GridSqlSortColumn) Column(org.h2.table.Column) GridSqlSortColumn(org.apache.ignite.internal.processors.query.h2.sql.GridSqlSortColumn) GridSqlType(org.apache.ignite.internal.processors.query.h2.sql.GridSqlType) Collections.singletonList(java.util.Collections.singletonList) List(java.util.List) ArrayList(java.util.ArrayList) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) ConcurrentMap(java.util.concurrent.ConcurrentMap) LinkedHashMap(java.util.LinkedHashMap) Collections.singletonMap(java.util.Collections.singletonMap) Session(org.h2.engine.Session)

Example 32 with Alias

use of org.h2.expression.Alias in project ignite by apache.

the class PartitionExtractor method prepareTable.

/**
 * Prepare single table.
 *
 * @param from Expression.
 * @param tblModel Table model.
 * @return Added table or {@code null} if table is exlcuded from the model.
 */
private static PartitionTable prepareTable(GridSqlAst from, PartitionTableModel tblModel) {
    // Unwrap alias. We assume that every table must be aliased.
    assert from instanceof GridSqlAlias;
    String alias = ((GridSqlAlias) from).alias();
    from = from.child();
    if (from instanceof GridSqlTable) {
        // Normal table.
        GridSqlTable from0 = (GridSqlTable) from;
        GridH2Table tbl0 = from0.dataTable();
        // Unknown table type, e.g. temp table.
        if (tbl0 == null) {
            tblModel.addExcludedTable(alias);
            return null;
        }
        String cacheName = tbl0.cacheName();
        String affColName = null;
        String secondAffColName = null;
        for (Column col : tbl0.getColumns()) {
            if (tbl0.isColumnForPartitionPruningStrict(col)) {
                if (affColName == null)
                    affColName = col.getName();
                else {
                    secondAffColName = col.getName();
                    // Break as we cannot have more than two affinity key columns.
                    break;
                }
            }
        }
        PartitionTable tbl = new PartitionTable(alias, cacheName, affColName, secondAffColName);
        PartitionTableAffinityDescriptor aff = affinityForCache(tbl0.cacheInfo().config());
        if (aff == null) {
            // Non-standard affinity, exclude table.
            tblModel.addExcludedTable(alias);
            return null;
        }
        tblModel.addTable(tbl, aff);
        return tbl;
    } else {
        // Subquery/union/view, etc.
        assert alias != null;
        tblModel.addExcludedTable(alias);
        return null;
    }
}
Also used : PartitionTable(org.apache.ignite.internal.sql.optimizer.affinity.PartitionTable) 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) PartitionTableAffinityDescriptor(org.apache.ignite.internal.sql.optimizer.affinity.PartitionTableAffinityDescriptor)

Example 33 with Alias

use of org.h2.expression.Alias in project ignite by apache.

the class UpdatePlanBuilder method verifyDmlColumns.

/**
 * Checks that DML query (insert, merge, update, bulk load aka copy) columns: <br/>
 * 1) doesn't contain both entire key (_key or alias) and columns referring to part of the key; <br/>
 * 2) doesn't contain both entire value (_val or alias) and columns referring to part of the value. <br/>
 *
 * @param tab - updated table.
 * @param affectedCols - table's column names affected by dml query. Their order should be the same as in the
 * dml statement only to have the same columns order in the error message.
 * @throws IgniteSQLException if check failed.
 */
private static void verifyDmlColumns(GridH2Table tab, Collection<Column> affectedCols) {
    GridH2RowDescriptor desc = tab.rowDescriptor();
    // _key (_val) or it alias exist in the update columns.
    String keyColName = null;
    String valColName = null;
    // Whether fields that are part of the key (value) exist in the updated columns.
    boolean hasKeyProps = false;
    boolean hasValProps = false;
    for (Column col : affectedCols) {
        int colId = col.getColumnId();
        // Checking that it's not specified both _key(_val) and its alias by the way.
        if (desc.isKeyColumn(colId)) {
            if (keyColName == null)
                keyColName = col.getName();
            else
                throw new IgniteSQLException("Columns " + keyColName + " and " + col + " both refer to entire cache key object.", IgniteQueryErrorCode.PARSING);
        } else if (desc.isValueColumn(colId)) {
            if (valColName == null)
                valColName = col.getName();
            else
                throw new IgniteSQLException("Columns " + valColName + " and " + col + " both refer to entire cache value object.", IgniteQueryErrorCode.PARSING);
        } else {
            // Column ids 0..2 are _key, _val, _ver
            assert colId >= QueryUtils.DEFAULT_COLUMNS_COUNT : "Unexpected column [name=" + col + ", id=" + colId + "].";
            if (desc.isColumnKeyProperty(colId - QueryUtils.DEFAULT_COLUMNS_COUNT))
                hasKeyProps = true;
            else
                hasValProps = true;
        }
        // And check invariants for the fast fail.
        boolean hasEntireKeyCol = keyColName != null;
        boolean hasEntireValcol = valColName != null;
        if (hasEntireKeyCol && hasKeyProps)
            throw new IgniteSQLException("Column " + keyColName + " refers to entire key cache object. " + "It must not be mixed with other columns that refer to parts of key.", IgniteQueryErrorCode.PARSING);
        if (hasEntireValcol && hasValProps)
            throw new IgniteSQLException("Column " + valColName + " refers to entire value cache object. " + "It must not be mixed with other columns that refer to parts of value.", IgniteQueryErrorCode.PARSING);
        if (!ALLOW_KEY_VAL_UPDATES) {
            if (desc.isKeyColumn(colId) && !QueryUtils.isSqlType(desc.type().keyClass())) {
                throw new IgniteSQLException("Update of composite key column is not supported", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
            }
            if (desc.isValueColumn(colId) && !QueryUtils.isSqlType(desc.type().valueClass())) {
                throw new IgniteSQLException("Update of composite value column is not supported", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
            }
        }
    }
}
Also used : GridH2RowDescriptor(org.apache.ignite.internal.processors.query.h2.opt.GridH2RowDescriptor) GridSqlColumn(org.apache.ignite.internal.processors.query.h2.sql.GridSqlColumn) Column(org.h2.table.Column) IgniteSQLException(org.apache.ignite.internal.processors.query.IgniteSQLException)

Example 34 with Alias

use of org.h2.expression.Alias 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 35 with Alias

use of org.h2.expression.Alias 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)

Aggregations

ResultSet (java.sql.ResultSet)38 Statement (java.sql.Statement)38 Connection (java.sql.Connection)31 SimpleResultSet (org.h2.tools.SimpleResultSet)31 PreparedStatement (java.sql.PreparedStatement)28 CallableStatement (java.sql.CallableStatement)18 ValueString (org.h2.value.ValueString)17 SQLException (java.sql.SQLException)11 Column (org.h2.table.Column)10 GridSqlColumn (org.apache.ignite.internal.processors.query.h2.sql.GridSqlColumn)6 Expression (org.h2.expression.Expression)6 ArrayList (java.util.ArrayList)5 HashMap (java.util.HashMap)5 GridSqlAlias (org.apache.ignite.internal.processors.query.h2.sql.GridSqlAlias)5 GridH2Table (org.apache.ignite.internal.processors.query.h2.opt.GridH2Table)4 GridSqlElement (org.apache.ignite.internal.processors.query.h2.sql.GridSqlElement)4 GridSqlSelect (org.apache.ignite.internal.processors.query.h2.sql.GridSqlSelect)4 GridSqlTable (org.apache.ignite.internal.processors.query.h2.sql.GridSqlTable)4 Session (org.h2.engine.Session)4 ValueExpression (org.h2.expression.ValueExpression)4