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

Add support for standard syntax of CREATE TABLE AS query

上级 b322526e
...@@ -739,7 +739,7 @@ CREATE SEQUENCE SEQ_ID ...@@ -739,7 +739,7 @@ CREATE SEQUENCE SEQ_ID
"Commands (DDL)","CREATE TABLE"," "Commands (DDL)","CREATE TABLE","
CREATE [ CACHED | MEMORY ] [ TEMP | [ GLOBAL | LOCAL ] TEMPORARY ] CREATE [ CACHED | MEMORY ] [ TEMP | [ GLOBAL | LOCAL ] TEMPORARY ]
TABLE [ IF NOT EXISTS ] name TABLE [ IF NOT EXISTS ] name
[ ( { columnName columnDefinition | constraint } [,...] ) ] [ ( { columnName [columnDefinition] | constraint } [,...] ) ]
[ ENGINE tableEngineName ] [ ENGINE tableEngineName ]
[ WITH tableEngineParamName [,...] ] [ WITH tableEngineParamName [,...] ]
[ NOT PERSISTENT ] [ TRANSACTIONAL ] [ NOT PERSISTENT ] [ TRANSACTIONAL ]
...@@ -769,7 +769,7 @@ in CREATE TABLE, then the engine specified by DEFAULT_TABLE_ENGINE option of dat ...@@ -769,7 +769,7 @@ in CREATE TABLE, then the engine specified by DEFAULT_TABLE_ENGINE option of dat
Tables with the NOT PERSISTENT modifier are kept fully in memory, and all Tables with the NOT PERSISTENT modifier are kept fully in memory, and all
rows are lost when the database is closed. rows are lost when the database is closed.
The column definition is optional if a query is specified. The column definitions are optional if a query is specified.
In that case the column list of the query is used. In that case the column list of the query is used.
If the query is specified its results are inserted into created table unless WITH NO DATA is specified. If the query is specified its results are inserted into created table unless WITH NO DATA is specified.
......
...@@ -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 #1708: CREATE TABLE AS doesn't support column lists without data types
</li>
<li>PR #1707: Fix sort order and ENUM data type in external results <li>PR #1707: Fix sort order and ENUM data type in external results
</li> </li>
<li>PR #1706: Add hypothetical set functions <li>PR #1706: Add hypothetical set functions
......
...@@ -7466,12 +7466,12 @@ public class Parser { ...@@ -7466,12 +7466,12 @@ public class Parser {
if (readIf(OPEN_PAREN)) { if (readIf(OPEN_PAREN)) {
command.setIfNotExists(false); command.setIfNotExists(false);
do { do {
parseTableColumnDefinition(command, schema, tableName); parseTableColumnDefinition(command, schema, tableName, false);
} while (readIfMore(true)); } while (readIfMore(true));
} else { } else {
boolean ifNotExists = readIfNotExists(); boolean ifNotExists = readIfNotExists();
command.setIfNotExists(ifNotExists); command.setIfNotExists(ifNotExists);
parseTableColumnDefinition(command, schema, tableName); parseTableColumnDefinition(command, schema, tableName, false);
} }
if (readIf("BEFORE")) { if (readIf("BEFORE")) {
command.setAddBefore(readColumnIdentifier()); command.setAddBefore(readColumnIdentifier());
...@@ -7717,7 +7717,7 @@ public class Parser { ...@@ -7717,7 +7717,7 @@ public class Parser {
if (readIf(OPEN_PAREN)) { if (readIf(OPEN_PAREN)) {
if (!readIf(CLOSE_PAREN)) { if (!readIf(CLOSE_PAREN)) {
do { do {
parseTableColumnDefinition(command, schema, tableName); parseTableColumnDefinition(command, schema, tableName, true);
} while (readIfMore(false)); } while (readIfMore(false));
} }
} }
...@@ -7806,13 +7806,17 @@ public class Parser { ...@@ -7806,13 +7806,17 @@ public class Parser {
return command; return command;
} }
private void parseTableColumnDefinition(CommandWithColumns command, Schema schema, String tableName) { private void parseTableColumnDefinition(CommandWithColumns command, Schema schema, String tableName,
DefineCommand c = parseAlterTableAddConstraintIf(tableName, boolean forCreateTable) {
schema, false); DefineCommand c = parseAlterTableAddConstraintIf(tableName, schema, false);
if (c != null) { if (c != null) {
command.addConstraintCommand(c); command.addConstraintCommand(c);
} else { } else {
String columnName = readColumnIdentifier(); String columnName = readColumnIdentifier();
if (forCreateTable && (currentTokenType == COMMA || currentTokenType == CLOSE_PAREN)) {
command.addColumn(new Column(columnName, TypeInfo.TYPE_UNKNOWN));
return;
}
Column column = parseColumnForTable(columnName, true, true); Column column = parseColumnForTable(columnName, true, true);
if (column.isAutoIncrement() && column.isPrimaryKey()) { if (column.isAutoIncrement() && column.isPrimaryKey()) {
column.setPrimaryKey(false); column.setPrimaryKey(false);
......
...@@ -21,6 +21,7 @@ import org.h2.schema.Sequence; ...@@ -21,6 +21,7 @@ import org.h2.schema.Sequence;
import org.h2.table.Column; import org.h2.table.Column;
import org.h2.table.Table; import org.h2.table.Table;
import org.h2.util.ColumnNamer; import org.h2.util.ColumnNamer;
import org.h2.value.Value;
/** /**
* This class represents the statement * This class represents the statement
...@@ -89,6 +90,14 @@ public class CreateTable extends CommandWithColumns { ...@@ -89,6 +90,14 @@ public class CreateTable extends CommandWithColumns {
generateColumnsFromQuery(); generateColumnsFromQuery();
} else if (data.columns.size() != asQuery.getColumnCount()) { } else if (data.columns.size() != asQuery.getColumnCount()) {
throw DbException.get(ErrorCode.COLUMN_COUNT_DOES_NOT_MATCH); throw DbException.get(ErrorCode.COLUMN_COUNT_DOES_NOT_MATCH);
} else {
ArrayList<Column> columns = data.columns;
for (int i = 0; i < columns.size(); i++) {
Column column = columns.get(i);
if (column.getType().getValueType() == Value.UNKNOWN) {
columns.set(i, new Column(column.getName(), asQuery.getExpressions().get(i).getType()));
}
}
} }
} }
changePrimaryKeysToNotNull(data.columns); changePrimaryKeysToNotNull(data.columns);
......
...@@ -114,3 +114,20 @@ SELECT CONSTRAINT_TYPE, TABLE_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHE ...@@ -114,3 +114,20 @@ SELECT CONSTRAINT_TYPE, TABLE_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHE
DROP TABLE TEST1, TEST2, TEST3; DROP TABLE TEST1, TEST2, TEST3;
> ok > ok
CREATE TABLE TEST(A);
> exception UNKNOWN_DATA_TYPE_1
CREATE TABLE TEST(A, B, C) AS SELECT 1, 2, CAST ('A' AS VARCHAR);
> ok
SELECT COLUMN_NAME, COLUMN_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'TEST';
> COLUMN_NAME COLUMN_TYPE
> ----------- -----------
> A INTEGER
> B INTEGER
> C VARCHAR
> rows: 3
DROP TABLE TEST;
> ok
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论