Search in sources :

Example 11 with Operation

use of org.h2.expression.Operation in project h2database by h2database.

the class TestView method testViewConstraintFromColumnExpression.

/**
 * Make sure that the table constraint is still available when create a view
 * of other table.
 */
private void testViewConstraintFromColumnExpression() throws SQLException {
    deleteDb("view");
    Connection conn = getConnection("view");
    Statement stat = conn.createStatement();
    stat.execute("create table t0(id1 int primary key CHECK ((ID1 % 2) = 0))");
    stat.execute("create table t1(id2 int primary key CHECK ((ID2 % 1) = 0))");
    stat.execute("insert into t0 values(0)");
    stat.execute("insert into t1 values(1)");
    stat.execute("create view v1 as select * from t0,t1");
    // Check with ColumnExpression
    ResultSet rs = stat.executeQuery("select * from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = 'V1'");
    assertTrue(rs.next());
    assertEquals("ID1", rs.getString("COLUMN_NAME"));
    assertEquals("((ID1 % 2) = 0)", rs.getString("CHECK_CONSTRAINT"));
    assertTrue(rs.next());
    assertEquals("ID2", rs.getString("COLUMN_NAME"));
    assertEquals("((ID2 % 1) = 0)", rs.getString("CHECK_CONSTRAINT"));
    // Check with AliasExpression
    stat.execute("create view v2 as select ID1 key1,ID2 key2 from t0,t1");
    rs = stat.executeQuery("select * from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = 'V2'");
    assertTrue(rs.next());
    assertEquals("KEY1", rs.getString("COLUMN_NAME"));
    assertEquals("((KEY1 % 2) = 0)", rs.getString("CHECK_CONSTRAINT"));
    assertTrue(rs.next());
    assertEquals("KEY2", rs.getString("COLUMN_NAME"));
    assertEquals("((KEY2 % 1) = 0)", rs.getString("CHECK_CONSTRAINT"));
    // Check hide of constraint if column is an Operation
    stat.execute("create view v3 as select ID1 + 1 ID1, ID2 + 1 ID2 from t0,t1");
    rs = stat.executeQuery("select * from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = 'V3'");
    assertTrue(rs.next());
    assertEquals("ID1", rs.getString("COLUMN_NAME"));
    assertEquals("", rs.getString("CHECK_CONSTRAINT"));
    assertTrue(rs.next());
    assertEquals("ID2", rs.getString("COLUMN_NAME"));
    assertEquals("", rs.getString("CHECK_CONSTRAINT"));
    conn.close();
    deleteDb("view");
}
Also used : Statement(java.sql.Statement) PreparedStatement(java.sql.PreparedStatement) Connection(java.sql.Connection) JdbcConnection(org.h2.jdbc.JdbcConnection) ResultSet(java.sql.ResultSet)

Example 12 with Operation

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

the class UpdatePlanBuilder method planForUpdate.

/**
     * Prepare update plan for UPDATE or DELETE.
     *
     * @param stmt UPDATE or DELETE statement.
     * @param errKeysPos index to inject param for re-run keys at. Null if it's not a re-run plan.
     * @return Update plan.
     * @throws IgniteCheckedException if failed.
     */
