提交 aaba8d61 authored 作者: Thomas Mueller's avatar Thomas Mueller

--no commit message

--no commit message
上级 624fa6ba
......@@ -637,7 +637,7 @@ SQLインジェクションとは
このデータベースは、ユーザー入力をデータベースに通す時、パラメータの使用を強制する方法を提供しています。 SQLステートメントの組み込まれたリテラルを無効にすることでこれを実行します。 次のステートメントを実行します:
@advanced_1212_p
その後、文字列リテラルや数値リテラルのSQLステートメントはもう認められません。これは、 WHERE NAME='abc' や WHERE CustomerId=10 といった形のSQLステートメントは失敗するという意味です。 PreparedStatementや上に記載されたパラメータは使用することができます。また、 リテラルの含まれないSQLステートメントと同様に、SQLステートメントを動的に生成したり、 APIステートメントを使用することも可能です。数値リテラルが許可されている二つ目のモードもあります: SET ALLOW_LITERALS NUMBERS 全てのリテラルを許可するには、 SET ALLOW_LITERALS ALL を実行します (これはデフォルトの設定です)。リテラルはadministratorのみによって使用可能、または使用不可になります。
#Afterwards, SQL statements with text and number literals are not allowed any more. That means, SQL statement of the form WHERE NAME='abc' or WHERE CustomerId=10 will fail. It is still possible to use PreparedStatements and parameters as described above. Also, it is still possible to generate SQL statements dynamically, and use the Statement API, as long as the SQL statements do not include literals. There is also a second mode where number literals are allowed: SET ALLOW_LITERALS NUMBERS. To allow all literals, execute SET ALLOW_LITERALS ALL (this is the default setting). Literals can only be enabled or disabled by an administrator.
@advanced_1213_h3
定数を使用する
......@@ -4846,7 +4846,7 @@ H2DRIVERSかCLASSPATHの環境変数に、ドライバのJarファイルの位
JDBCを使用してデータベースに接続
@tutorial_1065_p
データベースに接続するためにJavaアプリケーションに最初に必要なことは、 データベースドライバをロードし、接続することです。簡単な方法は、次のコードを使用します:
#To connect to a database, a Java application first needs to load the database driver, and then get a connection. A simple way to do that is using the following code:
@tutorial_1066_p
このコードは最初にドライバをロードして (Class.forName())、 接続を開始します (DriverManager.getConnection())。 このドライバの名前は全てのケースにおいて "org.h2.Driver" です。 データベースに認識されるため、データベースのURLは常に jdbc:h2: から始まります。 getConnection() 内の2番目のパラメーターはユーザ名を指しています ('sa' はこの場合、システム管理者を表しています)。3番目のパラメーターはパスワードです。このデータベースでは、ユーザ名は大文字と小文字を区別していませんが、パスワードは大文字と小文字を区別しています。
......
......@@ -829,9 +829,10 @@ public class Parser {
private TableFilter readTableFilter(boolean fromOuter) throws SQLException {
Table table;
String alias = null;
Schema mainSchema = database.getSchema(Constants.SCHEMA_MAIN);
if (readIf("(")) {
if (isToken("SELECT") || isToken("FROM")) {
if (isToken("SELECT") || isToken("FROM") || isToken("(")) {
Query query = parseSelect();
Session s;
if (prepared != null && prepared instanceof CreateView) {
......@@ -840,6 +841,7 @@ public class Parser {
s = session;
}
table = TableView.createTempView(s, session.getUser(), query);
alias = table.getName();
read(")");
} else {
TableFilter top = readTableFilter(fromOuter);
......@@ -869,7 +871,6 @@ public class Parser {
table = readTableOrView(tableName);
}
}
String alias = null;
if (readIf("AS")) {
alias = readAliasIdentifier();
} else if (currentTokenType == IDENTIFIER) {
......@@ -1196,9 +1197,7 @@ public class Parser {
ExplainPlan command = new ExplainPlan(session);
readIf("PLAN");
readIf("FOR");
if (isToken("SELECT") || isToken("FROM")) {
command.setCommand(parseSelect());
} else if (isToken("(")) {
if (isToken("SELECT") || isToken("FROM") || isToken("(")) {
command.setCommand(parseSelect());
} else if (readIf("DELETE")) {
command.setCommand(parseDelete());
......
......@@ -200,6 +200,7 @@ public class SessionRemote implements SessionInterface, DataHandler {
transferList = new ObjectArray();
// TODO cluster: support at most 2 connections
boolean switchOffCluster = false;
try {
for (int i = 0; i < len; i++) {
try {
Transfer trans = initTransfer(ci, databaseName, servers[i]);
......@@ -213,6 +214,10 @@ public class SessionRemote implements SessionInterface, DataHandler {
switchOffCluster();
}
switchOffAutoCommitIfCluster();
} catch (SQLException e) {
traceSystem.close();
throw e;
}
}
private void switchOffCluster() throws SQLException {
......
......@@ -47,8 +47,8 @@ implements Trigger
//#ifdef JDK14
private static HashMap indexers = new HashMap();
private static final String FIELD_DATA = "data";
private static final String FIELD_QUERY = "query";
private static final String FIELD_DATA = "DATA";
private static final String FIELD_QUERY = "QUERY";
private static final String FIELD_COLUMN_PREFIX = "_";
private static final String TRIGGER_PREFIX = "FTL_";
private static final String SCHEMA = "FTL";
......@@ -494,7 +494,6 @@ implements Trigger
}
}
private static IndexModifier getIndexModifier(Connection conn) throws SQLException {
try {
String path = getIndexPath(conn);
......
......@@ -5,7 +5,7 @@
package org.h2.fulltext;
public class IndexInfo {
long id;
int id;
String schemaName;
String tableName;
int[] keys;
......
......@@ -230,10 +230,17 @@ public class TraceSystem {
try {
fileWriter.close();
} catch (IOException e) {
// ignore exception
// ignore
}
fileWriter = null;
}
try {
if (fileName != null && FileUtils.length(fileName) == 0) {
FileUtils.delete(fileName);
}
} catch (SQLException e) {
// ignore
}
}
public void close() {
......
......@@ -9,6 +9,7 @@ import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.sql.SQLException;
......@@ -171,20 +172,7 @@ public class FtpControl extends Thread {
break;
case 'M':
if ("MKD".equals(command)) {
String fileName = getFileName(param);
boolean ok = false;
if (!readonly) {
try {
fs.mkdirs(fileName);
reply(257, StringUtils.quoteIdentifier(param) + " directory");
ok = true;
} catch (SQLException e) {
server.logError(e);
}
}
if (!ok) {
reply(500, "Failed");
}
processMakeDir(param);
} else if ("MODE".equals(command)) {
if ("S".equals(StringUtils.toUpperEnglish(param))) {
reply(200, "Ok");
......@@ -216,6 +204,18 @@ public class FtpControl extends Thread {
data.start();
int port = dataSocket.getLocalPort();
reply(227, "Passive Mode (" + serverIpAddress + "," + (port >> 8) + "," + (port & 255) + ")");
} else if ("PORT".equals(command)) {
String[] list = StringUtils.arraySplit(param, ',', true);
String host = list[0] + "." + list[1] + "." + list[2] + "." + list[3];
int port = (Integer.parseInt(list[4]) << 8) | Integer.parseInt(list[5]);
InetAddress address = InetAddress.getByName(host);
if (address.equals(control.getInetAddress())) {
data = new FtpData(server, address, port);
reply(200, "Ok");
} else {
server.log("Port REJECTED:" + address + " expected:" + control.getInetAddress());
reply(550, "Failed");
}
}
break;
case 'R':
......@@ -260,16 +260,12 @@ public class FtpControl extends Thread {
}
restart = 0;
} else {
processList(param, true); // Firefox compatibility (still not good)
processList(param, true); // Firefox compatibility (still
// not good)
// reply(426, "Not a file");
}
} else if ("RMD".equals(command)) {
String fileName = getFileName(param);
if (!readonly && fs.exists(fileName) && fs.isDirectory(fileName) && fs.tryDelete(fileName)) {
reply(250, "Ok");
} else {
reply(500, "Failed");
}
processRemoveDir(param);
} else if ("REST".equals(command)) {
try {
restart = Integer.parseInt(param);
......@@ -328,11 +324,43 @@ public class FtpControl extends Thread {
}
}
break;
case 'X':
if ("XMKD".equals(command)) {
processMakeDir(param);
} else if ("XRMD".equals(command)) {
processRemoveDir(param);
}
default:
break;
}
}
void processMakeDir(String param) throws IOException {
String fileName = getFileName(param);
boolean ok = false;
if (!readonly) {
try {
fs.mkdirs(fileName);
reply(257, StringUtils.quoteIdentifier(param) + " directory");
ok = true;
} catch (SQLException e) {
server.logError(e);
}
}
if (!ok) {
reply(500, "Failed");
}
}
void processRemoveDir(String param) throws IOException {
String fileName = getFileName(param);
if (!readonly && fs.exists(fileName) && fs.isDirectory(fileName) && fs.tryDelete(fileName)) {
reply(250, "Ok");
} else {
reply(500, "Failed");
}
}
private String getFileName(String file) {
return server.getFileName(file.startsWith("/") ? file : currentDir + file);
}
......@@ -353,7 +381,8 @@ public class FtpControl extends Thread {
String list = server.getDirectoryListing(directory, directories);
reply(150, "Starting transfer");
server.log(list);
// need to use the current locale (UTF-8 would be wrong for the Windows Explorer)
// need to use the current locale (UTF-8 would be wrong for the Windows
// Explorer)
data.send(list.getBytes());
reply(226, "Done");
}
......
......@@ -21,6 +21,8 @@ public class FtpData extends Thread {
private InetAddress address;
private ServerSocket serverSocket;
private volatile Socket socket;
private boolean active;
private int port;
public FtpData(FtpServer server, InetAddress address, ServerSocket serverSocket) throws IOException {
this.server = server;
......@@ -28,6 +30,13 @@ public class FtpData extends Thread {
this.serverSocket = serverSocket;
}
public FtpData(FtpServer server, InetAddress address, int port) throws IOException {
this.server = server;
this.address = address;
this.port = port;
active = true;
}
public void run() {
try {
synchronized (this) {
......@@ -46,6 +55,14 @@ public class FtpData extends Thread {
}
}
private void connect() throws IOException {
if (active) {
socket = new Socket(address, port);
} else {
waitUntilConnected();
}
}
private void waitUntilConnected() {
while (serverSocket != null && socket == null) {
try {
......@@ -63,7 +80,7 @@ public class FtpData extends Thread {
}
public synchronized void receive(FileSystem fs, String fileName) throws IOException, SQLException {
waitUntilConnected();
connect();
try {
InputStream in = socket.getInputStream();
OutputStream out = fs.openFileOutputStream(fileName, false);
......@@ -76,7 +93,7 @@ public class FtpData extends Thread {
}
public synchronized void send(FileSystem fs, String fileName, long skip) throws IOException {
waitUntilConnected();
connect();
try {
OutputStream out = socket.getOutputStream();
InputStream in = fs.openFileInputStream(fileName);
......@@ -90,7 +107,7 @@ public class FtpData extends Thread {
}
public synchronized void send(byte[] data) throws IOException {
waitUntilConnected();
connect();
try {
OutputStream out = socket.getOutputStream();
out.write(data);
......
......@@ -25,7 +25,7 @@ SELECT * FROM FT_SEARCH('World', 0, 0);
SELECT * FROM FT_SEARCH('World', 1, 0);
SELECT * FROM FT_SEARCH('World', 0, 2);
SELECT * FROM FT_SEARCH('World', 2, 1);
SELECT * FROM FT_SEARCH('1');
SELECT * FROM FT_SEARCH('1', 0, 0);
CALL FT_DROP_ALL();
SELECT * FROM FT_SEARCH('World', 2, 1);
CALL FT_DROP_ALL();
......
......@@ -150,37 +150,12 @@ java org.h2.test.TestAll timer
/*
create table test(id int, name varchar);
insert into test select x, '' from system_range(1, 10000);
-- fast
update test set name = 'y' where cast(id as varchar) like '1%';
-- slow
update test set name = 'x' where id in (select x from system_range(1, 10000) where cast(x as varchar) like '1%');
drop table test;
Optimize IN(...), IN(select), ID=? OR ID=?: create temp table and use join
Bug:
H2 1.0.62 (2007-11-25) has regressed on this query. Parser syntax error is returned (query is OK for derby, oracle, and earlier H2 versions).
SELECT COUNT(*) FROM (
SELECT TT.id,TT.table_name FROM (
SELECT DISTINCT id, table_name FROM information_schema.tables WHERE id=-8 UNION SELECT DISTINCT id, table_name FROM information_schema.tables WHERE id=-8) AS TT
) AS AWR WHERE AWR.id=-8
Remove the final predicate and the query parses & runs fine:
SELECT COUNT(*) FROM (
SELECT TT.id,TT.table_name FROM (
SELECT DISTINCT id, table_name FROM information_schema.tables WHERE id=-8 UNION SELECT DISTINCT id, table_name FROM information_schema.tables WHERE id=-8) AS TT
) AS AWR
toString: > the parameters for the prepared statements.
autocomplete only just after meaningful key (ctrl+space, space, bs, interpunctation, ...)
write more tests for the command line tools
avoid creating thousands of trace.db files
Known Problems:
link to history page, bug page
Add a link to the google code bug page
......
......@@ -16,39 +16,53 @@ public class TestFullText extends TestBase {
if (config.memory) {
return;
}
test(false);
String luceneFullTextClassName = "org.h2.fulltext.FullTextLucene";
try {
Class.forName(luceneFullTextClassName);
test(true);
} catch (ClassNotFoundException e) {
this.println("Class not found, not tested: " + luceneFullTextClassName);
// ok
}
}
private void test(boolean lucene) throws Exception {
deleteDb("fullText");
Connection conn = getConnection("fullText");
String prefix = lucene ? "FTL_" : "FT_";
Statement stat = conn.createStatement();
stat.execute("CREATE ALIAS IF NOT EXISTS FT_INIT FOR \"org.h2.fulltext.FullText.init\"");
stat.execute("CALL FT_INIT()");
String className = lucene ? "FullTextLucene" : "FullText";
stat.execute("CREATE ALIAS IF NOT EXISTS " + prefix + "INIT FOR \"org.h2.fulltext." + className + ".init\"");
stat.execute("CALL " + prefix + "INIT()");
stat.execute("DROP TABLE IF EXISTS TEST");
stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR)");
stat.execute("INSERT INTO TEST VALUES(1, 'Hello World')");
stat.execute("CALL FT_CREATE_INDEX('PUBLIC', 'TEST', NULL)");
stat.execute("CALL " + prefix + "CREATE_INDEX('PUBLIC', 'TEST', NULL)");
ResultSet rs;
rs = stat.executeQuery("SELECT * FROM FT_SEARCH('Hello', 0, 0)");
rs = stat.executeQuery("SELECT * FROM " + prefix + "SEARCH('Hello', 0, 0)");
rs.next();
check(rs.getString(1), "\"PUBLIC\".\"TEST\" WHERE \"ID\"=1");
checkFalse(rs.next());
rs = stat.executeQuery("SELECT * FROM FT_SEARCH('Hallo', 0, 0)");
rs = stat.executeQuery("SELECT * FROM " + prefix + "SEARCH('Hallo', 0, 0)");
checkFalse(rs.next());
stat.execute("INSERT INTO TEST VALUES(2, 'Hallo Welt')");
rs = stat.executeQuery("SELECT * FROM FT_SEARCH('Hello', 0, 0)");
rs = stat.executeQuery("SELECT * FROM " + prefix + "SEARCH('Hello', 0, 0)");
rs.next();
check(rs.getString(1), "\"PUBLIC\".\"TEST\" WHERE \"ID\"=1");
checkFalse(rs.next());
rs = stat.executeQuery("SELECT * FROM FT_SEARCH('Hallo', 0, 0)");
rs = stat.executeQuery("SELECT * FROM " + prefix + "SEARCH('Hallo', 0, 0)");
rs.next();
check(rs.getString(1), "\"PUBLIC\".\"TEST\" WHERE \"ID\"=2");
checkFalse(rs.next());
stat.execute("CALL FT_REINDEX()");
rs = stat.executeQuery("SELECT * FROM FT_SEARCH('Hello', 0, 0)");
stat.execute("CALL " + prefix + "REINDEX()");
rs = stat.executeQuery("SELECT * FROM " + prefix + "SEARCH('Hello', 0, 0)");
rs.next();
check(rs.getString(1), "\"PUBLIC\".\"TEST\" WHERE \"ID\"=1");
checkFalse(rs.next());
rs = stat.executeQuery("SELECT * FROM FT_SEARCH('Hallo', 0, 0)");
rs = stat.executeQuery("SELECT * FROM " + prefix + "SEARCH('Hallo', 0, 0)");
rs.next();
check(rs.getString(1), "\"PUBLIC\".\"TEST\" WHERE \"ID\"=2");
checkFalse(rs.next());
......@@ -57,45 +71,51 @@ public class TestFullText extends TestBase {
stat.execute("INSERT INTO TEST VALUES(4, 'Hello World')");
stat.execute("INSERT INTO TEST VALUES(5, 'Hello World')");
rs = stat.executeQuery("SELECT * FROM FT_SEARCH('World', 0, 0)");
rs.next();
check(rs.getString(1), "\"PUBLIC\".\"TEST\" WHERE \"ID\"=4");
rs = stat.executeQuery("SELECT * FROM " + prefix + "SEARCH('World', 0, 0) ORDER BY QUERY");
rs.next();
check(rs.getString(1), "\"PUBLIC\".\"TEST\" WHERE \"ID\"=1");
rs.next();
check(rs.getString(1), "\"PUBLIC\".\"TEST\" WHERE \"ID\"=5");
rs.next();
check(rs.getString(1), "\"PUBLIC\".\"TEST\" WHERE \"ID\"=3");
rs.next();
check(rs.getString(1), "\"PUBLIC\".\"TEST\" WHERE \"ID\"=4");
rs.next();
check(rs.getString(1), "\"PUBLIC\".\"TEST\" WHERE \"ID\"=5");
checkFalse(rs.next());
rs = stat.executeQuery("SELECT * FROM FT_SEARCH('World', 1, 0)");
rs = stat.executeQuery("SELECT * FROM " + prefix + "SEARCH('World', 1, 0)");
rs.next();
check(rs.getString(1), "\"PUBLIC\".\"TEST\" WHERE \"ID\"=4");
check(rs.getString(1).startsWith("\"PUBLIC\".\"TEST\" WHERE \"ID\"="));
checkFalse(rs.next());
rs = stat.executeQuery("SELECT * FROM FT_SEARCH('World', 0, 2)");
rs = stat.executeQuery("SELECT * FROM " + prefix + "SEARCH('World', 0, 2) ORDER BY QUERY");
rs.next();
check(rs.getString(1), "\"PUBLIC\".\"TEST\" WHERE \"ID\"=5");
check(rs.getString(1).startsWith("\"PUBLIC\".\"TEST\" WHERE \"ID\"="));
rs.next();
check(rs.getString(1), "\"PUBLIC\".\"TEST\" WHERE \"ID\"=3");
check(rs.getString(1).startsWith("\"PUBLIC\".\"TEST\" WHERE \"ID\"="));
checkFalse(rs.next());
rs = stat.executeQuery("SELECT * FROM FT_SEARCH('World', 2, 1)");
rs = stat.executeQuery("SELECT * FROM " + prefix + "SEARCH('World', 2, 1) ORDER BY QUERY");
rs.next();
check(rs.getString(1), "\"PUBLIC\".\"TEST\" WHERE \"ID\"=1");
check(rs.getString(1).startsWith("\"PUBLIC\".\"TEST\" WHERE \"ID\"="));
rs.next();
check(rs.getString(1), "\"PUBLIC\".\"TEST\" WHERE \"ID\"=5");
check(rs.getString(1).startsWith("\"PUBLIC\".\"TEST\" WHERE \"ID\"="));
checkFalse(rs.next());
rs = stat.executeQuery("SELECT * FROM FT_SEARCH('1', 0, 0)");
rs = stat.executeQuery("SELECT * FROM " + prefix + "SEARCH('1', 0, 0)");
rs.next();
check(rs.getString(1), "\"PUBLIC\".\"TEST\" WHERE \"ID\"=1");
checkFalse(rs.next());
conn.close();
stat.execute("CALL FT_DROP_ALL()");
rs = stat.executeQuery("SELECT * FROM FT_SEARCH('World', 2, 1)");
stat.execute("CALL FT_DROP_ALL()");
conn = getConnection("fullText");
stat = conn.createStatement();
rs = stat.executeQuery("SELECT * FROM " + prefix + "SEARCH('World', 0, 0)");
stat.execute("CALL " + prefix + "DROP_ALL()");
rs = stat.executeQuery("SELECT * FROM " + prefix + "SEARCH('World', 2, 1)");
stat.execute("CALL " + prefix + "DROP_ALL()");
conn.close();
}
}
select count(*) from (select * from dual union select * from dual) where x = 0;
> 0;
select count(*) from (select * from (select * from dual union select * from dual)) where x = 0;
> 0;
select instr('abcisj','s', -1) from dual;
> 5;
CREATE TABLE TEST(ID INT);
......
......@@ -565,16 +565,13 @@ public class PrepareTranslation {
}
/**
* Translate the text using Google
* Translate the text using Google Translate
*/
String translate(String text, String sourceLanguage, String targetLanguage) throws Exception {
Thread.sleep(4000);
String url = "http://translate.google.com/translate_t?langpair=" + sourceLanguage + "|" + targetLanguage + "&text="
+ URLEncoder.encode(text, "UTF-8");
HttpURLConnection conn = (HttpURLConnection) (new URL(url)).openConnection();
// conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)");
int todoTest;
// conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.10) Gecko/20071115 Firefox/2.0.0.10");
conn.setRequestProperty("User-Agent", "Mozilla/5.0 (compatible; Java)");
String result = IOUtils.readStringAndClose(IOUtils.getReader(conn.getInputStream()), -1);
int start = result.indexOf("<div id=result_box");
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论