提交 6186516b authored 作者: Andrei Tokar's avatar Andrei Tokar

Merge remote-tracking branch 'h2database/master' into batch-append

...@@ -651,10 +651,9 @@ public class Parser { ...@@ -651,10 +651,9 @@ public class Parser {
for (int i = 0;; i++) { for (int i = 0;; i++) {
Column column = parseColumnForTable("C" + i, true); Column column = parseColumnForTable("C" + i, true);
list.add(column); list.add(column);
if (readIf(")")) { if (!readIfMore(true)) {
break; break;
} }
read(",");
} }
} }
read("AS"); read("AS");
...@@ -3302,20 +3301,17 @@ public class Parser { ...@@ -3302,20 +3301,17 @@ public class Parser {
r = new ExpressionList(new Expression[0]); r = new ExpressionList(new Expression[0]);
} else { } else {
r = readExpression(); r = readExpression();
if (readIf(",")) { if (readIfMore(true)) {
ArrayList<Expression> list = Utils.newSmallArrayList(); ArrayList<Expression> list = Utils.newSmallArrayList();
list.add(r); list.add(r);
while (!readIf(")")) { while (!readIf(")")) {
r = readExpression(); r = readExpression();
list.add(r); list.add(r);
if (!readIf(",")) { if (!readIfMore(true)) {
read(")");
break; break;
} }
} }
r = new ExpressionList(list.toArray(new Expression[0])); r = new ExpressionList(list.toArray(new Expression[0]));
} else {
read(")");
} }
} }
break; break;
...@@ -5770,10 +5766,9 @@ public class Parser { ...@@ -5770,10 +5766,9 @@ public class Parser {
readIfEqualOrTo(); readIfEqualOrTo();
Set command = new Set(session, SetTypes.SCHEMA_SEARCH_PATH); Set command = new Set(session, SetTypes.SCHEMA_SEARCH_PATH);
ArrayList<String> list = Utils.newSmallArrayList(); ArrayList<String> list = Utils.newSmallArrayList();
do {
list.add(readAliasIdentifier()); list.add(readAliasIdentifier());
while (readIf(",")) { } while (readIf(","));
list.add(readAliasIdentifier());
}
command.setStringArray(list.toArray(new String[0])); command.setStringArray(list.toArray(new String[0]));
return command; return command;
} else if (readIf("JAVA_OBJECT_SERIALIZER")) { } else if (readIf("JAVA_OBJECT_SERIALIZER")) {
...@@ -5836,11 +5831,10 @@ public class Parser { ...@@ -5836,11 +5831,10 @@ public class Parser {
} }
private Set parseSetBinaryCollation() { private Set parseSetBinaryCollation() {
Set command = new Set(session, SetTypes.BINARY_COLLATION);
String name = readAliasIdentifier(); String name = readAliasIdentifier();
if (equalsToken(name, CompareMode.UNSIGNED) || equalsToken(name, CompareMode.SIGNED)) {
Set command = new Set(session, SetTypes.BINARY_COLLATION);
command.setString(name); command.setString(name);
if (equalsToken(name, CompareMode.UNSIGNED) ||
equalsToken(name, CompareMode.SIGNED)) {
return command; return command;
} }
throw DbException.getInvalidValueException("BINARY_COLLATION", name); throw DbException.getInvalidValueException("BINARY_COLLATION", name);
......
...@@ -17,6 +17,7 @@ import org.h2.table.Column; ...@@ -17,6 +17,7 @@ import org.h2.table.Column;
import org.h2.table.Table; import org.h2.table.Table;
import org.h2.table.TableType; import org.h2.table.TableType;
import org.h2.util.StatementBuilder; import org.h2.util.StatementBuilder;
import org.h2.value.DataType;
import org.h2.value.Value; import org.h2.value.Value;
import org.h2.value.ValueInt; import org.h2.value.ValueInt;
import org.h2.value.ValueNull; import org.h2.value.ValueNull;
...@@ -104,8 +105,7 @@ public class Analyze extends DefineCommand { ...@@ -104,8 +105,7 @@ public class Analyze extends DefineCommand {
StatementBuilder buff = new StatementBuilder("SELECT "); StatementBuilder buff = new StatementBuilder("SELECT ");
for (Column col : columns) { for (Column col : columns) {
buff.appendExceptFirst(", "); buff.appendExceptFirst(", ");
int type = col.getType(); if (DataType.isLargeObject(col.getType())) {
if (type == Value.BLOB || type == Value.CLOB) {
// can not index LOB columns, so calculating // can not index LOB columns, so calculating
// the selectivity is not required // the selectivity is not required
buff.append("MAX(NULL)"); buff.append("MAX(NULL)");
......
...@@ -7,7 +7,6 @@ package org.h2.engine; ...@@ -7,7 +7,6 @@ package org.h2.engine;
import java.util.ArrayDeque; import java.util.ArrayDeque;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Deque;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
...@@ -50,6 +49,7 @@ import org.h2.util.ColumnNamerConfiguration; ...@@ -50,6 +49,7 @@ import org.h2.util.ColumnNamerConfiguration;
import org.h2.util.CurrentTimestamp; import org.h2.util.CurrentTimestamp;
import org.h2.util.SmallLRUCache; import org.h2.util.SmallLRUCache;
import org.h2.util.Utils; import org.h2.util.Utils;
import org.h2.value.DataType;
import org.h2.value.Value; import org.h2.value.Value;
import org.h2.value.ValueArray; import org.h2.value.ValueArray;
import org.h2.value.ValueLong; import org.h2.value.ValueLong;
...@@ -129,8 +129,7 @@ public class Session extends SessionWithState implements TransactionStore.Rollba ...@@ -129,8 +129,7 @@ public class Session extends SessionWithState implements TransactionStore.Rollba
private SmallLRUCache<String, Command> queryCache; private SmallLRUCache<String, Command> queryCache;
private long modificationMetaID = -1; private long modificationMetaID = -1;
private SubQueryInfo subQueryInfo; private SubQueryInfo subQueryInfo;
private int parsingView; private ArrayDeque<String> viewNameStack;
private final Deque<String> viewNameStack = new ArrayDeque<>();
private int preparingQueryExpression; private int preparingQueryExpression;
private volatile SmallLRUCache<Object, ViewIndex> viewIndexCache; private volatile SmallLRUCache<Object, ViewIndex> viewIndexCache;
private HashMap<Object, ViewIndex> subQueryIndexCache; private HashMap<Object, ViewIndex> subQueryIndexCache;
...@@ -244,26 +243,23 @@ public class Session extends SessionWithState implements TransactionStore.Rollba ...@@ -244,26 +243,23 @@ public class Session extends SessionWithState implements TransactionStore.Rollba
* name of the view * name of the view
*/ */
public void setParsingCreateView(boolean parsingView, String viewName) { public void setParsingCreateView(boolean parsingView, String viewName) {
// It can be recursive, thus implemented as counter. if (viewNameStack == null) {
this.parsingView += parsingView ? 1 : -1; viewNameStack = new ArrayDeque<>(3);
assert this.parsingView >= 0; }
if (parsingView) { if (parsingView) {
viewNameStack.push(viewName); viewNameStack.push(viewName);
} else { } else {
assert viewName.equals(viewNameStack.peek()); String name = viewNameStack.pop();
viewNameStack.pop(); assert viewName.equals(name);
} }
} }
public String getParsingCreateViewName() { public String getParsingCreateViewName() {
if (viewNameStack.isEmpty()) { return viewNameStack != null ? viewNameStack.peek() : null;
return null;
}
return viewNameStack.peek();
} }
public boolean isParsingCreateView() { public boolean isParsingCreateView() {
assert parsingView >= 0; return viewNameStack != null && !viewNameStack.isEmpty();
return parsingView != 0;
} }
/** /**
...@@ -1701,7 +1697,7 @@ public class Session extends SessionWithState implements TransactionStore.Rollba ...@@ -1701,7 +1697,7 @@ public class Session extends SessionWithState implements TransactionStore.Rollba
@Override @Override
public void addTemporaryLob(Value v) { public void addTemporaryLob(Value v) {
if (v.getType() != Value.CLOB && v.getType() != Value.BLOB) { if (!DataType.isLargeObject(v.getType())) {
return; return;
} }
if (v.getTableId() == LobStorageFrontend.TABLE_RESULT if (v.getTableId() == LobStorageFrontend.TABLE_RESULT
......
...@@ -15,6 +15,7 @@ import org.h2.message.DbException; ...@@ -15,6 +15,7 @@ import org.h2.message.DbException;
import org.h2.table.ColumnResolver; import org.h2.table.ColumnResolver;
import org.h2.table.TableFilter; import org.h2.table.TableFilter;
import org.h2.value.CompareMode; import org.h2.value.CompareMode;
import org.h2.value.DataType;
import org.h2.value.Value; import org.h2.value.Value;
import org.h2.value.ValueBoolean; import org.h2.value.ValueBoolean;
import org.h2.value.ValueNull; import org.h2.value.ValueNull;
...@@ -198,9 +199,7 @@ public class CompareLike extends Condition { ...@@ -198,9 +199,7 @@ public class CompareLike extends Condition {
// can't use an index // can't use an index
return; return;
} }
int dataType = l.getColumn().getType(); if (!DataType.isStringType(l.getColumn().getType())) {
if (dataType != Value.STRING && dataType != Value.STRING_IGNORECASE &&
dataType != Value.STRING_FIXED) {
// column is not a varchar - can't use the index // column is not a varchar - can't use the index
return; return;
} }
......
...@@ -23,6 +23,7 @@ import org.h2.table.Table; ...@@ -23,6 +23,7 @@ import org.h2.table.Table;
import org.h2.table.TableFilter; import org.h2.table.TableFilter;
import org.h2.util.StatementBuilder; import org.h2.util.StatementBuilder;
import org.h2.util.StringUtils; import org.h2.util.StringUtils;
import org.h2.value.DataType;
import org.h2.value.Value; import org.h2.value.Value;
import org.h2.value.ValueNull; import org.h2.value.ValueNull;
...@@ -72,8 +73,7 @@ public abstract class BaseIndex extends SchemaObjectBase implements Index { ...@@ -72,8 +73,7 @@ public abstract class BaseIndex extends SchemaObjectBase implements Index {
*/ */
protected static void checkIndexColumnTypes(IndexColumn[] columns) { protected static void checkIndexColumnTypes(IndexColumn[] columns) {
for (IndexColumn c : columns) { for (IndexColumn c : columns) {
int type = c.column.getType(); if (DataType.isLargeObject(c.column.getType())) {
if (type == Value.CLOB || type == Value.BLOB) {
throw DbException.getUnsupportedException( throw DbException.getUnsupportedException(
"Index on BLOB or CLOB column: " + c.column.getCreateSQL()); "Index on BLOB or CLOB column: " + c.column.getCreateSQL());
} }
......
...@@ -23,6 +23,7 @@ import org.h2.table.Column; ...@@ -23,6 +23,7 @@ import org.h2.table.Column;
import org.h2.table.IndexColumn; import org.h2.table.IndexColumn;
import org.h2.table.Table; import org.h2.table.Table;
import org.h2.util.TempFileDeleter; import org.h2.util.TempFileDeleter;
import org.h2.value.DataType;
import org.h2.value.Value; import org.h2.value.Value;
import org.h2.value.ValueNull; import org.h2.value.ValueNull;
...@@ -118,7 +119,7 @@ public class ResultTempTable implements ResultExternal { ...@@ -118,7 +119,7 @@ public class ResultTempTable implements ResultExternal {
for (int i = 0; i < expressions.length; i++) { for (int i = 0; i < expressions.length; i++) {
int type = expressions[i].getType(); int type = expressions[i].getType();
Column col = new Column(COLUMN_NAME + i, type); Column col = new Column(COLUMN_NAME + i, type);
if (type == Value.CLOB || type == Value.BLOB) { if (DataType.isLargeObject(type)) {
containsLob = true; containsLob = true;
} }
data.columns.add(col); data.columns.add(col);
......
...@@ -13,6 +13,7 @@ import org.h2.engine.Session; ...@@ -13,6 +13,7 @@ import org.h2.engine.Session;
import org.h2.store.Data; import org.h2.store.Data;
import org.h2.store.FileStore; import org.h2.store.FileStore;
import org.h2.util.Utils; import org.h2.util.Utils;
import org.h2.value.DataType;
import org.h2.value.Value; import org.h2.value.Value;
/** /**
...@@ -63,7 +64,7 @@ public class RowList { ...@@ -63,7 +64,7 @@ public class RowList {
buff.writeByte((byte) 0); buff.writeByte((byte) 0);
} else { } else {
buff.writeByte((byte) 1); buff.writeByte((byte) 1);
if (v.getType() == Value.CLOB || v.getType() == Value.BLOB) { if (DataType.isLargeObject(v.getType())) {
// need to keep a reference to temporary lobs, // need to keep a reference to temporary lobs,
// otherwise the temp file is deleted // otherwise the temp file is deleted
if (v.getSmall() == null && v.getTableId() == 0) { if (v.getSmall() == null && v.getTableId() == 0) {
......
...@@ -37,6 +37,7 @@ import org.h2.store.LobStorageInterface; ...@@ -37,6 +37,7 @@ import org.h2.store.LobStorageInterface;
import org.h2.util.IOUtils; import org.h2.util.IOUtils;
import org.h2.util.SmallLRUCache; import org.h2.util.SmallLRUCache;
import org.h2.util.SmallMap; import org.h2.util.SmallMap;
import org.h2.value.DataType;
import org.h2.value.Transfer; import org.h2.value.Transfer;
import org.h2.value.Value; import org.h2.value.Value;
import org.h2.value.ValueLobDb; import org.h2.value.ValueLobDb;
...@@ -572,7 +573,7 @@ public class TcpServerThread implements Runnable { ...@@ -572,7 +573,7 @@ public class TcpServerThread implements Runnable {
} }
private void writeValue(Value v) throws IOException { private void writeValue(Value v) throws IOException {
if (v.getType() == Value.CLOB || v.getType() == Value.BLOB) { if (DataType.isLargeObject(v.getType())) {
if (v instanceof ValueLobDb) { if (v instanceof ValueLobDb) {
ValueLobDb lob = (ValueLobDb) v; ValueLobDb lob = (ValueLobDb) v;
if (lob.isStored()) { if (lob.isStored()) {
......
...@@ -502,7 +502,12 @@ public class Column { ...@@ -502,7 +502,12 @@ public class Column {
if (originalSQL != null) { if (originalSQL != null) {
buff.append(originalSQL); buff.append(originalSQL);
} else { } else {
buff.append(DataType.getDataType(type).name); DataType dataType = DataType.getDataType(type);
if (type == Value.TIMESTAMP_TZ) {
buff.append("TIMESTAMP");
} else {
buff.append(dataType.name);
}
switch (type) { switch (type) {
case Value.DECIMAL: case Value.DECIMAL:
buff.append('(').append(precision).append(", ").append(scale).append(')'); buff.append('(').append(precision).append(", ").append(scale).append(')');
...@@ -525,6 +530,16 @@ public class Column { ...@@ -525,6 +530,16 @@ public class Column {
buff.append('(').append(precision).append(')'); buff.append('(').append(precision).append(')');
} }
break; break;
case Value.TIME:
case Value.TIMESTAMP:
case Value.TIMESTAMP_TZ:
if (scale != dataType.defaultScale) {
buff.append('(').append(scale).append(')');
}
if (type == Value.TIMESTAMP_TZ) {
buff.append(" WITH TIME ZONE");
}
break;
default: default:
} }
} }
......
...@@ -420,7 +420,7 @@ public class SourceCompiler { ...@@ -420,7 +420,7 @@ public class SourceCompiler {
final BufferedReader reader = new BufferedReader(new StringReader(output)); final BufferedReader reader = new BufferedReader(new StringReader(output));
try { try {
for (String line; (line = reader.readLine()) != null;) { for (String line; (line = reader.readLine()) != null;) {
if (line.endsWith("warning")) { if (line.endsWith("warning") || line.endsWith("warnings")) {
// ignore summary line // ignore summary line
} else if (line.startsWith("Note:") } else if (line.startsWith("Note:")
|| line.startsWith("warning:")) { || line.startsWith("warning:")) {
......
...@@ -99,3 +99,30 @@ select cast('000102030405060708090a0b0c0d0e0f' as uuid); ...@@ -99,3 +99,30 @@ select cast('000102030405060708090a0b0c0d0e0f' as uuid);
select -cast(0 as double); select -cast(0 as double);
>> 0.0 >> 0.0
SELECT * FROM (SELECT CAST('11:11:11.123456789' AS TIME));
>> 11:11:11
SELECT * FROM (SELECT CAST('11:11:11.123456789' AS TIME(0)));
>> 11:11:11
SELECT * FROM (SELECT CAST('11:11:11.123456789' AS TIME(9)));
>> 11:11:11.123456789
SELECT * FROM (SELECT CAST('2000-01-01 11:11:11.123456789' AS TIMESTAMP));
>> 2000-01-01 11:11:11.123457
SELECT * FROM (SELECT CAST('2000-01-01 11:11:11.123456789' AS TIMESTAMP(0)));
>> 2000-01-01 11:11:11
SELECT * FROM (SELECT CAST('2000-01-01 11:11:11.123456789' AS TIMESTAMP(9)));
>> 2000-01-01 11:11:11.123456789
SELECT * FROM (SELECT CAST('2000-01-01 11:11:11.123456789Z' AS TIMESTAMP WITH TIME ZONE));
>> 2000-01-01 11:11:11.123457+00
SELECT * FROM (SELECT CAST('2000-01-01 11:11:11.123456789Z' AS TIMESTAMP(0) WITH TIME ZONE));
>> 2000-01-01 11:11:11+00
SELECT * FROM (SELECT CAST('2000-01-01 11:11:11.123456789Z' AS TIMESTAMP(9) WITH TIME ZONE));
>> 2000-01-01 11:11:11.123456789+00
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论