private static UpdatePlan planForUpdate(GridSqlStatement stmt, @Nullable Integer errKeysPos) throws IgniteCheckedException {
    GridSqlElement target;
    FastUpdateArguments fastUpdate;
    UpdateMode mode;
    if (stmt instanceof GridSqlUpdate) {
        // Let's verify that user is not trying to mess with key's columns directly
        verifyUpdateColumns(stmt);
        GridSqlUpdate update = (GridSqlUpdate) stmt;
        target = update.target();
        fastUpdate = DmlAstUtils.getFastUpdateArgs(update);
        mode = UpdateMode.UPDATE;
    } else if (stmt instanceof GridSqlDelete) {
        GridSqlDelete del = (GridSqlDelete) stmt;
        target = del.from();
        fastUpdate = DmlAstUtils.getFastDeleteArgs(del);
        mode = UpdateMode.DELETE;
    } else
        throw new IgniteSQLException("Unexpected DML operation [cls=" + stmt.getClass().getName() + ']', IgniteQueryErrorCode.UNEXPECTED_OPERATION);
    GridSqlTable tbl = gridTableForElement(target);
    GridH2Table gridTbl = tbl.dataTable();
    GridH2RowDescriptor desc = gridTbl.rowDescriptor();
    if (desc == null)
        throw new IgniteSQLException("Row descriptor undefined for table '" + gridTbl.getName() + "'", IgniteQueryErrorCode.NULL_TABLE_DESCRIPTOR);
    if (fastUpdate != null)
        return UpdatePlan.forFastUpdate(mode, gridTbl, fastUpdate);
    else {
        GridSqlSelect sel;
        if (stmt instanceof GridSqlUpdate) {
            List<GridSqlColumn> updatedCols = ((GridSqlUpdate) stmt).cols();
            int valColIdx = -1;
            String[] colNames = new String[updatedCols.size()];
            int[] colTypes = new int[updatedCols.size()];
            for (int i = 0; i < updatedCols.size(); i++) {
                colNames[i] = updatedCols.get(i).columnName();
                colTypes[i] = updatedCols.get(i).resultType().type();
                Column column = updatedCols.get(i).column();
                if (desc.isValueColumn(column.getColumnId()))
                    valColIdx = i;
            }
            boolean hasNewVal = (valColIdx != -1);
            // Statement updates distinct properties if it does not have _val in updated columns list
            // or if its list of updated columns includes only _val, i.e. is single element.
            boolean hasProps = !hasNewVal || updatedCols.size() > 1;
            // Index of new _val in results of SELECT
            if (hasNewVal)
                valColIdx += 2;
            int newValColIdx = (hasNewVal ? valColIdx : 1);
            KeyValueSupplier newValSupplier = createSupplier(desc.context(), desc.type(), newValColIdx, hasProps, false, true);
            sel = DmlAstUtils.selectForUpdate((GridSqlUpdate) stmt, errKeysPos);
            return UpdatePlan.forUpdate(gridTbl, colNames, colTypes, newValSupplier, valColIdx, sel.getSQL());
        } else {
            sel = DmlAstUtils.selectForDelete((GridSqlDelete) stmt, errKeysPos);
            return UpdatePlan.forDelete(gridTbl, sel.getSQL());
        }
    }
}
Also used : GridSqlDelete(org.apache.ignite.internal.processors.query.h2.sql.GridSqlDelete) GridSqlSelect(org.apache.ignite.internal.processors.query.h2.sql.GridSqlSelect) GridH2RowDescriptor(org.apache.ignite.internal.processors.query.h2.opt.GridH2RowDescriptor) 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) IgniteSQLException(org.apache.ignite.internal.processors.query.IgniteSQLException) GridSqlElement(org.apache.ignite.internal.processors.query.h2.sql.GridSqlElement) GridSqlUpdate(org.apache.ignite.internal.processors.query.h2.sql.GridSqlUpdate)

Example 13 with Operation

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

the class UpdatePlanBuilder method planForUpdate.

/**
 * Prepare update plan for UPDATE or DELETE.
 *
 * @param stmt UPDATE or DELETE statement.
 * @param loc Local query flag.
 * @param idx Indexing.
 * @param conn Connection.
 * @param fieldsQuery Original query.
 * @param errKeysPos index to inject param for re-run keys at. Null if it's not a re-run plan.
 * @return Update plan.
 * @throws IgniteCheckedException if failed.
 */
