提交 f28d45c5 authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov

Unify CREATE and ALTER SEQUENCE options parsing

上级 061618f0
......@@ -65,6 +65,7 @@ import org.h2.api.IntervalQualifier;
import org.h2.api.Trigger;
import org.h2.command.ddl.AlterIndexRename;
import org.h2.command.ddl.AlterSchemaRename;
import org.h2.command.ddl.AlterSequence;
import org.h2.command.ddl.AlterTableAddConstraint;
import org.h2.command.ddl.AlterTableAlterColumn;
import org.h2.command.ddl.AlterTableDropConstraint;
......@@ -108,9 +109,9 @@ import org.h2.command.ddl.DropView;
import org.h2.command.ddl.GrantRevoke;
import org.h2.command.ddl.PrepareProcedure;
import org.h2.command.ddl.SchemaCommand;
import org.h2.command.ddl.SequenceOptions;
import org.h2.command.ddl.SetComment;
import org.h2.command.ddl.TruncateTable;
import org.h2.command.dml.AlterSequence;
import org.h2.command.dml.AlterTableSet;
import org.h2.command.dml.BackupCommand;
import org.h2.command.dml.Call;
......@@ -171,10 +172,10 @@ import org.h2.expression.UnaryOperation;
import org.h2.expression.ValueExpression;
import org.h2.expression.Variable;
import org.h2.expression.Wildcard;
import org.h2.expression.aggregate.DataAnalysisOperation;
import org.h2.expression.aggregate.AbstractAggregate;
import org.h2.expression.aggregate.Aggregate;
import org.h2.expression.aggregate.Aggregate.AggregateType;
import org.h2.expression.aggregate.DataAnalysisOperation;
import org.h2.expression.aggregate.JavaAggregate;
import org.h2.expression.aggregate.Window;
import org.h2.expression.aggregate.WindowFrame;
......@@ -4875,19 +4876,12 @@ public class Parser {
}
read("AS");
read("IDENTITY");
long start = 1, increment = 1;
SequenceOptions options = new SequenceOptions();
if (readIf(OPEN_PAREN)) {
read("START");
readIf(WITH);
start = readLong();
readIf(COMMA);
if (readIf("INCREMENT")) {
readIf("BY");
increment = readLong();
}
parseSequenceOptions(options, null, true);
read(CLOSE_PAREN);
}
column.setAutoIncrement(true, start, increment);
column.setAutoIncrementOptions(options);
}
if (readIf(ON)) {
read("UPDATE");
......@@ -4924,15 +4918,15 @@ public class Parser {
}
private void parseAutoIncrement(Column column) {
long start = 1, increment = 1;
SequenceOptions options = new SequenceOptions();
if (readIf(OPEN_PAREN)) {
start = readLong();
options.setStartValue(ValueExpression.get(ValueLong.get(readLong())));
if (readIf(COMMA)) {
increment = readLong();
options.setIncrement(ValueExpression.get(ValueLong.get(readLong())));
}
read(CLOSE_PAREN);
}
column.setAutoIncrement(true, start, increment);
column.setAutoIncrementOptions(options);
}
private String readCommentIf() {
......@@ -5665,49 +5659,9 @@ public class Parser {
CreateSequence command = new CreateSequence(session, getSchema());
command.setIfNotExists(ifNotExists);
command.setSequenceName(sequenceName);
while (true) {
if (readIf("START")) {
readIf(WITH);
command.setStartWith(readExpression());
} else if (readIf("INCREMENT")) {
readIf("BY");
command.setIncrement(readExpression());
} else if (readIf("MINVALUE")) {
command.setMinValue(readExpression());
} else if (readIf("NOMINVALUE")) {
command.setMinValue(null);
} else if (readIf("MAXVALUE")) {
command.setMaxValue(readExpression());
} else if (readIf("NOMAXVALUE")) {
command.setMaxValue(null);
} else if (readIf("CYCLE")) {
command.setCycle(true);
} else if (readIf("NOCYCLE")) {
command.setCycle(false);
} else if (readIf("NO")) {
if (readIf("MINVALUE")) {
command.setMinValue(null);
} else if (readIf("MAXVALUE")) {
command.setMaxValue(null);
} else if (readIf("CYCLE")) {
command.setCycle(false);
} else if (readIf("CACHE")) {
command.setCacheSize(ValueExpression.get(ValueLong.get(1)));
} else {
break;
}
} else if (readIf("CACHE")) {
command.setCacheSize(readExpression());
} else if (readIf("NOCACHE")) {
command.setCacheSize(ValueExpression.get(ValueLong.get(1)));
} else if (readIf("BELONGS_TO_TABLE")) {
command.setBelongsToTable(true);
} else if (readIf(ORDER)) {
// Oracle compatibility
} else {
break;
}
}
SequenceOptions options = new SequenceOptions();
parseSequenceOptions(options, command, true);
command.setOptions(options);
return command;
}
......@@ -6230,46 +6184,60 @@ public class Parser {
AlterSequence command = new AlterSequence(session, getSchema());
command.setSequenceName(sequenceName);
command.setIfExists(ifExists);
while (true) {
if (readIf("RESTART")) {
read(WITH);
command.setStartWith(readExpression());
SequenceOptions options = new SequenceOptions();
parseSequenceOptions(options, null, false);
command.setOptions(options);
return command;
}
private void parseSequenceOptions(SequenceOptions options, CreateSequence command, boolean forCreate) {
for (;;) {
if (readIf(forCreate ? "START" : "RESTART")) {
readIf(WITH);
options.setStartValue(readExpression());
} else if (readIf("INCREMENT")) {
read("BY");
command.setIncrement(readExpression());
readIf("BY");
options.setIncrement(readExpression());
} else if (readIf("MINVALUE")) {
command.setMinValue(readExpression());
options.setMinValue(readExpression());
} else if (readIf("NOMINVALUE")) {
command.setMinValue(null);
options.setMinValue(null);
} else if (readIf("MAXVALUE")) {
command.setMaxValue(readExpression());
options.setMaxValue(readExpression());
} else if (readIf("NOMAXVALUE")) {
command.setMaxValue(null);
options.setMaxValue(null);
} else if (readIf("CYCLE")) {
command.setCycle(true);
options.setCycle(true);
} else if (readIf("NOCYCLE")) {
command.setCycle(false);
options.setCycle(false);
} else if (readIf("NO")) {
if (readIf("MINVALUE")) {
command.setMinValue(null);
options.setMinValue(null);
} else if (readIf("MAXVALUE")) {
command.setMaxValue(null);
options.setMaxValue(null);
} else if (readIf("CYCLE")) {
command.setCycle(false);
options.setCycle(false);
} else if (readIf("CACHE")) {
command.setCacheSize(ValueExpression.get(ValueLong.get(1)));
options.setCacheSize(ValueExpression.get(ValueLong.get(1)));
} else {
break;
}
} else if (readIf("CACHE")) {
command.setCacheSize(readExpression());
options.setCacheSize(readExpression());
} else if (readIf("NOCACHE")) {
command.setCacheSize(ValueExpression.get(ValueLong.get(1)));
options.setCacheSize(ValueExpression.get(ValueLong.get(1)));
} else if (command != null) {
if (readIf("BELONGS_TO_TABLE")) {
command.setBelongsToTable(true);
} else if (readIf(ORDER)) {
// Oracle compatibility
} else {
break;
}
} else {
break;
}
}
return command;
}
private AlterUser parseAlterUser() {
......@@ -7039,7 +7007,9 @@ public class Parser {
Expression start = readExpression();
AlterSequence command = new AlterSequence(session, schema);
command.setColumn(column);
command.setStartWith(start);
SequenceOptions options = new SequenceOptions();
options.setStartValue(start);
command.setOptions(options);
return commandIfTableExists(schema, tableName, ifTableExists, command);
} else if (readIf("SELECTIVITY")) {
AlterTableAlterColumn command = new AlterTableAlterColumn(
......
......@@ -3,15 +3,13 @@
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.command.dml;
package org.h2.command.ddl;
import org.h2.api.ErrorCode;
import org.h2.command.CommandInterface;
import org.h2.command.ddl.SchemaCommand;
import org.h2.engine.Database;
import org.h2.engine.Right;
import org.h2.engine.Session;
import org.h2.expression.Expression;
import org.h2.message.DbException;
import org.h2.schema.Schema;
import org.h2.schema.Sequence;
......@@ -19,21 +17,19 @@ import org.h2.table.Column;
import org.h2.table.Table;
/**
* This class represents the statement
* ALTER SEQUENCE
* This class represents the statement ALTER SEQUENCE.
*/
public class AlterSequence extends SchemaCommand {
private boolean ifExists;
private Table table;
private String sequenceName;
private Sequence sequence;
private Expression start;
private Expression increment;
private Boolean cycle;
private Expression minValue;
private Expression maxValue;
private Expression cacheSize;
private SequenceOptions options;
public AlterSequence(Session session, Schema schema) {
super(session, schema);
......@@ -47,6 +43,10 @@ public class AlterSequence extends SchemaCommand {
this.sequenceName = sequenceName;
}
public void setOptions(SequenceOptions options) {
this.options = options;
}
@Override
public boolean isTransactional() {
return true;
......@@ -60,30 +60,6 @@ public class AlterSequence extends SchemaCommand {
}
}
public void setStartWith(Expression start) {
this.start = start;
}
public void setIncrement(Expression increment) {
this.increment = increment;
}
public void setCycle(Boolean cycle) {
this.cycle = cycle;
}
public void setMinValue(Expression minValue) {
this.minValue = minValue;
}
public void setMaxValue(Expression maxValue) {
this.maxValue = maxValue;
}
public void setCacheSize(Expression cacheSize) {
this.cacheSize = cacheSize;
}
@Override
public int update() {
Database db = session.getDatabase();
......@@ -99,32 +75,22 @@ public class AlterSequence extends SchemaCommand {
if (table != null) {
session.getUser().checkRight(table, Right.ALL);
}
Boolean cycle = options.getCycle();
if (cycle != null) {
sequence.setCycle(cycle);
}
if (cacheSize != null) {
long size = cacheSize.optimize(session).getValue(session).getLong();
sequence.setCacheSize(size);
Long cache = options.getCacheSize(session);
if (cache != null) {
sequence.setCacheSize(cache);
}
if (start != null || minValue != null ||
maxValue != null || increment != null) {
Long startValue = getLong(start);
Long min = getLong(minValue);
Long max = getLong(maxValue);
Long inc = getLong(increment);
sequence.modify(startValue, min, max, inc);
if (options.isRangeSet()) {
sequence.modify(options.getStartValue(session), options.getMinValue(session), options.getMaxValue(session),
options.getIncrement(session));
}
db.updateMeta(session, sequence);
return 0;
}
private Long getLong(Expression expr) {
if (expr == null) {
return null;
}
return expr.optimize(session).getValue(session).getLong();
}
@Override
public int getType() {
return CommandInterface.ALTER_SEQUENCE;
......
......@@ -9,25 +9,21 @@ import org.h2.api.ErrorCode;
import org.h2.command.CommandInterface;
import org.h2.engine.Database;
import org.h2.engine.Session;
import org.h2.expression.Expression;
import org.h2.message.DbException;
import org.h2.schema.Schema;
import org.h2.schema.Sequence;
/**
* This class represents the statement
* CREATE SEQUENCE
* This class represents the statement CREATE SEQUENCE.
*/
public class CreateSequence extends SchemaCommand {
private String sequenceName;
private boolean ifNotExists;
private boolean cycle;
private Expression minValue;
private Expression maxValue;
private Expression start;
private Expression increment;
private Expression cacheSize;
private SequenceOptions options;
private boolean belongsToTable;
public CreateSequence(Session session, Schema schema) {
......@@ -42,8 +38,8 @@ public class CreateSequence extends SchemaCommand {
this.ifNotExists = ifNotExists;
}
public void setCycle(boolean cycle) {
this.cycle = cycle;
public void setOptions(SequenceOptions options) {
this.options = options;
}
@Override
......@@ -57,48 +53,17 @@ public class CreateSequence extends SchemaCommand {
throw DbException.get(ErrorCode.SEQUENCE_ALREADY_EXISTS_1, sequenceName);
}
int id = getObjectId();
Long startValue = getLong(start);
Long inc = getLong(increment);
Long cache = getLong(cacheSize);
Long min = getLong(minValue);
Long max = getLong(maxValue);
Sequence sequence = new Sequence(getSchema(), id, sequenceName, startValue, inc,
cache, min, max, cycle, belongsToTable);
Sequence sequence = new Sequence(getSchema(), id, sequenceName, options.getStartValue(session),
options.getIncrement(session), options.getCacheSize(session), options.getMinValue(session),
options.getMaxValue(session), Boolean.TRUE.equals(options.getCycle()), belongsToTable);
db.addSchemaObject(session, sequence);
return 0;
}
private Long getLong(Expression expr) {
if (expr == null) {
return null;
}
return expr.optimize(session).getValue(session).getLong();
}
public void setStartWith(Expression start) {
this.start = start;
}
public void setIncrement(Expression increment) {
this.increment = increment;
}
public void setMinValue(Expression minValue) {
this.minValue = minValue;
}
public void setMaxValue(Expression maxValue) {
this.maxValue = maxValue;
}
public void setBelongsToTable(boolean belongsToTable) {
this.belongsToTable = belongsToTable;
}
public void setCacheSize(Expression cacheSize) {
this.cacheSize = cacheSize;
}
@Override
public int getType() {
return CommandInterface.CREATE_SEQUENCE;
......
/*
* Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.command.ddl;
import org.h2.engine.Session;
import org.h2.expression.Expression;
/**
* Sequence options.
*/
public class SequenceOptions {
private Expression start;
private Expression increment;
private Expression maxValue;
private Expression minValue;
private Boolean cycle;
private Expression cacheSize;
private static Long getLong(Session session, Expression expr) {
return expr != null ? expr.optimize(session).getValue(session).getLong() : null;
}
public Long getStartValue(Session session) {
return getLong(session, start);
}
public void setStartValue(Expression start) {
this.start = start;
}
public Long getIncrement(Session session) {
return getLong(session, increment);
}
public void setIncrement(Expression increment) {
this.increment = increment;
}
public Long getMaxValue(Session session) {
return getLong(session, maxValue);
}
public void setMaxValue(Expression maxValue) {
this.maxValue = maxValue;
}
public Long getMinValue(Session session) {
return getLong(session, minValue);
}
public void setMinValue(Expression minValue) {
this.minValue = minValue;
}
public Boolean getCycle() {
return cycle;
}
public void setCycle(Boolean cycle) {
this.cycle = cycle;
}
public Long getCacheSize(Session session) {
return getLong(session, cacheSize);
}
public void setCacheSize(Expression cacheSize) {
this.cacheSize = cacheSize;
}
protected boolean isRangeSet() {
return start != null || minValue != null || maxValue != null || increment != null;
}
}
......@@ -10,6 +10,7 @@ import java.util.Objects;
import org.h2.api.ErrorCode;
import org.h2.command.Parser;
import org.h2.command.ddl.SequenceOptions;
import org.h2.engine.Constants;
import org.h2.engine.Mode;
import org.h2.engine.Session;
......@@ -77,9 +78,7 @@ public class Column {
private Expression checkConstraint;
private String checkConstraintSQL;
private String originalSQL;
private boolean autoIncrement;
private long start;
private long increment;
private SequenceOptions autoIncrementOptions;
private boolean convertNullToDefault;
private Sequence sequence;
private boolean isComputed;
......@@ -440,7 +439,7 @@ public class Column {
*/
public void convertAutoIncrementToSequence(Session session, Schema schema,
int id, boolean temporary) {
if (!autoIncrement) {
if (autoIncrementOptions == null) {
DbException.throwInternalError();
}
if ("IDENTITY".equals(originalSQL)) {
......@@ -455,10 +454,13 @@ public class Column {
s = StringUtils.toUpperEnglish(s.replace('-', '_'));
sequenceName = "SYSTEM_SEQUENCE_" + s;
} while (schema.findSequence(sequenceName) != null);
Sequence seq = new Sequence(schema, id, sequenceName, start, increment);
Sequence seq = new Sequence(schema, id, sequenceName, autoIncrementOptions.getStartValue(session),
autoIncrementOptions.getIncrement(session), autoIncrementOptions.getCacheSize(session),
autoIncrementOptions.getMinValue(session), autoIncrementOptions.getMaxValue(session),
Boolean.TRUE.equals(autoIncrementOptions.getCycle()), true);
seq.setTemporary(temporary);
session.getDatabase().addSchemaObject(session, seq);
setAutoIncrement(false, 0, 0);
setAutoIncrementOptions(null);
SequenceValue seqValue = new SequenceValue(seq);
setDefaultExpression(session, seqValue);
setSequence(seq);
......@@ -603,22 +605,19 @@ public class Column {
}
public boolean isAutoIncrement() {
return autoIncrement;
return autoIncrementOptions != null;
}
/**
* Set the autoincrement flag and related properties of this column.
* Set the autoincrement flag and related options of this column.
*
* @param autoInc the new autoincrement flag
* @param start the sequence start value
* @param increment the sequence increment
* @param sequenceOptions
* sequence options, or {@code null} to reset the flag
*/
public void setAutoIncrement(boolean autoInc, long start, long increment) {
this.autoIncrement = autoInc;
this.start = start;
this.increment = increment;
public void setAutoIncrementOptions(SequenceOptions sequenceOptions) {
this.autoIncrementOptions = sequenceOptions;
this.nullable = false;
if (autoInc) {
if (sequenceOptions != null) {
convertNullToDefault = true;
}
}
......@@ -829,7 +828,7 @@ public class Column {
if (primaryKey != newColumn.primaryKey) {
return false;
}
if (autoIncrement || newColumn.autoIncrement) {
if (autoIncrementOptions != null || newColumn.autoIncrementOptions != null) {
return false;
}
if (checkConstraint != null || newColumn.checkConstraint != null) {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论