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);
}
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;
}
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;
}
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;
}
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;
}
Aggregations