提交 28d40220 authored 作者: Thomas Mueller's avatar Thomas Mueller

--no commit message

--no commit message
上级 26d3dd03
......@@ -335,6 +335,31 @@
</target>
<target name="zip">
<delete includeemptydirs="true">
<fileset dir="dist" includes="**/*"/>
</delete>
<copy todir="dist">
<fileset dir=".." includes="h2/build.xml"/>
<fileset dir=".." includes="h2/ant-build.properties"/>
<fileset dir=".." includes="h2/bin/**/*"/>
<fileset dir=".." includes="h2/docs/**/*"/>
<fileset dir=".." includes="h2/service/**/*"/>
<fileset dir=".." includes="h2/src/**/*"/>
</copy>
<tar destfile="../h2.tar">
<fileset dir="dist" includes="**/*.java,**/*.css,**/*.js" />
<fileset dir="dist" includes="**/*.xml" />
<fileset dir="dist" includes="**/*.html,**/*.jsp" />
<fileset dir="dist" includes="**/*.csv,**/*.txt,**/*.properties" />
<fileset dir="dist" includes="**/*.sql,**/*.bat" />
<fileset dir="dist" excludes="**/*.java,,**/*.css,**/*.js,**/*.xml,**/*.html,**/*.jsp,**/*.csv,**/*.txt,**/*.properties,**/*.sql,**/*.bat" />
</tar>
<bzip2 destfile="../h2.tar.bz2" src="../h2.tar" />
<zip destfile="../h2.zip">
<fileset dir=".." includes="h2/build.xml"/>
<fileset dir=".." includes="h2/ant-build.properties"/>
......
......@@ -924,6 +924,19 @@ File encryption slows down the performance of the database engine. Compared to u
database operations take about 2.2 times longer when using XTEA, and 2.5 times longer using AES (embedded mode).
</p>
<h3>Wrong Password Delay</h3>
<p>
To protect against remote brute force password attacks, the delay after each unsuccessful
login gets double as long. Use the system properties h2.delayWrongPasswordMin
and h2.delayWrongPasswordMax to change the minimum (the default is 250 milliseconds)
or maximum delay (the default is 4000 milliseconds, or 4 seconds). The delay only
applies for those using the wrong password. Normally there is no delay for a user that knows the correct
password, with one exception: after using the wrong password, there is a delay of up (randomly distributed)
the same delay as for a wrong password. This is to protect against parallel brute force attacks,
so that an attacker needs to wait for the whole delay. Delays are synchronized. This is also required
to protect against parallel attacks.
</p>
<h3>SSL/TLS Connections</h3>
<p>
Remote SSL/TLS connections are supported using the Java Secure Socket Extension
......
......@@ -28,6 +28,9 @@ SQL Grammar
<c:forEach var="item" items="otherGrammar">
<a href="#${item.link}">${item.topic}</a><br />
</c:forEach>
<h2>System Tables</h2>
<a href="#information_schema">Information Schema</a><br />
<a href="#range_table">Range table</a><br />
<c:forEach var="item" items="commands">
<br />
......@@ -57,4 +60,27 @@ ${item.example}
<br />
</c:forEach>
<br />
<a name="information_schema"></a><h3>Information Schema</h3>
<p>
The system tables in the schema 'INFORMATION_SCHEMA' contain the meta data
of all tables in the database as well as the current settings.
</p>
<table><tr><th>Table</th><th>Columns</th></tr>
<c:forEach var="item" items="informationSchema">
<tr><td>${item.topic}</td><td>${item.syntax}</td></tr>
</c:forEach>
</table>
<br />
<a name="range_table"></a><h3>Range table</h3>
<p>
The range table is a dynamic system table that contains all values from a start to an end value.
The table contains one column called X. Both the start and end values are included in the result.
The table is used as follows:
</p>
<pre>
SELECT X FROM SYSTEM_RANGE(1, 10);
</pre>
</div></td></tr></table><!-- analytics --></body></html>
......@@ -755,126 +755,132 @@ Database encryption is meant for securing the database while it is not in use (s
File encryption slows down the performance of the database engine. Compared to unencrypted mode, database operations take about 2.2 times longer when using XTEA, and 2.5 times longer using AES (embedded mode).
@advanced_1252_h3
SSL/TLS Connections
Wrong Password Delay
@advanced_1253_p
Remote SSL/TLS connections are supported using the Java Secure Socket Extension (SSLServerSocket / SSLSocket). By default, anonymous SSL is enabled. The default cipher suite is <code>SSL_DH_anon_WITH_RC4_128_MD5</code> .
To protect against remote brute force password attacks, the delay after each unsuccessful login gets double as long. Use the system properties h2.delayWrongPasswordMin and h2.delayWrongPasswordMax to change the minimum (the default is 250 milliseconds) or maximum delay (the default is 4000 milliseconds, or 4 seconds). The delay only applies for those using the wrong password. Normally there is no delay for a user that knows the correct password, with one exception: after using the wrong password, there is a delay of up (randomly distributed) the same delay as for a wrong password. This is to protect against parallel brute force attacks, so that an attacker needs to wait for the whole delay. Delays are synchronized. This is also required to protect against parallel attacks.
@advanced_1254_h3
HTTPS Connections
SSL/TLS Connections
@advanced_1255_p
Remote SSL/TLS connections are supported using the Java Secure Socket Extension (SSLServerSocket / SSLSocket). By default, anonymous SSL is enabled. The default cipher suite is <code>SSL_DH_anon_WITH_RC4_128_MD5</code> .
@advanced_1256_h3
HTTPS Connections
@advanced_1257_p
The web server supports HTTP and HTTPS connections using SSLServerSocket. There is a default self-certified certificate to support an easy starting point, but custom certificates are supported as well.
@advanced_1256_h2
@advanced_1258_h2
Universally Unique Identifiers (UUID)
@advanced_1257_p
@advanced_1259_p
This database supports the UUIDs. Also supported is a function to create new UUIDs using a cryptographically strong pseudo random number generator. With random UUIDs, the chance of two having the same value can be calculated using the probability theory. See also 'Birthday Paradox'. Standardized randomly generated UUIDs have 122 random bits. 4 bits are used for the version (Randomly generated UUID), and 2 bits for the variant (Leach-Salz). This database supports generating such UUIDs using the built-in function RANDOM_UUID(). Here is a small program to estimate the probability of having two identical UUIDs after generating a number of values:
@advanced_1258_p
@advanced_1260_p
Some values are:
@advanced_1259_p
@advanced_1261_p
To help non-mathematicians understand what those numbers mean, here a comparison: One's annual risk of being hit by a meteorite is estimated to be one chance in 17 billion, that means the probability is about 0.000'000'000'06.
@advanced_1260_h2
@advanced_1262_h2
Settings Read from System Properties
@advanced_1261_p
@advanced_1263_p
Some settings of the database can be set on the command line using -DpropertyName=value. It is usually not required to change those settings manually. The settings are case sensitive. Example:
@advanced_1262_p
@advanced_1264_p
The current value of the settings can be read in the table INFORMATION_SCHEMA.SETTINGS.
@advanced_1263_p
@advanced_1265_p
For a complete list of settings, see <a href="../javadoc/org/h2/constant/SysProperties.html">SysProperties</a> .
@advanced_1264_h2
@advanced_1266_h2
Setting the Server Bind Address
@advanced_1265_p
@advanced_1267_p
Usually server sockets accept connections on any/all local addresses. This may be a problem on multi-homed hosts. To bind only to one address, use the system property h2.bindAddress. This setting is used for both regular server sockets and for SSL server sockets. IPv4 and IPv6 address formats are supported.
@advanced_1266_h2
@advanced_1268_h2
Glossary and Links
@advanced_1267_th
@advanced_1269_th
Term
@advanced_1268_th
@advanced_1270_th
Description
@advanced_1269_td
@advanced_1271_td
AES-128
@advanced_1270_td
@advanced_1272_td
A block encryption algorithm. See also: <a href="http://en.wikipedia.org/wiki/Advanced_Encryption_Standard">Wikipedia: AES</a>
@advanced_1271_td
@advanced_1273_td
Birthday Paradox
@advanced_1272_td
@advanced_1274_td
Describes the higher than expected probability that two persons in a room have the same birthday. Also valid for randomly generated UUIDs. See also: <a href="http://en.wikipedia.org/wiki/Birthday_paradox">Wikipedia: Birthday Paradox</a>
@advanced_1273_td
@advanced_1275_td
Digest
@advanced_1274_td
@advanced_1276_td
Protocol to protect a password (but not to protect data). See also: <a href="http://www.faqs.org/rfcs/rfc2617.html">RFC 2617: HTTP Digest Access Authentication</a>
@advanced_1275_td
@advanced_1277_td
GCJ
@advanced_1276_td
@advanced_1278_td
GNU Compiler for Java. <a href="http://gcc.gnu.org/java/">http://gcc.gnu.org/java/</a> and <a href="http://nativej.mtsystems.ch">http://nativej.mtsystems.ch/ (not free any more)</a>
@advanced_1277_td
@advanced_1279_td
HTTPS
@advanced_1278_td
@advanced_1280_td
A protocol to provide security to HTTP connections. See also: <a href="http://www.ietf.org/rfc/rfc2818.txt">RFC 2818: HTTP Over TLS</a>
@advanced_1279_td
@advanced_1281_td
Modes of Operation
@advanced_1280_a
@advanced_1282_a
Wikipedia: Block cipher modes of operation
@advanced_1281_td
@advanced_1283_td
Salt
@advanced_1282_td
@advanced_1284_td
Random number to increase the security of passwords. See also: <a href="http://en.wikipedia.org/wiki/Key_derivation_function">Wikipedia: Key derivation function</a>
@advanced_1283_td
@advanced_1285_td
SHA-256
@advanced_1284_td
@advanced_1286_td
A cryptographic one-way hash function. See also: <a href="http://en.wikipedia.org/wiki/SHA_family">Wikipedia: SHA hash functions</a>
@advanced_1285_td
@advanced_1287_td
SQL Injection
@advanced_1286_td
@advanced_1288_td
A security vulnerability where an application generates SQL statements with embedded user input. See also: <a href="http://en.wikipedia.org/wiki/SQL_injection">Wikipedia: SQL Injection</a>
@advanced_1287_td
@advanced_1289_td
Watermark Attack
@advanced_1288_td
@advanced_1290_td
Security problem of certain encryption programs where the existence of certain data can be proven without decrypting. For more information, search in the internet for 'watermark attack cryptoloop'
@advanced_1289_td
@advanced_1291_td
SSL/TLS
@advanced_1290_td
@advanced_1292_td
Secure Sockets Layer / Transport Layer Security. See also: <a href="http://java.sun.com/products/jsse/">Java Secure Socket Extension (JSSE)</a>
@advanced_1291_td
@advanced_1293_td
XTEA
@advanced_1292_td
@advanced_1294_td
A block encryption algorithm. See also: <a href="http://en.wikipedia.org/wiki/XTEA">Wikipedia: XTEA</a>
@build_1000_h1
......@@ -7415,7 +7421,7 @@ When using Java Web Start / JNLP (Java Network Launch Protocol), permissions tag
Using a Connection Pool
@tutorial_1179_p
For many databases, opening a connection is slow, and it is a good idea to use a connection pool to re-use connections. For H2 however opening a connection usually is fast if the database is already open. Using a connection pool manager for H2 actually slows down the process a bit, except if file encryption is used (in this case opening a connection is about half as fast as using a connection pool). A simple connection pool manager is included in H2. It is based on the <a href="http://www.source-code.biz/snippets/java/8.htm">Mini Connection Pool Manager</a> from Christian d'Heureuse. There are other, more complex connection pools available, for example <a href="http://jakarta.apache.org/commons/dbcp/">DBCP</a> . The build-in connection pool manager is used as follows:
For many databases, opening a connection is slow, and it is a good idea to use a connection pool to re-use connections. For H2 however opening a connection usually is fast if the database is already open. Using a connection pool for H2 actually slows down the process a bit, except if file encryption is used (in this case opening a connection is about half as fast as using a connection pool). A simple connection pool is included in H2. It is based on the <a href="http://www.source-code.biz/snippets/java/8.htm">Mini Connection Pool Manager</a> from Christian d'Heureuse. There are other, more complex connection pools available, for example <a href="http://jakarta.apache.org/commons/dbcp/">DBCP</a> . The build-in connection pool is used as follows:
@tutorial_1180_h2
Fulltext Search
......
......@@ -1133,6 +1133,7 @@ public class Parser {
read("JOIN");
// the right hand side is the 'inner' table usually
TableFilter newTop = readTableFilter(fromOuter);
newTop = readJoin(newTop, command, true);
Expression on = null;
if (readIf("ON")) {
on = readExpression();
......@@ -1144,6 +1145,7 @@ public class Parser {
readIf("OUTER");
read("JOIN");
TableFilter join = readTableFilter(true);
top = readJoin(top, command, true);
Expression on = null;
if (readIf("ON")) {
on = readExpression();
......@@ -1155,6 +1157,7 @@ public class Parser {
} else if (readIf("INNER")) {
read("JOIN");
TableFilter join = readTableFilter(fromOuter);
top = readJoin(top, command, false);
Expression on = null;
if (readIf("ON")) {
on = readExpression();
......@@ -1163,6 +1166,7 @@ public class Parser {
last = join;
} else if (readIf("JOIN")) {
TableFilter join = readTableFilter(fromOuter);
top = readJoin(top, command, false);
Expression on = null;
if (readIf("ON")) {
on = readExpression();
......
......@@ -159,22 +159,22 @@ public class SysProperties {
public static final int DEFAULT_LOCK_MODE = getIntSetting("h2.defaultLockMode", Constants.LOCK_MODE_READ_COMMITTED);
/**
* System property <code>h2.delayWrongPasswordMin</code> (default: 200).<br />
* System property <code>h2.delayWrongPasswordMin</code> (default: 250).<br />
* The minimum delay in milliseconds before an exception is thrown for using
* the wrong user name or password. This slows down brute force attacks. The
* delay is reset to this value after a successful login. Unsuccessful
* logins will double the time until DELAY_WRONG_PASSWORD_MAX.
*/
public static final int DELAY_WRONG_PASSWORD_MIN = getIntSetting("h2.delayWrongPasswordMin", 200);
public static final int DELAY_WRONG_PASSWORD_MIN = getIntSetting("h2.delayWrongPasswordMin", 250);
/**
* System property <code>h2.delayWrongPasswordMax</code> (default: 0).<br />
* System property <code>h2.delayWrongPasswordMax</code> (default: 4000).<br />
* The maximum delay in milliseconds before an exception is thrown for using
* the wrong user name or password. This slows down brute force attacks. The
* delay is reset after a successful login. The value 0 means there is no
* maximum delay.
*/
public static final int DELAY_WRONG_PASSWORD_MAX = getIntSetting("h2.delayWrongPasswordMax", 0);
public static final int DELAY_WRONG_PASSWORD_MAX = getIntSetting("h2.delayWrongPasswordMax", 4000);
/**
* System property <code>h2.emergencySpaceInitial</code> (default: 262144).<br />
......
......@@ -193,10 +193,25 @@ public class Engine {
private static void validateUserAndPassword(boolean correct) throws SQLException {
int min = SysProperties.DELAY_WRONG_PASSWORD_MIN;
if (correct) {
wrongPasswordDelay = min;
long delay = wrongPasswordDelay;
if (delay > min && delay > 0) {
// the first correct password must be blocked,
// otherwise parallel attacks are possible
synchronized (wrongPasswordSync) {
// delay up to the last delay
// an attacker can't know how long it will be
delay = RandomUtils.nextInt((int) delay);
try {
Thread.sleep(delay);
} catch (InterruptedException e) {
// ignore
}
wrongPasswordDelay = min;
}
}
} else {
// this method is not synchronized on the Engine, so that
// successful attempts are not blocked
// regular successful attempts are not blocked
synchronized (wrongPasswordSync) {
long delay = wrongPasswordDelay;
int max = SysProperties.DELAY_WRONG_PASSWORD_MAX;
......
......@@ -2898,35 +2898,11 @@ CURRENT_USER()
"
"System tables","Information schema","
INFORMATION_SCHEMA.tableName
","
INFORMATION_SCHEMA.CATALOGS contains the catalogs.
INFORMATION_SCHEMA.COLLATIONS contains the available collations.
INFORMATION_SCHEMA.COLUMNS contains the columns.
INFORMATION_SCHEMA.COLUMN_PRIVILEGES contains column privileges.
INFORMATION_SCHEMA.CONSTANTS contains the constants.
INFORMATION_SCHEMA.CONSTRAINTS contains the constraints.
INFORMATION_SCHEMA.CROSS_REFERENCES contains all foreign key constraint data.
INFORMATION_SCHEMA.DOMAINS contains all domains (custom data types).
INFORMATION_SCHEMA.FUNCTION_ALIASES contains the function aliases.
INFORMATION_SCHEMA.FUNCTION_COLUMNS contains the function columns.
INFORMATION_SCHEMA.HELP contains the reference help.
INFORMATION_SCHEMA.INDEXES contains the indexes.
INFORMATION_SCHEMA.IN_DOUBT contains all in-doubt transactions.
INFORMATION_SCHEMA.LOCKS contains all locks.
INFORMATION_SCHEMA.RIGHTS contains the rights.
INFORMATION_SCHEMA.ROLES contains the roles.
INFORMATION_SCHEMA.SCHEMATA contains the schemas.
INFORMATION_SCHEMA.SESSIONS contains the open sessions.
INFORMATION_SCHEMA.SEQUENCES contains the sequences.
INFORMATION_SCHEMA.SETTINGS contains the settings.
INFORMATION_SCHEMA.TABLES contains the tables.
INFORMATION_SCHEMA.TABLE_PRIVILEGES contains table privileges.
INFORMATION_SCHEMA.TABLE_TYPES contains the table types.
INFORMATION_SCHEMA.TRIGGERS contains the triggers.
INFORMATION_SCHEMA.TYPE_INFO contains the data types.
INFORMATION_SCHEMA.USERS contains the users.
INFORMATION_SCHEMA.VIEWS contains the views.
INFORMATION_SCHEMA
","
To get the list of system tables, execute the statement
SELECT * FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'INFORMATION_SCHEMA'
","
"
......
......@@ -32,7 +32,7 @@ public class ConvertTraceFile extends Tool {
String sql;
int executeCount;
long time;
long resultCountTotal;
long resultCount;
public int compareTo(Object o) {
Stat other = (Stat) o;
......@@ -141,7 +141,7 @@ public class ConvertTraceFile extends Tool {
String sql = line.substring(end + "*/".length());
line = line.substring("/*SQL".length(), end);
if (line.length() > 0) {
int len = sql.length();
String statement = sql;
int count = 0;
int time = 0;
line = line.trim();
......@@ -150,7 +150,8 @@ public class ConvertTraceFile extends Tool {
while (tk.hasMoreElements()) {
String token = tk.nextToken();
if ("l".equals(token)) {
len = Integer.parseInt(tk.nextToken());
int len = Integer.parseInt(tk.nextToken());
statement = sql.substring(0, len) + ";";
} else if ("#".equals(token)) {
count = Integer.parseInt(tk.nextToken());
} else if ("t".equals(token)) {
......@@ -158,7 +159,6 @@ public class ConvertTraceFile extends Tool {
}
}
}
String statement = sql.substring(0, len);
addToStats(statement, count, time);
}
scriptWriter.println(StringUtils.javaDecode(sql));
......@@ -169,16 +169,43 @@ public class ConvertTraceFile extends Tool {
reader.close();
javaWriter.close();
if (stats.size() > 0) {
scriptWriter.println("---------------------------------------------------------------");
scriptWriter.println("-----------------------------------------");
scriptWriter.println("-- SQL Statement Statistics");
scriptWriter.println("-- time: total time in milliseconds");
scriptWriter.println("-- count: how many times the statement ran");
scriptWriter.println("-- result: total update count or row count");
scriptWriter.println("-----------------------------------------");
scriptWriter.println("-- self accu time count result sql");
int accumTime = 0;
ArrayList list = new ArrayList(stats.values());
Collections.sort(list);
int todo;
scriptWriter.println("--");
if (timeTotal == 0) {
timeTotal = 1;
}
for (int i = 0; i < list.size(); i++) {
Stat stat = (Stat) list.get(i);
StringBuffer buff = new StringBuffer(100);
buff.append("-- ");
buff.append(padNumberLeft(100 * stat.time / timeTotal, 3));
buff.append("% ");
accumTime += stat.time;
buff.append(padNumberLeft(100 * accumTime / timeTotal, 3));
buff.append('%');
buff.append(padNumberLeft(stat.time, 8));
buff.append(padNumberLeft(stat.executeCount, 8));
buff.append(padNumberLeft(stat.resultCount, 8));
buff.append(' ');
buff.append(stat.sql);
scriptWriter.println(buff.toString());
}
}
scriptWriter.close();
}
private String padNumberLeft(long number, int digits) {
return StringUtils.pad(String.valueOf(number), digits, " ", false);
}
private void addToStats(String sql, int resultCount, int time) {
Stat stat = (Stat) stats.get(sql);
if (stat == null) {
......@@ -187,7 +214,7 @@ public class ConvertTraceFile extends Tool {
stats.put(sql, stat);
}
stat.executeCount++;
stat.resultCountTotal += resultCount;
stat.resultCount += resultCount;
stat.time += time;
timeTotal += time;
}
......
......@@ -159,35 +159,10 @@ java org.h2.test.TestAll timer
/*
1. get application here: http://krtonozka23.savana.cz/mismatch_error.zip
2. unpack and execute: java -jar executeh2script.jar
3. it will copy the prepared database from basedb into dbtest
directory and execute the crashScript.txt upon it.
4. connect to created dbtest database with h2 console and execute:
SELECT Data FROM FD_12_5001 WHERE TypeId=4 ORDER BY Ts DESC;
5. you should got something like: General error: java.lang.Error: File
ID mismatch got=1707400262 expected=41 pos=57219 true
org.h2.store.DiskFile:E:\WiMax\projects\Java\ExecuteH2Script\dbtest
\dbtest.data.db blockCount:-755423910 [50000-67] (Help)
File ID mismatch: 2008-03-21.trace.zip
test ConvertTraceFile
include in the execution times in the debug log.
(for each SQL statement ran)
SQL:checksum:1ms SELECT * FROM TEST
checksum: not including values, case insensitive
better document system tables
.tar.bz2 instead of .zip
drop table test;
create table test(id int);
select * from test t1 inner join test t2
inner join test t3 on t3.id=t2.id on t1.id=t2.id;
-- supported by PostgreSQL, Derby,...;
not supported by MySQL,...
test self runnable jar with uncompressed jar inside compressed jar
implementation javadocs
.tar.bz2 in addition to .zip
optimize where x not in (select):
SELECT c FROM color LEFT OUTER JOIN (SELECT c FROM TABLE(c
......@@ -252,18 +227,23 @@ The Japanese translation of the error messages and the
Optimization for MIN() and MAX() when using MVCC.
To protect against remote brute force password attacks,
the delay after each unsuccessful login now gets double as long.
Use the system properties h2.delayWrongPasswordMin
and h2.delayWrongPasswordMax
New system properties h2.delayWrongPasswordMin
and h2.delayWrongPasswordMax.
After setting the query timeout and then resetting it, the next query
would still timeout. Fixed.
Adding a IDENTITY column to a table with data threw a lock timeout.
OutOfMemoryError could occur when using EXISTS or IN(SELECT ..).
The built-in connection pool is not called JdbcConnectionPool.
The API and documentation has been changed.
The ConvertTraceFile tool now generates SQL statement statistics
at the end of the SQL script file (similar to the profiling data
generated when using java -Xrunhprof).
Nested joins are now supported (A JOIN B JOIN C ON .. ON ..)
Roadmap:
Doclet (javadocs): constructors are not listed
Support direct lookup for MIN and MAX when using WHERE (see todo.txt / Direct Lookup)
Support direct lookup for MIN and MAX when using WHERE
(see todo.txt / Direct Lookup)
......
--- special grammar and test cases ---------------------------------------------------------------------------------------------
select * from system_range(1, 3) t1 inner join system_range(2, 3) t2 inner join system_range(1, 2) t3 on t3.x=t2.x on t1.x=t2.x;
> ok
CREATE TABLE p(d date);
> ok
......@@ -2830,7 +2833,7 @@ create table test(id int primary key);
explain select * from test a inner join test b left outer join test c on c.id = a.id;
> PLAN
> ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
> SELECT A.ID, B.ID, C.ID FROM PUBLIC.TEST A /* PUBLIC.TEST_TABLE_SCAN */ INNER JOIN PUBLIC.TEST B /* PUBLIC.TEST_TABLE_SCAN */ LEFT OUTER JOIN PUBLIC.TEST C /* PUBLIC.PRIMARY_KEY_2: ID = A.ID */ ON C.ID = A.ID
> SELECT A.ID, C.ID, B.ID FROM PUBLIC.TEST A /* PUBLIC.TEST_TABLE_SCAN */ LEFT OUTER JOIN PUBLIC.TEST C /* PUBLIC.PRIMARY_KEY_2: ID = A.ID */ ON C.ID = A.ID INNER JOIN PUBLIC.TEST B /* PUBLIC.TEST_TABLE_SCAN */
> rows: 1
SELECT T.ID FROM TEST "T";
......
......@@ -68,6 +68,9 @@ public class GenerateDoc {
map("functionsAll",
"SELECT * FROM INFORMATION_SCHEMA.HELP WHERE SECTION LIKE 'Functions%' ORDER BY SECTION, ID");
map("dataTypes", "SELECT * FROM INFORMATION_SCHEMA.HELP WHERE SECTION LIKE 'Data Types%' ORDER BY SECTION, ID");
map("informationSchema", "SELECT TABLE_NAME TOPIC, GROUP_CONCAT(COLUMN_NAME " +
"ORDER BY ORDINAL_POSITION SEPARATOR ', ') SYNTAX FROM INFORMATION_SCHEMA.COLUMNS " +
"WHERE TABLE_SCHEMA='INFORMATION_SCHEMA' GROUP BY TABLE_NAME ORDER BY TABLE_NAME");
processAll("");
conn.close();
}
......
......@@ -489,4 +489,5 @@ frontbase intersys maxwidth belonging learning mono typical toggle winexe
hider ikvmc invert recycle filtering lesser recycled assertion runner teradata
christian lgpl elapsed ncr disposed heureuse tera years retrieves unlocked
selecting vista everywhere locations zones fragment svg thought constructors
doubles validating
\ No newline at end of file
doubles validating matched established accu accum stats resetting parallel
delays
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论