提交 2aec7182 authored 作者: Sergi's avatar Sergi

Merge branch 'master' of https://github.com/h2database/h2database

...@@ -12,3 +12,4 @@ temp ...@@ -12,3 +12,4 @@ temp
test.out.txt test.out.txt
.idea/ .idea/
*.log *.log
target/
...@@ -613,7 +613,8 @@ CREATE SEQUENCE SEQ_ID ...@@ -613,7 +613,8 @@ CREATE SEQUENCE SEQ_ID
CREATE [ CACHED | MEMORY ] [ TEMP | [ GLOBAL | LOCAL ] TEMPORARY ] CREATE [ CACHED | MEMORY ] [ TEMP | [ GLOBAL | LOCAL ] TEMPORARY ]
TABLE [ IF NOT EXISTS ] name TABLE [ IF NOT EXISTS ] name
[ ( { columnDefinition | constraint } [,...] ) ] [ ( { columnDefinition | constraint } [,...] ) ]
[ ENGINE tableEngineName [ WITH tableEngineParamName [,...] ] ] [ ENGINE tableEngineName ]
[ WITH tableEngineParamName [,...] ]
[ NOT PERSISTENT ] [ TRANSACTIONAL ] [ NOT PERSISTENT ] [ TRANSACTIONAL ]
[ AS select ]"," [ AS select ]","
Creates a new table. Creates a new table.
...@@ -635,6 +636,9 @@ The ENGINE option is only required when custom table implementations are used. ...@@ -635,6 +636,9 @@ The ENGINE option is only required when custom table implementations are used.
The table engine class must implement the interface ""org.h2.api.TableEngine"". The table engine class must implement the interface ""org.h2.api.TableEngine"".
Any table engine parameters are passed down in the tableEngineParams field of the CreateTableData object. Any table engine parameters are passed down in the tableEngineParams field of the CreateTableData object.
Either ENGINE, or WITH (table engine params), or both may be specified. If ENGINE is not specified
in CREATE TABLE, then the engine specified by DEFAULT_TABLE_ENGINE option of database params is used.
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.
......
...@@ -6126,6 +6126,8 @@ public class Parser { ...@@ -6126,6 +6126,8 @@ public class Parser {
} }
} else { } else {
command.setTableEngine(readUniqueIdentifier()); command.setTableEngine(readUniqueIdentifier());
}
}
if (readIf("WITH")) { if (readIf("WITH")) {
ArrayList<String> tableEngineParams = New.arrayList(); ArrayList<String> tableEngineParams = New.arrayList();
do { do {
...@@ -6133,8 +6135,6 @@ public class Parser { ...@@ -6133,8 +6135,6 @@ public class Parser {
} while (readIf(",")); } while (readIf(","));
command.setTableEngineParams(tableEngineParams); command.setTableEngineParams(tableEngineParams);
} }
}
}
// MySQL compatibility // MySQL compatibility
if (readIf("AUTO_INCREMENT")) { if (readIf("AUTO_INCREMENT")) {
read("="); read("=");
......
...@@ -194,6 +194,13 @@ public class Comparison extends Condition { ...@@ -194,6 +194,13 @@ public class Comparison extends Condition {
return ValueExpression.getNull(); return ValueExpression.getNull();
} }
} }
int colType = left.getType();
int constType = r.getType();
int resType = Value.getHigherOrder(colType, constType);
// If not the column values will need to be promoted
// to constant type, but vise versa, then let's do this here once.
if (constType != resType)
right = ValueExpression.get(r.convertTo(resType));
} else if (right instanceof Parameter) { } else if (right instanceof Parameter) {
((Parameter) right).setColumn( ((Parameter) right).setColumn(
((ExpressionColumn) left).getColumn()); ((ExpressionColumn) left).getColumn());
......
...@@ -399,11 +399,13 @@ class FileNioMemData { ...@@ -399,11 +399,13 @@ class FileNioMemData {
private static final int BLOCK_SIZE = 1 << BLOCK_SIZE_SHIFT; private static final int BLOCK_SIZE = 1 << BLOCK_SIZE_SHIFT;
private static final int BLOCK_SIZE_MASK = BLOCK_SIZE - 1; private static final int BLOCK_SIZE_MASK = BLOCK_SIZE - 1;
private static final CompressLZF LZF = new CompressLZF();
private static final byte[] BUFFER = new byte[BLOCK_SIZE * 2];
private static final ByteBuffer COMPRESSED_EMPTY_BLOCK; private static final ByteBuffer COMPRESSED_EMPTY_BLOCK;
private static final CompressLaterCache<CompressItem, CompressItem> COMPRESS_LATER = private final CompressLZF LZF = new CompressLZF();
/** the output buffer when compressing */
private final byte[] compressOutputBuffer = new byte[BLOCK_SIZE * 2];
private final CompressLaterCache<CompressItem, CompressItem> compressLaterCache =
new CompressLaterCache<CompressItem, CompressItem>(CACHE_SIZE); new CompressLaterCache<CompressItem, CompressItem>(CACHE_SIZE);
private String name; private String name;
...@@ -417,10 +419,11 @@ class FileNioMemData { ...@@ -417,10 +419,11 @@ class FileNioMemData {
private int sharedLockCount; private int sharedLockCount;
static { static {
byte[] n = new byte[BLOCK_SIZE]; final byte[] n = new byte[BLOCK_SIZE];
int len = LZF.compress(n, BLOCK_SIZE, BUFFER, 0); final byte[] output = new byte[BLOCK_SIZE * 2];
int len = new CompressLZF().compress(n, BLOCK_SIZE, output, 0);
COMPRESSED_EMPTY_BLOCK = ByteBuffer.allocateDirect(len); COMPRESSED_EMPTY_BLOCK = ByteBuffer.allocateDirect(len);
COMPRESSED_EMPTY_BLOCK.put(BUFFER, 0, len); COMPRESSED_EMPTY_BLOCK.put(output, 0, len);
} }
FileNioMemData(String name, boolean compress) { FileNioMemData(String name, boolean compress) {
...@@ -530,9 +533,7 @@ class FileNioMemData { ...@@ -530,9 +533,7 @@ class FileNioMemData {
private void addToCompressLaterCache(int page) { private void addToCompressLaterCache(int page) {
CompressItem c = new CompressItem(this, page); CompressItem c = new CompressItem(this, page);
synchronized (LZF) { compressLaterCache.put(c, c);
COMPRESS_LATER.put(c, c);
}
} }
private void expand(int page) { private void expand(int page) {
...@@ -548,11 +549,9 @@ class FileNioMemData { ...@@ -548,11 +549,9 @@ class FileNioMemData {
} }
ByteBuffer out = ByteBuffer.allocateDirect(BLOCK_SIZE); ByteBuffer out = ByteBuffer.allocateDirect(BLOCK_SIZE);
if (d != COMPRESSED_EMPTY_BLOCK) { if (d != COMPRESSED_EMPTY_BLOCK) {
synchronized (LZF) {
d.position(0); d.position(0);
CompressLZF.expand(d, out); CompressLZF.expand(d, out);
} }
}
list[page] = out; list[page] = out;
} }
...@@ -568,13 +567,11 @@ class FileNioMemData { ...@@ -568,13 +567,11 @@ class FileNioMemData {
return; return;
} }
ByteBuffer d = list[page]; ByteBuffer d = list[page];
synchronized (LZF) { int len = LZF.compress(d, 0, compressOutputBuffer, 0);
int len = LZF.compress(d, 0, BUFFER, 0);
d = ByteBuffer.allocateDirect(len); d = ByteBuffer.allocateDirect(len);
d.put(BUFFER, 0, len); d.put(compressOutputBuffer, 0, len);
list[page] = d; list[page] = d;
} }
}
/** /**
* Update the last modified time. * Update the last modified time.
...@@ -602,7 +599,7 @@ class FileNioMemData { ...@@ -602,7 +599,7 @@ class FileNioMemData {
* *
* @param newLength the new length * @param newLength the new length
*/ */
void truncate(long newLength) { synchronized void truncate(long newLength) {
changeLength(newLength); changeLength(newLength);
long end = MathUtils.roundUpLong(newLength, BLOCK_SIZE); long end = MathUtils.roundUpLong(newLength, BLOCK_SIZE);
if (end != newLength) { if (end != newLength) {
...@@ -642,7 +639,7 @@ class FileNioMemData { ...@@ -642,7 +639,7 @@ class FileNioMemData {
* @param write true for writing * @param write true for writing
* @return the new position * @return the new position
*/ */
long readWrite(long pos, ByteBuffer b, int off, int len, boolean write) { synchronized long readWrite(long pos, ByteBuffer b, int off, int len, boolean write) {
long end = pos + len; long end = pos + len;
if (end > length) { if (end > length) {
if (write) { if (write) {
......
...@@ -58,6 +58,7 @@ public class TestOptimizations extends TestBase { ...@@ -58,6 +58,7 @@ public class TestOptimizations extends TestBase {
testNestedIn(); testNestedIn();
testConstantIn1(); testConstantIn1();
testConstantIn2(); testConstantIn2();
testConstantTypeConversionToColumnType();
testNestedInSelectAndLike(); testNestedInSelectAndLike();
testNestedInSelect(); testNestedInSelect();
testInSelectJoin(); testInSelectJoin();
...@@ -463,6 +464,25 @@ public class TestOptimizations extends TestBase { ...@@ -463,6 +464,25 @@ public class TestOptimizations extends TestBase {
conn.close(); conn.close();
} }
private void testConstantTypeConversionToColumnType() throws SQLException {
deleteDb("optimizations");
Connection conn = getConnection("optimizations;IGNORECASE=TRUE");
Statement stat = conn.createStatement();
stat.executeUpdate("CREATE TABLE test (x int)");
ResultSet resultSet;
resultSet = stat.executeQuery(
"EXPLAIN SELECT x FROM test WHERE x = '5'");
assertTrue(resultSet.next());
// String constant '5' has been converted to int constant 5 on optimization
assertTrue(resultSet.getString(1).endsWith("X = 5"));
stat.execute("drop table test");
conn.close();
}
private void testNestedInSelect() throws SQLException { private void testNestedInSelect() throws SQLException {
deleteDb("optimizations"); deleteDb("optimizations");
Connection conn = getConnection("optimizations"); Connection conn = getConnection("optimizations");
......
...@@ -104,6 +104,13 @@ public class TestTableEngines extends TestBase { ...@@ -104,6 +104,13 @@ public class TestTableEngines extends TestBase {
Statement stat = conn.createStatement(); Statement stat = conn.createStatement();
stat.execute("CREATE TABLE t1(id int, name varchar) ENGINE \"" + stat.execute("CREATE TABLE t1(id int, name varchar) ENGINE \"" +
EndlessTableEngine.class.getName() + "\" WITH \"param1\", \"param2\""); EndlessTableEngine.class.getName() + "\" WITH \"param1\", \"param2\"");
assertEquals(2,
EndlessTableEngine.createTableData.tableEngineParams.size());
assertEquals("param1",
EndlessTableEngine.createTableData.tableEngineParams.get(0));
assertEquals("param2",
EndlessTableEngine.createTableData.tableEngineParams.get(1));
stat.execute("CREATE TABLE t2(id int, name varchar) WITH \"param1\", \"param2\"");
assertEquals(2, assertEquals(2,
EndlessTableEngine.createTableData.tableEngineParams.size()); EndlessTableEngine.createTableData.tableEngineParams.size());
assertEquals("param1", assertEquals("param1",
......
...@@ -8172,8 +8172,8 @@ select * from s; ...@@ -8172,8 +8172,8 @@ select * from s;
> rows: 1 > rows: 1
select some(y>10), every(y>10), min(y), max(y) from t; select some(y>10), every(y>10), min(y), max(y) from t;
> BOOL_OR(Y > 10) BOOL_AND(Y > 10) MIN(Y) MAX(Y) > BOOL_OR(Y > 10.0) BOOL_AND(Y > 10.0) MIN(Y) MAX(Y)
> --------------- ---------------- ------ ------ > ----------------- ------------------ ------ ------
> null null null null > null null null null
> rows: 1 > rows: 1
...@@ -8230,8 +8230,8 @@ stddev_pop(distinct y) s_py, stddev_samp(distinct y) s_sy, var_pop(distinct y) v ...@@ -8230,8 +8230,8 @@ stddev_pop(distinct y) s_py, stddev_samp(distinct y) s_sy, var_pop(distinct y) v
> rows: 1 > rows: 1
select some(y>10), every(y>10), min(y), max(y) from t; select some(y>10), every(y>10), min(y), max(y) from t;
> BOOL_OR(Y > 10) BOOL_AND(Y > 10) MIN(Y) MAX(Y) > BOOL_OR(Y > 10.0) BOOL_AND(Y > 10.0) MIN(Y) MAX(Y)
> --------------- ---------------- ------ ------ > ----------------- ------------------ ------ ------
> TRUE FALSE 4.0 16.0 > TRUE FALSE 4.0 16.0
> rows: 1 > rows: 1
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论