提交 41540b10 authored 作者: Thomas Mueller's avatar Thomas Mueller

--no commit message

--no commit message
上级 22752adb
......@@ -31,7 +31,7 @@ public class Bnf {
static final boolean COMBINE_KEYWORDS = false;
private static final String SEPARATORS = " [](){}|.,\r\n<>:-+*/=<\">!'";
private static final String SEPARATORS = " [](){}|.,\r\n<>:-+*/=<\">!'$";
private static final long MAX_PARSE_TIME = 100;
private final Random random = new Random();
......@@ -127,6 +127,7 @@ public class Bnf {
addFixedRule("anythingExceptDoubleQuote", RuleFixed.ANY_EXCEPT_DOUBLE_QUOTE);
addFixedRule("anythingUntilEndOfLine", RuleFixed.ANY_UNTIL_EOL);
addFixedRule("anythingUntilEndComment", RuleFixed.ANY_UNTIL_END);
addFixedRule("anythingExceptTwoDollarSigns", RuleFixed.ANY_EXCEPT_2_DOLLAR);
addFixedRule("anything", RuleFixed.ANY_WORD);
addFixedRule("@hexStart@", RuleFixed.HEX_START);
addFixedRule("@concat@", RuleFixed.CONCAT);
......
......@@ -19,6 +19,7 @@ public class RuleFixed implements Rule {
static final int ANY_UNTIL_EOL = 5;
static final int ANY_UNTIL_END = 6;
static final int ANY_WORD = 7;
static final int ANY_EXCEPT_2_DOLLAR = 8;
static final int HEX_START = 10, CONCAT = 11, AZ_UNDERLINE = 12, AF = 13, DIGIT = 14;
private final int type;
......@@ -39,6 +40,7 @@ public class RuleFixed implements Rule {
case ANY_EXCEPT_SINGLE_QUOTE:
case ANY_EXCEPT_DOUBLE_QUOTE:
case ANY_WORD:
case ANY_EXCEPT_2_DOLLAR:
case ANY_UNTIL_END: {
return "XYZ";
}
......@@ -70,6 +72,7 @@ public class RuleFixed implements Rule {
case ANY_EXCEPT_SINGLE_QUOTE:
case ANY_EXCEPT_DOUBLE_QUOTE:
case ANY_WORD:
case ANY_EXCEPT_2_DOLLAR:
case ANY_UNTIL_END: {
StringBuffer buff = new StringBuffer();
int len = r.nextBoolean() ? 1 : r.nextInt(5);
......@@ -168,6 +171,14 @@ public class RuleFixed implements Rule {
}
}
break;
case ANY_EXCEPT_2_DOLLAR:
while (true) {
while (s.length() > 0 && !s.startsWith("$$")) {
s = s.substring(1);
}
break;
}
break;
case HEX_START:
if (s.startsWith("0X") || s.startsWith("0x")) {
s = s.substring(2);
......@@ -237,6 +248,12 @@ public class RuleFixed implements Rule {
sentence.add("'", "'", Sentence.KEYWORD);
}
break;
case ANY_EXCEPT_2_DOLLAR:
if (query.length() == 0) {
sentence.add("anything", "Hello World", Sentence.KEYWORD);
sentence.add("'", "'", Sentence.KEYWORD);
}
break;
case ANY_EXCEPT_DOUBLE_QUOTE:
if (query.length() == 0) {
sentence.add("anything", "identifier", Sentence.KEYWORD);
......
......@@ -57,7 +57,7 @@ public class CommandRemote implements CommandInterface {
for (int i = 0; i < transferList.size(); i++) {
try {
Transfer transfer = (Transfer) transferList.get(i);
if (readParams) {
if (readParams && createParams) {
session.traceOperation("SESSION_PREPARE_READ_PARAMS", id);
transfer.writeInt(SessionRemote.SESSION_PREPARE_READ_PARAMS).writeInt(id).writeString(sql);
} else {
......
......@@ -150,7 +150,7 @@ public class Parser {
// used during the tokenizer phase
private static final int CHAR_END = -1, CHAR_VALUE = 2, CHAR_QUOTED = 3;
private static final int CHAR_NAME = 4, CHAR_SPECIAL_1 = 5, CHAR_SPECIAL_2 = 6;
private static final int CHAR_STRING = 7, CHAR_DECIMAL = 8;
private static final int CHAR_STRING = 7, CHAR_DECIMAL = 8, CHAR_DOLLAR_QUOTED_STRING = 9;
// this are token types
private static final int KEYWORD = 1, IDENTIFIER = 2, PARAMETER = 3, END = 4, VALUE = 5;
......@@ -2561,7 +2561,21 @@ public class Parser {
i++;
}
currentToken = "'";
checkLiterals(false);
checkLiterals(true);
currentValue = ValueString.get(StringCache.getNew(result));
parseIndex = i;
currentTokenType = VALUE;
return;
}
case CHAR_DOLLAR_QUOTED_STRING: {
String result = null;
int begin = i - 1;
while (types[i] == CHAR_DOLLAR_QUOTED_STRING) {
i++;
}
result = sqlCommand.substring(begin, i);
currentToken = "'";
checkLiterals(true);
currentValue = ValueString.get(StringCache.getNew(result));
parseIndex = i;
currentTokenType = VALUE;
......@@ -2712,6 +2726,26 @@ public class Parser {
type = CHAR_SPECIAL_1;
}
break;
case '$':
if (SysProperties.DOLLAR_QUOTING && command[i + 1] == '$' && (i == 0 || command[i - 1] <= ' ')) {
// dollar quoted string
changed = true;
command[i] = ' ';
command[i + 1] = ' ';
startLoop = i;
i += 2;
checkRunOver(i, len, startLoop);
while (command[i] != '$' || command[i + 1] != '$') {
types[i++] = CHAR_DOLLAR_QUOTED_STRING;
checkRunOver(i, len, startLoop);
}
command[i] = ' ';
command[i + 1] = ' ';
i++;
} else {
type = CHAR_SPECIAL_1;
}
break;
case '(':
case ')':
case '{':
......@@ -2723,7 +2757,6 @@ public class Parser {
case '%':
case '?':
case '@':
case '$':
case ']':
type = CHAR_SPECIAL_1;
break;
......
......@@ -183,6 +183,14 @@ public class SysProperties {
*/
public static final int DELAY_WRONG_PASSWORD_MAX = getIntSetting("h2.delayWrongPasswordMax", 4000);
/**
* System property <code>h2.dollarQuoting</code> (default: true).<br />
* Dollar quoting is used to quote text without having to use escape
* characters. A dollar quoted string starts and ends with $$. Inside the
* text, $$ is not allowed.
*/
public static final boolean DOLLAR_QUOTING = getBooleanSetting("h2.dollarQuoting", true);
/**
* System property <code>h2.emergencySpaceInitial</code> (default: 262144).<br />
* Size of 'reserve' file to detect disk full problems early.
......
......@@ -35,7 +35,8 @@ package org.h2.engine;
* - No " Message.get" (must be "throw Message.get")
* - No TODO in the docs, remove @~ in .utf8.txt files
* - Run regression test with JDK 1.4 and 1.5
* - Use latest versions of other dbs (Derby 10.4.1.3; PostgreSQL 8.3.1; MySQL 5.0.51)
* - Use latest versions of other dbs (Derby 10.4.1.3;
* PostgreSQL 8.3.1; MySQL 5.0.51)
* - Change version(s) in performance.html
* - Run 'ant benchmark' (with JDK 1.4 currently)
* - Copy the benchmark results and update the performance page and diagram
......
......@@ -580,6 +580,9 @@ public class Session implements SessionInterface {
return firstUncommittedPos;
}
/**
* This method is called after the log file has committed this session.
*/
public void setAllCommitted() {
firstUncommittedLog = LogSystem.LOG_WRITTEN;
firstUncommittedPos = LogSystem.LOG_WRITTEN;
......
......@@ -238,7 +238,8 @@ public class SessionRemote implements SessionInterface, DataHandler {
private void upgradeClientVersionIfPossible() {
try {
// TODO check if a newer client version can be used - not required when sending TCP_DRIVER_VERSION_6
// TODO check if a newer client version can be used
// not required when sending TCP_DRIVER_VERSION_6
CommandInterface command = prepareCommand("SELECT VALUE FROM INFORMATION_SCHEMA.SETTINGS WHERE NAME=?", 1);
ParameterInterface param = (ParameterInterface) command.getParameters().get(0);
param.setValue(ValueString.get("info.BUILD_ID"));
......
......@@ -75,5 +75,4 @@ public class ParameterRemote implements ParameterInterface {
transfer.writeInt(p.getNullable());
}
}
......@@ -1027,6 +1027,16 @@ public class JdbcConnection extends TraceObject implements Connection {
private int translateGetEnd(String sql, int i, char c) throws SQLException {
int len = sql.length();
switch(c) {
case '$': {
if (i < len - 1 && sql.charAt(i + 1) == '$' && (i == 0 || sql.charAt(i - 1) <= ' ')) {
int j = sql.indexOf("$$", i + 2);
if (j < 0) {
throw Message.getSyntaxError(sql, i);
}
return j + 1;
}
return i;
}
case '\'': {
int j = sql.indexOf('\'', i + 1);
if (j < 0) {
......@@ -1173,6 +1183,11 @@ public class JdbcConnection extends TraceObject implements Connection {
}
chars[i] = ' ';
break;
case '$':
if (SysProperties.DOLLAR_QUOTING) {
i = translateGetEnd(sql, i, c);
}
break;
default:
}
}
......
......@@ -77,6 +77,12 @@ public class Trace {
buff.append(lineSeparator);
buff.append("/*SQL ");
if (params.length() > 0) {
// This looks like a bug, but it is intentional:
// If there are no parameters, the SQL statement is
// the rest of the line. If there are parameters, they
// are appended at the end of the line. Knowing the size
// of the statement simplifies separating the SQL statement
// from the parameters (no need to parse).
buff.append("l:");
buff.append(sql.length());
}
......
......@@ -1333,7 +1333,7 @@ A value. Parameters can be indexed, for example ?1 meaning the first parameter.
'Hello'
"
"Other Grammar","Value","
string | hexNumber | int | long | decimal | double |
string | dollarQuotedString | hexNumber | int | long | decimal | double |
date | time | timestamp | boolean | bytes | array | null
","
A value of any data type, or null
......@@ -1398,6 +1398,7 @@ An alias is a name that is only valid in the context of the statement.
","
A
"
"Other Grammar","Quoted Name","
""anythingExceptDoubleQuote""
","
......@@ -1406,6 +1407,7 @@ Two double quotes can be used to create a single double quote inside an identifi
","
""FirstName""
"
"Other Grammar","String","
'anythingExceptSingleQuote'
","
......@@ -1414,6 +1416,17 @@ Two single quotes can be used to create a single quote inside a string.
","
'John''s car'
"
"Other Grammar","Dollar Quoted String","
$$anythingExceptTwoDollarSigns$$
","
A string starts and ends with two dollar signs.
Two dollar signs are not allowed within the text.
No escaping is required within the text.
","
$$John's car$$
"
"Other Grammar","Int","
[- | +] digit [...]
","
......@@ -1421,6 +1434,7 @@ The maximum integer number is 2147483647, the minimum is -2147483648.
","
10
"
"Other Grammar","Long","
[- | +] digit [...]
","
......
......@@ -10,6 +10,7 @@ import java.io.IOException;
import java.io.Reader;
import java.sql.SQLException;
import org.h2.constant.SysProperties;
import org.h2.message.Message;
/**
......@@ -49,6 +50,7 @@ public class ScriptReader {
return null;
}
StringBuffer buff = new StringBuffer(200);
int previous = 0;
int c = read();
while (true) {
if (c < 0) {
......@@ -58,6 +60,34 @@ public class ScriptReader {
break;
}
switch (c) {
case '$': {
buff.append((char) c);
c = read();
if (c == '$' && SysProperties.DOLLAR_QUOTING && previous <= ' ') {
// dollar quoted string
buff.append((char) c);
while (true) {
c = read();
if (c < 0) {
break;
}
buff.append((char) c);
if (c == '$') {
c = read();
if (c < 0) {
break;
}
buff.append((char) c);
if (c == '$') {
break;
}
}
}
previous = c;
c = read();
}
break;
}
case '\'':
buff.append((char) c);
while (true) {
......@@ -70,6 +100,7 @@ public class ScriptReader {
break;
}
}
previous = c;
c = read();
break;
case '"':
......@@ -84,10 +115,12 @@ public class ScriptReader {
break;
}
}
previous = c;
c = read();
break;
case '/': {
int last = c;
previous = c;
c = read();
if (c == '*') {
// block comment
......@@ -119,6 +152,7 @@ public class ScriptReader {
}
}
}
previous = c;
c = read();
} else if (c == '/') {
// single line comment
......@@ -141,6 +175,7 @@ public class ScriptReader {
break;
}
}
previous = c;
c = read();
} else {
buff.append((char) last);
......@@ -148,6 +183,7 @@ public class ScriptReader {
break;
}
case '-': {
previous = c;
int last = c;
c = read();
if (c == '-') {
......@@ -171,16 +207,19 @@ public class ScriptReader {
break;
}
}
previous = c;
c = read();
} else {
buff.append((char) last);
}
break;
}
default:
default: {
buff.append((char) c);
previous = c;
c = read();
}
}
}
return buff.toString();
}
......
......@@ -219,13 +219,14 @@ http://www.w3schools.com/sql/
History:
Some databases could not be opened when appending
;RECOVER=1 to the database URL.
The Japanese translation of the error messages and the H2 Console has been completed
by Masahiro Ikemoto (Arizona Design Inc.)
The Japanese translation of the error messages and the H2 Console
has been completed by Masahiro Ikemoto (Arizona Design Inc.)
Updates made to updatable rows are now visible within the same result set.
DatabaseMetaData.ownUpdatesAreVisible now returns true.
ParameterMetaData now returns the correct data
for INSERT and UPDATE statements.
H2 Shell: DESCRIBE now supports an schema name.
A subset of the PostgreSQL 'dollar quoting' feature is now supported.
Roadmap:
......@@ -428,53 +429,54 @@ Roadmap:
* Run all tests with the current settings.
*/
private void test() throws Exception {
System.out.println();
System.out.println("Test big:"+big+" net:"+networked+" cipher:"+cipher+" memory:"+memory+" log:"+logMode+" diskResult:"+diskResult + " mvcc:" + mvcc + " deleteIndex:" + deleteIndex);
beforeTest();
// db
// new TestScriptSimple().runTest(this);
// new TestScript().runTest(this);
// new TestAutoRecompile().runTest(this);
// new TestBackup().runTest(this);
// new TestBigDb().runTest(this);
// new TestBigResult().runTest(this);
// new TestCases().runTest(this);
// new TestCheckpoint().runTest(this);
// new TestCluster().runTest(this);
// new TestCompatibility().runTest(this);
// new TestCsv().runTest(this);
// new TestEncryptedDb().runTest(this);
// new TestExclusive().runTest(this);
// new TestFullText().runTest(this);
// new TestFunctions().runTest(this);
// new TestIndex().runTest(this);
// new TestLinkedTable().runTest(this);
// new TestListener().runTest(this);
// new TestLob().runTest(this);
// new TestLogFile().runTest(this);
// new TestMemoryUsage().runTest(this);
// new TestMultiConn().runTest(this);
// new TestMultiDimension().runTest(this);
// new TestMultiThread().runTest(this);
// new TestOpenClose().runTest(this);
// new TestOptimizations().runTest(this);
// new TestPowerOff().runTest(this);
// new TestReadOnly().runTest(this);
// new TestRights().runTest(this);
// new TestRunscript().runTest(this);
// new TestSQLInjection().runTest(this);
// new TestSessionsLocks().runTest(this);
// new TestSequence().runTest(this);
// new TestSpaceReuse().runTest(this);
// new TestSpeed().runTest(this);
// new TestTempTables().runTest(this);
// new TestTransaction().runTest(this);
// new TestTriggersConstraints().runTest(this);
// new TestTwoPhaseCommit().runTest(this);
// new TestView().runTest(this);
//
// // jdbc
new TestScriptSimple().runTest(this);
new TestScript().runTest(this);
new TestAutoRecompile().runTest(this);
new TestBackup().runTest(this);
new TestBigDb().runTest(this);
new TestBigResult().runTest(this);
new TestCases().runTest(this);
new TestCheckpoint().runTest(this);
new TestCluster().runTest(this);
new TestCompatibility().runTest(this);
new TestCsv().runTest(this);
new TestEncryptedDb().runTest(this);
new TestExclusive().runTest(this);
new TestFullText().runTest(this);
new TestFunctions().runTest(this);
new TestIndex().runTest(this);
new TestLinkedTable().runTest(this);
new TestListener().runTest(this);
new TestLob().runTest(this);
new TestLogFile().runTest(this);
new TestMemoryUsage().runTest(this);
new TestMultiConn().runTest(this);
new TestMultiDimension().runTest(this);
new TestMultiThread().runTest(this);
new TestOpenClose().runTest(this);
new TestOptimizations().runTest(this);
new TestPowerOff().runTest(this);
new TestReadOnly().runTest(this);
new TestRights().runTest(this);
new TestRunscript().runTest(this);
new TestSQLInjection().runTest(this);
new TestSessionsLocks().runTest(this);
new TestSequence().runTest(this);
new TestSpaceReuse().runTest(this);
new TestSpeed().runTest(this);
new TestTempTables().runTest(this);
new TestTransaction().runTest(this);
new TestTriggersConstraints().runTest(this);
new TestTwoPhaseCommit().runTest(this);
new TestView().runTest(this);
// jdbc
new TestBatchUpdates().runTest(this);
new TestCallableStatement().runTest(this);
new TestCancel().runTest(this);
......@@ -489,57 +491,57 @@ Roadmap:
new TestUpdatableResultSet().runTest(this);
new TestZloty().runTest(this);
// // jdbcx
// new TestConnectionPool().runTest(this);
// new TestDataSource().runTest(this);
// new TestXA().runTest(this);
// new TestXASimple().runTest(this);
//
// // server
// new TestNestedLoop().runTest(this);
// new TestWeb().runTest(this);
// new TestPgServer().runTest(this);
//
// // mvcc
// new TestMvcc1().runTest(this);
// new TestMvcc2().runTest(this);
// new TestMvcc3().runTest(this);
//
// // synth
// new TestCrashAPI().runTest(this);
// new TestRandomSQL().runTest(this);
// new TestKillRestart().runTest(this);
// new TestKillRestartMulti().runTest(this);
//
// // unit
// new TestBitField().runTest(this);
// new TestCache().runTest(this);
// new TestCompress().runTest(this);
// new TestDataPage().runTest(this);
// new TestDate().runTest(this);
// new TestExit().runTest(this);
// new TestFile().runTest(this);
// new TestFileLock().runTest(this);
// new TestFtp().runTest(this);
// new TestFileSystem().runTest(this);
// new TestIntArray().runTest(this);
// new TestIntIntHashMap().runTest(this);
// new TestMultiThreadedKernel().runTest(this);
// new TestOverflow().runTest(this);
// new TestPattern().runTest(this);
// new TestReader().runTest(this);
// new TestRecovery().runTest(this);
// new TestSampleApps().runTest(this);
// new TestScriptReader().runTest(this);
// runTest("org.h2.test.unit.TestServlet");
// new TestSecurity().runTest(this);
// new TestStreams().runTest(this);
// new TestStringCache().runTest(this);
// new TestStringUtils().runTest(this);
// new TestTools().runTest(this);
// new TestValue().runTest(this);
// new TestValueHashMap().runTest(this);
// new TestValueMemory().runTest(this);
// jdbcx
new TestConnectionPool().runTest(this);
new TestDataSource().runTest(this);
new TestXA().runTest(this);
new TestXASimple().runTest(this);
// server
new TestNestedLoop().runTest(this);
new TestWeb().runTest(this);
new TestPgServer().runTest(this);
// mvcc
new TestMvcc1().runTest(this);
new TestMvcc2().runTest(this);
new TestMvcc3().runTest(this);
// synth
new TestCrashAPI().runTest(this);
new TestRandomSQL().runTest(this);
new TestKillRestart().runTest(this);
new TestKillRestartMulti().runTest(this);
// unit
new TestBitField().runTest(this);
new TestCache().runTest(this);
new TestCompress().runTest(this);
new TestDataPage().runTest(this);
new TestDate().runTest(this);
new TestExit().runTest(this);
new TestFile().runTest(this);
new TestFileLock().runTest(this);
new TestFtp().runTest(this);
new TestFileSystem().runTest(this);
new TestIntArray().runTest(this);
new TestIntIntHashMap().runTest(this);
new TestMultiThreadedKernel().runTest(this);
new TestOverflow().runTest(this);
new TestPattern().runTest(this);
new TestReader().runTest(this);
new TestRecovery().runTest(this);
new TestSampleApps().runTest(this);
new TestScriptReader().runTest(this);
runTest("org.h2.test.unit.TestServlet");
new TestSecurity().runTest(this);
new TestStreams().runTest(this);
new TestStringCache().runTest(this);
new TestStringUtils().runTest(this);
new TestTools().runTest(this);
new TestValue().runTest(this);
new TestValueHashMap().runTest(this);
new TestValueMemory().runTest(this);
afterTest();
}
......
......@@ -570,8 +570,12 @@ public abstract class TestBase {
}
protected void checkNotGeneralException(SQLException e) throws Exception {
checkNotGeneralException("", e);
}
protected void checkNotGeneralException(String message, SQLException e) throws Exception {
if (e != null && e.getSQLState().startsWith("HY000")) {
TestBase.logError("Unexpected General error", e);
TestBase.logError("Unexpected General error " + message, e);
}
}
......
......@@ -36,6 +36,24 @@ public class TestSQLInjection extends TestBase {
check(checkPasswordSecure("123456"));
checkFalse(checkPasswordSecure("abcdef"));
checkFalse(checkPasswordSecure("' OR ''='"));
stat.execute("CALL 123");
stat.execute("CALL 'Hello'");
stat.execute("CALL $$Hello World$$");
stat.execute("SET ALLOW_LITERALS NUMBERS");
stat.execute("CALL 123");
try {
stat.execute("CALL 'Hello'");
error();
} catch (SQLException e) {
checkNotGeneralException(e);
}
try {
stat.execute("CALL $$Hello World$$");
error();
} catch (SQLException e) {
checkNotGeneralException(e);
}
stat.execute("SET ALLOW_LITERALS NONE");
try {
......
......@@ -7,8 +7,10 @@
package org.h2.test.jdbc;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Random;
import org.h2.test.TestBase;
......@@ -16,14 +18,157 @@ import org.h2.test.TestBase;
* Tests the Connection.nativeSQL method.
*/
public class TestNativeSQL extends TestBase {
Connection conn;
public void test() throws Exception {
deleteDb("nativeSql");
Connection conn = getConnection("nativeSql");
conn = getConnection("nativeSql");
testPairs();
testCases();
testRandom();
testQuotes();
conn.close();
check(conn.isClosed());
}
private void testQuotes() throws Exception {
Statement stat = conn.createStatement();
Random random = new Random(1);
String s = "'\"$/-* \n";
for (int i = 0; i < 200; i++) {
StringBuffer buffQuoted = new StringBuffer();
StringBuffer buffRaw = new StringBuffer();
if (random.nextBoolean()) {
buffQuoted.append("'");
for (int j = 0; j < 10; j++) {
char c = s.charAt(random.nextInt(s.length()));
if (c == '\'') {
buffQuoted.append('\'');
}
buffQuoted.append(c);
buffRaw.append(c);
}
buffQuoted.append("'");
} else {
buffQuoted.append("$$");
for (int j = 0; j < 10; j++) {
char c = s.charAt(random.nextInt(s.length()));
buffQuoted.append(c);
buffRaw.append(c);
if (c == '$') {
buffQuoted.append(' ');
buffRaw.append(' ');
}
}
buffQuoted.append("$$");
}
String sql = "CALL " + buffQuoted.toString();
ResultSet rs = stat.executeQuery(sql);
rs.next();
String raw = buffRaw.toString();
check(raw, rs.getString(1));
}
}
private void testRandom() throws Exception {
Random random = new Random(1);
for (int i = 0; i < 100; i++) {
StringBuffer buff = new StringBuffer("{oj }");
String s = "{}\'\"-/*$ $-";
for (int j = random.nextInt(30); j > 0; j--) {
buff.append(s.charAt(random.nextInt(s.length())));
}
String sql = buff.toString();
try {
conn.nativeSQL(sql);
} catch (SQLException e) {
checkNotGeneralException(sql, e);
}
}
String smallest = null;
for (int i = 0; i < 1000; i++) {
StringBuffer buff = new StringBuffer("{oj }");
for (int j = random.nextInt(10); j > 0; j--) {
String s;
switch(random.nextInt(7)) {
case 0:
buff.append(" $$");
s = "{}\'\"-/* a\n";
for (int k = random.nextInt(5); k > 0; k--) {
buff.append(s.charAt(random.nextInt(s.length())));
}
buff.append("$$");
break;
case 1:
buff.append("'");
s = "{}\"-/*$ a\n";
for (int k = random.nextInt(5); k > 0; k--) {
buff.append(s.charAt(random.nextInt(s.length())));
}
buff.append("'");
break;
case 2:
buff.append("\"");
s = "{}'-/*$ a\n";
for (int k = random.nextInt(5); k > 0; k--) {
buff.append(s.charAt(random.nextInt(s.length())));
}
buff.append("\"");
break;
case 3:
buff.append("/*");
s = "{}'\"-/$ a\n";
for (int k = random.nextInt(5); k > 0; k--) {
buff.append(s.charAt(random.nextInt(s.length())));
}
buff.append("*/");
break;
case 4:
buff.append("--");
s = "{}'\"-/$ a";
for (int k = random.nextInt(5); k > 0; k--) {
buff.append(s.charAt(random.nextInt(s.length())));
}
buff.append("\n");
break;
case 5:
buff.append("//");
s = "{}'\"-/$ a";
for (int k = random.nextInt(5); k > 0; k--) {
buff.append(s.charAt(random.nextInt(s.length())));
}
buff.append("\n");
break;
case 6:
s = " a\n";
for (int k = random.nextInt(5); k > 0; k--) {
buff.append(s.charAt(random.nextInt(s.length())));
}
break;
}
}
String sql = buff.toString();
try {
conn.nativeSQL(sql);
} catch (Exception e) {
if (smallest == null || sql.length() < smallest.length()) {
smallest = sql;
}
}
}
if (smallest != null) {
conn.nativeSQL(smallest);
}
}
private void testPairs() throws Exception {
for (int i = 0; i < PAIRS.length; i += 2) {
test(conn, PAIRS[i], PAIRS[i + 1]);
}
}
private void testCases() throws Exception {
conn.nativeSQL("TEST");
conn.nativeSQL("TEST--testing");
conn.nativeSQL("TEST--testing{oj }");
......@@ -49,15 +194,13 @@ public class TestNativeSQL extends TestBase {
checkNotGeneralException(e);
}
checkFalse(conn.isClosed());
conn.close();
check(conn.isClosed());
}
static final String[] PAIRS = new String[] { "CREATE TABLE TEST(ID INT PRIMARY KEY)",
static final String[] PAIRS = new String[] {
"CREATE TABLE TEST(ID INT PRIMARY KEY)",
"CREATE TABLE TEST(ID INT PRIMARY KEY)",
"INSERT INTO TEST VALUES(1)", "INSERT INTO TEST VALUES(1)",
"SELECT '{nothing}' FROM TEST", "SELECT '{nothing}' FROM TEST",
"SELECT '{fn ABS(1)}' FROM TEST", "SELECT '{fn ABS(1)}' FROM TEST",
......
......@@ -58,7 +58,7 @@ public class TestScriptReader extends TestBase {
switch (random.nextInt(10)) {
case 0: {
int l = random.nextInt(4);
String[] ch = new String[] { "\n", "\r", " ", "*", "a", "0" };
String[] ch = new String[] { "\n", "\r", " ", "*", "a", "0", "$ " };
for (int j = 0; j < l; j++) {
buff.append(ch[random.nextInt(ch.length)]);
}
......@@ -67,7 +67,7 @@ public class TestScriptReader extends TestBase {
case 1: {
buff.append('\'');
int l = random.nextInt(4);
String[] ch = new String[] { ";", "\n", "\r", "--", "//", "/", "-", "*", "/*", "*/", "\"" };
String[] ch = new String[] { ";", "\n", "\r", "--", "//", "/", "-", "*", "/*", "*/", "\"", "$ " };
for (int j = 0; j < l; j++) {
buff.append(ch[random.nextInt(ch.length)]);
}
......@@ -77,7 +77,7 @@ public class TestScriptReader extends TestBase {
case 2: {
buff.append('"');
int l = random.nextInt(4);
String[] ch = new String[] { ";", "\n", "\r", "--", "//", "/", "-", "*", "/*", "*/", "\'" };
String[] ch = new String[] { ";", "\n", "\r", "--", "//", "/", "-", "*", "/*", "*/", "\'", "$" };
for (int j = 0; j < l; j++) {
buff.append(ch[random.nextInt(ch.length)]);
}
......@@ -87,14 +87,14 @@ public class TestScriptReader extends TestBase {
case 3: {
buff.append('-');
if (random.nextBoolean()) {
String[] ch = new String[] { "\n", "\r", "*", "a", " " };
String[] ch = new String[] { "\n", "\r", "*", "a", " ", "$ " };
int l = 1 + random.nextInt(4);
for (int j = 0; j < l; j++) {
buff.append(ch[random.nextInt(ch.length)]);
}
} else {
buff.append('-');
String[] ch = new String[] { ";", "-", "//", "/*", "*/", "a" };
String[] ch = new String[] { ";", "-", "//", "/*", "*/", "a", "$" };
int l = random.nextInt(4);
for (int j = 0; j < l; j++) {
buff.append(ch[random.nextInt(ch.length)]);
......@@ -106,14 +106,14 @@ public class TestScriptReader extends TestBase {
case 4: {
buff.append('/');
if (random.nextBoolean()) {
String[] ch = new String[] { "\n", "\r", "a", " ", "- " };
String[] ch = new String[] { "\n", "\r", "a", " ", "- ", "$ " };
int l = 1 + random.nextInt(4);
for (int j = 0; j < l; j++) {
buff.append(ch[random.nextInt(ch.length)]);
}
} else {
buff.append('*');
String[] ch = new String[] { ";", "-", "//", "/* ", "--", "\n", "\r", "a" };
String[] ch = new String[] { ";", "-", "//", "/* ", "--", "\n", "\r", "a", "$" };
int l = random.nextInt(4);
for (int j = 0; j < l; j++) {
buff.append(ch[random.nextInt(ch.length)]);
......@@ -122,6 +122,27 @@ public class TestScriptReader extends TestBase {
}
break;
}
case 5: {
if (buff.length() > 0) {
buff.append(" ");
}
buff.append("$");
if (random.nextBoolean()) {
String[] ch = new String[] { "\n", "\r", "a", " ", "- ", "/ " };
int l = 1 + random.nextInt(4);
for (int j = 0; j < l; j++) {
buff.append(ch[random.nextInt(ch.length)]);
}
} else {
buff.append("$");
String[] ch = new String[] { ";", "-", "//", "/* ", "--", "\n", "\r", "a", "$ " };
int l = random.nextInt(4);
for (int j = 0; j < l; j++) {
buff.append(ch[random.nextInt(ch.length)]);
}
buff.append("$$");
}
}
}
}
return buff.toString();
......@@ -139,6 +160,11 @@ public class TestScriptReader extends TestBase {
check(source.readStatement(), "//;\na");
check(source.readStatement(), null);
source.close();
s = "/\n$ \n\n $';$$a$$ $\n;'";
source = new ScriptReader(new StringReader(s));
check(source.readStatement(), "/\n$ \n\n $';$$a$$ $\n;'");
check(source.readStatement(), null);
source.close();
}
}
......@@ -507,4 +507,5 @@ originator brought contribution effectively assumes waives conjunction
informs negotiations collectively omissions trial nor qualify steward neither
worldwide everyone additions expense lawsuit checksums jazoon flashback
dieguez dfile mvn dversion dgroup dpackaging dartifact durl dpom pom
subpackages slowed deactivate throttled noindex expired
subpackages slowed deactivate throttled noindex expired arizona export
intentional knowing
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论