提交 7a26b926 authored 作者: Thomas Mueller's avatar Thomas Mueller

LIKE: the escape mechanism can now be disable using ESCAPE ''.

The default escape character can be changed using the system property h2.defaultEscape.
上级 180480ee
...@@ -1344,11 +1344,16 @@ compare { {{ALL|ANY|SOME}(select)} | operand } ...@@ -1344,11 +1344,16 @@ compare { {{ALL|ANY|SOME}(select)} | operand }
| [NOT] LIKE operand [ESCAPE string] | [NOT] LIKE operand [ESCAPE string]
| [NOT] REGEXP operand | [NOT] REGEXP operand
"," ","
The right hand side of a condition. When comparing with LIKE, the wildcards The right hand side of a condition.
characters are _ (any one character) and % (any characters). The database uses
an index when comparing with LIKE except if the operand starts with a wildcard. When comparing with LIKE, the wildcards characters are _ (any one character)
When comparing with REGEXP, regular expression matching is used. See Java and % (any characters). The database uses an index when comparing with LIKE
Matcher.find for details. except if the operand starts with a wildcard. To search for the characters % and
_, the characters need to be escaped. The default escape character is \ (backslash).
To select no escape character, use ESCAPE '' (empty string).
When comparing with REGEXP, regular expression matching is used.
See Java Matcher.find for details.
"," ","
LIKE 'Jo%' LIKE 'Jo%'
" "
......
...@@ -18,7 +18,10 @@ Change Log ...@@ -18,7 +18,10 @@ Change Log
<h1>Change Log</h1> <h1>Change Log</h1>
<h2>Next Version (unreleased)</h2> <h2>Next Version (unreleased)</h2>
<ul><li>Views using functions were not re-evaluated when necessary. <ul><li>LIKE: the escape mechanism can now be disable using ESCAPE ''.
The default escape character can be changed using the system property h2.defaultEscape.
The default is still '\' (as in MySQL and PostgreSQL).
</li><li>Views using functions were not re-evaluated when necessary.
</li><li>Improved MySQL compatibility for SHOW COLUMNS. </li><li>Improved MySQL compatibility for SHOW COLUMNS.
</li><li>Improved PostgreSQL compatibility for timestamp literals with timezone. </li><li>Improved PostgreSQL compatibility for timestamp literals with timezone.
</li><li>Sergi Vladykin translated the error messages to Russian. Thanks a lot! </li><li>Sergi Vladykin translated the error messages to Russian. Thanks a lot!
......
...@@ -438,6 +438,7 @@ See also <a href="build.html#providing_patches">Providing Patches</a>. ...@@ -438,6 +438,7 @@ See also <a href="build.html#providing_patches">Providing Patches</a>.
</li><li>Support =ANY(array) as in PostgreSQL. </li><li>Support =ANY(array) as in PostgreSQL.
</li><li>IBM DB2 compatibility: support PREVIOUS VALUE FOR sequence. </li><li>IBM DB2 compatibility: support PREVIOUS VALUE FOR sequence.
</li><li>MySQL compatibility: alter table add index i(c), add constraint c foreign key(c) references t(c); </li><li>MySQL compatibility: alter table add index i(c), add constraint c foreign key(c) references t(c);
</li><li>Compatibility: use different LIKE ESCAPE characters depending on the mode (disable for Derby, HSQLDB, DB2, Oracle).
</li></ul> </li></ul>
<h2>Not Planned</h2> <h2>Not Planned</h2>
......
...@@ -48,7 +48,7 @@ public class CreateUser extends DefineCommand { ...@@ -48,7 +48,7 @@ public class CreateUser extends DefineCommand {
} }
private char[] getCharArray(Expression e) throws SQLException { private char[] getCharArray(Expression e) throws SQLException {
return e.getValue(session).getString().toCharArray(); return e.optimize(session).getValue(session).getString().toCharArray();
} }
private byte[] getByteArray(Expression e) throws SQLException { private byte[] getByteArray(Expression e) throws SQLException {
...@@ -74,11 +74,13 @@ public class CreateUser extends DefineCommand { ...@@ -74,11 +74,13 @@ public class CreateUser extends DefineCommand {
user.setComment(comment); user.setComment(comment);
if (hash != null && salt != null) { if (hash != null && salt != null) {
user.setSaltAndHash(getByteArray(salt), getByteArray(hash)); user.setSaltAndHash(getByteArray(salt), getByteArray(hash));
} else { } else if (password != null) {
SHA256 sha = new SHA256(); SHA256 sha = new SHA256();
char[] passwordChars = getCharArray(password); char[] passwordChars = getCharArray(password);
byte[] userPasswordHash = sha.getKeyPasswordHash(userName, passwordChars); byte[] userPasswordHash = sha.getKeyPasswordHash(userName, passwordChars);
user.setUserPasswordHash(userPasswordHash); user.setUserPasswordHash(userPasswordHash);
} else {
throw Message.throwInternalError();
} }
db.addDatabaseObject(session, user); db.addDatabaseObject(session, user);
return 0; return 0;
......
...@@ -179,6 +179,13 @@ public class SysProperties { ...@@ -179,6 +179,13 @@ public class SysProperties {
*/ */
public static final String CLIENT_TRACE_DIRECTORY = getStringSetting("h2.clientTraceDirectory", "trace.db/"); public static final String CLIENT_TRACE_DIRECTORY = getStringSetting("h2.clientTraceDirectory", "trace.db/");
/**
* System property <code>h2.defaultEscape</code> (default: \).<br />
* The default escape character for LIKE comparisons. To select no escape
* character, use an empty string.
*/
public static final Character DEFAULT_ESCAPE_CHAR = getEscapeChar(getStringSetting("h2.defaultEscape", "\\"));
/** /**
* System property <code>h2.defaultMaxOperationMemory</code> (default: * System property <code>h2.defaultMaxOperationMemory</code> (default:
* 100000).<br /> * 100000).<br />
...@@ -730,4 +737,8 @@ public class SysProperties { ...@@ -730,4 +737,8 @@ public class SysProperties {
return getBooleanSetting(H2_PAGE_STORE, false); return getBooleanSetting(H2_PAGE_STORE, false);
} }
private static Character getEscapeChar(String s) {
return s == null || s.length() == 0 ? null : s.charAt(0);
}
} }
...@@ -147,11 +147,6 @@ public class Constants { ...@@ -147,11 +147,6 @@ public class Constants {
*/ */
public static final int DEFAULT_DATA_PAGE_SIZE = 512; public static final int DEFAULT_DATA_PAGE_SIZE = 512;
/**
* The default escape character for LIKE comparisons.
*/
public static final char DEFAULT_ESCAPE_CHAR = '\\';
/** /**
* If the HTTP server should allow connections from other computers by * If the HTTP server should allow connections from other computers by
* default. * default.
......
...@@ -11,7 +11,7 @@ import java.util.regex.Pattern; ...@@ -11,7 +11,7 @@ import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException; import java.util.regex.PatternSyntaxException;
import org.h2.constant.ErrorCode; import org.h2.constant.ErrorCode;
import org.h2.engine.Constants; import org.h2.constant.SysProperties;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.index.IndexCondition; import org.h2.index.IndexCondition;
import org.h2.message.Message; import org.h2.message.Message;
...@@ -112,14 +112,16 @@ public class CompareLike extends Condition { ...@@ -112,14 +112,16 @@ public class CompareLike extends Condition {
return this; return this;
} }
private char getEscapeChar(Value e) { private Character getEscapeChar(Value e) {
if (e == null) { if (e == null) {
return Constants.DEFAULT_ESCAPE_CHAR; return SysProperties.DEFAULT_ESCAPE_CHAR;
} }
String es = e.getString(); String es = e.getString();
char esc; Character esc;
if (es == null || es.length() == 0) { if (es == null) {
esc = Constants.DEFAULT_ESCAPE_CHAR; esc = SysProperties.DEFAULT_ESCAPE_CHAR;
} else if (es.length() == 0) {
esc = null;
} else { } else {
esc = es.charAt(0); esc = es.charAt(0);
} }
...@@ -274,7 +276,7 @@ public class CompareLike extends Condition { ...@@ -274,7 +276,7 @@ public class CompareLike extends Condition {
return compareAt(value, 0, 0, value.length()); return compareAt(value, 0, 0, value.length());
} }
private void initPattern(String p, char escapeChar) throws SQLException { private void initPattern(String p, Character escape) throws SQLException {
if (regexp) { if (regexp) {
patternString = p; patternString = p;
try { try {
...@@ -301,12 +303,12 @@ public class CompareLike extends Condition { ...@@ -301,12 +303,12 @@ public class CompareLike extends Condition {
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
char c = p.charAt(i); char c = p.charAt(i);
int type; int type;
if (escapeChar == c) { if (escape != null && escape == c) {
if (i >= len - 1) { if (i >= len - 1) {
throw Message.getSQLException(ErrorCode.LIKE_ESCAPE_ERROR_1, StringUtils.addAsterisk(p, i)); throw Message.getSQLException(ErrorCode.LIKE_ESCAPE_ERROR_1, StringUtils.addAsterisk(p, i));
} }
c = p.charAt(++i); c = p.charAt(++i);
if (c != '_' && c != '%' && c != escapeChar) { if (c != '_' && c != '%' && c != escape) {
throw Message.getSQLException(ErrorCode.LIKE_ESCAPE_ERROR_1, StringUtils.addAsterisk(p, i)); throw Message.getSQLException(ErrorCode.LIKE_ESCAPE_ERROR_1, StringUtils.addAsterisk(p, i));
} }
type = MATCH; type = MATCH;
......
...@@ -155,9 +155,9 @@ public class JdbcDatabaseMetaData extends TraceObject implements DatabaseMetaDat ...@@ -155,9 +155,9 @@ public class JdbcDatabaseMetaData extends TraceObject implements DatabaseMetaDat
+ "TYPE_NAME REF_GENERATION, " + "TYPE_NAME REF_GENERATION, "
+ "SQL " + "SQL "
+ "FROM INFORMATION_SCHEMA.TABLES " + "FROM INFORMATION_SCHEMA.TABLES "
+ "WHERE TABLE_CATALOG LIKE ? " + "WHERE TABLE_CATALOG LIKE ? ESCAPE '\\' "
+ "AND TABLE_SCHEMA LIKE ? " + "AND TABLE_SCHEMA LIKE ? ESCAPE '\\' "
+ "AND TABLE_NAME LIKE ? " + "AND TABLE_NAME LIKE ? ESCAPE '\\' "
+ "AND (" + tableType + ") " + "AND (" + tableType + ") "
+ "ORDER BY TABLE_TYPE, TABLE_SCHEMA, TABLE_NAME"); + "ORDER BY TABLE_TYPE, TABLE_SCHEMA, TABLE_NAME");
prep.setString(1, getCatalogPattern(catalogPattern)); prep.setString(1, getCatalogPattern(catalogPattern));
...@@ -248,10 +248,10 @@ public class JdbcDatabaseMetaData extends TraceObject implements DatabaseMetaDat ...@@ -248,10 +248,10 @@ public class JdbcDatabaseMetaData extends TraceObject implements DatabaseMetaDat
+ "SOURCE_DATA_TYPE, " + "SOURCE_DATA_TYPE, "
+ "CASE WHEN SEQUENCE_NAME IS NULL THEN 'NO' ELSE 'YES' END IS_AUTOINCREMENT " + "CASE WHEN SEQUENCE_NAME IS NULL THEN 'NO' ELSE 'YES' END IS_AUTOINCREMENT "
+ "FROM INFORMATION_SCHEMA.COLUMNS " + "FROM INFORMATION_SCHEMA.COLUMNS "
+ "WHERE TABLE_CATALOG LIKE ? " + "WHERE TABLE_CATALOG LIKE ? ESCAPE '\\' "
+ "AND TABLE_SCHEMA LIKE ? " + "AND TABLE_SCHEMA LIKE ? ESCAPE '\\' "
+ "AND TABLE_NAME LIKE ? " + "AND TABLE_NAME LIKE ? ESCAPE '\\' "
+ "AND COLUMN_NAME LIKE ? " + "AND COLUMN_NAME LIKE ? ESCAPE '\\' "
+ "ORDER BY TABLE_SCHEM, TABLE_NAME, ORDINAL_POSITION"); + "ORDER BY TABLE_SCHEM, TABLE_NAME, ORDINAL_POSITION");
prep.setString(1, getCatalogPattern(catalogPattern)); prep.setString(1, getCatalogPattern(catalogPattern));
prep.setString(2, getSchemaPattern(schemaPattern)); prep.setString(2, getSchemaPattern(schemaPattern));
...@@ -327,8 +327,8 @@ public class JdbcDatabaseMetaData extends TraceObject implements DatabaseMetaDat ...@@ -327,8 +327,8 @@ public class JdbcDatabaseMetaData extends TraceObject implements DatabaseMetaDat
+ "FILTER_CONDITION, " + "FILTER_CONDITION, "
+ "SORT_TYPE " + "SORT_TYPE "
+ "FROM INFORMATION_SCHEMA.INDEXES " + "FROM INFORMATION_SCHEMA.INDEXES "
+ "WHERE TABLE_CATALOG LIKE ? " + "WHERE TABLE_CATALOG LIKE ? ESCAPE '\\' "
+ "AND TABLE_SCHEMA LIKE ? " + "AND TABLE_SCHEMA LIKE ? ESCAPE '\\' "
+ "AND (" + uniqueCondition + ") " + "AND (" + uniqueCondition + ") "
+ "AND TABLE_NAME = ? " + "AND TABLE_NAME = ? "
+ "ORDER BY NON_UNIQUE, TYPE, TABLE_SCHEM, INDEX_NAME, ORDINAL_POSITION"); + "ORDER BY NON_UNIQUE, TYPE, TABLE_SCHEM, INDEX_NAME, ORDINAL_POSITION");
...@@ -377,8 +377,8 @@ public class JdbcDatabaseMetaData extends TraceObject implements DatabaseMetaDat ...@@ -377,8 +377,8 @@ public class JdbcDatabaseMetaData extends TraceObject implements DatabaseMetaDat
+ "ORDINAL_POSITION KEY_SEQ, " + "ORDINAL_POSITION KEY_SEQ, "
+ "IFNULL(CONSTRAINT_NAME, INDEX_NAME) PK_NAME " + "IFNULL(CONSTRAINT_NAME, INDEX_NAME) PK_NAME "
+ "FROM INFORMATION_SCHEMA.INDEXES " + "FROM INFORMATION_SCHEMA.INDEXES "
+ "WHERE TABLE_CATALOG LIKE ? " + "WHERE TABLE_CATALOG LIKE ? ESCAPE '\\' "
+ "AND TABLE_SCHEMA LIKE ? " + "AND TABLE_SCHEMA LIKE ? ESCAPE '\\' "
+ "AND TABLE_NAME = ? " + "AND TABLE_NAME = ? "
+ "AND PRIMARY_KEY = TRUE " + "AND PRIMARY_KEY = TRUE "
+ "ORDER BY COLUMN_NAME"); + "ORDER BY COLUMN_NAME");
...@@ -554,9 +554,9 @@ public class JdbcDatabaseMetaData extends TraceObject implements DatabaseMetaDat ...@@ -554,9 +554,9 @@ public class JdbcDatabaseMetaData extends TraceObject implements DatabaseMetaDat
+ "RETURNS_RESULT PROCEDURE_TYPE, " + "RETURNS_RESULT PROCEDURE_TYPE, "
+ "ALIAS_NAME SPECIFIC_NAME " + "ALIAS_NAME SPECIFIC_NAME "
+ "FROM INFORMATION_SCHEMA.FUNCTION_ALIASES " + "FROM INFORMATION_SCHEMA.FUNCTION_ALIASES "
+ "WHERE ALIAS_CATALOG LIKE ? " + "WHERE ALIAS_CATALOG LIKE ? ESCAPE '\\' "
+ "AND ALIAS_SCHEMA LIKE ? " + "AND ALIAS_SCHEMA LIKE ? ESCAPE '\\' "
+ "AND ALIAS_NAME LIKE ? " + "AND ALIAS_NAME LIKE ? ESCAPE '\\' "
+ "ORDER BY PROCEDURE_SCHEM, PROCEDURE_NAME, NUM_INPUT_PARAMS"); + "ORDER BY PROCEDURE_SCHEM, PROCEDURE_NAME, NUM_INPUT_PARAMS");
prep.setString(1, getCatalogPattern(catalogPattern)); prep.setString(1, getCatalogPattern(catalogPattern));
prep.setString(2, getSchemaPattern(schemaPattern)); prep.setString(2, getSchemaPattern(schemaPattern));
...@@ -638,10 +638,10 @@ public class JdbcDatabaseMetaData extends TraceObject implements DatabaseMetaDat ...@@ -638,10 +638,10 @@ public class JdbcDatabaseMetaData extends TraceObject implements DatabaseMetaDat
+ "'YES' IS_NULLABLE, " + "'YES' IS_NULLABLE, "
+ "ALIAS_NAME SPECIFIC_NAME " + "ALIAS_NAME SPECIFIC_NAME "
+ "FROM INFORMATION_SCHEMA.FUNCTION_COLUMNS " + "FROM INFORMATION_SCHEMA.FUNCTION_COLUMNS "
+ "WHERE ALIAS_CATALOG LIKE ? " + "WHERE ALIAS_CATALOG LIKE ? ESCAPE '\\' "
+ "AND ALIAS_SCHEMA LIKE ? " + "AND ALIAS_SCHEMA LIKE ? ESCAPE '\\' "
+ "AND ALIAS_NAME LIKE ? " + "AND ALIAS_NAME LIKE ? ESCAPE '\\' "
+ "AND COLUMN_NAME LIKE ? " + "AND COLUMN_NAME LIKE ? ESCAPE '\\' "
+ "ORDER BY PROCEDURE_SCHEM, PROCEDURE_NAME, ORDINAL_POSITION"); + "ORDER BY PROCEDURE_SCHEM, PROCEDURE_NAME, ORDINAL_POSITION");
prep.setString(1, getCatalogPattern(catalogPattern)); prep.setString(1, getCatalogPattern(catalogPattern));
prep.setString(2, getSchemaPattern(schemaPattern)); prep.setString(2, getSchemaPattern(schemaPattern));
...@@ -780,10 +780,10 @@ public class JdbcDatabaseMetaData extends TraceObject implements DatabaseMetaDat ...@@ -780,10 +780,10 @@ public class JdbcDatabaseMetaData extends TraceObject implements DatabaseMetaDat
+ "PRIVILEGE_TYPE PRIVILEGE, " + "PRIVILEGE_TYPE PRIVILEGE, "
+ "IS_GRANTABLE " + "IS_GRANTABLE "
+ "FROM INFORMATION_SCHEMA.COLUMN_PRIVILEGES " + "FROM INFORMATION_SCHEMA.COLUMN_PRIVILEGES "
+ "WHERE TABLE_CATALOG LIKE ? " + "WHERE TABLE_CATALOG LIKE ? ESCAPE '\\' "
+ "AND TABLE_SCHEMA LIKE ? " + "AND TABLE_SCHEMA LIKE ? ESCAPE '\\' "
+ "AND TABLE_NAME = ? " + "AND TABLE_NAME = ? "
+ "AND COLUMN_NAME LIKE ? " + "AND COLUMN_NAME LIKE ? ESCAPE '\\' "
+ "ORDER BY COLUMN_NAME, PRIVILEGE"); + "ORDER BY COLUMN_NAME, PRIVILEGE");
prep.setString(1, getCatalogPattern(catalogPattern)); prep.setString(1, getCatalogPattern(catalogPattern));
prep.setString(2, getSchemaPattern(schemaPattern)); prep.setString(2, getSchemaPattern(schemaPattern));
...@@ -837,9 +837,9 @@ public class JdbcDatabaseMetaData extends TraceObject implements DatabaseMetaDat ...@@ -837,9 +837,9 @@ public class JdbcDatabaseMetaData extends TraceObject implements DatabaseMetaDat
+ "PRIVILEGE_TYPE PRIVILEGE, " + "PRIVILEGE_TYPE PRIVILEGE, "
+ "IS_GRANTABLE " + "IS_GRANTABLE "
+ "FROM INFORMATION_SCHEMA.TABLE_PRIVILEGES " + "FROM INFORMATION_SCHEMA.TABLE_PRIVILEGES "
+ "WHERE TABLE_CATALOG LIKE ? " + "WHERE TABLE_CATALOG LIKE ? ESCAPE '\\' "
+ "AND TABLE_SCHEMA LIKE ? " + "AND TABLE_SCHEMA LIKE ? ESCAPE '\\' "
+ "AND TABLE_NAME LIKE ? " + "AND TABLE_NAME LIKE ? ESCAPE '\\' "
+ "ORDER BY TABLE_SCHEM, TABLE_NAME, PRIVILEGE"); + "ORDER BY TABLE_SCHEM, TABLE_NAME, PRIVILEGE");
prep.setString(1, getCatalogPattern(catalogPattern)); prep.setString(1, getCatalogPattern(catalogPattern));
prep.setString(2, getSchemaPattern(schemaPattern)); prep.setString(2, getSchemaPattern(schemaPattern));
...@@ -897,8 +897,8 @@ public class JdbcDatabaseMetaData extends TraceObject implements DatabaseMetaDat ...@@ -897,8 +897,8 @@ public class JdbcDatabaseMetaData extends TraceObject implements DatabaseMetaDat
+" INFORMATION_SCHEMA.COLUMNS C " +" INFORMATION_SCHEMA.COLUMNS C "
+ "WHERE C.TABLE_NAME = I.TABLE_NAME " + "WHERE C.TABLE_NAME = I.TABLE_NAME "
+ "AND C.COLUMN_NAME = I.COLUMN_NAME " + "AND C.COLUMN_NAME = I.COLUMN_NAME "
+ "AND C.TABLE_CATALOG LIKE ? " + "AND C.TABLE_CATALOG LIKE ? ESCAPE '\\' "
+ "AND C.TABLE_SCHEMA LIKE ? " + "AND C.TABLE_SCHEMA LIKE ? ESCAPE '\\' "
+ "AND C.TABLE_NAME = ? " + "AND C.TABLE_NAME = ? "
+ "AND I.PRIMARY_KEY = TRUE " + "AND I.PRIMARY_KEY = TRUE "
+ "ORDER BY SCOPE"); + "ORDER BY SCOPE");
...@@ -1019,8 +1019,8 @@ public class JdbcDatabaseMetaData extends TraceObject implements DatabaseMetaDat ...@@ -1019,8 +1019,8 @@ public class JdbcDatabaseMetaData extends TraceObject implements DatabaseMetaDat
+ "PK_NAME, " + "PK_NAME, "
+ "DEFERRABILITY " + "DEFERRABILITY "
+ "FROM INFORMATION_SCHEMA.CROSS_REFERENCES " + "FROM INFORMATION_SCHEMA.CROSS_REFERENCES "
+ "WHERE FKTABLE_CATALOG LIKE ? " + "WHERE FKTABLE_CATALOG LIKE ? ESCAPE '\\' "
+ "AND FKTABLE_SCHEMA LIKE ? " + "AND FKTABLE_SCHEMA LIKE ? ESCAPE '\\' "
+ "AND FKTABLE_NAME = ? " + "AND FKTABLE_NAME = ? "
+ "ORDER BY PKTABLE_CAT, PKTABLE_SCHEM, PKTABLE_NAME, FK_NAME, KEY_SEQ"); + "ORDER BY PKTABLE_CAT, PKTABLE_SCHEM, PKTABLE_NAME, FK_NAME, KEY_SEQ");
prep.setString(1, getCatalogPattern(catalogPattern)); prep.setString(1, getCatalogPattern(catalogPattern));
...@@ -1089,8 +1089,8 @@ public class JdbcDatabaseMetaData extends TraceObject implements DatabaseMetaDat ...@@ -1089,8 +1089,8 @@ public class JdbcDatabaseMetaData extends TraceObject implements DatabaseMetaDat
+ "PK_NAME, " + "PK_NAME, "
+ "DEFERRABILITY " + "DEFERRABILITY "
+ "FROM INFORMATION_SCHEMA.CROSS_REFERENCES " + "FROM INFORMATION_SCHEMA.CROSS_REFERENCES "
+ "WHERE PKTABLE_CATALOG LIKE ? " + "WHERE PKTABLE_CATALOG LIKE ? ESCAPE '\\' "
+ "AND PKTABLE_SCHEMA LIKE ? " + "AND PKTABLE_SCHEMA LIKE ? ESCAPE '\\' "
+ "AND PKTABLE_NAME = ? " + "AND PKTABLE_NAME = ? "
+ "ORDER BY FKTABLE_CAT, FKTABLE_SCHEM, FKTABLE_NAME, FK_NAME, KEY_SEQ"); + "ORDER BY FKTABLE_CAT, FKTABLE_SCHEM, FKTABLE_NAME, FK_NAME, KEY_SEQ");
prep.setString(1, getCatalogPattern(catalogPattern)); prep.setString(1, getCatalogPattern(catalogPattern));
...@@ -1169,11 +1169,11 @@ public class JdbcDatabaseMetaData extends TraceObject implements DatabaseMetaDat ...@@ -1169,11 +1169,11 @@ public class JdbcDatabaseMetaData extends TraceObject implements DatabaseMetaDat
+ "PK_NAME, " + "PK_NAME, "
+ "DEFERRABILITY " + "DEFERRABILITY "
+ "FROM INFORMATION_SCHEMA.CROSS_REFERENCES " + "FROM INFORMATION_SCHEMA.CROSS_REFERENCES "
+ "WHERE PKTABLE_CATALOG LIKE ? " + "WHERE PKTABLE_CATALOG LIKE ? ESCAPE '\\' "
+ "AND PKTABLE_SCHEMA LIKE ? " + "AND PKTABLE_SCHEMA LIKE ? ESCAPE '\\' "
+ "AND PKTABLE_NAME = ? " + "AND PKTABLE_NAME = ? "
+ "AND FKTABLE_CATALOG LIKE ? " + "AND FKTABLE_CATALOG LIKE ? ESCAPE '\\' "
+ "AND FKTABLE_SCHEMA LIKE ? " + "AND FKTABLE_SCHEMA LIKE ? ESCAPE '\\' "
+ "AND FKTABLE_NAME = ? " + "AND FKTABLE_NAME = ? "
+ "ORDER BY FKTABLE_CAT, FKTABLE_SCHEM, FKTABLE_NAME, FK_NAME, KEY_SEQ"); + "ORDER BY FKTABLE_CAT, FKTABLE_SCHEM, FKTABLE_NAME, FK_NAME, KEY_SEQ");
prep.setString(1, getCatalogPattern(primaryCatalogPattern)); prep.setString(1, getCatalogPattern(primaryCatalogPattern));
...@@ -1421,13 +1421,15 @@ public class JdbcDatabaseMetaData extends TraceObject implements DatabaseMetaDat ...@@ -1421,13 +1421,15 @@ public class JdbcDatabaseMetaData extends TraceObject implements DatabaseMetaDat
} }
/** /**
* Returns the default escape character for LIKE. * Returns the default escape character for DatabaseMetaData search
* patterns.
* *
* @return the character '\' * @return the default escape character (always '\', independent on the
* mode)
*/ */
public String getSearchStringEscape() { public String getSearchStringEscape() {
debugCodeCall("getSearchStringEscape"); debugCodeCall("getSearchStringEscape");
return "" + Constants.DEFAULT_ESCAPE_CHAR; return "\\";
} }
/** /**
......
...@@ -295,15 +295,6 @@ java org.h2.test.TestAll timer ...@@ -295,15 +295,6 @@ java org.h2.test.TestAll timer
/* /*
LIKE: Use no default escape character, except for PostgreSQL and MySQL compatibility
See DatabaseMetaData.getSearchStringEscape
PostgreSQL: select no escape character by writing ESCAPE ''
drop table test;
create table test(id int);
insert into test values(1);
select * from test where '\' like '\' escape '';
select * from test where '\' like '\';
page store: TestBtreeIndex page store: TestBtreeIndex
better document that ddl statements commit better document that ddl statements commit
...@@ -355,10 +346,10 @@ kill -9 `jps -l | grep "org.h2.test.TestAll" | cut -d " " -f 1` ...@@ -355,10 +346,10 @@ kill -9 `jps -l | grep "org.h2.test.TestAll" | cut -d " " -f 1`
test.runTests(); test.runTests();
TestPerformance.main(new String[]{ "-init", "-db", "1"}); TestPerformance.main(new String[]{ "-init", "-db", "1"});
// System.setProperty(SysProperties.H2_PAGE_STORE, "false"); System.setProperty(SysProperties.H2_PAGE_STORE, "false");
// test.pageStore = false; test.pageStore = false;
// test.runTests(); test.runTests();
// TestPerformance.main(new String[]{ "-init", "-db", "1"}); TestPerformance.main(new String[]{ "-init", "-db", "1"});
} }
System.out.println(TestBase.formatTime(System.currentTimeMillis() - time) + " total"); System.out.println(TestBase.formatTime(System.currentTimeMillis() - time) + " total");
} }
......
select 1 from dual where '\' like '\' escape '';
> 1;
select left(timestamp '2001-02-03 08:20:31+04', 4); select left(timestamp '2001-02-03 08:20:31+04', 4);
> 2001; > 2001;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论