提交 71d41cb0 authored 作者: Thomas Mueller's avatar Thomas Mueller

In the MySQL mode, SHOW TABLES didn't work, and meta data tables were not case…

In the MySQL mode, SHOW TABLES didn't work, and meta data tables were not case insensitive. Updateable result sets didn't work as expected. Issue 249.
上级 6fba42b3
...@@ -18,7 +18,9 @@ Change Log ...@@ -18,7 +18,9 @@ Change Log
<h1>Change Log</h1> <h1>Change Log</h1>
<h2>Next Version (unreleased)</h2> <h2>Next Version (unreleased)</h2>
<ul><li>Connection-created Clob and Blob objects can now be filled using <ul><li>In the MySQL mode, SHOW TABLES didn't work, and meta data tables were not
case insensitive. Updateable result sets didn't work as expected. Issue 249.
</li><li>Connection-created Clob and Blob objects can now be filled using
Clob.setCharacterStream(1), Clob.setString(1, s), Blob.setBytes(1, x), Blob.setBinaryStream(1). Clob.setCharacterStream(1), Clob.setString(1, s), Blob.setBytes(1, x), Blob.setBinaryStream(1).
Issue 235. Issue 235.
</li><li>Trying to convert a very small CLOB to a BLOB or a very small CLOB to a BLOB threw a NullPointerException. </li><li>Trying to convert a very small CLOB to a BLOB or a very small CLOB to a BLOB threw a NullPointerException.
...@@ -30,7 +32,8 @@ Change Log ...@@ -30,7 +32,8 @@ Change Log
there is a EOFException (because that is the expected behavior). there is a EOFException (because that is the expected behavior).
</li><li>CALL calling a Java function with return type ResultSet and </li><li>CALL calling a Java function with return type ResultSet and
return value null threw a ClassCastException. return value null threw a ClassCastException.
</li><li>SELECT ... FROM CSVREAD no longer creates a temporary file. </li><li>SELECT ... FROM CSVREAD no longer creates a temporary file.
Some large imports are now twice as fast.
</li></ul> </li></ul>
<h2>Version 1.2.145 (2010-11-02)</h2> <h2>Version 1.2.145 (2010-11-02)</h2>
......
...@@ -77,19 +77,26 @@ public class UpdatableRow { ...@@ -77,19 +77,26 @@ public class UpdatableRow {
// system table // system table
return; return;
} }
String table = rs.getString("TABLE_NAME");
// if the table name in the database meta data is lower case,
// but the table in the result set meta data is not, then the column
// in the database meta data is also lower case
boolean toUpper = !table.equals(tableName) && table.equalsIgnoreCase(tableName);
key = New.arrayList(); key = New.arrayList();
rs = meta.getPrimaryKeys(null, rs = meta.getPrimaryKeys(null,
JdbcUtils.escapeMetaDataPattern(schemaName), JdbcUtils.escapeMetaDataPattern(schemaName),
tableName); tableName);
while (rs.next()) { while (rs.next()) {
key.add(rs.getString("COLUMN_NAME")); String c = rs.getString("COLUMN_NAME");
key.add(toUpper ? StringUtils.toUpperEnglish(c) : c);
} }
if (key.size() == 0) { if (key.size() == 0) {
rs = meta.getIndexInfo(null, rs = meta.getIndexInfo(null,
JdbcUtils.escapeMetaDataPattern(schemaName), JdbcUtils.escapeMetaDataPattern(schemaName),
tableName, true, true); tableName, true, true);
while (rs.next()) { while (rs.next()) {
key.add(rs.getString("COLUMN_NAME")); String c = rs.getString("COLUMN_NAME");
key.add(toUpper ? StringUtils.toUpperEnglish(c) : c);
} }
} }
isUpdatable = key.size() > 0; isUpdatable = key.size() > 0;
......
...@@ -61,6 +61,7 @@ import org.h2.value.DataType; ...@@ -61,6 +61,7 @@ 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;
import org.h2.value.ValueString; import org.h2.value.ValueString;
import org.h2.value.ValueStringIgnoreCase;
/** /**
* This class is responsible to build the database meta data pseudo tables. * This class is responsible to build the database meta data pseudo tables.
...@@ -529,7 +530,7 @@ public class MetaTable extends Table { ...@@ -529,7 +530,7 @@ public class MetaTable extends Table {
int dataType; int dataType;
String name; String name;
if (idx < 0) { if (idx < 0) {
dataType = Value.STRING; dataType = database.getMode().lowerCaseIdentifiers ? Value.STRING_IGNORECASE : Value.STRING;
name = nameType; name = nameType;
} else { } else {
dataType = DataType.getTypeByName(nameType.substring(idx + 1)).type; dataType = DataType.getTypeByName(nameType.substring(idx + 1)).type;
...@@ -580,12 +581,19 @@ public class MetaTable extends Table { ...@@ -580,12 +581,19 @@ public class MetaTable extends Table {
return true; return true;
} }
Database db = session.getDatabase(); Database db = session.getDatabase();
Value v = ValueString.get(value); if (database.getMode().lowerCaseIdentifiers) {
if (indexFrom != null && db.compare(v, indexFrom) < 0) { Value v = ValueStringIgnoreCase.get(value);
return false; if (indexFrom.equals(indexTo) && db.compare(v, indexFrom) != 0) {
} return false;
if (indexTo != null && db.compare(v, indexTo) > 0) { }
return false; } else {
Value v = ValueString.get(value);
if (indexFrom != null && db.compare(v, indexFrom) < 0) {
return false;
}
if (indexTo != null && db.compare(v, indexTo) > 0) {
return false;
}
} }
return true; return true;
} }
......
...@@ -153,7 +153,7 @@ public class TestCompatibility extends TestBase { ...@@ -153,7 +153,7 @@ public class TestCompatibility extends TestBase {
Statement stat = conn.createStatement(); Statement stat = conn.createStatement();
stat.execute("SELECT 1"); stat.execute("SELECT 1");
stat.execute("DROP TABLE IF EXISTS TEST"); stat.execute("DROP TABLE IF EXISTS TEST");
stat.execute("CREATE TABLE TEST(ID INT, NAME VARCHAR)"); stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR)");
stat.execute("INSERT INTO TEST VALUES(1, 'Hello'), (2, 'World')"); stat.execute("INSERT INTO TEST VALUES(1, 'Hello'), (2, 'World')");
org.h2.mode.FunctionsMySQL.register(conn); org.h2.mode.FunctionsMySQL.register(conn);
assertResult("1196418619", stat, "SELECT UNIX_TIMESTAMP('2007-11-30 10:30:19Z')"); assertResult("1196418619", stat, "SELECT UNIX_TIMESTAMP('2007-11-30 10:30:19Z')");
...@@ -161,6 +161,21 @@ public class TestCompatibility extends TestBase { ...@@ -161,6 +161,21 @@ public class TestCompatibility extends TestBase {
assertResult("2007 November", stat, "SELECT FROM_UNIXTIME(1196300000, '%Y %M')"); assertResult("2007 November", stat, "SELECT FROM_UNIXTIME(1196300000, '%Y %M')");
assertResult("2003-12-31", stat, "SELECT DATE('2003-12-31 11:02:03')"); assertResult("2003-12-31", stat, "SELECT DATE('2003-12-31 11:02:03')");
if (config.memory) {
return;
}
// need to reconnect, because meta data tables may be initialized
conn.close();
conn = getConnection("compatibility;MODE=MYSQL");
stat = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
assertResult("test", stat, "SHOW TABLES");
ResultSet rs = stat.executeQuery("SELECT * FROM TEST");
rs.next();
rs.updateString(2, "Hallo");
rs.updateRow();
conn.close();
conn = getConnection("compatibility");
} }
private void testPlusSignAsConcatOperator() throws SQLException { private void testPlusSignAsConcatOperator() throws SQLException {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论