Search in sources :

Example 1 with Merge

use of org.h2.command.dml.Merge in project ignite by apache.

the class DmlStatementsProcessor method streamUpdateQuery.

/**
     * Perform given statement against given data streamer. Only rows based INSERT and MERGE are supported
     * as well as key bound UPDATE and DELETE (ones with filter {@code WHERE _key = ?}).
     *
     * @param streamer Streamer to feed data to.
     * @param stmt Statement.
     * @param args Statement arguments.
     * @return Number of rows in given statement for INSERT and MERGE, {@code 1} otherwise.
     * @throws IgniteCheckedException if failed.
     */
@SuppressWarnings({ "unchecked", "ConstantConditions" })
long streamUpdateQuery(IgniteDataStreamer streamer, PreparedStatement stmt, Object[] args) throws IgniteCheckedException {
    args = U.firstNotNull(args, X.EMPTY_OBJECT_ARRAY);
    Prepared p = GridSqlQueryParser.prepared(stmt);
    assert p != null;
    UpdatePlan plan = UpdatePlanBuilder.planForStatement(p, null);
    if (!F.eq(streamer.cacheName(), plan.tbl.rowDescriptor().context().name()))
        throw new IgniteSQLException("Cross cache streaming is not supported, please specify cache explicitly" + " in connection options", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
    if (plan.mode == UpdateMode.INSERT && plan.rowsNum > 0) {
        assert plan.isLocSubqry;
        final GridCacheContext cctx = plan.tbl.rowDescriptor().context();
        QueryCursorImpl<List<?>> cur;
        final ArrayList<List<?>> data = new ArrayList<>(plan.rowsNum);
        final GridQueryFieldsResult res = idx.queryLocalSqlFields(idx.schema(cctx.name()), plan.selectQry, F.asList(args), null, false, 0, null);
        QueryCursorImpl<List<?>> stepCur = new QueryCursorImpl<>(new Iterable<List<?>>() {

            @Override
            public Iterator<List<?>> iterator() {
                try {
                    return new GridQueryCacheObjectsIterator(res.iterator(), idx.objectContext(), cctx.keepBinary());
                } catch (IgniteCheckedException e) {
                    throw new IgniteException(e);
                }
            }
        }, null);
        data.addAll(stepCur.getAll());
        cur = new QueryCursorImpl<>(new Iterable<List<?>>() {

            @Override
            public Iterator<List<?>> iterator() {
                return data.iterator();
            }
        }, null);
        if (plan.rowsNum == 1) {
            IgniteBiTuple t = rowToKeyValue(cctx, cur.iterator().next(), plan);
            streamer.addData(t.getKey(), t.getValue());
            return 1;
        }
        Map<Object, Object> rows = new LinkedHashMap<>(plan.rowsNum);
        for (List<?> row : cur) {
            final IgniteBiTuple t = rowToKeyValue(cctx, row, plan);
            rows.put(t.getKey(), t.getValue());
        }
        streamer.addData(rows);
        return rows.size();
    } else
        throw new IgniteSQLException("Only tuple based INSERT statements are supported in streaming mode", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
}
Also used : GridCacheContext(org.apache.ignite.internal.processors.cache.GridCacheContext) IgniteBiTuple(org.apache.ignite.lang.IgniteBiTuple) Prepared(org.h2.command.Prepared) ArrayList(java.util.ArrayList) QueryCursorImpl(org.apache.ignite.internal.processors.cache.QueryCursorImpl) GridQueryCacheObjectsIterator(org.apache.ignite.internal.processors.query.GridQueryCacheObjectsIterator) GridQueryFieldsResult(org.apache.ignite.internal.processors.query.GridQueryFieldsResult) LinkedHashMap(java.util.LinkedHashMap) GridBoundedConcurrentLinkedHashMap(org.apache.ignite.internal.util.GridBoundedConcurrentLinkedHashMap) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) IgniteException(org.apache.ignite.IgniteException) IgniteSQLException(org.apache.ignite.internal.processors.query.IgniteSQLException) GridQueryCacheObjectsIterator(org.apache.ignite.internal.processors.query.GridQueryCacheObjectsIterator) IgniteSingletonIterator(org.apache.ignite.internal.util.lang.IgniteSingletonIterator) Iterator(java.util.Iterator) List(java.util.List) ArrayList(java.util.ArrayList) BinaryObject(org.apache.ignite.binary.BinaryObject) UpdatePlan(org.apache.ignite.internal.processors.query.h2.dml.UpdatePlan)

Example 2 with Merge

use of org.h2.command.dml.Merge in project h2database by h2database.

the class Parser method parseMerge.

private Prepared parseMerge() {
    Merge command = new Merge(session);
    currentPrepared = command;
    int start = lastParseIndex;
    read("INTO");
    List<String> excludeIdentifiers = Arrays.asList("USING", "KEY", "VALUES");
    TableFilter targetTableFilter = readSimpleTableFilter(0, excludeIdentifiers);
    command.setTargetTableFilter(targetTableFilter);
    Table table = command.getTargetTable();
    if (readIf("USING")) {
        return parseMergeUsing(command, start);
    }
    if (readIf("(")) {
        if (isSelect()) {
            command.setQuery(parseSelect());
            read(")");
            return command;
        }
        Column[] columns = parseColumnList(table);
        command.setColumns(columns);
    }
    if (readIf("KEY")) {
        read("(");
        Column[] keys = parseColumnList(table);
        command.setKeys(keys);
    }
    if (readIf("VALUES")) {
        do {
            ArrayList<Expression> values = New.arrayList();
            read("(");
            if (!readIf(")")) {
                do {
                    if (readIf("DEFAULT")) {
                        values.add(null);
                    } else {
                        values.add(readExpression());
                    }
                } while (readIfMore(false));
            }
            command.addRow(values.toArray(new Expression[0]));
        } while (readIf(","));
    } else {
        command.setQuery(parseSelect());
    }
    return command;
}
Also used : RangeTable(org.h2.table.RangeTable) TruncateTable(org.h2.command.ddl.TruncateTable) CreateTable(org.h2.command.ddl.CreateTable) FunctionTable(org.h2.table.FunctionTable) CreateLinkedTable(org.h2.command.ddl.CreateLinkedTable) Table(org.h2.table.Table) DropTable(org.h2.command.ddl.DropTable) Merge(org.h2.command.dml.Merge) TableFilter(org.h2.table.TableFilter) AlterTableRenameColumn(org.h2.command.ddl.AlterTableRenameColumn) AlterTableAlterColumn(org.h2.command.ddl.AlterTableAlterColumn) Column(org.h2.table.Column) ExpressionColumn(org.h2.expression.ExpressionColumn) IndexColumn(org.h2.table.IndexColumn) Expression(org.h2.expression.Expression) ValueExpression(org.h2.expression.ValueExpression) ValueString(org.h2.value.ValueString) AlterTableRenameConstraint(org.h2.command.ddl.AlterTableRenameConstraint) AlterTableAddConstraint(org.h2.command.ddl.AlterTableAddConstraint) AlterTableDropConstraint(org.h2.command.ddl.AlterTableDropConstraint)

Example 3 with Merge

use of org.h2.command.dml.Merge in project h2database by h2database.

the class Parser method parseMergeUsing.

private MergeUsing parseMergeUsing(Merge oldCommand, int start) {
    MergeUsing command = new MergeUsing(oldCommand);
    currentPrepared = command;
    if (readIf("(")) {
        /* a select query is supplied */
        if (isSelect()) {
            command.setQuery(parseSelect());
            read(")");
        }
        command.setQueryAlias(readFromAlias(null, Collections.singletonList("ON")));
        String[] querySQLOutput = { null };
        List<Column> columnTemplateList = TableView.createQueryColumnTemplateList(null, command.getQuery(), querySQLOutput);
        TableView temporarySourceTableView = createCTEView(command.getQueryAlias(), querySQLOutput[0], columnTemplateList, false, /* no recursion */
        false, /* do not add to session */
        false, /* isPersistent */
        session);
        TableFilter sourceTableFilter = new TableFilter(session, temporarySourceTableView, command.getQueryAlias(), rightsChecked, (Select) command.getQuery(), 0, null);
        command.setSourceTableFilter(sourceTableFilter);
    } else {
        /* Its a table name, simulate a query by building a select query for the table */
        List<String> excludeIdentifiers = Collections.singletonList("ON");
        TableFilter sourceTableFilter = readSimpleTableFilter(0, excludeIdentifiers);
        command.setSourceTableFilter(sourceTableFilter);
        StringBuilder buff = new StringBuilder("SELECT * FROM ");
        appendTableWithSchemaAndAlias(buff, sourceTableFilter.getTable(), sourceTableFilter.getTableAlias());
        Prepared preparedQuery = prepare(session, buff.toString(), null);
        command.setQuery((Select) preparedQuery);
    }
    read("ON");
    read("(");
    Expression condition = readExpression();
    command.setOnCondition(condition);
    read(")");
    if (readIfAll("WHEN", "MATCHED", "THEN")) {
        int startMatched = lastParseIndex;
        if (readIf("UPDATE")) {
            Update updateCommand = new Update(session);
            // currentPrepared = updateCommand;
            TableFilter filter = command.getTargetTableFilter();
            updateCommand.setTableFilter(filter);
            parseUpdateSetClause(updateCommand, filter, startMatched);
            command.setUpdateCommand(updateCommand);
        }
        startMatched = lastParseIndex;
        if (readIf("DELETE")) {
            Delete deleteCommand = new Delete(session);
            TableFilter filter = command.getTargetTableFilter();
            deleteCommand.setTableFilter(filter);
            parseDeleteGivenTable(deleteCommand, null, startMatched);
            command.setDeleteCommand(deleteCommand);
        }
    }
    if (readIfAll("WHEN", "NOT", "MATCHED", "THEN")) {
        if (readIf("INSERT")) {
            Insert insertCommand = new Insert(session);
            insertCommand.setTable(command.getTargetTable());
            parseInsertGivenTable(insertCommand, command.getTargetTable());
            command.setInsertCommand(insertCommand);
        }
    }
    setSQL(command, "MERGE", start);
    // build and prepare the targetMatchQuery ready to test each rows
    // existence in the target table (using source row to match)
    StringBuilder targetMatchQuerySQL = new StringBuilder("SELECT _ROWID_ FROM ");
    appendTableWithSchemaAndAlias(targetMatchQuerySQL, command.getTargetTable(), command.getTargetTableFilter().getTableAlias());
    targetMatchQuerySQL.append(" WHERE ").append(command.getOnCondition().getSQL());
    command.setTargetMatchQuery((Select) parse(targetMatchQuerySQL.toString()));
    return command;
}
Also used : Delete(org.h2.command.dml.Delete) ValueString(org.h2.value.ValueString) Update(org.h2.command.dml.Update) Insert(org.h2.command.dml.Insert) AlterTableRenameConstraint(org.h2.command.ddl.AlterTableRenameConstraint) AlterTableAddConstraint(org.h2.command.ddl.AlterTableAddConstraint) AlterTableDropConstraint(org.h2.command.ddl.AlterTableDropConstraint) AlterTableRenameColumn(org.h2.command.ddl.AlterTableRenameColumn) AlterTableAlterColumn(org.h2.command.ddl.AlterTableAlterColumn) Column(org.h2.table.Column) ExpressionColumn(org.h2.expression.ExpressionColumn) IndexColumn(org.h2.table.IndexColumn) TableFilter(org.h2.table.TableFilter) Expression(org.h2.expression.Expression) ValueExpression(org.h2.expression.ValueExpression) MergeUsing(org.h2.command.dml.MergeUsing) TableView(org.h2.table.TableView)

Example 4 with Merge

use of org.h2.command.dml.Merge in project h2database by h2database.

the class Parser method parsePrepared.

private Prepared parsePrepared() {
    int start = lastParseIndex;
    Prepared c = null;
    String token = currentToken;
    if (token.length() == 0) {
        c = new NoOperation(session);
    } else {
        char first = token.charAt(0);
        switch(first) {
            case '?':
                // read the ? as a parameter
                readTerm();
                // this is an 'out' parameter - set a dummy value
                parameters.get(0).setValue(ValueNull.INSTANCE);
                read("=");
                read("CALL");
                c = parseCall();
                break;
            case '(':
                c = parseSelect();
                break;
            case 'a':
            case 'A':
                if (readIf("ALTER")) {
                    c = parseAlter();
                } else if (readIf("ANALYZE")) {
                    c = parseAnalyze();
                }
                break;
            case 'b':
            case 'B':
                if (readIf("BACKUP")) {
                    c = parseBackup();
                } else if (readIf("BEGIN")) {
                    c = parseBegin();
                }
                break;
            case 'c':
            case 'C':
                if (readIf("COMMIT")) {
                    c = parseCommit();
                } else if (readIf("CREATE")) {
                    c = parseCreate();
                } else if (readIf("CALL")) {
                    c = parseCall();
                } else if (readIf("CHECKPOINT")) {
                    c = parseCheckpoint();
                } else if (readIf("COMMENT")) {
                    c = parseComment();
                }
                break;
            case 'd':
            case 'D':
                if (readIf("DELETE")) {
                    c = parseDelete();
                } else if (readIf("DROP")) {
                    c = parseDrop();
                } else if (readIf("DECLARE")) {
                    // support for DECLARE GLOBAL TEMPORARY TABLE...
                    c = parseCreate();
                } else if (readIf("DEALLOCATE")) {
                    c = parseDeallocate();
                }
                break;
            case 'e':
            case 'E':
                if (readIf("EXPLAIN")) {
                    c = parseExplain();
                } else if (readIf("EXECUTE")) {
                    c = parseExecute();
                }
                break;
            case 'f':
            case 'F':
                if (isToken("FROM")) {
                    c = parseSelect();
                }
                break;
            case 'g':
            case 'G':
                if (readIf("GRANT")) {
                    c = parseGrantRevoke(CommandInterface.GRANT);
                }
                break;
            case 'h':
            case 'H':
                if (readIf("HELP")) {
                    c = parseHelp();
                }
                break;
            case 'i':
            case 'I':
                if (readIf("INSERT")) {
                    c = parseInsert();
                }
                break;
            case 'm':
            case 'M':
                if (readIf("MERGE")) {
                    c = parseMerge();
                }
                break;
            case 'p':
            case 'P':
                if (readIf("PREPARE")) {
                    c = parsePrepare();
                }
                break;
            case 'r':
            case 'R':
                if (readIf("ROLLBACK")) {
                    c = parseRollback();
                } else if (readIf("REVOKE")) {
                    c = parseGrantRevoke(CommandInterface.REVOKE);
                } else if (readIf("RUNSCRIPT")) {
                    c = parseRunScript();
                } else if (readIf("RELEASE")) {
                    c = parseReleaseSavepoint();
                } else if (readIf("REPLACE")) {
                    c = parseReplace();
                }
                break;
            case 's':
            case 'S':
                if (isToken("SELECT")) {
                    c = parseSelect();
                } else if (readIf("SET")) {
                    c = parseSet();
                } else if (readIf("SAVEPOINT")) {
                    c = parseSavepoint();
                } else if (readIf("SCRIPT")) {
                    c = parseScript();
                } else if (readIf("SHUTDOWN")) {
                    c = parseShutdown();
                } else if (readIf("SHOW")) {
                    c = parseShow();
                }
                break;
            case 't':
            case 'T':
                if (readIf("TRUNCATE")) {
                    c = parseTruncate();
                }
                break;
            case 'u':
            case 'U':
                if (readIf("UPDATE")) {
                    c = parseUpdate();
                } else if (readIf("USE")) {
                    c = parseUse();
                }
                break;
            case 'v':
            case 'V':
                if (readIf("VALUES")) {
                    c = parseValues();
                }
                break;
            case 'w':
            case 'W':
                if (readIf("WITH")) {
                    c = parseWithStatementOrQuery();
                }
                break;
            case ';':
                c = new NoOperation(session);
                break;
            default:
                throw getSyntaxError();
        }
        if (indexedParameterList != null) {
            for (int i = 0, size = indexedParameterList.size(); i < size; i++) {
                if (indexedParameterList.get(i) == null) {
                    indexedParameterList.set(i, new Parameter(i));
                }
            }
            parameters = indexedParameterList;
        }
        if (readIf("{")) {
            do {
                int index = (int) readLong() - 1;
                if (index < 0 || index >= parameters.size()) {
                    throw getSyntaxError();
                }
                Parameter p = parameters.get(index);
                if (p == null) {
                    throw getSyntaxError();
                }
                read(":");
                Expression expr = readExpression();
                expr = expr.optimize(session);
                p.setValue(expr.getValue(session));
            } while (readIf(","));
            read("}");
            for (Parameter p : parameters) {
                p.checkSet();
            }
            parameters.clear();
        }
    }
    if (c == null) {
        throw getSyntaxError();
    }
    setSQL(c, null, start);
    return c;
}
Also used : NoOperation(org.h2.command.dml.NoOperation) Expression(org.h2.expression.Expression) ValueExpression(org.h2.expression.ValueExpression) Parameter(org.h2.expression.Parameter) ConditionInParameter(org.h2.expression.ConditionInParameter) ValueString(org.h2.value.ValueString) AlterTableRenameConstraint(org.h2.command.ddl.AlterTableRenameConstraint) AlterTableAddConstraint(org.h2.command.ddl.AlterTableAddConstraint) AlterTableDropConstraint(org.h2.command.ddl.AlterTableDropConstraint)

Example 5 with Merge

use of org.h2.command.dml.Merge in project h2database by h2database.

the class Parser method parseWith.

private Prepared parseWith() {
    List<TableView> viewsCreated = new ArrayList<>();
    readIf("RECURSIVE");
    // this WITH statement might not be a temporary view - allow optional keyword to
    // tell us that this keyword. This feature will not be documented - H2 internal use only.
    boolean isPersistent = readIf("PERSISTENT");
    // as in CREATE VIEW abc AS WITH my_cte - this auto detects that condition
    if (session.isParsingCreateView()) {
        isPersistent = true;
    }
    do {
        viewsCreated.add(parseSingleCommonTableExpression(isPersistent));
    } while (readIf(","));
    Prepared p = null;
    // reverse the order of constructed CTE views - as the destruction order
    // (since later created view may depend on previously created views -
    // we preserve that dependency order in the destruction sequence )
    // used in setCteCleanups
    Collections.reverse(viewsCreated);
    if (isToken("SELECT")) {
        Query query = parseSelectUnion();
        query.setPrepareAlways(true);
        query.setNeverLazy(true);
        p = query;
    } else if (readIf("INSERT")) {
        p = parseInsert();
        p.setPrepareAlways(true);
    } else if (readIf("UPDATE")) {
        p = parseUpdate();
        p.setPrepareAlways(true);
    } else if (readIf("MERGE")) {
        p = parseMerge();
        p.setPrepareAlways(true);
    } else if (readIf("DELETE")) {
        p = parseDelete();
        p.setPrepareAlways(true);
    } else if (readIf("CREATE")) {
        if (!isToken("TABLE")) {
            throw DbException.get(ErrorCode.SYNTAX_ERROR_1, WITH_STATEMENT_SUPPORTS_LIMITED_SUB_STATEMENTS);
        }
        p = parseCreate();
        p.setPrepareAlways(true);
    } else {
        throw DbException.get(ErrorCode.SYNTAX_ERROR_1, WITH_STATEMENT_SUPPORTS_LIMITED_SUB_STATEMENTS);
    }
    // dependencies) - but only if they are not persistent
    if (!isPersistent) {
        p.setCteCleanups(viewsCreated);
    }
    return p;
}
Also used : Query(org.h2.command.dml.Query) ArrayList(java.util.ArrayList) TableView(org.h2.table.TableView)

Aggregations

Column (org.h2.table.Column)13 PreparedStatement (java.sql.PreparedStatement)9 ArrayList (java.util.ArrayList)9 Expression (org.h2.expression.Expression)8 IgniteSQLException (org.apache.ignite.internal.processors.query.IgniteSQLException)7 ResultSet (java.sql.ResultSet)6 SQLException (java.sql.SQLException)6 Statement (java.sql.Statement)6 Connection (java.sql.Connection)5 List (java.util.List)5 IgniteCheckedException (org.apache.ignite.IgniteCheckedException)5 GridH2RowDescriptor (org.apache.ignite.internal.processors.query.h2.opt.GridH2RowDescriptor)5 HashMap (java.util.HashMap)4 IgniteException (org.apache.ignite.IgniteException)4 ValueExpression (org.h2.expression.ValueExpression)4 DbException (org.h2.message.DbException)4 ValueString (org.h2.value.ValueString)4 LinkedHashMap (java.util.LinkedHashMap)3 GridCacheContext (org.apache.ignite.internal.processors.cache.GridCacheContext)3 GridQueryTypeDescriptor (org.apache.ignite.internal.processors.query.GridQueryTypeDescriptor)3