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

Merge pull request #959 from katzyn/on_update

Add optional MySQL-style ON UPDATE to columns
...@@ -329,9 +329,11 @@ ALTER TABLE [ IF EXISTS ] tableName ALTER COLUMN columnName ...@@ -329,9 +329,11 @@ ALTER TABLE [ IF EXISTS ] tableName ALTER COLUMN columnName
| { RESTART WITH long } | { RESTART WITH long }
| { SELECTIVITY int } | { SELECTIVITY int }
| { SET DEFAULT expression } | { SET DEFAULT expression }
| { SET ON UPDATE expression }
| { SET NULL } | { SET NULL }
| { SET NOT NULL } | { SET NOT NULL }
| { SET { VISIBLE | INVISIBLE } } } | { SET { VISIBLE | INVISIBLE } }
| { DROP { DEFAULT | ON UPDATE } } }
"," ","
Changes the data type of a column, rename a column, Changes the data type of a column, rename a column,
change the identity value, or change the selectivity. change the identity value, or change the selectivity.
...@@ -349,6 +351,8 @@ Selectivity 100 means values are unique, 10 means every distinct value appears 1 ...@@ -349,6 +351,8 @@ Selectivity 100 means values are unique, 10 means every distinct value appears 1
SET DEFAULT changes the default value of a column. SET DEFAULT changes the default value of a column.
SET ON UPDATE changes the value that is set on update if value for this column is not specified in update statement.
SET NULL sets a column to allow NULL. The row may not be part of a primary key. SET NULL sets a column to allow NULL. The row may not be part of a primary key.
Single column indexes on this column are dropped. Single column indexes on this column are dropped.
...@@ -357,6 +361,10 @@ SET NOT NULL sets a column to not allow NULL. Rows may not contains NULL in this ...@@ -357,6 +361,10 @@ SET NOT NULL sets a column to not allow NULL. Rows may not contains NULL in this
SET INVISIBLE makes the column hidden, i.e. it will not appear in SELECT * results. SET INVISIBLE makes the column hidden, i.e. it will not appear in SELECT * results.
SET VISIBLE has the reverse effect. SET VISIBLE has the reverse effect.
DROP DEFAULT removes the default value of a column.
DROP ON UPDATE removes the value that is set on update of a column.
This command commits an open transaction in this connection. This command commits an open transaction in this connection.
"," ","
ALTER TABLE TEST ALTER COLUMN NAME CLOB; ALTER TABLE TEST ALTER COLUMN NAME CLOB;
...@@ -2050,13 +2058,17 @@ AES ...@@ -2050,13 +2058,17 @@ AES
"Other Grammar","Column Definition"," "Other Grammar","Column Definition","
dataType [ VISIBLE | INVISIBLE ] dataType [ VISIBLE | INVISIBLE ]
[ { DEFAULT expression | AS computedColumnExpression } ] [ [ NOT ] NULL ] [ { DEFAULT expression | AS computedColumnExpression } ]
[ ON UPDATE expression ] [ [ NOT ] NULL ]
[ { AUTO_INCREMENT | IDENTITY } [ ( startInt [, incrementInt ] ) ] ] [ { AUTO_INCREMENT | IDENTITY } [ ( startInt [, incrementInt ] ) ] ]
[ SELECTIVITY selectivity ] [ COMMENT expression ] [ SELECTIVITY selectivity ] [ COMMENT expression ]
[ PRIMARY KEY [ HASH ] | UNIQUE ] [ CHECK condition ] [ PRIMARY KEY [ HASH ] | UNIQUE ] [ CHECK condition ]
"," ","
Default expressions are used if no explicit value was used when adding a row. Default expressions are used if no explicit value was used when adding a row.
The computed column expression is evaluated and assigned whenever the row changes. The computed column expression is evaluated and assigned whenever the row changes.
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
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 and auto-increment columns are columns with a sequence as the
default. The column declared as the identity columns is implicitly the default. The column declared as the identity columns is implicitly the
......
...@@ -478,6 +478,11 @@ public interface CommandInterface { ...@@ -478,6 +478,11 @@ public interface CommandInterface {
*/ */
int DROP_SYNONYM = 89; int DROP_SYNONYM = 89;
/**
* The type of a ALTER TABLE ALTER COLUMN SET ON UPDATE statement.
*/
int ALTER_TABLE_ALTER_COLUMN_ON_UPDATE = 90;
/** /**
* Get command type. * Get command type.
* *
......
...@@ -4291,6 +4291,11 @@ public class Parser { ...@@ -4291,6 +4291,11 @@ public class Parser {
column.setPrimaryKey(true); column.setPrimaryKey(true);
column.setAutoIncrement(true, start, increment); column.setAutoIncrement(true, start, increment);
} }
if (readIf("ON")) {
read("UPDATE");
Expression onUpdateExpression = readExpression();
column.setOnUpdateExpression(session, onUpdateExpression);
}
if (NullConstraintType.NULL_IS_NOT_ALLOWED == parseNotNullConstraint()) { if (NullConstraintType.NULL_IS_NOT_ALLOWED == parseNotNullConstraint()) {
column.setNullable(false); column.setNullable(false);
} }
...@@ -6205,6 +6210,16 @@ public class Parser { ...@@ -6205,6 +6210,16 @@ public class Parser {
command.setDefaultExpression(null); command.setDefaultExpression(null);
return command; return command;
} }
if (readIf("ON")) {
read("UPDATE");
AlterTableAlterColumn command = new AlterTableAlterColumn(session, schema);
command.setTableName(tableName);
command.setIfTableExists(ifTableExists);
command.setOldColumn(column);
command.setType(CommandInterface.ALTER_TABLE_ALTER_COLUMN_ON_UPDATE);
command.setDefaultExpression(null);
return command;
}
read("NOT"); read("NOT");
read("NULL"); read("NULL");
AlterTableAlterColumn command = new AlterTableAlterColumn( AlterTableAlterColumn command = new AlterTableAlterColumn(
...@@ -6243,11 +6258,14 @@ public class Parser { ...@@ -6243,11 +6258,14 @@ public class Parser {
Expression defaultExpression = readExpression(); Expression defaultExpression = readExpression();
command.setType(CommandInterface.ALTER_TABLE_ALTER_COLUMN_DEFAULT); command.setType(CommandInterface.ALTER_TABLE_ALTER_COLUMN_DEFAULT);
command.setDefaultExpression(defaultExpression); command.setDefaultExpression(defaultExpression);
} else if (readIf("ON")) {
read("UPDATE");
Expression onUpdateExpression = readExpression();
command.setType(CommandInterface.ALTER_TABLE_ALTER_COLUMN_ON_UPDATE);
command.setDefaultExpression(onUpdateExpression);
} else if (readIf("INVISIBLE")) { } else if (readIf("INVISIBLE")) {
command.setType(CommandInterface.ALTER_TABLE_ALTER_COLUMN_VISIBILITY); command.setType(CommandInterface.ALTER_TABLE_ALTER_COLUMN_VISIBILITY);
command.setVisible(false); command.setVisible(false);
} else if (readIf("VISIBLE")) { } else if (readIf("VISIBLE")) {
command.setType(CommandInterface.ALTER_TABLE_ALTER_COLUMN_VISIBILITY); command.setType(CommandInterface.ALTER_TABLE_ALTER_COLUMN_VISIBILITY);
command.setVisible(true); command.setVisible(true);
......
...@@ -54,6 +54,9 @@ public class AlterTableAlterColumn extends CommandWithColumns { ...@@ -54,6 +54,9 @@ public class AlterTableAlterColumn extends CommandWithColumns {
private Column oldColumn; private Column oldColumn;
private Column newColumn; private Column newColumn;
private int type; private int type;
/**
* Default or on update expression.
*/
private Expression defaultExpression; private Expression defaultExpression;
private Expression newSelectivity; private Expression newSelectivity;
private boolean addFirst; private boolean addFirst;
...@@ -147,6 +150,12 @@ public class AlterTableAlterColumn extends CommandWithColumns { ...@@ -147,6 +150,12 @@ public class AlterTableAlterColumn extends CommandWithColumns {
db.updateMeta(session, table); db.updateMeta(session, table);
break; break;
} }
case CommandInterface.ALTER_TABLE_ALTER_COLUMN_ON_UPDATE: {
checkDefaultReferencesTable(table, defaultExpression);
oldColumn.setOnUpdateExpression(session, defaultExpression);
db.updateMeta(session, table);
break;
}
case CommandInterface.ALTER_TABLE_ALTER_COLUMN_CHANGE_TYPE: { case CommandInterface.ALTER_TABLE_ALTER_COLUMN_CHANGE_TYPE: {
// if the change is only increasing the precision, then we don't // if the change is only increasing the precision, then we don't
// need to copy the table because the length is only a constraint, // need to copy the table because the length is only a constraint,
...@@ -551,6 +560,11 @@ public class AlterTableAlterColumn extends CommandWithColumns { ...@@ -551,6 +560,11 @@ public class AlterTableAlterColumn extends CommandWithColumns {
newSelectivity = selectivity; newSelectivity = selectivity;
} }
/**
* Set default or on update expression.
*
* @param defaultExpression default or on update expression
*/
public void setDefaultExpression(Expression defaultExpression) { public void setDefaultExpression(Expression defaultExpression) {
this.defaultExpression = defaultExpression; this.defaultExpression = defaultExpression;
} }
......
...@@ -7,6 +7,8 @@ package org.h2.command.dml; ...@@ -7,6 +7,8 @@ package org.h2.command.dml;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Objects;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.api.Trigger; import org.h2.api.Trigger;
import org.h2.command.CommandInterface; import org.h2.command.CommandInterface;
...@@ -115,20 +117,43 @@ public class Update extends Prepared { ...@@ -115,20 +117,43 @@ public class Update extends Prepared {
if (condition == null || condition.getBooleanValue(session)) { if (condition == null || condition.getBooleanValue(session)) {
Row oldRow = targetTableFilter.get(); Row oldRow = targetTableFilter.get();
Row newRow = table.getTemplateRow(); Row newRow = table.getTemplateRow();
boolean setOnUpdate = false;
for (int i = 0; i < columnCount; i++) { for (int i = 0; i < columnCount; i++) {
Expression newExpr = expressionMap.get(columns[i]); Expression newExpr = expressionMap.get(columns[i]);
Column column = table.getColumn(i);
Value newValue; Value newValue;
if (newExpr == null) { if (newExpr == null) {
if (column.getOnUpdateExpression() != null) {
setOnUpdate = true;
}
newValue = oldRow.getValue(i); newValue = oldRow.getValue(i);
} else if (newExpr == ValueExpression.getDefault()) { } else if (newExpr == ValueExpression.getDefault()) {
Column column = table.getColumn(i);
newValue = table.getDefaultValue(session, column); newValue = table.getDefaultValue(session, column);
} else { } else {
Column column = table.getColumn(i);
newValue = column.convert(newExpr.getValue(session)); newValue = column.convert(newExpr.getValue(session));
} }
newRow.setValue(i, newValue); newRow.setValue(i, newValue);
} }
if (setOnUpdate) {
setOnUpdate = false;
for (int i = 0; i < columnCount; i++) {
// Use equals here to detect changes from numeric 0 to 0.0 and similar
if (!Objects.equals(oldRow.getValue(i), newRow.getValue(i))) {
setOnUpdate = true;
break;
}
}
if (setOnUpdate) {
for (int i = 0; i < columnCount; i++) {
if (expressionMap.get(columns[i]) == null) {
Column column = table.getColumn(i);
if (column.getOnUpdateExpression() != null) {
newRow.setValue(i, table.getOnUpdateValue(session, column));
}
}
}
}
}
table.validateConvertUpdateSequence(session, newRow); table.validateConvertUpdateSequence(session, newRow);
boolean done = false; boolean done = false;
if (table.fireRow()) { if (table.fireRow()) {
......
...@@ -75,6 +75,7 @@ public class Column { ...@@ -75,6 +75,7 @@ public class Column {
private int columnId; private int columnId;
private boolean nullable = true; private boolean nullable = true;
private Expression defaultExpression; private Expression defaultExpression;
private Expression onUpdateExpression;
private Expression checkConstraint; private Expression checkConstraint;
private String checkConstraintSQL; private String checkConstraintSQL;
private String originalSQL; private String originalSQL;
...@@ -248,6 +249,23 @@ public class Column { ...@@ -248,6 +249,23 @@ public class Column {
this.defaultExpression = defaultExpression; this.defaultExpression = defaultExpression;
} }
/**
* Set the on update expression.
*
* @param session the session
* @param onUpdateExpression the on update expression
*/
public void setOnUpdateExpression(Session session, Expression onUpdateExpression) {
// also to test that no column names are used
if (onUpdateExpression != null) {
onUpdateExpression = onUpdateExpression.optimize(session);
if (onUpdateExpression.isConstant()) {
onUpdateExpression = ValueExpression.get(onUpdateExpression.getValue(session));
}
}
this.onUpdateExpression = onUpdateExpression;
}
public int getColumnId() { public int getColumnId() {
return columnId; return columnId;
} }
...@@ -461,11 +479,16 @@ public class Column { ...@@ -461,11 +479,16 @@ public class Column {
* @param session the session * @param session the session
*/ */
public void prepareExpression(Session session) { public void prepareExpression(Session session) {
if (defaultExpression != null) { if (defaultExpression != null || onUpdateExpression != null) {
computeTableFilter = new TableFilter(session, table, null, false, null, 0, computeTableFilter = new TableFilter(session, table, null, false, null, 0, null);
null); if (defaultExpression != null) {
defaultExpression.mapColumns(computeTableFilter, 0); defaultExpression.mapColumns(computeTableFilter, 0);
defaultExpression = defaultExpression.optimize(session); defaultExpression = defaultExpression.optimize(session);
}
if (onUpdateExpression != null) {
onUpdateExpression.mapColumns(computeTableFilter, 0);
onUpdateExpression = onUpdateExpression.optimize(session);
}
} }
} }
...@@ -526,6 +549,12 @@ public class Column { ...@@ -526,6 +549,12 @@ public class Column {
} }
} }
} }
if (onUpdateExpression != null) {
String sql = onUpdateExpression.getSQL();
if (sql != null) {
buff.append(" ON UPDATE ").append(sql);
}
}
if (!nullable) { if (!nullable) {
buff.append(" NOT NULL"); buff.append(" NOT NULL");
} }
...@@ -563,6 +592,10 @@ public class Column { ...@@ -563,6 +592,10 @@ public class Column {
return defaultExpression; return defaultExpression;
} }
public Expression getOnUpdateExpression() {
return onUpdateExpression;
}
public boolean isAutoIncrement() { public boolean isAutoIncrement() {
return autoIncrement; return autoIncrement;
} }
...@@ -695,6 +728,10 @@ public class Column { ...@@ -695,6 +728,10 @@ public class Column {
return defaultExpression == null ? null : defaultExpression.getSQL(); return defaultExpression == null ? null : defaultExpression.getSQL();
} }
String getOnUpdateSQL() {
return onUpdateExpression == null ? null : onUpdateExpression.getSQL();
}
int getPrecisionAsInt() { int getPrecisionAsInt() {
return MathUtils.convertLongToInt(precision); return MathUtils.convertLongToInt(precision);
} }
...@@ -800,6 +837,9 @@ public class Column { ...@@ -800,6 +837,9 @@ public class Column {
if (isComputed || newColumn.isComputed) { if (isComputed || newColumn.isComputed) {
return false; return false;
} }
if (onUpdateExpression != null || newColumn.onUpdateExpression != null) {
return false;
}
return true; return true;
} }
...@@ -821,6 +861,7 @@ public class Column { ...@@ -821,6 +861,7 @@ public class Column {
// columnId is not set // columnId is not set
nullable = source.nullable; nullable = source.nullable;
defaultExpression = source.defaultExpression; defaultExpression = source.defaultExpression;
onUpdateExpression = source.onUpdateExpression;
originalSQL = source.originalSQL; originalSQL = source.originalSQL;
// autoIncrement, start, increment is not set // autoIncrement, start, increment is not set
convertNullToDefault = source.convertNullToDefault; convertNullToDefault = source.convertNullToDefault;
......
...@@ -179,7 +179,8 @@ public class MetaTable extends Table { ...@@ -179,7 +179,8 @@ public class MetaTable extends Table {
"SEQUENCE_NAME", "SEQUENCE_NAME",
"REMARKS", "REMARKS",
"SOURCE_DATA_TYPE SMALLINT", "SOURCE_DATA_TYPE SMALLINT",
"COLUMN_TYPE" "COLUMN_TYPE",
"COLUMN_ON_UPDATE"
); );
indexColumnName = "TABLE_NAME"; indexColumnName = "TABLE_NAME";
break; break;
...@@ -882,7 +883,9 @@ public class MetaTable extends Table { ...@@ -882,7 +883,9 @@ public class MetaTable extends Table {
// SOURCE_DATA_TYPE // SOURCE_DATA_TYPE
null, null,
// COLUMN_TYPE // COLUMN_TYPE
c.getCreateSQLWithoutName() c.getCreateSQLWithoutName(),
// COLUMN_ON_UPDATE
c.getOnUpdateSQL()
); );
} }
} }
......
...@@ -1209,6 +1209,16 @@ public abstract class Table extends SchemaObjectBase { ...@@ -1209,6 +1209,16 @@ public abstract class Table extends SchemaObjectBase {
database.checkWritingAllowed(); database.checkWritingAllowed();
} }
private static Value getGeneratedValue(Session session, Column column, Expression expression) {
Value v;
if (expression == null) {
v = column.validateConvertUpdateSequence(session, null);
} else {
v = expression.getValue(session);
}
return column.convert(v);
}
/** /**
* Get or generate a default value for the given column. * Get or generate a default value for the given column.
* *
...@@ -1217,14 +1227,18 @@ public abstract class Table extends SchemaObjectBase { ...@@ -1217,14 +1227,18 @@ public abstract class Table extends SchemaObjectBase {
* @return the value * @return the value
*/ */
public Value getDefaultValue(Session session, Column column) { public Value getDefaultValue(Session session, Column column) {
Expression defaultExpr = column.getDefaultExpression(); return getGeneratedValue(session, column, column.getDefaultExpression());
Value v; }
if (defaultExpr == null) {
v = column.validateConvertUpdateSequence(session, null); /**
} else { * Generates on update value for the given column.
v = defaultExpr.getValue(session); *
} * @param session the session
return column.convert(v); * @param column the column
* @return the value
*/
public Value getOnUpdateValue(Session session, Column column) {
return getGeneratedValue(session, column, column.getOnUpdateExpression());
} }
@Override @Override
......
...@@ -847,6 +847,7 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData, ...@@ -847,6 +847,7 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData,
* *
* @param columnIndex the column index (1, 2, ...) * @param columnIndex the column index (1, 2, ...)
* @param type the class of the returned value * @param type the class of the returned value
* @return the value
*/ */
@Override @Override
public <T> T getObject(int columnIndex, Class<T> type) throws SQLException { public <T> T getObject(int columnIndex, Class<T> type) throws SQLException {
...@@ -900,6 +901,7 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData, ...@@ -900,6 +901,7 @@ public class SimpleResultSet implements ResultSet, ResultSetMetaData,
* *
* @param columnName the column name * @param columnName the column name
* @param type the class of the returned value * @param type the class of the returned value
* @return the value
*/ */
@Override @Override
public <T> T getObject(String columnName, Class<T> type) throws SQLException { public <T> T getObject(String columnName, Class<T> type) throws SQLException {
......
...@@ -1470,10 +1470,10 @@ public class DateTimeUtils { ...@@ -1470,10 +1470,10 @@ public class DateTimeUtils {
} }
return nanosOfDay - mod; return nanosOfDay - mod;
} }
/** /**
* Truncate the given date to 'day' * Truncate the given date to 'day'
* *
* @param timeUnit the time unit (e.g. 'DAY', 'HOUR', etc.) * @param timeUnit the time unit (e.g. 'DAY', 'HOUR', etc.)
* @param value the date * @param value the date
* @return date truncated to 'day' * @return date truncated to 'day'
...@@ -1500,7 +1500,7 @@ public class DateTimeUtils { ...@@ -1500,7 +1500,7 @@ public class DateTimeUtils {
} else { } else {
// By default, we create a timestamp by setting the // By default, we create a timestamp by setting the
// datevalue to the datevalue retrieved and the time in // date value to the date value retrieved and the time in
// nanoseconds since midnight to 0. // nanoseconds since midnight to 0.
result = ValueTimestamp.fromDateValueAndNanos(dateValue, 0); result = ValueTimestamp.fromDateValueAndNanos(dateValue, 0);
......
...@@ -86,6 +86,7 @@ public class TestScript extends TestBase { ...@@ -86,6 +86,7 @@ public class TestScript extends TestBase {
testScript("information_schema.sql"); testScript("information_schema.sql");
testScript("joins.sql"); testScript("joins.sql");
testScript("altertable-index-reuse.sql"); testScript("altertable-index-reuse.sql");
testScript("default-and-on_update.sql");
testScript("query-optimisations.sql"); testScript("query-optimisations.sql");
String decimal2; String decimal2;
if (SysProperties.BIG_DECIMAL_IS_DECIMAL) { if (SysProperties.BIG_DECIMAL_IS_DECIMAL) {
...@@ -150,7 +151,7 @@ public class TestScript extends TestBase { ...@@ -150,7 +151,7 @@ public class TestScript extends TestBase {
"parsedatetime", "quarter", "second", "truncate", "week", "year", "date_trunc" }) { "parsedatetime", "quarter", "second", "truncate", "week", "year", "date_trunc" }) {
testScript("functions/timeanddate/" + s + ".sql"); testScript("functions/timeanddate/" + s + ".sql");
} }
deleteDb("script"); deleteDb("script");
System.out.flush(); System.out.flush();
} }
......
...@@ -9,13 +9,13 @@ create memory table orders ( orderid varchar(10), name varchar(20), customer_id ...@@ -9,13 +9,13 @@ create memory table orders ( orderid varchar(10), name varchar(20), customer_id
> ok > ok
select * from information_schema.columns where table_name = 'ORDERS'; select * from information_schema.columns where table_name = 'ORDERS';
> TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_PRECISION_RADIX NUMERIC_SCALE CHARACTER_SET_NAME COLLATION_NAME TYPE_NAME NULLABLE IS_COMPUTED SELECTIVITY CHECK_CONSTRAINT SEQUENCE_NAME REMARKS SOURCE_DATA_TYPE COLUMN_TYPE > TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_PRECISION_RADIX NUMERIC_SCALE CHARACTER_SET_NAME COLLATION_NAME TYPE_NAME NULLABLE IS_COMPUTED SELECTIVITY CHECK_CONSTRAINT SEQUENCE_NAME REMARKS SOURCE_DATA_TYPE COLUMN_TYPE COLUMN_ON_UPDATE
> ------------- ------------ ---------- ----------- ---------------- -------------- ----------- --------- ------------------------ ---------------------- ----------------- ----------------------- ------------- ------------------ -------------- --------- -------- ----------- ----------- ---------------- ------------- ------- ---------------- ------------------- > ------------- ------------ ---------- ----------- ---------------- -------------- ----------- --------- ------------------------ ---------------------- ----------------- ----------------------- ------------- ------------------ -------------- --------- -------- ----------- ----------- ---------------- ------------- ------- ---------------- ------------------- ----------------
> SCRIPT PUBLIC ORDERS COMPLETED 4 null NO 3 1 1 1 10 0 Unicode OFF DECIMAL 0 FALSE 50 null null NUMERIC(1) NOT NULL > SCRIPT PUBLIC ORDERS COMPLETED 4 null NO 3 1 1 1 10 0 Unicode OFF DECIMAL 0 FALSE 50 null null NUMERIC(1) NOT NULL null
> SCRIPT PUBLIC ORDERS CUSTOMER_ID 3 null YES 12 10 10 10 10 0 Unicode OFF VARCHAR 1 FALSE 50 null null VARCHAR(10) > SCRIPT PUBLIC ORDERS CUSTOMER_ID 3 null YES 12 10 10 10 10 0 Unicode OFF VARCHAR 1 FALSE 50 null null VARCHAR(10) null
> SCRIPT PUBLIC ORDERS NAME 2 null YES 12 20 20 20 10 0 Unicode OFF VARCHAR 1 FALSE 50 null null VARCHAR(20) > SCRIPT PUBLIC ORDERS NAME 2 null YES 12 20 20 20 10 0 Unicode OFF VARCHAR 1 FALSE 50 null null VARCHAR(20) null
> SCRIPT PUBLIC ORDERS ORDERID 1 null YES 12 10 10 10 10 0 Unicode OFF VARCHAR 1 FALSE 50 null null VARCHAR(10) > SCRIPT PUBLIC ORDERS ORDERID 1 null YES 12 10 10 10 10 0 Unicode OFF VARCHAR 1 FALSE 50 null null VARCHAR(10) null
> SCRIPT PUBLIC ORDERS VERIFIED 5 null YES 3 1 1 1 10 0 Unicode OFF DECIMAL 1 FALSE 50 null null NUMERIC(1) > SCRIPT PUBLIC ORDERS VERIFIED 5 null YES 3 1 1 1 10 0 Unicode OFF DECIMAL 1 FALSE 50 null null NUMERIC(1) null
> rows: 5 > rows: 5
drop table orders; drop table orders;
......
...@@ -9,13 +9,13 @@ create memory table orders ( orderid varchar(10), name varchar(20), customer_id ...@@ -9,13 +9,13 @@ create memory table orders ( orderid varchar(10), name varchar(20), customer_id
> ok > ok
select * from information_schema.columns where table_name = 'ORDERS'; select * from information_schema.columns where table_name = 'ORDERS';
> TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_PRECISION_RADIX NUMERIC_SCALE CHARACTER_SET_NAME COLLATION_NAME TYPE_NAME NULLABLE IS_COMPUTED SELECTIVITY CHECK_CONSTRAINT SEQUENCE_NAME REMARKS SOURCE_DATA_TYPE COLUMN_TYPE > TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_PRECISION_RADIX NUMERIC_SCALE CHARACTER_SET_NAME COLLATION_NAME TYPE_NAME NULLABLE IS_COMPUTED SELECTIVITY CHECK_CONSTRAINT SEQUENCE_NAME REMARKS SOURCE_DATA_TYPE COLUMN_TYPE COLUMN_ON_UPDATE
> ------------- ------------ ---------- ----------- ---------------- -------------- ----------- --------- ------------------------ ---------------------- ----------------- ----------------------- ------------- ------------------ -------------- --------- -------- ----------- ----------- ---------------- ------------- ------- ---------------- ------------------- > ------------- ------------ ---------- ----------- ---------------- -------------- ----------- --------- ------------------------ ---------------------- ----------------- ----------------------- ------------- ------------------ -------------- --------- -------- ----------- ----------- ---------------- ------------- ------- ---------------- ------------------- ----------------
> SCRIPT PUBLIC ORDERS COMPLETED 4 null NO 2 1 1 1 10 0 Unicode OFF NUMERIC 0 FALSE 50 null null NUMERIC(1) NOT NULL > SCRIPT PUBLIC ORDERS COMPLETED 4 null NO 2 1 1 1 10 0 Unicode OFF NUMERIC 0 FALSE 50 null null NUMERIC(1) NOT NULL null
> SCRIPT PUBLIC ORDERS CUSTOMER_ID 3 null YES 12 10 10 10 10 0 Unicode OFF VARCHAR 1 FALSE 50 null null VARCHAR(10) > SCRIPT PUBLIC ORDERS CUSTOMER_ID 3 null YES 12 10 10 10 10 0 Unicode OFF VARCHAR 1 FALSE 50 null null VARCHAR(10) null
> SCRIPT PUBLIC ORDERS NAME 2 null YES 12 20 20 20 10 0 Unicode OFF VARCHAR 1 FALSE 50 null null VARCHAR(20) > SCRIPT PUBLIC ORDERS NAME 2 null YES 12 20 20 20 10 0 Unicode OFF VARCHAR 1 FALSE 50 null null VARCHAR(20) null
> SCRIPT PUBLIC ORDERS ORDERID 1 null YES 12 10 10 10 10 0 Unicode OFF VARCHAR 1 FALSE 50 null null VARCHAR(10) > SCRIPT PUBLIC ORDERS ORDERID 1 null YES 12 10 10 10 10 0 Unicode OFF VARCHAR 1 FALSE 50 null null VARCHAR(10) null
> SCRIPT PUBLIC ORDERS VERIFIED 5 null YES 2 1 1 1 10 0 Unicode OFF NUMERIC 1 FALSE 50 null null NUMERIC(1) > SCRIPT PUBLIC ORDERS VERIFIED 5 null YES 2 1 1 1 10 0 Unicode OFF NUMERIC 1 FALSE 50 null null NUMERIC(1) null
> rows: 5 > rows: 5
drop table orders; drop table orders;
......
-- 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
--
CREATE SEQUENCE SEQ;
> ok
CREATE TABLE TEST(ID INT PRIMARY KEY, V INT DEFAULT NEXT VALUE FOR SEQ ON UPDATE 1000 * NEXT VALUE FOR SEQ);
> ok
INSERT INTO TEST(ID) VALUES (1), (2);
> update count: 2
SELECT * FROM TEST ORDER BY ID;
> ID V
> -- -
> 1 1
> 2 2
> rows (ordered): 2
UPDATE TEST SET ID = 3 WHERE ID = 2;
> update count: 1
SELECT * FROM TEST ORDER BY ID;
> ID V
> -- ----
> 1 1
> 3 3000
> rows (ordered): 2
UPDATE TEST SET V = 3 WHERE ID = 3;
> update count: 1
SELECT * FROM TEST ORDER BY ID;
> ID V
> -- -
> 1 1
> 3 3
> rows (ordered): 2
ALTER TABLE TEST ADD V2 TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;
> ok
UPDATE TEST SET V = 4 WHERE ID = 3;
> update count: 1
SELECT ID, V, LENGTH(V2) > 18 AS L FROM TEST ORDER BY ID;
> ID V L
> -- - ----
> 1 1 null
> 3 4 TRUE
> rows (ordered): 2
UPDATE TEST SET V = 1 WHERE V = 1;
> update count: 1
SELECT ID, V, LENGTH(V2) > 18 AS L FROM TEST ORDER BY ID;
> ID V L
> -- - ----
> 1 1 null
> 3 4 TRUE
> rows (ordered): 2
MERGE INTO TEST(ID, V) KEY(ID) VALUES (1, 1);
> update count: 1
SELECT ID, V, LENGTH(V2) > 18 AS L FROM TEST ORDER BY ID;
> ID V L
> -- - ----
> 1 1 null
> 3 4 TRUE
> rows (ordered): 2
MERGE INTO TEST(ID, V) KEY(ID) VALUES (1, 2);
> update count: 1
SELECT ID, V, LENGTH(V2) > 18 AS L FROM TEST ORDER BY ID;
> ID V L
> -- - ----
> 1 2 TRUE
> 3 4 TRUE
> rows (ordered): 2
ALTER TABLE TEST ALTER COLUMN V SET ON UPDATE NULL;
> ok
SELECT COLUMN_NAME, COLUMN_DEFAULT, COLUMN_ON_UPDATE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'TEST' ORDER BY COLUMN_NAME;
> COLUMN_NAME COLUMN_DEFAULT COLUMN_ON_UPDATE
> ----------- --------------------------- -------------------
> ID null null
> V (NEXT VALUE FOR PUBLIC.SEQ) NULL
> V2 null CURRENT_TIMESTAMP()
> rows (ordered): 3
ALTER TABLE TEST ALTER COLUMN V DROP ON UPDATE;
> ok
SELECT COLUMN_NAME, COLUMN_DEFAULT, COLUMN_ON_UPDATE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'TEST' ORDER BY COLUMN_NAME;
> COLUMN_NAME COLUMN_DEFAULT COLUMN_ON_UPDATE
> ----------- --------------------------- -------------------
> ID null null
> V (NEXT VALUE FOR PUBLIC.SEQ) null
> V2 null CURRENT_TIMESTAMP()
> rows (ordered): 3
DROP TABLE TEST;
> ok
DROP SEQUENCE SEQ;
> ok
-- 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
--
select DATE_TRUNC('day', time '00:00:00'); select DATE_TRUNC('day', time '00:00:00');
>> 1970-01-01 00:00:00 >> 1970-01-01 00:00:00
......
...@@ -747,7 +747,7 @@ public class TestTransactionStore extends TestBase { ...@@ -747,7 +747,7 @@ public class TestTransactionStore extends TestBase {
Class.forName("org.postgresql.Driver"); Class.forName("org.postgresql.Driver");
for (int i = 0; i < connectionCount; i++) { for (int i = 0; i < connectionCount; i++) {
Connection conn = DriverManager.getConnection( Connection conn = DriverManager.getConnection(
"jdbc:postgresql:test", "sa", "sa"); "jdbc:postgresql:test?loggerLevel=OFF", "sa", "sa");
statements.add(conn.createStatement()); statements.add(conn.createStatement());
} }
} catch (Exception e) { } catch (Exception e) {
......
...@@ -54,7 +54,7 @@ public class TestNestedJoins extends TestBase { ...@@ -54,7 +54,7 @@ public class TestNestedJoins extends TestBase {
try { try {
Class.forName("org.postgresql.Driver"); Class.forName("org.postgresql.Driver");
Connection c2 = DriverManager.getConnection("jdbc:postgresql:test", "sa", "sa"); Connection c2 = DriverManager.getConnection("jdbc:postgresql:test?loggerLevel=OFF", "sa", "sa");
dbs.add(c2.createStatement()); dbs.add(c2.createStatement());
} catch (Exception e) { } catch (Exception e) {
// database not installed - ok // database not installed - ok
......
...@@ -53,7 +53,7 @@ public class TestOuterJoins extends TestBase { ...@@ -53,7 +53,7 @@ public class TestOuterJoins extends TestBase {
try { try {
Class.forName("org.postgresql.Driver"); Class.forName("org.postgresql.Driver");
Connection c2 = DriverManager.getConnection( Connection c2 = DriverManager.getConnection(
"jdbc:postgresql:test", "sa", "sa"); "jdbc:postgresql:test?loggerLevel=OFF", "sa", "sa");
dbs.add(c2.createStatement()); dbs.add(c2.createStatement());
} catch (Exception e) { } catch (Exception e) {
// database not installed - ok // database not installed - ok
......
...@@ -50,7 +50,7 @@ public class TestRandomCompare extends TestBase { ...@@ -50,7 +50,7 @@ public class TestRandomCompare extends TestBase {
try { try {
Class.forName("org.postgresql.Driver"); Class.forName("org.postgresql.Driver");
Connection c2 = DriverManager.getConnection( Connection c2 = DriverManager.getConnection(
"jdbc:postgresql:test", "sa", "sa"); "jdbc:postgresql:test?loggerLevel=OFF", "sa", "sa");
dbs.add(c2.createStatement()); dbs.add(c2.createStatement());
} catch (Exception e) { } catch (Exception e) {
// database not installed - ok // database not installed - ok
......
...@@ -766,4 +766,4 @@ interpolated thead ...@@ -766,4 +766,4 @@ interpolated thead
die weekdiff osx subprocess dow proleptic microsecond microseconds divisible cmp denormalized suppressed saturated mcs die weekdiff osx subprocess dow proleptic microsecond microseconds divisible cmp denormalized suppressed saturated mcs
london dfs weekdays intermittent looked msec tstz africa monrovia asia tokyo weekday joi callers multipliers ucn london dfs weekdays intermittent looked msec tstz africa monrovia asia tokyo weekday joi callers multipliers ucn
openoffice organize libre systemtables gmane sea borders openoffice organize libre systemtables gmane sea borders announced millennium
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论