private static UpdatePlan planForUpdate(GridSqlStatement stmt, boolean loc, IgniteH2Indexing idx, @Nullable Connection conn, @Nullable SqlFieldsQuery fieldsQuery, @Nullable Integer errKeysPos) throws IgniteCheckedException {
    GridSqlElement target;
    FastUpdate fastUpdate;
    UpdateMode mode;
    if (stmt instanceof GridSqlUpdate) {
        // Let's verify that user is not trying to mess with key's columns directly
        verifyUpdateColumns(stmt);
        GridSqlUpdate update = (GridSqlUpdate) stmt;
        target = update.target();
        fastUpdate = DmlAstUtils.getFastUpdateArgs(update);
        mode = UpdateMode.UPDATE;
    } else if (stmt instanceof GridSqlDelete) {
        GridSqlDelete del = (GridSqlDelete) stmt;
        target = del.from();
        fastUpdate = DmlAstUtils.getFastDeleteArgs(del);
        mode = UpdateMode.DELETE;
    } else
        throw new IgniteSQLException("Unexpected DML operation [cls=" + stmt.getClass().getName() + ']', IgniteQueryErrorCode.UNEXPECTED_OPERATION);
    GridSqlTable tbl = DmlAstUtils.gridTableForElement(target);
    GridH2Table h2Tbl = tbl.dataTable();
    GridH2RowDescriptor desc = h2Tbl.rowDescriptor();
    if (desc == null)
        throw new IgniteSQLException("Row descriptor undefined for table '" + h2Tbl.getName() + "'", IgniteQueryErrorCode.NULL_TABLE_DESCRIPTOR);
    if (fastUpdate != null) {
        return new UpdatePlan(mode, h2Tbl, null, fastUpdate, null);
    } else {
        GridSqlSelect sel;
        if (stmt instanceof GridSqlUpdate) {
            List<GridSqlColumn> updatedCols = ((GridSqlUpdate) stmt).cols();
            int valColIdx = -1;
            String[] colNames = new String[updatedCols.size()];
            int[] colTypes = new int[updatedCols.size()];
            for (int i = 0; i < updatedCols.size(); i++) {
                colNames[i] = updatedCols.get(i).columnName();
                colTypes[i] = updatedCols.get(i).resultType().type();
                Column col = updatedCols.get(i).column();
                if (desc.isValueColumn(col.getColumnId()))
                    valColIdx = i;
            }
            boolean hasNewVal = (valColIdx != -1);
            // Statement updates distinct properties if it does not have _val in updated columns list
            // or if its list of updated columns includes only _val, i.e. is single element.
            boolean hasProps = !hasNewVal || updatedCols.size() > 1;
            // Index of new _val in results of SELECT
            if (hasNewVal)
                valColIdx += 2;
            int newValColIdx = (hasNewVal ? valColIdx : 1);
            KeyValueSupplier valSupplier = createSupplier(desc.context(), desc.type(), newValColIdx, hasProps, false, true);
            sel = DmlAstUtils.selectForUpdate((GridSqlUpdate) stmt, errKeysPos);
            String selectSql = sel.getSQL();
            DmlDistributedPlanInfo distributed = F.isEmpty(selectSql) ? null : checkPlanCanBeDistributed(idx, conn, fieldsQuery, loc, selectSql, tbl.dataTable().cacheName());
            return new UpdatePlan(UpdateMode.UPDATE, h2Tbl, colNames, colTypes, null, valSupplier, -1, valColIdx, selectSql, false, null, 0, null, distributed);
        } else {
            sel = DmlAstUtils.selectForDelete((GridSqlDelete) stmt, errKeysPos);
            String selectSql = sel.getSQL();
            DmlDistributedPlanInfo distributed = F.isEmpty(selectSql) ? null : checkPlanCanBeDistributed(idx, conn, fieldsQuery, loc, selectSql, tbl.dataTable().cacheName());
            return new UpdatePlan(UpdateMode.DELETE, h2Tbl, selectSql, null, distributed);
        }
    }
}
Also used : GridSqlDelete(org.apache.ignite.internal.processors.query.h2.sql.GridSqlDelete) GridSqlSelect(org.apache.ignite.internal.processors.query.h2.sql.GridSqlSelect) GridH2RowDescriptor(org.apache.ignite.internal.processors.query.h2.opt.GridH2RowDescriptor) 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) IgniteSQLException(org.apache.ignite.internal.processors.query.IgniteSQLException) GridSqlElement(org.apache.ignite.internal.processors.query.h2.sql.GridSqlElement) GridSqlUpdate(org.apache.ignite.internal.processors.query.h2.sql.GridSqlUpdate)

Example 14 with Operation

use of org.h2.expression.Operation in project h2database by h2database.

the class Recover method dumpPageLogStream.

