Unverified 提交 f30a0ba7 authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov 提交者: GitHub

Merge pull request #1468 from katzyn/identity

Parse GENERATED * AS IDENTITY correctly
...@@ -703,12 +703,7 @@ CREATE SCHEMA TEST_SCHEMA AUTHORIZATION SA ...@@ -703,12 +703,7 @@ CREATE SCHEMA TEST_SCHEMA AUTHORIZATION SA
"Commands (DDL)","CREATE SEQUENCE"," "Commands (DDL)","CREATE SEQUENCE","
CREATE SEQUENCE [ IF NOT EXISTS ] newSequenceName CREATE SEQUENCE [ IF NOT EXISTS ] newSequenceName
[ START WITH long ] sequenceOptions
[ INCREMENT BY long ]
[ MINVALUE long | NOMINVALUE | NO MINVALUE ]
[ MAXVALUE long | NOMAXVALUE | NO MAXVALUE ]
[ CYCLE long | NOCYCLE | NO CYCLE ]
[ CACHE long | NOCACHE | NO CACHE ]
"," ","
Creates a new sequence. Creates a new sequence.
The data type of a sequence is BIGINT. The data type of a sequence is BIGINT.
...@@ -2085,7 +2080,9 @@ AES ...@@ -2085,7 +2080,9 @@ AES
"Other Grammar","Column Definition"," "Other Grammar","Column Definition","
dataType [ VISIBLE | INVISIBLE ] dataType [ VISIBLE | INVISIBLE ]
[ { DEFAULT expression | AS computedColumnExpression } ] [ { DEFAULT expression
| AS computedColumnExpression
| GENERATED {ALWAYS | BY DEFAULT} AS IDENTITY [(sequenceOptions)]} ]
[ ON UPDATE expression ] [ [ NOT ] NULL ] [ ON UPDATE expression ] [ [ NOT ] NULL ]
[ { AUTO_INCREMENT | IDENTITY } [ ( startInt [, incrementInt ] ) ] ] [ { AUTO_INCREMENT | IDENTITY } [ ( startInt [, incrementInt ] ) ] ]
[ SELECTIVITY selectivity ] [ COMMENT expression ] [ SELECTIVITY selectivity ] [ COMMENT expression ]
...@@ -2097,9 +2094,11 @@ On update column expression is used if row is updated, ...@@ -2097,9 +2094,11 @@ On update column expression is used if row is updated,
at least one column have a new value that is different from its previous value at least one column have a new value that is different from its previous value
and value for this column is not set explicitly in update statement. and value for this column is not set explicitly in update statement.
Identity and auto-increment columns are columns with a sequence as the Identity, auto-increment, or generated as identity columns are columns with a sequence as the default.
default. The column declared as the identity columns is implicitly the The column declared as the identity columns with IDENTITY data type or with IDENTITY () clause
primary key column of this table (unlike auto-increment columns). is implicitly the primary key column of this table.
AUTO_INCREMENT and GENERATED clauses do not create the primary key constraint.
GENERATED ALWAYS is accepted by treated in the same way as GENERATED BY DEFAULT.
The invisible column will not be displayed as a result of SELECT * query. The invisible column will not be displayed as a result of SELECT * query.
Otherwise, it works as normal column. Otherwise, it works as normal column.
...@@ -2483,6 +2482,19 @@ An expression in a SELECT statement. ...@@ -2483,6 +2482,19 @@ An expression in a SELECT statement.
ID AS VALUE ID AS VALUE
" "
"Other Grammar","Sequence options","
[ START WITH long ]
[ INCREMENT BY long ]
[ MINVALUE long | NOMINVALUE | NO MINVALUE ]
[ MAXVALUE long | NOMAXVALUE | NO MAXVALUE ]
[ CYCLE long | NOCYCLE | NO CYCLE ]
[ CACHE long | NOCACHE | NO CACHE ]
","
Options of a sequence.
","
START WITH 1
"
"Other Grammar","Set clause list"," "Other Grammar","Set clause list","
{ { columnName = { DEFAULT | expression } } [,...] } | { { columnName = { DEFAULT | expression } } [,...] } |
{ ( columnName [,...] ) = ( select ) } { ( columnName [,...] ) = ( select ) }
......
...@@ -21,6 +21,8 @@ Change Log ...@@ -21,6 +21,8 @@ Change Log
<h2>Next Version (unreleased)</h2> <h2>Next Version (unreleased)</h2>
<ul> <ul>
<li>Issue #1437: Generated as Identity has a different behaviour.
</li>
<li>PR #1467: Fix subtraction of timestamps <li>PR #1467: Fix subtraction of timestamps
</li> </li>
<li>PR #1464: Assorted minor changes in window processing code <li>PR #1464: Assorted minor changes in window processing code
......
...@@ -65,6 +65,7 @@ import org.h2.api.IntervalQualifier; ...@@ -65,6 +65,7 @@ import org.h2.api.IntervalQualifier;
import org.h2.api.Trigger; import org.h2.api.Trigger;
import org.h2.command.ddl.AlterIndexRename; import org.h2.command.ddl.AlterIndexRename;
import org.h2.command.ddl.AlterSchemaRename; import org.h2.command.ddl.AlterSchemaRename;
import org.h2.command.ddl.AlterSequence;
import org.h2.command.ddl.AlterTableAddConstraint; import org.h2.command.ddl.AlterTableAddConstraint;
import org.h2.command.ddl.AlterTableAlterColumn; import org.h2.command.ddl.AlterTableAlterColumn;
import org.h2.command.ddl.AlterTableDropConstraint; import org.h2.command.ddl.AlterTableDropConstraint;
...@@ -108,9 +109,9 @@ import org.h2.command.ddl.DropView; ...@@ -108,9 +109,9 @@ import org.h2.command.ddl.DropView;
import org.h2.command.ddl.GrantRevoke; import org.h2.command.ddl.GrantRevoke;
import org.h2.command.ddl.PrepareProcedure; import org.h2.command.ddl.PrepareProcedure;
import org.h2.command.ddl.SchemaCommand; import org.h2.command.ddl.SchemaCommand;
import org.h2.command.ddl.SequenceOptions;
import org.h2.command.ddl.SetComment; import org.h2.command.ddl.SetComment;
import org.h2.command.ddl.TruncateTable; import org.h2.command.ddl.TruncateTable;
import org.h2.command.dml.AlterSequence;
import org.h2.command.dml.AlterTableSet; import org.h2.command.dml.AlterTableSet;
import org.h2.command.dml.BackupCommand; import org.h2.command.dml.BackupCommand;
import org.h2.command.dml.Call; import org.h2.command.dml.Call;
...@@ -171,10 +172,10 @@ import org.h2.expression.UnaryOperation; ...@@ -171,10 +172,10 @@ import org.h2.expression.UnaryOperation;
import org.h2.expression.ValueExpression; import org.h2.expression.ValueExpression;
import org.h2.expression.Variable; import org.h2.expression.Variable;
import org.h2.expression.Wildcard; import org.h2.expression.Wildcard;
import org.h2.expression.aggregate.DataAnalysisOperation;
import org.h2.expression.aggregate.AbstractAggregate; import org.h2.expression.aggregate.AbstractAggregate;
import org.h2.expression.aggregate.Aggregate; import org.h2.expression.aggregate.Aggregate;
import org.h2.expression.aggregate.Aggregate.AggregateType; import org.h2.expression.aggregate.Aggregate.AggregateType;
import org.h2.expression.aggregate.DataAnalysisOperation;
import org.h2.expression.aggregate.JavaAggregate; import org.h2.expression.aggregate.JavaAggregate;
import org.h2.expression.aggregate.Window; import org.h2.expression.aggregate.Window;
import org.h2.expression.aggregate.WindowFrame; import org.h2.expression.aggregate.WindowFrame;
...@@ -4875,20 +4876,12 @@ public class Parser { ...@@ -4875,20 +4876,12 @@ public class Parser {
} }
read("AS"); read("AS");
read("IDENTITY"); read("IDENTITY");
long start = 1, increment = 1; SequenceOptions options = new SequenceOptions();
if (readIf(OPEN_PAREN)) { if (readIf(OPEN_PAREN)) {
read("START"); parseSequenceOptions(options, null, true);
readIf(WITH);
start = readLong();
readIf(COMMA);
if (readIf("INCREMENT")) {
readIf("BY");
increment = readLong();
}
read(CLOSE_PAREN); read(CLOSE_PAREN);
} }
column.setPrimaryKey(true); column.setAutoIncrementOptions(options);
column.setAutoIncrement(true, start, increment);
} }
if (readIf(ON)) { if (readIf(ON)) {
read("UPDATE"); read("UPDATE");
...@@ -4925,15 +4918,15 @@ public class Parser { ...@@ -4925,15 +4918,15 @@ public class Parser {
} }
private void parseAutoIncrement(Column column) { private void parseAutoIncrement(Column column) {
long start = 1, increment = 1; SequenceOptions options = new SequenceOptions();
if (readIf(OPEN_PAREN)) { if (readIf(OPEN_PAREN)) {
start = readLong(); options.setStartValue(ValueExpression.get(ValueLong.get(readLong())));
if (readIf(COMMA)) { if (readIf(COMMA)) {
increment = readLong(); options.setIncrement(ValueExpression.get(ValueLong.get(readLong())));
} }
read(CLOSE_PAREN); read(CLOSE_PAREN);
} }
column.setAutoIncrement(true, start, increment); column.setAutoIncrementOptions(options);
} }
private String readCommentIf() { private String readCommentIf() {
...@@ -5666,49 +5659,9 @@ public class Parser { ...@@ -5666,49 +5659,9 @@ public class Parser {
CreateSequence command = new CreateSequence(session, getSchema()); CreateSequence command = new CreateSequence(session, getSchema());
command.setIfNotExists(ifNotExists); command.setIfNotExists(ifNotExists);
command.setSequenceName(sequenceName); command.setSequenceName(sequenceName);
while (true) { SequenceOptions options = new SequenceOptions();
if (readIf("START")) { parseSequenceOptions(options, command, true);
readIf(WITH); command.setOptions(options);
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;
}
}
return command; return command;
} }
...@@ -6231,46 +6184,60 @@ public class Parser { ...@@ -6231,46 +6184,60 @@ public class Parser {
AlterSequence command = new AlterSequence(session, getSchema()); AlterSequence command = new AlterSequence(session, getSchema());
command.setSequenceName(sequenceName); command.setSequenceName(sequenceName);
command.setIfExists(ifExists); command.setIfExists(ifExists);
while (true) { SequenceOptions options = new SequenceOptions();
if (readIf("RESTART")) { parseSequenceOptions(options, null, false);
read(WITH); command.setOptions(options);
command.setStartWith(readExpression()); 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")) { } else if (readIf("INCREMENT")) {
read("BY"); readIf("BY");
command.setIncrement(readExpression()); options.setIncrement(readExpression());
} else if (readIf("MINVALUE")) { } else if (readIf("MINVALUE")) {
command.setMinValue(readExpression()); options.setMinValue(readExpression());
} else if (readIf("NOMINVALUE")) { } else if (readIf("NOMINVALUE")) {
command.setMinValue(null); options.setMinValue(ValueExpression.getNull());
} else if (readIf("MAXVALUE")) { } else if (readIf("MAXVALUE")) {
command.setMaxValue(readExpression()); options.setMaxValue(readExpression());
} else if (readIf("NOMAXVALUE")) { } else if (readIf("NOMAXVALUE")) {
command.setMaxValue(null); options.setMaxValue(ValueExpression.getNull());
} else if (readIf("CYCLE")) { } else if (readIf("CYCLE")) {
command.setCycle(true); options.setCycle(true);
} else if (readIf("NOCYCLE")) { } else if (readIf("NOCYCLE")) {
command.setCycle(false); options.setCycle(false);
} else if (readIf("NO")) { } else if (readIf("NO")) {
if (readIf("MINVALUE")) { if (readIf("MINVALUE")) {
command.setMinValue(null); options.setMinValue(ValueExpression.getNull());
} else if (readIf("MAXVALUE")) { } else if (readIf("MAXVALUE")) {
command.setMaxValue(null); options.setMaxValue(ValueExpression.getNull());
} else if (readIf("CYCLE")) { } else if (readIf("CYCLE")) {
command.setCycle(false); options.setCycle(false);
} else if (readIf("CACHE")) { } else if (readIf("CACHE")) {
command.setCacheSize(ValueExpression.get(ValueLong.get(1))); options.setCacheSize(ValueExpression.get(ValueLong.get(1)));
} else { } else {
break; break;
} }
} else if (readIf("CACHE")) { } else if (readIf("CACHE")) {
command.setCacheSize(readExpression()); options.setCacheSize(readExpression());
} else if (readIf("NOCACHE")) { } 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 { } else {
break; break;
} }
} }
return command;
} }
private AlterUser parseAlterUser() { private AlterUser parseAlterUser() {
...@@ -7040,7 +7007,9 @@ public class Parser { ...@@ -7040,7 +7007,9 @@ public class Parser {
Expression start = readExpression(); Expression start = readExpression();
AlterSequence command = new AlterSequence(session, schema); AlterSequence command = new AlterSequence(session, schema);
command.setColumn(column); command.setColumn(column);
command.setStartWith(start); SequenceOptions options = new SequenceOptions();
options.setStartValue(start);
command.setOptions(options);
return commandIfTableExists(schema, tableName, ifTableExists, command); return commandIfTableExists(schema, tableName, ifTableExists, command);
} else if (readIf("SELECTIVITY")) { } else if (readIf("SELECTIVITY")) {
AlterTableAlterColumn command = new AlterTableAlterColumn( AlterTableAlterColumn command = new AlterTableAlterColumn(
......
...@@ -3,15 +3,13 @@ ...@@ -3,15 +3,13 @@
* and the EPL 1.0 (http://h2database.com/html/license.html). * and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group * Initial Developer: H2 Group
*/ */
package org.h2.command.dml; package org.h2.command.ddl;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.command.CommandInterface; import org.h2.command.CommandInterface;
import org.h2.command.ddl.SchemaCommand;
import org.h2.engine.Database; import org.h2.engine.Database;
import org.h2.engine.Right; import org.h2.engine.Right;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.expression.Expression;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.schema.Schema; import org.h2.schema.Schema;
import org.h2.schema.Sequence; import org.h2.schema.Sequence;
...@@ -19,21 +17,19 @@ import org.h2.table.Column; ...@@ -19,21 +17,19 @@ import org.h2.table.Column;
import org.h2.table.Table; import org.h2.table.Table;
/** /**
* This class represents the statement * This class represents the statement ALTER SEQUENCE.
* ALTER SEQUENCE
*/ */
public class AlterSequence extends SchemaCommand { public class AlterSequence extends SchemaCommand {
private boolean ifExists; private boolean ifExists;
private Table table; private Table table;
private String sequenceName; private String sequenceName;
private Sequence sequence; private Sequence sequence;
private Expression start;
private Expression increment; private SequenceOptions options;
private Boolean cycle;
private Expression minValue;
private Expression maxValue;
private Expression cacheSize;
public AlterSequence(Session session, Schema schema) { public AlterSequence(Session session, Schema schema) {
super(session, schema); super(session, schema);
...@@ -47,6 +43,10 @@ public class AlterSequence extends SchemaCommand { ...@@ -47,6 +43,10 @@ public class AlterSequence extends SchemaCommand {
this.sequenceName = sequenceName; this.sequenceName = sequenceName;
} }
public void setOptions(SequenceOptions options) {
this.options = options;
}
@Override @Override
public boolean isTransactional() { public boolean isTransactional() {
return true; return true;
...@@ -60,30 +60,6 @@ public class AlterSequence extends SchemaCommand { ...@@ -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 @Override
public int update() { public int update() {
Database db = session.getDatabase(); Database db = session.getDatabase();
...@@ -99,32 +75,22 @@ public class AlterSequence extends SchemaCommand { ...@@ -99,32 +75,22 @@ public class AlterSequence extends SchemaCommand {
if (table != null) { if (table != null) {
session.getUser().checkRight(table, Right.ALL); session.getUser().checkRight(table, Right.ALL);
} }
Boolean cycle = options.getCycle();
if (cycle != null) { if (cycle != null) {
sequence.setCycle(cycle); sequence.setCycle(cycle);
} }
if (cacheSize != null) { Long cache = options.getCacheSize(session);
long size = cacheSize.optimize(session).getValue(session).getLong(); if (cache != null) {
sequence.setCacheSize(size); sequence.setCacheSize(cache);
} }
if (start != null || minValue != null || if (options.isRangeSet()) {
maxValue != null || increment != null) { sequence.modify(options.getStartValue(session), options.getMinValue(sequence, session),
Long startValue = getLong(start); options.getMaxValue(sequence, session), options.getIncrement(session));
Long min = getLong(minValue);
Long max = getLong(maxValue);
Long inc = getLong(increment);
sequence.modify(startValue, min, max, inc);
} }
db.updateMeta(session, sequence); db.updateMeta(session, sequence);
return 0; return 0;
} }
private Long getLong(Expression expr) {
if (expr == null) {
return null;
}
return expr.optimize(session).getValue(session).getLong();
}
@Override @Override
public int getType() { public int getType() {
return CommandInterface.ALTER_SEQUENCE; return CommandInterface.ALTER_SEQUENCE;
......
...@@ -9,25 +9,21 @@ import org.h2.api.ErrorCode; ...@@ -9,25 +9,21 @@ import org.h2.api.ErrorCode;
import org.h2.command.CommandInterface; import org.h2.command.CommandInterface;
import org.h2.engine.Database; import org.h2.engine.Database;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.expression.Expression;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.schema.Schema; import org.h2.schema.Schema;
import org.h2.schema.Sequence; import org.h2.schema.Sequence;
/** /**
* This class represents the statement * This class represents the statement CREATE SEQUENCE.
* CREATE SEQUENCE
*/ */
public class CreateSequence extends SchemaCommand { public class CreateSequence extends SchemaCommand {
private String sequenceName; private String sequenceName;
private boolean ifNotExists; private boolean ifNotExists;
private boolean cycle;
private Expression minValue; private SequenceOptions options;
private Expression maxValue;
private Expression start;
private Expression increment;
private Expression cacheSize;
private boolean belongsToTable; private boolean belongsToTable;
public CreateSequence(Session session, Schema schema) { public CreateSequence(Session session, Schema schema) {
...@@ -42,8 +38,8 @@ public class CreateSequence extends SchemaCommand { ...@@ -42,8 +38,8 @@ public class CreateSequence extends SchemaCommand {
this.ifNotExists = ifNotExists; this.ifNotExists = ifNotExists;
} }
public void setCycle(boolean cycle) { public void setOptions(SequenceOptions options) {
this.cycle = cycle; this.options = options;
} }
@Override @Override
...@@ -57,48 +53,17 @@ public class CreateSequence extends SchemaCommand { ...@@ -57,48 +53,17 @@ public class CreateSequence extends SchemaCommand {
throw DbException.get(ErrorCode.SEQUENCE_ALREADY_EXISTS_1, sequenceName); throw DbException.get(ErrorCode.SEQUENCE_ALREADY_EXISTS_1, sequenceName);
} }
int id = getObjectId(); int id = getObjectId();
Long startValue = getLong(start); Sequence sequence = new Sequence(getSchema(), id, sequenceName, options.getStartValue(session),
Long inc = getLong(increment); options.getIncrement(session), options.getCacheSize(session), options.getMinValue(null, session),
Long cache = getLong(cacheSize); options.getMaxValue(null, session), Boolean.TRUE.equals(options.getCycle()), belongsToTable);
Long min = getLong(minValue);
Long max = getLong(maxValue);
Sequence sequence = new Sequence(getSchema(), id, sequenceName, startValue, inc,
cache, min, max, cycle, belongsToTable);
db.addSchemaObject(session, sequence); db.addSchemaObject(session, sequence);
return 0; 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) { public void setBelongsToTable(boolean belongsToTable) {
this.belongsToTable = belongsToTable; this.belongsToTable = belongsToTable;
} }
public void setCacheSize(Expression cacheSize) {
this.cacheSize = cacheSize;
}
@Override @Override
public int getType() { public int getType() {
return CommandInterface.CREATE_SEQUENCE; 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;
import org.h2.expression.ValueExpression;
import org.h2.schema.Sequence;
import org.h2.value.Value;
import org.h2.value.ValueNull;
/**
* 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) {
if (expr != null) {
Value value = expr.optimize(session).getValue(session);
if (value != ValueNull.INSTANCE) {
return value.getLong();
}
}
return 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(Sequence sequence, Session session) {
if (maxValue == ValueExpression.getNull() && sequence != null) {
return Sequence.getDefaultMaxValue(getCurrentStart(sequence, session),
increment != null ? getIncrement(session) : sequence.getIncrement());
}
return getLong(session, maxValue);
}
public void setMaxValue(Expression maxValue) {
this.maxValue = maxValue;
}
public Long getMinValue(Sequence sequence, Session session) {
if (minValue == ValueExpression.getNull() && sequence != null) {
return Sequence.getDefaultMinValue(getCurrentStart(sequence, session),
increment != null ? getIncrement(session) : sequence.getIncrement());
}
return getLong(session, minValue);
}
public long getCurrentStart(Sequence sequence, Session session) {
return start != null ? getStartValue(session) : sequence.getCurrentValue() + sequence.getIncrement();
}
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;
}
}
...@@ -148,7 +148,7 @@ public class Sequence extends SchemaObjectBase { ...@@ -148,7 +148,7 @@ public class Sequence extends SchemaObjectBase {
Math.abs(increment) + Long.MIN_VALUE <= maxValue - minValue + Long.MIN_VALUE; Math.abs(increment) + Long.MIN_VALUE <= maxValue - minValue + Long.MIN_VALUE;
} }
private static long getDefaultMinValue(Long startValue, long increment) { public static long getDefaultMinValue(Long startValue, long increment) {
long v = increment >= 0 ? 1 : Long.MIN_VALUE; long v = increment >= 0 ? 1 : Long.MIN_VALUE;
if (startValue != null && increment >= 0 && startValue < v) { if (startValue != null && increment >= 0 && startValue < v) {
v = startValue; v = startValue;
...@@ -156,7 +156,7 @@ public class Sequence extends SchemaObjectBase { ...@@ -156,7 +156,7 @@ public class Sequence extends SchemaObjectBase {
return v; return v;
} }
private static long getDefaultMaxValue(Long startValue, long increment) { public static long getDefaultMaxValue(Long startValue, long increment) {
long v = increment >= 0 ? Long.MAX_VALUE : -1; long v = increment >= 0 ? Long.MAX_VALUE : -1;
if (startValue != null && increment < 0 && startValue > v) { if (startValue != null && increment < 0 && startValue > v) {
v = startValue; v = startValue;
......
...@@ -10,6 +10,7 @@ import java.util.Objects; ...@@ -10,6 +10,7 @@ import java.util.Objects;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.command.Parser; import org.h2.command.Parser;
import org.h2.command.ddl.SequenceOptions;
import org.h2.engine.Constants; import org.h2.engine.Constants;
import org.h2.engine.Mode; import org.h2.engine.Mode;
import org.h2.engine.Session; import org.h2.engine.Session;
...@@ -77,9 +78,7 @@ public class Column { ...@@ -77,9 +78,7 @@ public class Column {
private Expression checkConstraint; private Expression checkConstraint;
private String checkConstraintSQL; private String checkConstraintSQL;
private String originalSQL; private String originalSQL;
private boolean autoIncrement; private SequenceOptions autoIncrementOptions;
private long start;
private long increment;
private boolean convertNullToDefault; private boolean convertNullToDefault;
private Sequence sequence; private Sequence sequence;
private boolean isComputed; private boolean isComputed;
...@@ -440,7 +439,7 @@ public class Column { ...@@ -440,7 +439,7 @@ public class Column {
*/ */
public void convertAutoIncrementToSequence(Session session, Schema schema, public void convertAutoIncrementToSequence(Session session, Schema schema,
int id, boolean temporary) { int id, boolean temporary) {
if (!autoIncrement) { if (autoIncrementOptions == null) {
DbException.throwInternalError(); DbException.throwInternalError();
} }
if ("IDENTITY".equals(originalSQL)) { if ("IDENTITY".equals(originalSQL)) {
...@@ -455,10 +454,13 @@ public class Column { ...@@ -455,10 +454,13 @@ public class Column {
s = StringUtils.toUpperEnglish(s.replace('-', '_')); s = StringUtils.toUpperEnglish(s.replace('-', '_'));
sequenceName = "SYSTEM_SEQUENCE_" + s; sequenceName = "SYSTEM_SEQUENCE_" + s;
} while (schema.findSequence(sequenceName) != null); } 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(null, session), autoIncrementOptions.getMaxValue(null, session),
Boolean.TRUE.equals(autoIncrementOptions.getCycle()), true);
seq.setTemporary(temporary); seq.setTemporary(temporary);
session.getDatabase().addSchemaObject(session, seq); session.getDatabase().addSchemaObject(session, seq);
setAutoIncrement(false, 0, 0); setAutoIncrementOptions(null);
SequenceValue seqValue = new SequenceValue(seq); SequenceValue seqValue = new SequenceValue(seq);
setDefaultExpression(session, seqValue); setDefaultExpression(session, seqValue);
setSequence(seq); setSequence(seq);
...@@ -603,22 +605,19 @@ public class Column { ...@@ -603,22 +605,19 @@ public class Column {
} }
public boolean isAutoIncrement() { 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 sequenceOptions
* @param start the sequence start value * sequence options, or {@code null} to reset the flag
* @param increment the sequence increment
*/ */
public void setAutoIncrement(boolean autoInc, long start, long increment) { public void setAutoIncrementOptions(SequenceOptions sequenceOptions) {
this.autoIncrement = autoInc; this.autoIncrementOptions = sequenceOptions;
this.start = start;
this.increment = increment;
this.nullable = false; this.nullable = false;
if (autoInc) { if (sequenceOptions != null) {
convertNullToDefault = true; convertNullToDefault = true;
} }
} }
...@@ -829,7 +828,7 @@ public class Column { ...@@ -829,7 +828,7 @@ public class Column {
if (primaryKey != newColumn.primaryKey) { if (primaryKey != newColumn.primaryKey) {
return false; return false;
} }
if (autoIncrement || newColumn.autoIncrement) { if (autoIncrementOptions != null || newColumn.autoIncrementOptions != null) {
return false; return false;
} }
if (checkConstraint != null || newColumn.checkConstraint != null) { if (checkConstraint != null || newColumn.checkConstraint != null) {
......
...@@ -45,3 +45,36 @@ DROP SEQUENCE SEQ; ...@@ -45,3 +45,36 @@ DROP SEQUENCE SEQ;
CREATE SEQUENCE SEQ START WITH 0 INCREMENT BY -9223372036854775808 MINVALUE 0 MAXVALUE 9223372036854775807; CREATE SEQUENCE SEQ START WITH 0 INCREMENT BY -9223372036854775808 MINVALUE 0 MAXVALUE 9223372036854775807;
> exception SEQUENCE_ATTRIBUTES_INVALID > exception SEQUENCE_ATTRIBUTES_INVALID
CREATE SEQUENCE SEQ START WITH 0 MINVALUE -10 MAXVALUE 10;
> ok
SELECT SEQUENCE_NAME, CURRENT_VALUE, INCREMENT, CACHE, MIN_VALUE, MAX_VALUE, IS_CYCLE
FROM INFORMATION_SCHEMA.SEQUENCES;
> SEQUENCE_NAME CURRENT_VALUE INCREMENT CACHE MIN_VALUE MAX_VALUE IS_CYCLE
> ------------- ------------- --------- ----- --------- --------- --------
> SEQ -1 1 32 -10 10 FALSE
> rows: 1
ALTER SEQUENCE SEQ NO MINVALUE NO MAXVALUE;
> ok
SELECT SEQUENCE_NAME, CURRENT_VALUE, INCREMENT, CACHE, MIN_VALUE, MAX_VALUE, IS_CYCLE
FROM INFORMATION_SCHEMA.SEQUENCES;
> SEQUENCE_NAME CURRENT_VALUE INCREMENT CACHE MIN_VALUE MAX_VALUE IS_CYCLE
> ------------- ------------- --------- ----- --------- ------------------- --------
> SEQ -1 1 32 0 9223372036854775807 FALSE
> rows: 1
ALTER SEQUENCE SEQ MINVALUE -100 MAXVALUE 100;
> ok
SELECT SEQUENCE_NAME, CURRENT_VALUE, INCREMENT, CACHE, MIN_VALUE, MAX_VALUE, IS_CYCLE
FROM INFORMATION_SCHEMA.SEQUENCES;
> SEQUENCE_NAME CURRENT_VALUE INCREMENT CACHE MIN_VALUE MAX_VALUE IS_CYCLE
> ------------- ------------- --------- ----- --------- --------- --------
> SEQ -1 1 32 -100 100 FALSE
> rows: 1
DROP SEQUENCE SEQ;
> ok
...@@ -95,3 +95,22 @@ SELECT COLUMN_NAME, IS_VISIBLE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME ...@@ -95,3 +95,22 @@ SELECT COLUMN_NAME, IS_VISIBLE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME
DROP TABLE TEST; DROP TABLE TEST;
> ok > ok
CREATE TABLE TEST1(ID IDENTITY);
> ok
CREATE TABLE TEST2(ID BIGINT IDENTITY);
> ok
CREATE TABLE TEST3(ID BIGINT GENERATED BY DEFAULT AS IDENTITY);
> ok
SELECT CONSTRAINT_TYPE, TABLE_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE TABLE_SCHEMA = 'PUBLIC';
> CONSTRAINT_TYPE TABLE_NAME
> --------------- ----------
> PRIMARY KEY TEST1
> PRIMARY KEY TEST2
> rows: 2
DROP TABLE TEST1, TEST2, TEST3;
> ok
...@@ -797,3 +797,4 @@ xym normalizes coord setz xyzm geometrycollection multipolygon mixup rings polyg ...@@ -797,3 +797,4 @@ xym normalizes coord setz xyzm geometrycollection multipolygon mixup rings polyg
pointzm pointz pointm dimensionality redefine forum measures pointzm pointz pointm dimensionality redefine forum measures
mpg casted pzm mls constrained subtypes complains mpg casted pzm mls constrained subtypes complains
ranks rno dro rko precede cume reopens preceding unbounded rightly itr lag maximal tiles tile ntile signify ranks rno dro rko precede cume reopens preceding unbounded rightly itr lag maximal tiles tile ntile signify
partitioned
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论