use of org.h2.command.dml.Delete 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;
}
use of org.h2.command.dml.Delete in project h2database by h2database.
the class Parser method parseDelete.
private Delete parseDelete() {
Delete command = new Delete(session);
Expression limit = null;
if (readIf("TOP")) {
limit = readTerm().optimize(session);
}
currentPrepared = command;
int start = lastParseIndex;
if (!readIf("FROM") && database.getMode().getEnum() == ModeEnum.MySQL) {
readIdentifierWithSchema();
read("FROM");
}
TableFilter filter = readSimpleTableFilter(0, null);
command.setTableFilter(filter);
parseDeleteGivenTable(command, limit, start);
return command;
}
use of org.h2.command.dml.Delete in project h2database by h2database.
the class MergeUsing method prepare.
@Override
public void prepare() {
onCondition.addFilterConditions(sourceTableFilter, true);
onCondition.addFilterConditions(targetTableFilter, true);
onCondition.mapColumns(sourceTableFilter, 2);
onCondition.mapColumns(targetTableFilter, 1);
if (keys == null) {
HashSet<Column> targetColumns = buildColumnListFromOnCondition(targetTableFilter);
keys = targetColumns.toArray(new Column[0]);
}
if (keys.length == 0) {
throw DbException.get(ErrorCode.COLUMN_NOT_FOUND_1, "No references to target columns found in ON clause:" + targetTableFilter.toString());
}
if (sourceKeys == null) {
HashSet<Column> sourceColumns = buildColumnListFromOnCondition(sourceTableFilter);
sourceKeys = sourceColumns.toArray(new Column[0]);
}
if (sourceKeys.length == 0) {
throw DbException.get(ErrorCode.COLUMN_NOT_FOUND_1, "No references to source columns found in ON clause:" + sourceTableFilter.toString());
}
// only do the optimize now - before we have already gathered the
// unoptimized column data
onCondition = onCondition.optimize(session);
onCondition.createIndexConditions(session, sourceTableFilter);
onCondition.createIndexConditions(session, targetTableFilter);
if (columns == null) {
if (!valuesExpressionList.isEmpty() && valuesExpressionList.get(0).length == 0) {
// special case where table is used as a sequence
columns = new Column[0];
} else {
columns = targetTable.getColumns();
}
}
if (!valuesExpressionList.isEmpty()) {
for (Expression[] expr : valuesExpressionList) {
if (expr.length != columns.length) {
throw DbException.get(ErrorCode.COLUMN_COUNT_DOES_NOT_MATCH);
}
for (int i = 0; i < expr.length; i++) {
Expression e = expr[i];
if (e != null) {
expr[i] = e.optimize(session);
}
}
}
} else {
query.prepare();
}
int embeddedStatementsCount = 0;
// collaboration
if (updateCommand != null) {
updateCommand.setSourceTableFilter(sourceTableFilter);
updateCommand.setCondition(appendOnCondition(updateCommand));
updateCommand.prepare();
embeddedStatementsCount++;
}
if (deleteCommand != null) {
deleteCommand.setSourceTableFilter(sourceTableFilter);
deleteCommand.setCondition(appendOnCondition(deleteCommand));
deleteCommand.prepare();
embeddedStatementsCount++;
}
if (insertCommand != null) {
insertCommand.setSourceTableFilter(sourceTableFilter);
insertCommand.prepare();
embeddedStatementsCount++;
}
if (embeddedStatementsCount == 0) {
throw DbException.get(ErrorCode.SYNTAX_ERROR_1, "At least UPDATE, DELETE or INSERT embedded statement must be supplied.");
}
// setup the targetMatchQuery - for detecting if the target row exists
Expression targetMatchCondition = targetMatchQuery.getCondition();
targetMatchCondition.addFilterConditions(sourceTableFilter, true);
targetMatchCondition.mapColumns(sourceTableFilter, 2);
targetMatchCondition = targetMatchCondition.optimize(session);
targetMatchCondition.createIndexConditions(session, sourceTableFilter);
targetMatchQuery.prepare();
}
use of org.h2.command.dml.Delete in project h2database by h2database.
the class ConstraintReferential method checkRowRefTable.
private void checkRowRefTable(Session session, Row oldRow, Row newRow) {
if (oldRow == null) {
// this is an insert
return;
}
if (newRow != null && isEqual(oldRow, newRow)) {
// on an update, if both old and new are the same, don't do anything
return;
}
if (newRow == null) {
// this is a delete
if (deleteAction == ConstraintActionType.RESTRICT) {
checkRow(session, oldRow);
} else {
int i = deleteAction == ConstraintActionType.CASCADE ? 0 : columns.length;
Prepared deleteCommand = getDelete(session);
setWhere(deleteCommand, i, oldRow);
updateWithSkipCheck(deleteCommand);
}
} else {
// this is an update
if (updateAction == ConstraintActionType.RESTRICT) {
checkRow(session, oldRow);
} else {
Prepared updateCommand = getUpdate(session);
if (updateAction == ConstraintActionType.CASCADE) {
ArrayList<Parameter> params = updateCommand.getParameters();
for (int i = 0, len = columns.length; i < len; i++) {
Parameter param = params.get(i);
Column refCol = refColumns[i].column;
param.setValue(newRow.getValue(refCol.getColumnId()));
}
}
setWhere(updateCommand, columns.length, oldRow);
updateWithSkipCheck(updateCommand);
}
}
}
use of org.h2.command.dml.Delete in project h2database by h2database.
the class ConstraintReferential method getCreateSQLForCopy.
/**
* Create the SQL statement of this object so a copy of the table can be
* made.
*
* @param forTable the table to create the object for
* @param forRefTable the referenced table
* @param quotedName the name of this object (quoted if necessary)
* @param internalIndex add the index name to the statement
* @return the SQL statement
*/
public String getCreateSQLForCopy(Table forTable, Table forRefTable, String quotedName, boolean internalIndex) {
StatementBuilder buff = new StatementBuilder("ALTER TABLE ");
String mainTable = forTable.getSQL();
buff.append(mainTable).append(" ADD CONSTRAINT ");
if (forTable.isHidden()) {
buff.append("IF NOT EXISTS ");
}
buff.append(quotedName);
if (comment != null) {
buff.append(" COMMENT ").append(StringUtils.quoteStringSQL(comment));
}
IndexColumn[] cols = columns;
IndexColumn[] refCols = refColumns;
buff.append(" FOREIGN KEY(");
for (IndexColumn c : cols) {
buff.appendExceptFirst(", ");
buff.append(c.getSQL());
}
buff.append(')');
if (internalIndex && indexOwner && forTable == this.table) {
buff.append(" INDEX ").append(index.getSQL());
}
buff.append(" REFERENCES ");
String quotedRefTable;
if (this.table == this.refTable) {
// self-referencing constraints: need to use new table
quotedRefTable = forTable.getSQL();
} else {
quotedRefTable = forRefTable.getSQL();
}
buff.append(quotedRefTable).append('(');
buff.resetCount();
for (IndexColumn r : refCols) {
buff.appendExceptFirst(", ");
buff.append(r.getSQL());
}
buff.append(')');
if (internalIndex && refIndexOwner && forTable == this.table) {
buff.append(" INDEX ").append(refIndex.getSQL());
}
if (deleteAction != ConstraintActionType.RESTRICT) {
buff.append(" ON DELETE ").append(deleteAction.getSqlName());
}
if (updateAction != ConstraintActionType.RESTRICT) {
buff.append(" ON UPDATE ").append(updateAction.getSqlName());
}
return buff.append(" NOCHECK").toString();
}
Aggregations