private void dumpPageLogStream(PrintWriter writer, int logKey, int logFirstTrunkPage, int logFirstDataPage, long pageCount) throws IOException {
    Data s = Data.create(this, pageSize);
    DataReader in = new DataReader(new PageInputStream(writer, this, store, logKey, logFirstTrunkPage, logFirstDataPage, pageSize));
    writer.println("---- Transaction log ----");
    CompressLZF compress = new CompressLZF();
    while (true) {
        int x = in.readByte();
        if (x < 0) {
            break;
        }
        if (x == PageLog.NOOP) {
        // ignore
        } else if (x == PageLog.UNDO) {
            int pageId = in.readVarInt();
            int size = in.readVarInt();
            byte[] data = new byte[pageSize];
            if (size == 0) {
                in.readFully(data, pageSize);
            } else if (size == 1) {
            // empty
            } else {
                byte[] compressBuffer = new byte[size];
                in.readFully(compressBuffer, size);
                try {
                    compress.expand(compressBuffer, 0, size, data, 0, pageSize);
                } catch (ArrayIndexOutOfBoundsException e) {
                    throw DbException.convertToIOException(e);
                }
            }
            String typeName = "";
            int type = data[0];
            boolean last = (type & Page.FLAG_LAST) != 0;
            type &= ~Page.FLAG_LAST;
            switch(type) {
                case Page.TYPE_EMPTY:
                    typeName = "empty";
                    break;
                case Page.TYPE_DATA_LEAF:
                    typeName = "data leaf " + (last ? "(last)" : "");
                    break;
                case Page.TYPE_DATA_NODE:
                    typeName = "data node " + (last ? "(last)" : "");
                    break;
                case Page.TYPE_DATA_OVERFLOW:
                    typeName = "data overflow " + (last ? "(last)" : "");
                    break;
                case Page.TYPE_BTREE_LEAF:
                    typeName = "b-tree leaf " + (last ? "(last)" : "");
                    break;
                case Page.TYPE_BTREE_NODE:
                    typeName = "b-tree node " + (last ? "(last)" : "");
                    break;
                case Page.TYPE_FREE_LIST:
                    typeName = "free list " + (last ? "(last)" : "");
                    break;
                case Page.TYPE_STREAM_TRUNK:
                    typeName = "log trunk";
                    break;
                case Page.TYPE_STREAM_DATA:
                    typeName = "log data";
                    break;
                default:
                    typeName = "ERROR: unknown type " + type;
                    break;
            }
            writer.println("-- undo page " + pageId + " " + typeName);
            if (trace) {
                Data d = Data.create(null, data);
                dumpPage(writer, d, pageId, pageCount);
            }
        } else if (x == PageLog.ADD) {
            int sessionId = in.readVarInt();
            setStorage(in.readVarInt());
            Row row = PageLog.readRow(RowFactory.DEFAULT, in, s);
            writer.println("-- session " + sessionId + " table " + storageId + " + " + row.toString());
            if (transactionLog) {
                if (storageId == 0 && row.getColumnCount() >= 4) {
                    int tableId = (int) row.getKey();
                    String sql = row.getValue(3).getString();
                    String name = extractTableOrViewName(sql);
                    if (row.getValue(2).getInt() == DbObject.TABLE_OR_VIEW) {
                        tableMap.put(tableId, name);
                    }
                    writer.println(sql + ";");
                } else {
                    String tableName = tableMap.get(storageId);
                    if (tableName != null) {
                        StatementBuilder buff = new StatementBuilder();
                        buff.append("INSERT INTO ").append(tableName).append(" VALUES(");
                        for (int i = 0; i < row.getColumnCount(); i++) {
                            buff.appendExceptFirst(", ");
                            buff.append(row.getValue(i).getSQL());
                        }
                        buff.append(");");
                        writer.println(buff.toString());
                    }
                }
            }
        } else if (x == PageLog.REMOVE) {
            int sessionId = in.readVarInt();
            setStorage(in.readVarInt());
            long key = in.readVarLong();
            writer.println("-- session " + sessionId + " table " + storageId + " - " + key);
            if (transactionLog) {
                if (storageId == 0) {
                    int tableId = (int) key;
                    String tableName = tableMap.get(tableId);
                    if (tableName != null) {
                        writer.println("DROP TABLE IF EXISTS " + tableName + ";");
                    }
                } else {
                    String tableName = tableMap.get(storageId);
                    if (tableName != null) {
                        String sql = "DELETE FROM " + tableName + " WHERE _ROWID_ = " + key + ";";
                        writer.println(sql);
                    }
                }
            }
        } else if (x == PageLog.TRUNCATE) {
            int sessionId = in.readVarInt();
            setStorage(in.readVarInt());
            writer.println("-- session " + sessionId + " table " + storageId + " truncate");
            if (transactionLog) {
                writer.println("TRUNCATE TABLE " + storageId);
            }
        } else if (x == PageLog.COMMIT) {
            int sessionId = in.readVarInt();
            writer.println("-- commit " + sessionId);
        } else if (x == PageLog.ROLLBACK) {
            int sessionId = in.readVarInt();
            writer.println("-- rollback " + sessionId);
        } else if (x == PageLog.PREPARE_COMMIT) {
            int sessionId = in.readVarInt();
            String transaction = in.readString();
            writer.println("-- prepare commit " + sessionId + " " + transaction);
        } else if (x == PageLog.NOOP) {
        // nothing to do
        } else if (x == PageLog.CHECKPOINT) {
            writer.println("-- checkpoint");
        } else if (x == PageLog.FREE_LOG) {
            int size = in.readVarInt();
            StringBuilder buff = new StringBuilder("-- free");
            for (int i = 0; i < size; i++) {
                buff.append(' ').append(in.readVarInt());
            }
            writer.println(buff);
        } else {
            writer.println("-- ERROR: unknown operation " + x);
            break;
        }
    }
}
Also used : DataReader(org.h2.store.DataReader) CompressLZF(org.h2.compress.CompressLZF) StatementBuilder(org.h2.util.StatementBuilder) Data(org.h2.store.Data) Row(org.h2.result.Row) SimpleRow(org.h2.result.SimpleRow)

Example 15 with Operation

use of org.h2.expression.Operation in project h2database by h2database.

the class RegularTable method addRow.

@Override
public void addRow(Session session, Row row) {
    lastModificationId = database.getNextModificationDataId();
    if (database.isMultiVersion()) {
        row.setSessionId(session.getId());
    }
    int i = 0;
    try {
        for (int size = indexes.size(); i < size; i++) {
            Index index = indexes.get(i);
            index.add(session, row);
            checkRowCount(session, index, 1);
        }
        rowCount++;
    } catch (Throwable e) {
        try {
            while (--i >= 0) {
                Index index = indexes.get(i);
                index.remove(session, row);
                checkRowCount(session, index, 0);
            }
        } catch (DbException e2) {
            // this could happen, for example on failure in the storage
            // but if that is not the case it means there is something wrong
            // with the database
            trace.error(e2, "could not undo operation");
            throw e2;
        }
        DbException de = DbException.convert(e);
        if (de.getErrorCode() == ErrorCode.DUPLICATE_KEY_1) {
            for (Index index : indexes) {
                if (index.getIndexType().isUnique() && index instanceof MultiVersionIndex) {
                    MultiVersionIndex mv = (MultiVersionIndex) index;
                    if (mv.isUncommittedFromOtherSession(session, row)) {
                        throw DbException.get(ErrorCode.CONCURRENT_UPDATE_1, index.getName());
                    }
                }
            }
        }
        throw de;
    }
    analyzeIfRequired(session);
}
Also used : MultiVersionIndex(org.h2.index.MultiVersionIndex) NonUniqueHashIndex(org.h2.index.NonUniqueHashIndex) Index(org.h2.index.Index) HashIndex(org.h2.index.HashIndex) ScanIndex(org.h2.index.ScanIndex) PageBtreeIndex(org.h2.index.PageBtreeIndex) TreeIndex(org.h2.index.TreeIndex) PageDataIndex(org.h2.index.PageDataIndex) PageDelegateIndex(org.h2.index.PageDelegateIndex) MultiVersionIndex(org.h2.index.MultiVersionIndex) SpatialTreeIndex(org.h2.index.SpatialTreeIndex) Constraint(org.h2.constraint.Constraint) DbException(org.h2.message.DbException)

Aggregations

Column (org.h2.table.Column)7 IgniteSQLException (org.apache.ignite.internal.processors.query.IgniteSQLException)6 GridH2Table (org.apache.ignite.internal.processors.query.h2.opt.GridH2Table)6 GridH2RowDescriptor (org.apache.ignite.internal.processors.query.h2.opt.GridH2RowDescriptor)5 GridSqlColumn (org.apache.ignite.internal.processors.query.h2.sql.GridSqlColumn)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 Connection (java.sql.Connection)3 List (java.util.List)3 GridSqlDelete (org.apache.ignite.internal.processors.query.h2.sql.GridSqlDelete)3 GridSqlUpdate (org.apache.ignite.internal.processors.query.h2.sql.GridSqlUpdate)3 AlterTableAlterColumn (org.h2.command.ddl.AlterTableAlterColumn)3 NoOperation (org.h2.command.dml.NoOperation)3 Constraint (org.h2.constraint.Constraint)3 IndexColumn (org.h2.table.IndexColumn)3 ResultSet (java.sql.ResultSet)2 SQLException (java.sql.SQLException)2 Statement (java.sql.Statement)2 ArrayList (java.util.ArrayList)2