提交 624fa6ba authored 作者: Thomas Mueller's avatar Thomas Mueller

--no commit message

--no commit message
上级 a55cd699
......@@ -58,7 +58,7 @@
<arg line="+JDK13 -JDK14 -JDK16 -AWT ../src/main/org/h2"/>
</java>
</target>
<target name="codeswitchJdk13" depends="codeswitchPrepare">
<propertyfile file="ant-build.properties">
<entry key="jdk" value="1.3" />
......@@ -97,26 +97,26 @@
<fileset dir="bin" includes="org/h2/util/ResourceData.java"/>
</delete>
</target>
<target name="compileFullTextLucene" depends="compileFullTextLuceneTest, compile" if="lucene.jar.present">
<javac target="${jdk}" source="${jdk}" executable="${javac}" srcdir="src/main" destdir="bin" debug="true">
<classpath location="${path.lucene.jar}" />
<include name="org/h2/fulltext/FullTextLucene.java"/>
</javac>
</target>
<target name="compileFullTextLuceneTest" depends="init" unless="lucene.jar.present">
<echo message="Lucene jar not found, LuceneFullText not compiled."/>
<echo message="Please set ant-build.properties / path.lucene.jar"/>
</target>
</target>
<target name="compileServlet" depends="compileServletTest, compile" if="servlet.jar.present">
<javac target="${jdk}" source="${jdk}" executable="${javac}" srcdir="src/tools" destdir="bin" debug="true">
<classpath location="${path.servlet.jar}" />
<include name="org/h2/server/web/*.*"/>
</javac>
</target>
<target name="compileServletTest" depends="init" unless="servlet.jar.present">
<echo message="Servlet API jar not found, console servlet not compiled."/>
<echo message="Please set ant-build.properties / path.servlet.jar"/>
......@@ -139,7 +139,7 @@
<fileset dir="src/test" includes="**/*.properties"/>
</copy>
</target>
<target name="compileCoverage" depends="compile">
<copy todir="bin" overwrite="true">
<fileset dir="src/main"/>
......@@ -149,19 +149,12 @@
</java>
<javac target="${jdk}" source="${jdk}" executable="${javac}" srcdir="bin" destdir="bin" debug="true" includes="org/h2/**"/>
</target>
<target name="compileTest" unless="java.version.ok">
<echo message="Java version is ${java.specification.version} but source code is switched to ${jdk}."/>
<echo message="Run ant codeswitchJdk... first."/>
</target>
<target name="createPatch" depends="clean">
<delete file="../h2-patch.*"/>
<tar destfile="../h2-patch.tar" basedir="." includes="src/**/*.java,build.xml"/>
<bzip2 destfile="../h2-patch.tar.bz2" src="../h2-patch.tar"/>
<delete file="../h2-patch.tar"/>
</target>
<target name="docs" depends="clean,javadoc,compile">
<copy todir="docs">
<fileset dir="src/docsrc" includes="index.html"/>
......@@ -204,7 +197,7 @@
</condition>
<echo message="build-jdk:${java.specification.version} ant-build.properties/jdk:${jdk}"></echo>
</target>
<target name="jar" depends="compile, compileServlet, compileFullTextLucene, manifest">
<manifest file="bin/META-INF/MANIFEST.MF" mode="update">
<attribute name="Main-Class" value="org.h2.tools.Console"/>
......@@ -225,7 +218,7 @@
<target name="jarClient" depends="compileResources, manifest">
<javac target="${jdk}" source="${jdk}" executable="${javac}" srcdir="src/main" destdir="bin" debug="true">
<include name="org/h2/*" />
<include name="org/h2/jdbc/**" />
<include name="org/h2/jdbc/**" />
<include name="org/h2/jdbcx/**" />
</javac>
<jar jarfile="bin/h2client.jar" basedir="bin" manifest="bin/META-INF/MANIFEST.MF">
......@@ -233,19 +226,19 @@
<exclude name="**/*.bat"/>
</jar>
</target>
<target name="jarDb" depends="compileResources, manifest">
<javac target="${jdk}" source="${jdk}" executable="${javac}" srcdir="src/main" destdir="bin" debug="true">
<include name="org/h2/*" />
<include name="org/h2/engine/**" />
<include name="org/h2/jdbc/**" />
<include name="org/h2/engine/**" />
<include name="org/h2/jdbc/**" />
<include name="org/h2/jdbcx/**" />
</javac>
<jar jarfile="bin/h2db.jar" basedir="bin" manifest="bin/META-INF/MANIFEST.MF">
<include name="**/*.*"/>
<exclude name="**/*.bat"/>
</jar>
</target>
</target>
<target name="javadoc">
<javac target="${jdk}" source="${jdk}" executable="${javac}" srcdir="src/test" destdir="bin" debug="true" includes="org/h2/test/bnf/*.java"/>
......@@ -261,7 +254,7 @@
<fileset dir="src/docsrc/javadoc" includes="**/*"/>
</copy>
</target>
<target name="javadocImpl">
<mkdir dir="docs/javadocImpl"/>
<javadoc
......@@ -272,8 +265,8 @@
<copy todir="docs/javadoc">
<fileset dir="src/docsrc/javadoc" includes="**/*"/>
</copy>
</target>
</target>
<target name="manifest">
<mkdir dir="bin/META-INF"/>
<manifest file="bin/META-INF/MANIFEST.MF">
......@@ -286,7 +279,7 @@
<attribute name="Build-Jdk" value="${jdk}"/>
</manifest>
</target>
<target name="mavenBuildCentral">
<copy tofile="bin/h2-${version.name.maven}.jar" file="bin/h2.jar" />
<copy tofile="bin/pom.xml" filtering="true" file="src/installer/pom.xml">
......@@ -347,7 +340,7 @@
<!-- <jvmarg value="-agentlib:hprof=help"/> -->
</java>
</target>
<target name="warConsole" depends="compileServlet, jar">
<fail unless="servlet.jar.present" message="Servlet API jar not found"/>
<war destfile="bin/h2console.war" webxml="src/tools/WEB-INF/web.xml" basedir="src/tools/WEB-INF" includes="console.html">
......
......@@ -551,7 +551,7 @@ public class Parser {
command.setSavepointName(readUniqueIdentifier());
return command;
}
private Prepared parseReleaseSavepoint() throws SQLException {
Prepared command = new NoOperation(session);
readIf("SAVEPOINT");
......@@ -673,7 +673,7 @@ public class Parser {
setSQL(command, "DELETE", start);
return command;
}
private IndexColumn[] parseIndexColumnList() throws SQLException {
ObjectArray columns = new ObjectArray();
do {
......@@ -693,7 +693,7 @@ public class Parser {
column.sortType |= SortOrder.NULLS_LAST;
}
} else {
}
} while (readIf(","));
read(")");
......@@ -833,19 +833,13 @@ public class Parser {
if (readIf("(")) {
if (isToken("SELECT") || isToken("FROM")) {
Query query = parseSelect();
String querySQL = query.getSQL();
Session s;
if (prepared != null && prepared instanceof CreateView) {
s = database.getSystemSession();
} else {
s = session;
}
String tempViewName = s.getNextTempViewName();
TableView v = new TableView(mainSchema, 0, tempViewName, querySQL, query.getParameters(), null, s,
false);
v.setOwner(session.getUser());
v.setTemporary(true);
table = v;
table = TableView.createTempView(s, session.getUser(), query);
read(")");
} else {
TableFilter top = readTableFilter(fromOuter);
......@@ -1076,7 +1070,7 @@ public class Parser {
command.setIfExists(ifExists);
return command;
}
DropAggregate parseDropAggregate() throws SQLException {
boolean ifExists = readIfExists(false);
DropAggregate command = new DropAggregate(session);
......@@ -1148,9 +1142,9 @@ public class Parser {
for (int j = 0; j < joinCols.length; j++) {
String joinColumnName = joinCols[j].getName();
if (tableColumnName.equals(joinColumnName)) {
Expression tableExpr = new ExpressionColumn(database, currentSelect, tableSchema, last
Expression tableExpr = new ExpressionColumn(database, tableSchema, last
.getTableAlias(), tableColumnName);
Expression joinExpr = new ExpressionColumn(database, currentSelect, joinSchema, join
Expression joinExpr = new ExpressionColumn(database, joinSchema, join
.getTableAlias(), joinColumnName);
Expression equal = new Comparison(session, Comparison.EQUAL, tableExpr, joinExpr);
if (on == null) {
......@@ -1759,7 +1753,7 @@ public class Parser {
JavaFunction func = new JavaFunction(functionAlias, args);
return func;
}
private JavaAggregate readJavaAggregate(UserAggregate aggregate) throws SQLException {
ObjectArray params = new ObjectArray();
do {
......@@ -1955,11 +1949,11 @@ public class Parser {
return expr;
}
name = readColumnIdentifier();
return new ExpressionColumn(database, currentSelect, schemaName, objectName, name);
return new ExpressionColumn(database, schemaName, objectName, name);
}
return new ExpressionColumn(database, currentSelect, schemaName, objectName, name);
return new ExpressionColumn(database, schemaName, objectName, name);
}
return new ExpressionColumn(database, currentSelect, null, objectName, name);
return new ExpressionColumn(database, null, objectName, name);
}
private Expression readTerm() throws SQLException {
......@@ -2014,7 +2008,7 @@ public class Parser {
} else if (readIf(".")) {
r = readTermObjectDot(name);
} else {
r = new ExpressionColumn(database, currentSelect, null, null, name);
r = new ExpressionColumn(database, null, null, name);
}
} else {
read();
......@@ -2046,7 +2040,7 @@ public class Parser {
} else if (readIf("DATE")) {
r = readFunctionWithoutParameters("CURRENT_DATE");
} else {
r = new ExpressionColumn(database, currentSelect, null, null, name);
r = new ExpressionColumn(database, null, null, name);
}
} else if ("NEXT".equals(name) && readIf("VALUE")) {
read("FOR");
......@@ -2070,7 +2064,7 @@ public class Parser {
read();
r = ValueExpression.get(ValueString.get(text));
} else {
r = new ExpressionColumn(database, currentSelect, null, null, name);
r = new ExpressionColumn(database, null, null, name);
}
}
break;
......@@ -3352,7 +3346,7 @@ public class Parser {
command.setIfNotExists(ifNotExists);
return command;
}
private CreateAggregate parseCreateAggregate(boolean force) throws SQLException {
boolean ifNotExists = readIfNoExists();
CreateAggregate command = new CreateAggregate(session);
......@@ -3365,7 +3359,7 @@ public class Parser {
command.setIfNotExists(ifNotExists);
read("FOR");
command.setJavaClassMethod(readUniqueIdentifier());
return command;
return command;
}
private CreateUserDataType parseCreateUserDataType() throws SQLException {
......
......@@ -46,7 +46,7 @@ public class Call extends Prepared {
for (int i = 0; i < list.length; i++) {
Value e = list[i];
Column col = new Column("C" + (i + 1), e.getType(), e.getPrecision(), e.getScale(), e.getDisplaySize());
expr.add(new ExpressionColumn(session.getDatabase(), null, col));
expr.add(new ExpressionColumn(session.getDatabase(), col));
}
LocalResult result = new LocalResult(session, expr, list.length);
result.addRow(list);
......
......@@ -22,19 +22,19 @@ public class ExplainPlan extends Prepared {
private Prepared command;
private LocalResult result;
public ExplainPlan(Session session) {
super(session);
}
public void setCommand(Prepared command) {
this.command = command;
}
public void prepare() throws SQLException {
command.prepare();
}
public LocalResult queryMeta() throws SQLException {
return query(-1);
}
......@@ -43,7 +43,7 @@ public class ExplainPlan extends Prepared {
// TODO rights: are rights required for explain?
ObjectArray expressions = new ObjectArray();
Column column = new Column("PLAN", Value.STRING);
ExpressionColumn expr = new ExpressionColumn(session.getDatabase(), null, column);
ExpressionColumn expr = new ExpressionColumn(session.getDatabase(), column);
expressions.add(expr);
result = new LocalResult(session, expressions, 1);
if (maxrows >= 0) {
......@@ -53,18 +53,18 @@ public class ExplainPlan extends Prepared {
result.done();
return result;
}
private void add(String text) throws SQLException {
Value[] row = new Value[1];
Value value = ValueString.get(text);
row[0] = value;
result.addRow(row);
}
public boolean isQuery() {
return true;
}
}
public boolean isTransactional() {
return true;
}
......
......@@ -31,21 +31,21 @@ import org.h2.value.ValueNull;
* Represents a SELECT statement (simple, or union).
*/
public abstract class Query extends Prepared {
protected Expression limit, offset;
protected int sampleSize;
private int lastLimit;
private long lastEvaluated;
private LocalResult lastResult;
private Value[] lastParameters;
abstract LocalResult queryWithoutCache(int limit) throws SQLException;
public Query(Session session) {
super(session);
}
public boolean isQuery() {
return true;
}
......@@ -53,7 +53,7 @@ public abstract class Query extends Prepared {
public boolean isTransactional() {
return true;
}
public final boolean sameResultAsLast(Session session, Value[] params, Value[] lastParams, long lastEvaluated)
throws SQLException {
Database db = session.getDatabase();
......@@ -70,7 +70,7 @@ public abstract class Query extends Prepared {
}
return true;
}
public final Value[] getParameterValues() throws SQLException {
ObjectArray list = getParameters();
if (list == null) {
......@@ -83,7 +83,7 @@ public abstract class Query extends Prepared {
}
return params;
}
public final LocalResult query(int limit) throws SQLException {
if (!session.getDatabase().getOptimizeReuseResults()) {
return queryWithoutCache(limit);
......@@ -105,7 +105,7 @@ public abstract class Query extends Prepared {
lastLimit = limit;
return lastResult;
}
protected void initOrder(ObjectArray expressions, ObjectArray expressionSQL, ObjectArray orderList, int visible,
boolean mustBeInResult) throws SQLException {
for (int i = 0; i < orderList.size(); i++) {
......@@ -185,7 +185,7 @@ public abstract class Query extends Prepared {
o.columnIndexExpr = ValueExpression.get(ValueInt.get(idx + 1));
}
}
public SortOrder prepareOrder(ObjectArray expressions, ObjectArray orderList) throws SQLException {
int[] index = new int[orderList.size()];
int[] sortType = new int[orderList.size()];
......@@ -228,11 +228,11 @@ public abstract class Query extends Prepared {
}
return new SortOrder(session.getDatabase(), index, sortType);
}
public void setOffset(Expression offset) {
this.offset = offset;
}
public void setLimit(Expression limit) {
this.limit = limit;
}
......@@ -248,6 +248,7 @@ public abstract class Query extends Prepared {
public abstract void setEvaluatable(TableFilter tableFilter, boolean b);
public abstract void addGlobalCondition(Expression expr, int columnId, int comparisonType) throws SQLException;
public abstract void setDistinct(boolean b);
public abstract String getFirstColumnAlias(Session session);
public void setSampleSize(int sampleSize) {
this.sampleSize = sampleSize;
......@@ -260,7 +261,7 @@ public abstract class Query extends Prepared {
}
public abstract boolean isEverything(ExpressionVisitor visitor);
public final boolean isEverything(int expressionVisitorType) {
ExpressionVisitor visitor = ExpressionVisitor.get(expressionVisitorType);
return isEverything(visitor);
......
......@@ -77,7 +77,7 @@ public class ScriptCommand extends ScriptBase {
public boolean isQuery() {
return true;
}
// TODO lock all tables for 'script' command
public void setData(boolean data) {
......@@ -91,24 +91,24 @@ public class ScriptCommand extends ScriptBase {
public void setSettings(boolean settings) {
this.settings = settings;
}
public void setLobBlockSize(long blockSize) {
this.lobBlockSize = MathUtils.convertLongToInt(blockSize);
}
public void setDrop(boolean drop) {
this.drop = drop;
}
public LocalResult queryMeta() throws SQLException {
LocalResult result = createResult();
result.done();
return result;
}
private LocalResult createResult() {
ObjectArray cols = new ObjectArray();
cols.add(new ExpressionColumn(session.getDatabase(), null, new Column("SCRIPT", Value.STRING)));
cols.add(new ExpressionColumn(session.getDatabase(), new Column("SCRIPT", Value.STRING)));
return new LocalResult(session, cols, 1);
}
......@@ -314,7 +314,7 @@ public class ScriptCommand extends ScriptBase {
reset();
return r;
}
private int writeLobStream(ValueLob v) throws IOException, SQLException {
if (!tempLobTableCreated) {
add("CREATE TABLE IF NOT EXISTS SYSTEM_LOB_STREAM(ID INT, PART INT, CDATA VARCHAR, BDATA BINARY, PRIMARY KEY(ID, PART))", true);
......@@ -371,7 +371,7 @@ public class ScriptCommand extends ScriptBase {
}
return id;
}
// called from the script
public static InputStream combineBlob(Connection conn, int id) throws SQLException, IOException {
if (id < 0) {
......
......@@ -10,6 +10,7 @@ import java.util.HashSet;
import org.h2.constant.ErrorCode;
import org.h2.constant.SysProperties;
import org.h2.engine.Session;
import org.h2.expression.Alias;
import org.h2.expression.Comparison;
import org.h2.expression.ConditionAndOr;
import org.h2.expression.Expression;
......@@ -34,12 +35,12 @@ import org.h2.value.ValueNull;
/**
* This class represents a simple SELECT statement.
*
*
* For each select statement:
* visibleColumnCount <= distinctColumnCount <= expressionCount.
* Sortable count could include ORDER BY expressions that are not in the select list.
* Expression count could include GROUP BY expressions.
*
*
* The call sequence is init(), mapColumns() if it's a subquery, prepare().
*/
public class Select extends Query {
......@@ -198,7 +199,7 @@ public class Select extends Query {
* This is to avoid running a separate ORDER BY if an index can be used.
* This is specially important for large result sets, if only the first few rows are important
* (LIMIT is used)
*
*
* @return the index if one is found
*/
private Index getSortIndex() throws SQLException {
......@@ -249,7 +250,7 @@ public class Select extends Query {
}
boolean ok = true;
for (int j = 0; j < sortCols.length; j++) {
// the index and the sort order must start
// the index and the sort order must start
// with the exact same columns
IndexColumn idxCol = indexCols[j];
Column sortCol = sortCols[j];
......@@ -270,8 +271,9 @@ public class Select extends Query {
return null;
}
private void queryFlat(int columnCount, LocalResult result, int limitRows) throws SQLException {
private void queryFlat(int columnCount, LocalResult result, long limitRows) throws SQLException {
if (limitRows != 0 && offset != null) {
// limitRows must be long, otherwise we get an int overflow if limitRows is at or near Integer.MAX_VALUE
limitRows += offset.getValue(session).getInt();
}
int rowNumber = 0;
......@@ -386,7 +388,7 @@ public class Select extends Query {
Column[] columns = t.getColumns();
for (int j = 0; j < columns.length; j++) {
Column c = columns[j];
ExpressionColumn ec = new ExpressionColumn(session.getDatabase(), this, null, alias, c.getName());
ExpressionColumn ec = new ExpressionColumn(session.getDatabase(), null, alias, c.getName());
expressions.add(i++, ec);
}
i--;
......@@ -425,8 +427,8 @@ public class Select extends Query {
havingIndex = -1;
}
// first visible columns, then order by, then having, and then group by
// at the end
// first visible columns, then order by, then having,
// and group by at the end
if (group != null) {
groupIndex = new int[group.size()];
for (int i = 0; i < group.size(); i++) {
......@@ -486,6 +488,9 @@ public class Select extends Query {
}
if (condition != null) {
condition = condition.optimize(session);
if (SysProperties.OPTIMIZE_IN_JOIN) {
condition = condition.optimizeInJoin(session, this);
}
for (int j = 0; j < filters.size(); j++) {
TableFilter f = (TableFilter) filters.get(j);
condition.createIndexConditions(session, f);
......@@ -561,7 +566,7 @@ public class Select extends Query {
for (int i = 0; i < expressions.size(); i++) {
Expression e = (Expression) expressions.get(i);
e.setEvaluatable(f, true);
}
}
f = f.getJoin();
}
topTableFilter.prepare();
......@@ -638,7 +643,7 @@ public class Select extends Query {
if (isForUpdate) {
buff.append("\nFOR UPDATE");
}
if (isQuickQuery) {
buff.append("\n/* direct lookup query */");
}
......@@ -777,4 +782,20 @@ public class Select extends Query {
return isEverything(ExpressionVisitor.READONLY);
}
public String getFirstColumnAlias(Session session) {
if (SysProperties.CHECK) {
if (visibleColumnCount > 1) {
throw Message.getInternalError("" + visibleColumnCount);
}
}
Expression expr = (Expression) expressions.get(0);
if (expr instanceof Alias) {
return expr.getAlias();
} else {
expr = new Alias(expr, session.getNextTempViewName() + "_X");
expressions.set(0, expr);
}
return expr.getAlias();
}
}
......@@ -35,28 +35,28 @@ public class SelectUnion extends Query {
private Query left, right;
private ObjectArray expressions;
private ObjectArray orderList;
private SortOrder sort;
private SortOrder sort;
private boolean distinct;
private boolean isPrepared, checkInit;
private boolean isForUpdate;
public SelectUnion(Session session, Query query) {
super(session);
this.left = query;
}
public void setUnionType(int type) {
this.unionType = type;
}
public void setRight(Query select) throws JdbcSQLException {
right = select;
}
public void setSQL(String sql) {
this.sql = sql;
}
}
public void setOrder(ObjectArray order) {
orderList = order;
}
......@@ -207,7 +207,7 @@ public class SelectUnion extends Query {
int scale = Math.max(l.getScale(), r.getScale());
int displaySize = Math.max(l.getDisplaySize(), r.getDisplaySize());
Column col = new Column(l.getAlias(), type, prec, scale, displaySize);
Expression e = new ExpressionColumn(session.getDatabase(), null, col);
Expression e = new ExpressionColumn(session.getDatabase(), col);
expressions.add(e);
}
if (orderList != null) {
......@@ -331,5 +331,9 @@ public class SelectUnion extends Query {
left.updateAggregate(session);
right.updateAggregate(session);
}
public String getFirstColumnAlias(Session session) {
return null;
}
}
......@@ -27,6 +27,10 @@ public class SysProperties {
public static final boolean OPTIMIZE_EVALUATABLE_SUBQUERIES = getBooleanSetting("h2.optimizeEvaluatableSubqueries", true);
public static final boolean OPTIMIZE_IN = getBooleanSetting("h2.optimizeIn", true);
private int testing;
public static final boolean OPTIMIZE_IN_JOIN = getBooleanSetting("h2.optimizeInJoin", true);
public static final boolean OPTIMIZE_MIN_MAX = getBooleanSetting("h2.optimizeMinMax", true);
public static final boolean OPTIMIZE_SUBQUERY_CACHE = getBooleanSetting("h2.optimizeSubqueryCache", true);
public static final boolean OPTIMIZE_NOT = getBooleanSetting("h2.optimizeNot", true);
......@@ -62,7 +66,7 @@ public class SysProperties {
public static final int LOB_FILES_PER_DIRECTORY = getIntSetting("h2.lobFilesPerDirectory", 256);
public static final boolean NEW_DISPLAY_SIZE = getBooleanSetting("h2.newDisplaySize", true);
public static final int DEFAULT_MAX_OPERATION_MEMORY = getIntSetting("h2.defaultMaxOperationMemory", 100000);
private static boolean getBooleanSetting(String name, boolean defaultValue) {
String s = System.getProperty(name);
if (s != null) {
......@@ -73,12 +77,12 @@ public class SysProperties {
}
return defaultValue;
}
private static String getStringSetting(String name, String defaultValue) {
String s = System.getProperty(name);
return s == null ? defaultValue : s;
}
private static int getIntSetting(String name, int defaultValue) {
String s = System.getProperty(name);
if (s != null) {
......@@ -89,7 +93,7 @@ public class SysProperties {
}
return defaultValue;
}
/**
* INTERNAL
*/
......@@ -99,7 +103,7 @@ public class SysProperties {
}
baseDir = dir;
}
/**
* INTERNAL
*/
......
......@@ -6,6 +6,7 @@ package org.h2.expression;
import java.sql.SQLException;
import org.h2.command.dml.Select;
import org.h2.constant.SysProperties;
import org.h2.engine.Session;
import org.h2.message.Message;
......@@ -20,9 +21,6 @@ import org.h2.value.ValueNull;
*/
public class ConditionAndOr extends Condition {
// TODO optimization: we could extend (ID=1 AND ID=B) to (ID=1 AND ID=B AND
// B=1)
public static final int AND = 0, OR = 1;
private final int andOrType;
......@@ -221,5 +219,20 @@ public class ConditionAndOr extends Condition {
public int getCost() {
return left.getCost() + right.getCost();
}
public Expression optimizeInJoin(Session session, Select select) throws SQLException {
if (andOrType == AND) {
Expression l = left.optimizeInJoin(session, select);
Expression r = right.optimizeInJoin(session, select);
if (l != left || r != right) {
left = l;
right = r;
// only optimize again if there was some change
// otherwise some expressions are 'over-optimized'
return optimize(session);
}
}
return this;
}
}
......@@ -6,12 +6,16 @@ package org.h2.expression;
import java.sql.SQLException;
import org.h2.command.dml.Select;
import org.h2.constant.SysProperties;
import org.h2.engine.Constants;
import org.h2.engine.Database;
import org.h2.engine.Session;
import org.h2.index.IndexCondition;
import org.h2.schema.Schema;
import org.h2.table.Column;
import org.h2.table.ColumnResolver;
import org.h2.table.FunctionTable;
import org.h2.table.TableFilter;
import org.h2.util.ObjectArray;
import org.h2.value.CompareMode;
......@@ -200,4 +204,36 @@ public class ConditionIn extends Condition {
return cost;
}
public Expression optimizeInJoin(Session session, Select select) throws SQLException {
if (!areAllValues(ExpressionVisitor.get(ExpressionVisitor.EVALUATABLE))) {
return this;
}
Database db = session.getDatabase();
Schema mainSchema = db.getSchema(Constants.SCHEMA_MAIN);
Function function = Function.getFunction(database, "TABLE_DISTINCT");
Expression[] array = new Expression[values.size()];
for (int i = 0; i < values.size(); i++) {
Expression e = (Expression) values.get(i);
array[i] = e;
}
ExpressionList list = new ExpressionList(array);
function.setParameter(0, list);
function.doneWithParameters();
ObjectArray columns = new ObjectArray();
int dataType = left.getType();
String columnName = session.getNextTempViewName() + "_X";
Column col = new Column(columnName, dataType);
columns.add(col);
function.setColumns(columns);
FunctionTable table = new FunctionTable(mainSchema, session, function);
String viewName = session.getNextTempViewName();
TableFilter filter = new TableFilter(session, table, viewName, false, select);
select.addTableFilter(filter, true);
ExpressionColumn column = new ExpressionColumn(db, null, viewName, columnName);
Comparison on = new Comparison(session, Comparison.EQUAL, left, column);
on.mapColumns(filter, 0);
filter.addFilterCondition(on, true);
return ValueExpression.get(ValueBoolean.get(true));
}
}
......@@ -7,6 +7,7 @@ package org.h2.expression;
import java.sql.SQLException;
import org.h2.command.dml.Query;
import org.h2.command.dml.Select;
import org.h2.constant.ErrorCode;
import org.h2.engine.Database;
import org.h2.engine.Session;
......@@ -14,6 +15,7 @@ import org.h2.message.Message;
import org.h2.result.LocalResult;
import org.h2.table.ColumnResolver;
import org.h2.table.TableFilter;
import org.h2.table.TableView;
import org.h2.value.Value;
import org.h2.value.ValueBoolean;
import org.h2.value.ValueNull;
......@@ -122,4 +124,26 @@ public class ConditionInSelect extends Condition {
return left.getCost() + 10 + (int) (10 * query.getCost());
}
public Expression optimizeInJoin(Session session, Select select) throws SQLException {
if (all || compareType != Comparison.EQUAL) {
return this;
}
if (!query.isEverything(ExpressionVisitor.EVALUATABLE)) {
return this;
}
String alias = query.getFirstColumnAlias(session);
query.setDistinct(true);
if (alias == null) {
return this;
}
TableView view = TableView.createTempView(session, session.getUser(), query);
TableFilter filter = new TableFilter(session, view, view.getName(), false, select);
select.addTableFilter(filter, true);
ExpressionColumn column = new ExpressionColumn(session.getDatabase(), null, view.getName(), alias);
Comparison on = new Comparison(session, Comparison.EQUAL, left, column);
on.mapColumns(filter, 0);
filter.addFilterCondition(on, true);
return ValueExpression.get(ValueBoolean.get(true));
}
}
......@@ -6,6 +6,7 @@ package org.h2.expression;
import java.sql.SQLException;
import org.h2.command.dml.Select;
import org.h2.engine.Session;
import org.h2.table.Column;
import org.h2.table.ColumnResolver;
......@@ -103,4 +104,12 @@ public abstract class Expression {
addedToFilter = true;
}
}
public String toString() {
return getSQL();
}
public Expression optimizeInJoin(Session session, Select select) throws SQLException {
return this;
}
}
......@@ -32,12 +32,12 @@ public class ExpressionColumn extends Expression {
private Column column;
private boolean evaluatable;
public ExpressionColumn(Database database, Select select, Column column) {
public ExpressionColumn(Database database, Column column) {
this.database = database;
this.column = column;
}
public ExpressionColumn(Database database, Select select, String schemaName, String tableAlias, String columnName) {
public ExpressionColumn(Database database, String schemaName, String tableAlias, String columnName) {
this.database = database;
this.schemaName = schemaName;
this.tableAlias = tableAlias;
......@@ -184,7 +184,7 @@ public class ExpressionColumn extends Expression {
public long getPrecision() {
return column.getPrecision();
}
public int getDisplaySize() {
return column.getDisplaySize();
}
......
......@@ -21,6 +21,7 @@ import org.h2.engine.Database;
import org.h2.engine.Mode;
import org.h2.engine.Session;
import org.h2.message.Message;
import org.h2.result.LocalResult;
import org.h2.schema.Sequence;
import org.h2.security.BlockCipher;
import org.h2.security.CipherFactory;
......@@ -31,14 +32,12 @@ import org.h2.table.LinkSchema;
import org.h2.table.TableFilter;
import org.h2.tools.CompressTool;
import org.h2.tools.Csv;
import org.h2.tools.SimpleResultSet;
import org.h2.util.ObjectUtils;
import org.h2.util.MathUtils;
import org.h2.util.MemoryUtils;
import org.h2.util.ObjectArray;
import org.h2.util.ObjectUtils;
import org.h2.util.RandomUtils;
import org.h2.util.StringUtils;
import org.h2.value.DataType;
import org.h2.value.Value;
import org.h2.value.ValueArray;
import org.h2.value.ValueBoolean;
......@@ -85,7 +84,7 @@ public class Function extends Expression implements FunctionCall {
public static final int IFNULL = 200, CASEWHEN = 201, CONVERT = 202, CAST = 203, COALESCE = 204, NULLIF = 205,
CASE = 206, NEXTVAL = 207, CURRVAL = 208, ARRAY_GET = 209, CSVREAD = 210, CSVWRITE = 211,
MEMORY_FREE = 212, MEMORY_USED = 213, LOCK_MODE = 214, SCHEMA = 215, SESSION_ID = 216, ARRAY_LENGTH = 217,
LINK_SCHEMA = 218, TABLE = 219, LEAST = 220, GREATEST = 221;
LINK_SCHEMA = 218, TABLE = 219, LEAST = 220, GREATEST = 221, TABLE_DISTINCT = 222;
private static final int VAR_ARGS = -1;
......@@ -286,6 +285,7 @@ public class Function extends Expression implements FunctionCall {
addFunction("ARRAY_LENGTH", ARRAY_LENGTH, 1, Value.INT);
addFunction("LINK_SCHEMA", LINK_SCHEMA, 6, Value.RESULT_SET);
addFunctionWithNull("TABLE", TABLE, VAR_ARGS, Value.RESULT_SET);
addFunctionWithNull("TABLE_DISTINCT", TABLE_DISTINCT, VAR_ARGS, Value.RESULT_SET);
addFunctionWithNull("LEAST", LEAST, VAR_ARGS, Value.NULL);
addFunctionWithNull("GREATEST", GREATEST, VAR_ARGS, Value.NULL);
}
......@@ -817,14 +817,16 @@ public class Function extends Expression implements FunctionCall {
return ValueResultSet.get(rs);
}
case TABLE:
return getTable(session, args, false);
return getTable(session, args, false, false);
case TABLE_DISTINCT:
return getTable(session, args, false, true);
case CSVWRITE: {
session.getUser().checkAdmin();
Connection conn = session.createConnection(false);
String charset = v2 == null ? null : v2.getString();
String fieldSeparatorWrite = v3 == null ? null : v3.getString();
String fieldDelimiter = v4 == null ? null : v4.getString();
String escapeCharacter = v5 == null ? null : v5.getString();
String escapeCharacter = v5 == null ? null : v5.getString();
Csv csv = Csv.getInstance();
setCsvDelimiterEscape(csv, fieldSeparatorWrite, fieldDelimiter, escapeCharacter);
int rows = csv.write(conn, v0.getString(), v1.getString(), charset);
......@@ -1266,6 +1268,7 @@ public class Function extends Expression implements FunctionCall {
case COALESCE:
case CSVREAD:
case TABLE:
case TABLE_DISTINCT:
case LEAST:
case GREATEST:
min = 1;
......@@ -1438,14 +1441,14 @@ public class Function extends Expression implements FunctionCall {
}
return precision;
}
public int getDisplaySize() {
if (precision == 0) {
calculatePrecisionAndDisplaySize();
}
return displaySize;
}
private void calculatePrecisionAndDisplaySize() {
switch (info.type) {
case ENCRYPT:
......@@ -1529,6 +1532,7 @@ public class Function extends Expression implements FunctionCall {
buff.append(args[1].getSQL());
break;
}
case TABLE_DISTINCT:
case TABLE: {
for (int i = 0; i < args.length; i++) {
if (i > 0) {
......@@ -1597,14 +1601,17 @@ public class Function extends Expression implements FunctionCall {
return vr;
}
case TABLE: {
return getTable(session, args, true);
return getTable(session, args, true, false);
}
case TABLE_DISTINCT: {
return getTable(session, args, true, true);
}
default:
break;
}
return (ValueResultSet) getValueWithArgs(session, args);
}
private void setCsvDelimiterEscape(Csv csv, String fieldSeparator, String fieldDelimiter, String escapeCharacter) {
if (fieldSeparator != null) {
csv.setFieldSeparatorWrite(fieldSeparator);
......@@ -1648,19 +1655,21 @@ public class Function extends Expression implements FunctionCall {
return cost;
}
public ValueResultSet getTable(Session session, Expression[] args, boolean onlyColumnList) throws SQLException {
SimpleResultSet rs = new SimpleResultSet();
public ValueResultSet getTable(Session session, Expression[] args, boolean onlyColumnList, boolean distinct) throws SQLException {
int len = columnList.length;
Expression[] header = new Expression[len];
Database db = session.getDatabase();
for (int i = 0; i < len; i++) {
Column c = columnList[i];
String columnName = c.getName();
int dataType = DataType.convertTypeToSQLType(c.getType());
int precision = MathUtils.convertLongToInt(c.getPrecision());
int scale = c.getScale();
rs.addColumn(columnName, dataType, precision, scale);
ExpressionColumn col = new ExpressionColumn(db, c);
header[i] = col;
}
LocalResult result = new LocalResult(session, header, len);
if (distinct) {
result.setDistinct();
}
if (!onlyColumnList) {
Value[][] list = new Value[args.length][];
Value[][] list = new Value[len][];
int rowCount = 0;
for (int i = 0; i < len; i++) {
Value v = args[i].getValue(session);
......@@ -1674,7 +1683,7 @@ public class Function extends Expression implements FunctionCall {
}
}
for (int row = 0; row < rowCount; row++) {
Object[] r = new Object[len];
Value[] r = new Value[len];
for (int j = 0; j < len; j++) {
Value[] l = list[j];
Value v;
......@@ -1687,12 +1696,13 @@ public class Function extends Expression implements FunctionCall {
v = v.convertPrecision(c.getPrecision());
v = v.convertScale(true, c.getScale());
}
r[j] = v.getObject();
r[j] = v;
}
rs.addRow(r);
result.addRow(r);
}
}
ValueResultSet vr = ValueResultSet.get(rs);
result.done();
ValueResultSet vr = ValueResultSet.getCopy(result, Integer.MAX_VALUE);
return vr;
}
......
......@@ -391,7 +391,7 @@ userString, passwordString, originalTableString)
","
Creates a table link to an external table.
The driver name may be empty if the driver is already loaded.
Usually, for update statements, the old rows are deleted first
Usually, for update statements, the old rows are deleted first
and then the new rows inserted. It is possible to emit update
statements (however this is not possible on rollback), however
in this case multi-row unique key updates may not always work.
......@@ -426,7 +426,7 @@ CREATE SEQUENCE [IF NOT EXISTS] newSequenceName
[CACHE long]
","
Creates a new sequence. The data type of a sequence is BIGINT.
The cache is the number of pre-allocated numbers. If the system crashes without closing the
The cache is the number of pre-allocated numbers. If the system crashes without closing the
database, at most this many numbers are lost. The default cache size is 32.
","
CREATE SEQUENCE SEQ_ID
......@@ -933,7 +933,7 @@ SET MAX_MEMORY_ROWS 1000
SET MAX_MEMORY_UNDO int
","
The maximum number of undo records per a session that are kept in-memory.
If a transaction is larger, the records are buffered to disk. The default value is 100000.
If a transaction is larger, the records are buffered to disk. The default value is 100000.
Changes to tables without a primary key can not be buffered to disk.
This setting is persistent.
Admin rights are required to execute this command.
......@@ -1177,7 +1177,7 @@ TEST AS T LEFT JOIN TEST AS T1 ON T.ID = T1.ID
{int | expression} [ASC | DESC]
[NULLS {FIRST | LAST}]
","
Sorts the result by the given column number, or by an expression.
Sorts the result by the given column number, or by an expression.
If the expression is a single parameter, then the value is interpreted
as a column number. Negative column numbers reverse the sort order.
","
......@@ -1215,7 +1215,7 @@ compare { {{ALL|ANY|SOME}(select)} | operand }
| [NOT] LIKE operand [ESCAPE string]
| [NOT] REGEXP operand
","
The right hand side of a condition.
The right hand side of a condition.
When comparing with LIKE, the wildcards characters are _ (any one character) and % (any characters).
When comparing with REGEXP, regular expression matching is used. See Java Matcher.find for details.
","
......@@ -2636,7 +2636,7 @@ LOCK_TIMEOUT()
"
"Functions (System)","LINK_SCHEMA","
LINK_SCHEMA(targetSchemaString, driverString, urlString,
LINK_SCHEMA(targetSchemaString, driverString, urlString,
userString, passwordString, sourceSchemaString): resultSet
","
Creates table links for all tables in a schema.
......@@ -2724,9 +2724,9 @@ CALL SESSION_ID()
"
"Functions (System)","TABLE","
TABLE( { name dataType = expression } [,..]): result set
TABLE|TABLE_DISTINCT( { name dataType = expression } [,..]): result set
","
Returns the result set.
Returns the result set. TABLE_DISTINCT removes duplicate rows.
","
SELECT * FROM TABLE(ID INT=(1, 2), NAME VARCHAR=('Hello', 'World'))
"
......
......@@ -55,7 +55,7 @@ public class LocalResult implements ResultInterface {
int scale = meta.getScale(i + 1);
int displaySize = meta.getColumnDisplaySize(i + 1);
Column col = new Column(name, type, precision, scale, displaySize);
Expression expr = new ExpressionColumn(db, null, col);
Expression expr = new ExpressionColumn(db, col);
cols.add(expr);
}
LocalResult result = new LocalResult(session, cols, columnCount);
......@@ -108,7 +108,17 @@ public class LocalResult implements ResultInterface {
return updateCount;
}
public LocalResult(Session session, ObjectArray cols, int visibleColumnCount) {
public LocalResult(Session session, ObjectArray expressionList, int visibleColumnCount) {
this(session, getList(expressionList), visibleColumnCount);
}
private static Expression[] getList(ObjectArray expressionList) {
Expression[] expressions = new Expression[expressionList.size()];
expressionList.toArray(expressions);
return expressions;
}
public LocalResult(Session session, Expression[] expressions, int visibleColumnCount) {
this.session = session;
if (session == null) {
this.maxMemoryRows = Integer.MAX_VALUE;
......@@ -118,9 +128,8 @@ public class LocalResult implements ResultInterface {
rows = new ObjectArray();
this.visibleColumnCount = visibleColumnCount;
rowId = -1;
this.expressions = new Expression[cols.size()];
cols.toArray(expressions);
this.displaySizes = new int[cols.size()];
this.expressions = expressions;
this.displaySizes = new int[expressions.length];
}
public void setSortOrder(SortOrder sort) {
......@@ -128,9 +137,8 @@ public class LocalResult implements ResultInterface {
}
public void setDistinct() {
// TODO big result sets: how to buffer distinct result sets? maybe do
// the
// distinct when sorting each block, and final merging
// TODO big result sets: how to buffer distinct result sets?
// maybe remove duplicates when sorting each block, and when merging
distinctRows = new ValueHashMap(session.getDatabase());
}
......@@ -340,7 +348,7 @@ public class LocalResult implements ResultInterface {
}
}
}
public String toString() {
return "columns: " + visibleColumnCount + " rows: " + rowCount + " pos: " + rowId;
}
......
......@@ -55,6 +55,7 @@ public class WebServer implements Service {
{ "pt_BR", "Portugu\u00eas (Brasil)"},
{ "pt_PT", "Portugu\u00eas (Europeu)"},
{ "ru", "\u0440\u0443\u0441\u0441\u043a\u0438\u0439"},
{ "uk", "\u0423\u043A\u0440\u0430\u0457\u043D\u0441\u044C\u043A\u0430"},
{ "zh_CN", "\u4E2D\u6587"},
};
......@@ -76,6 +77,8 @@ public class WebServer implements Service {
};
/*
String[] list = Locale.getISOLanguages();
for(int i=0; i<list.length; i++) System.out.print(list[i] + " ");
String lang = new java.util.Locale("hu").getDisplayLanguage(new java.util.Locale("hu"));
java.util.Locale.CHINESE.getDisplayLanguage(
java.util.Locale.CHINESE);
......
.translator=Igor Dobrovolskyi
a.help=&\#x0414;&\#x043E;&\#x043F;&\#x043E;&\#x043C;&\#x043E;&\#x0433;&\#x0430;
a.language=&\#x0423;&\#x043A;&\#x0440;&\#x0430;&\#x0457;&\#x043D;&\#x0441;&\#x044C;&\#x043A;&\#x0430;
a.lynxNotSupported=&\#x0412;&\#x0438;&\#x0431;&\#x0430;&\#x0447;&\#x0442;&\#x0435;, &\#x0430;&\#x043B;&\#x0435; Lynx &\#x043D;&\#x0435; &\#x043F;&\#x0456;&\#x0434;&\#x0442;&\#x0440;&\#x0438;&\#x043C;&\#x0443;&\#x0454;&\#x0442;&\#x044C;&\#x0441;&\#x044F;
a.password=&\#x041F;&\#x0430;&\#x0440;&\#x043E;&\#x043B;&\#x044C;
a.remoteConnectionsDisabled=&\#x0412;&\#x0438;&\#x0431;&\#x0430;&\#x0447;&\#x0442;&\#x0435;, &\#x0432;&\#x0456;&\#x0434;&\#x0434;&\#x0430;&\#x043B;&\#x0435;&\#x043D;&\#x0456; &\#x043F;&\#x0456;&\#x0434;&\#x043A;&\#x043B;&\#x044E;&\#x0447;&\#x0435;&\#x043D;&\#x043D;&\#x044F; ('webAllowOthers') &\#x043D;&\#x0430; &\#x0446;&\#x044C;&\#x043E;&\#x043C;&\#x0443; &\#x0441;&\#x0435;&\#x0440;&\#x0432;&\#x0435;&\#x0440;&\#x0456; &\#x0437;&\#x0430;&\#x0431;&\#x043E;&\#x0440;&\#x043E;&\#x043D;&\#x0435;&\#x043D;&\#x0456;.
a.title=&\#x041A;&\#x043E;&\#x043D;&\#x0441;&\#x043E;&\#x043B;&\#x044C; H2
a.user=&\#x046;&\#x043C;'&\#x044F; &\#x043A;&\#x043E;&\#x0440;&\#x0438;&\#x0441;&\#x0442;&\#x0443;&\#x0432;&\#x0430;&\#x0447;&\#x0430;
admin.executing=&\#x0412;&\#x0438;&\#x043A;&\#x043E;&\#x043D;&\#x0443;&\#x0454;&\#x0442;&\#x044C;&\#x0441;&\#x044F;
admin.ip=IP
admin.lastAccess=&\#x041E;&\#x0441;&\#x0442;&\#x0430;&\#x043D;&\#x043D;&\#x0456;&\#x0439; &\#x0434;&\#x043E;&\#x0441;&\#x0442;&\#x0443;&\#x043F;
admin.lastQuery=&\#x041E;&\#x0441;&\#x0442;&\#x0430;&\#x043D;&\#x043D;&\#x0456;&\#x0439; &\#x0437;&\#x0430;&\#x043F;&\#x0438;&\#x0442;
admin.url=URL
adminAllow=&\#x0414;&\#x043E;&\#x0437;&\#x0432;&\#x043E;&\#x043B;&\#x0435;&\#x043D;&\#x0456; &\#x043A;&\#x043B;&\#x0456;&\#x0454;&\#x043D;&\#x0442;&\#x0438;
adminConnection=&\#x0411;&\#x0435;&\#x0437;&\#x043F;&\#x0435;&\#x043A;&\#x0430; &\#x043F;&\#x0456;&\#x0434;'&\#x0454;&\#x0434;&\#x043D;&\#x0430;&\#x043D;&\#x043D;&\#x044F;
adminHttp=&\#x0412;&\#x0438;&\#x043A;&\#x043E;&\#x0440;&\#x0438;&\#x0441;&\#x0442;&\#x043E;&\#x0432;&\#x0443;&\#x0439;&\#x0442;&\#x0435; &\#x043D;&\#x0435;&\#x0437;&\#x0430;&\#x0448;&\#x0438;&\#x0444;&\#x0440;&\#x043E;&\#x0432;&\#x0430;&\#x043D;&\#x0456; HTTP &\#x043F;&\#x0456;&\#x0434;'&\#x0454;&\#x0434;&\#x043D;&\#x0430;&\#x043D;&\#x043D;&\#x044F;
adminHttps=&\#x0412;&\#x0438;&\#x043A;&\#x043E;&\#x0440;&\#x0438;&\#x0441;&\#x0442;&\#x043E;&\#x0432;&\#x0443;&\#x0439;&\#x0442;&\#x0435; &\#x0437;&\#x0430;&\#x0448;&\#x0438;&\#x0444;&\#x0440;&\#x043E;&\#x0432;&\#x0430;&\#x043D;&\#x0456; SSL (HTTPS) &\#x043F;&\#x0456;&\#x0434;'&\#x0454;&\#x0434;&\#x043D;&\#x0430;&\#x043D;&\#x043D;&\#x044F;
adminLocal=&\#x0414;&\#x043E;&\#x0437;&\#x0432;&\#x043E;&\#x043B;&\#x0435;&\#x043D;&\#x043E; &\#x043B;&\#x0438;&\#x0448;&\#x0435; &\#x043B;&\#x043E;&\#x043A;&\#x0430;&\#x043B;&\#x044C;&\#x043D;&\#x0456; &\#x043F;&\#x0456;&\#x0434;'&\#x0454;&\#x0434;&\#x043D;&\#x0430;&\#x043D;&\#x043D;&\#x044F;
adminLogin=&\#x0410;&\#x0434;&\#x043C;&\#x0456;&\#x043D;&\#x0456;&\#x0441;&\#x0442;&\#x0440;&\#x0430;&\#x0442;&\#x0438;&\#x0432;&\#x043D;&\#x0438;&\#x0439; &\#x043B;&\#x043E;&\#x0433;&\#x0456;&\#x043D;
adminLoginCancel=&\#x0412;&\#x0456;&\#x0434;&\#x043C;&\#x0456;&\#x043D;&\#x0438;&\#x0442;&\#x0438;
adminLoginOk=OK
adminLogout=&\#x0417;&\#x0430;&\#x0432;&\#x0435;&\#x0440;&\#x0448;&\#x0435;&\#x043D;&\#x043D;&\#x044F; &\#x0441;&\#x0435;&\#x0430;&\#x043D;&\#x0441;&\#x0443;
adminOthers=&\#x0414;&\#x043E;&\#x0437;&\#x0432;&\#x043E;&\#x043B;&\#x0438;&\#x0442;&\#x0438; &\#x043F;&\#x0456;&\#x0434;'&\#x0454;&\#x0434;&\#x043D;&\#x0430;&\#x043D;&\#x043D;&\#x044F; &\#x0437; &\#x0456;&\#x043D;&\#x0448;&\#x0438;&\#x0445; &\#x043A;&\#x043E;&\#x043F;&\#x043C;'&\#x044E;&\#x0442;&\#x0435;&\#x0440;&\#x0456;&\#x0432;
adminPort=&\#x041D;&\#x043E;&\#x043C;&\#x0435;&\#x0440; &\#x043F;&\#x043E;&\#x0440;&\#x0442;&\#x0430;
adminPortWeb=&\#x041D;&\#x043E;&\#x043C;&\#x0435;&\#x0440; &\#x043F;&\#x043E;&\#x0440;&\#x0442;&\#x0430; &\#x0432;&\#x0435;&\#x0431; &\#x0441;&\#x0435;&\#x0440;&\#x0432;&\#x0435;&\#x0440;&\#x0430;
adminRestart=&\#x0417;&\#x043C;&\#x0456;&\#x043D;&\#x0438; &\#x0432;&\#x0441;&\#x0442;&\#x0443;&\#x043F;&\#x043B;&\#x044F;&\#x0442;&\#x044C; &\#x0432; &\#x0441;&\#x0438;&\#x043B;&\#x0443; &\#x043F;&\#x0456;&\#x0441;&\#x043B;&\#x044F; &\#x043F;&\#x0435;&\#x0440;&\#x0435;&\#x0437;&\#x0430;&\#x0432;&\#x0430;&\#x043D;&\#x0442;&\#x0430;&\#x0436;&\#x0435;&\#x043D;&\#x043D;&\#x044F; &\#x0441;&\#x0435;&\#x0440;&\#x0432;&\#x0435;&\#x0440;&\#x0430;.
adminSave=&\#x0417;&\#x0431;&\#x0435;&\#x0440;&\#x0435;&\#x0433;&\#x0442;&\#x0438;
adminSessions=&\#x0410;&\#x043A;&\#x0442;&\#x0438;&\#x0432;&\#x043D;&\#x0456; &\#x0441;&\#x0435;&\#x0441;&\#x0456;&\#x0457;
adminShutdown=&\#x0412;&\#x0438;&\#x043A;&\#x043B;&\#x044E;&\#x0447;&\#x0438;&\#x0442;&\#x0438;
adminTitle=&\#x041D;&\#x0430;&\#x0441;&\#x0442;&\#x0440;&\#x043E;&\#x0439;&\#x043A;&\#x0438; &\#x043A;&\#x043E;&\#x043D;&\#x0441;&\#x043E;&\#x043B;&\#x0456; H2
helpAction=&\#x0414;&\#x0456;&\#x044F;
helpAddAnotherRow=&\#x0414;&\#x043E;&\#x0434;&\#x0430;&\#x0442;&\#x0438; &\#x043D;&\#x043E;&\#x0432;&\#x0438;&\#x0439; &\#x0440;&\#x044F;&\#x0434;&\#x043E;&\#x043A;
helpAddDrivers=&\#x0414;&\#x043E;&\#x0434;&\#x0430;&\#x0454;&\#x0442;&\#x044C;&\#x0441;&\#x044F; &\#x0434;&\#x0440;&\#x0430;&\#x0439;&\#x0432;&\#x0435;&\#x0440; &\#x0431;&\#x0430;&\#x0437;&\#x0438; &\#x0434;&\#x0430;&\#x043D;&\#x0438;&\#x0445;
helpAddDriversOnlyJava=&\#x041B;&\#x0438;&\#x0448;&\#x0435; Java &\#x0432;&\#x0435;&\#x0440;&\#x0441;&\#x0456;&\#x044F; &\#x043F;&\#x0456;&\#x0434;&\#x0442;&\#x0440;&\#x0438;&\#x043C;&\#x0443;&\#x0454; &\#x0434;&\#x043E;&\#x0434;&\#x0430;&\#x0442;&\#x043A;&\#x043E;&\#x0432;&\#x0456; &\#x0434;&\#x0440;&\#x0430;&\#x0439;&\#x0432;&\#x0435;&\#x0440;&\#x0438; (&\#x0446;&\#x044F; &\#x043C;&\#x043E;&\#x0436;&\#x043B;&\#x0438;&\#x0432;&\#x0456;&\#x0441;&\#x0442;&\#x044C; &\#x043D;&\#x0435; &\#x043F;&\#x0456;&\#x0434;&\#x0442;&\#x0440;&\#x0438;&\#x043C;&\#x0443;&\#x0454;&\#x0442;&\#x044C;&\#x0441;&\#x044F; &\#x0440;&\#x0456;&\#x0434;&\#x043D;&\#x043E;&\#x044E; &\#x0432;&\#x0435;&\#x0440;&\#x0441;&\#x0456;&\#x0454;&\#x044E;).
helpAddDriversText=&\#x041D;&\#x043E;&\#x0432;&\#x0456; &\#x0434;&\#x0440;&\#x0430;&\#x0439;&\#x0432;&\#x0435;&\#x0440;&\#x0438; &\#x0431;&\#x0430;&\#x0437; &\#x0434;&\#x0430;&\#x043D;&\#x0438;&\#x0445; &\#x043C;&\#x043E;&\#x0436;&\#x0443;&\#x0442;&\#x044C; &\#x0431;&\#x0443;&\#x0442;&\#x0438; &\#x0437;&\#x0430;&\#x0440;&\#x0435;&\#x0454;&\#x0441;&\#x0442;&\#x0440;&\#x043E;&\#x0432;&\#x0430;&\#x043D;&\#x0456; &\#x0434;&\#x043E;&\#x0434;&\#x0430;&\#x0432;&\#x0430;&\#x043D;&\#x043D;&\#x044F;&\#x043C; &\#x0448;&\#x043B;&\#x044F;&\#x0445;&\#x0443; &\#x0434;&\#x043E; Jar-&\#x0444;&\#x0430;&\#x0439;&\#x043B;&\#x0443; &\#x0437; &\#x0434;&\#x0440;&\#x0430;&\#x0439;&\#x0432;&\#x0435;&\#x0440;&\#x043E;&\#x043C; &\#x0434;&\#x043E; &\#x0437;&\#x043C;&\#x0456;&\#x043D;&\#x043D;&\#x043E;&\#x0457; &\#x043E;&\#x0442;&\#x043E;&\#x0447;&\#x0435;&\#x043D;&\#x043D;&\#x044F; H2DRIVERS &\#x0430;&\#x0431;&\#x043E; CLASSPATH. &\#x041D;&\#x0430;&\#x043F;&\#x0440;&\#x0438;&\#x043A;&\#x043B;&\#x0430;&\#x0434; (Windows)\: &\#x0429;&\#x043E;&\#x0431; &\#x0434;&\#x043E;&\#x0434;&\#x0430;&\#x0442;&\#x0438; &\#x0434;&\#x0440;&\#x0430;&\#x0439;&\#x0432;&\#x0435;&\#x0440; &\#x0431;&\#x0430;&\#x0437;&\#x0438; &\#x0434;&\#x0430;&\#x043D;&\#x0438;&\#x0445; C\:\\Programs\\hsqldb\\lib\\hsqldb.jar, &\#x0432;&\#x0441;&\#x0442;&\#x0430;&\#x043D;&\#x043E;&\#x0432;&\#x0456;&\#x0442;&\#x044C; &\#x0437;&\#x043C;&\#x0456;&\#x043D;&\#x043D;&\#x0443; &\#x043E;&\#x0442;&\#x043E;&\#x0447;&\#x0435;&\#x043D;&\#x043D;&\#x044F; H2DRIVERS &\#x0440;&\#x0456;&\#x0432;&\#x043D;&\#x043E;&\#x044E; C\:\\Programs\\hsqldb\\lib\\hsqldb.jar.
helpAddRow=&\#x0414;&\#x043E;&\#x0434;&\#x0430;&\#x0442;&\#x0438; &\#x043D;&\#x043E;&\#x0432;&\#x0438;&\#x0439; &\#x0440;&\#x044F;&\#x0434;&\#x043E;&\#x043A;
helpCommandHistory=&\#x041F;&\#x043E;&\#x043A;&\#x0430;&\#x0437;&\#x0443;&\#x0454; &\#x0456;&\#x0441;&\#x0442;&\#x043E;&\#x0440;&\#x0456;&\#x044E; &\#x043A;&\#x043E;&\#x043C;&\#x0430;&\#x043D;&\#x0434;
helpCreateTable=&\#x0421;&\#x0442;&\#x0432;&\#x043E;&\#x0440;&\#x0438;&\#x0442;&\#x0438; &\#x043D;&\#x043E;&\#x0432;&\#x0443; &\#x0442;&\#x0430;&\#x0431;&\#x043B;&\#x0438;&\#x0446;&\#x044E;
helpDeleteRow=&\#x0412;&\#x0438;&\#x0434;&\#x0430;&\#x043B;&\#x0438;&\#x0442;&\#x0438; &\#x0440;&\#x044F;&\#x0434;&\#x043E;&\#x043A;
helpDisconnect=&\#x0412;&\#x0456;&\#x0434;'&\#x0454;&\#x0434;&\#x043D;&\#x0443;&\#x0454; &\#x0432;&\#x0456;&\#x0434; &\#x0431;&\#x0430;&\#x0437;&\#x0438; &\#x0434;&\#x0430;&\#x043D;&\#x0438;&\#x0445;
helpDisplayThis=&\#x041F;&\#x043E;&\#x043A;&\#x0430;&\#x0437;&\#x0443;&\#x0454; &\#x0446;&\#x044E; &\#x0441;&\#x0442;&\#x043E;&\#x0440;&\#x0456;&\#x043D;&\#x043A;&\#x0443; &\#x0434;&\#x043E;&\#x043F;&\#x043E;&\#x043C;&\#x043E;&\#x0433;&\#x0438;
helpDropTable=&\#x0412;&\#x0438;&\#x0434;&\#x0430;&\#x043B;&\#x0438;&\#x0442;&\#x0438; &\#x0442;&\#x0430;&\#x0431;&\#x043B;&\#x0438;&\#x0446;&\#x044E;, &\#x044F;&\#x043A;&\#x0449;&\#x043E; &\#x0432;&\#x043E;&\#x043D;&\#x0430; &\#x0456;&\#x0441;&\#x043D;&\#x0443;&\#x0454;
helpExecuteCurrent=&\#x0412;&\#x0438;&\#x043A;&\#x043E;&\#x043D;&\#x0443;&\#x0454; &\#x043F;&\#x043E;&\#x0442;&\#x043E;&\#x0447;&\#x043D;&\#x0438;&\#x0439; SQL &\#x0437;&\#x0430;&\#x043F;&\#x0438;&\#x0442;
helpIcon=&\#x046;&\#x043A;&\#x043E;&\#x043D;&\#x043A;&\#x0430;
helpImportantCommands=&\#x0412;&\#x0430;&\#x0436;&\#x043B;&\#x0438;&\#x0432;&\#x0456; &\#x043A;&\#x043E;&\#x043C;&\#x0430;&\#x043D;&\#x0434;&\#x0438;
helpOperations=&\#x041E;&\#x043F;&\#x0435;&\#x0440;&\#x0430;&\#x0446;&\#x0456;&\#x0457;
helpQuery=&\#x0417;&\#x0430;&\#x043F;&\#x0438;&\#x0442; &\#x0434;&\#x043E; &\#x0442;&\#x0430;&\#x0431;&\#x043B;&\#x0438;&\#x0446;&\#x0456;
helpSampleSQL=&\#x041F;&\#x0440;&\#x0438;&\#x043A;&\#x043B;&\#x0430;&\#x0434; SQL &\#x0437;&\#x0430;&\#x043F;&\#x0438;&\#x0442;&\#x0443;
helpStatements=SQL &\#x0437;&\#x0430;&\#x043F;&\#x0438;&\#x0442;&\#x0438;
helpUpdate=&\#x0417;&\#x043C;&\#x0456;&\#x043D;&\#x0438;&\#x0442;&\#x0438; &\#x0434;&\#x0430;&\#x043D;&\#x0456; &\#x0432; &\#x0440;&\#x044F;&\#x0434;&\#x043A;&\#x0443;
helpWithColumnsIdName=&\#x0437; ID &\#x0456; NAME &\#x043A;&\#x043E;&\#x043B;&\#x043E;&\#x043D;&\#x043A;&\#x0430;&\#x043C;&\#x0438;
login.connect=&\#x041F;&\#x0456;&\#x0434;'&\#x0454;&\#x0434;&\#x043D;&\#x0430;&\#x0442;&\#x0438;&\#x0441;&\#x044C;
login.driverClass=Driver Class
login.driverNotFound=&\#x0414;&\#x0440;&\#x0430;&\#x0432;&\#x0435;&\#x0440; &\#x0431;&\#x0430;&\#x0437;&\#x0438; &\#x0434;&\#x0430;&\#x043D;&\#x0438;&\#x0445; &\#x043D;&\#x0435; &\#x0437;&\#x043D;&\#x0430;&\#x0439;&\#x0434;&\#x0435;&\#x043D;&\#x043E;<br />&\#x041F;&\#x043E;&\#x0434;&\#x0438;&\#x0432;&\#x0456;&\#x0442;&\#x044C;&\#x0441;&\#x044F; &\#x0432; &\#x0434;&\#x043E;&\#x043F;&\#x043E;&\#x043C;&\#x043E;&\#x0437;&\#x0456; &\#x044F;&\#x043A; &\#x0434;&\#x043E;&\#x0434;&\#x0430;&\#x0442;&\#x0438; &\#x043D;&\#x043E;&\#x0432;&\#x0456; &\#x0434;&\#x0440;&\#x0430;&\#x0439;&\#x0432;&\#x0435;&\#x0440;&\#x0438;
login.goAdmin=&\#x041D;&\#x0430;&\#x0441;&\#x0442;&\#x0440;&\#x043E;&\#x0439;&\#x043A;&\#x0438;
login.jdbcUrl=JDBC URL
login.language=&\#x041C;&\#x043E;&\#x0432;&\#x0430;
login.login=&\#x041B;&\#x043E;&\#x0433;&\#x0456;&\#x043D;
login.remove=&\#x0412;&\#x0438;&\#x0434;&\#x0430;&\#x043B;&\#x0438;&\#x0442;&\#x0438;
login.save=&\#x0417;&\#x0431;&\#x0435;&\#x0440;&\#x0435;&\#x0433;&\#x0442;&\#x0438;
login.savedSetting=&\#x0417;&\#x0431;&\#x0435;&\#x0440;&\#x0435;&\#x0436;&\#x0435;&\#x043D;&\#x0456; &\#x043D;&\#x0430;&\#x043B;&\#x0430;&\#x0448;&\#x0442;&\#x0443;&\#x0432;&\#x0430;&\#x043D;&\#x043D;&\#x044F;
login.settingName=&\#x046;&\#x043C;'&\#x044F; &\#x043D;&\#x0430;&\#x043B;&\#x0430;&\#x0448;&\#x0442;&\#x0443;&\#x0432;&\#x0430;&\#x043D;&\#x043D;&\#x044F;
login.testConnection=&\#x0422;&\#x0435;&\#x0441;&\#x0442;&\#x043E;&\#x0432;&\#x0435; &\#x043F;&\#x0456;&\#x0434;'&\#x0454;&\#x0434;&\#x043D;&\#x0430;&\#x043D;&\#x043D;&\#x044F;
login.testSuccessful=&\#x0422;&\#x0435;&\#x0441;&\#x0442; &\#x043F;&\#x0440;&\#x043E;&\#x0439;&\#x0434;&\#x0435;&\#x043D;&\#x043E; &\#x0443;&\#x0441;&\#x043F;&\#x0456;&\#x0448;&\#x043D;&\#x043E;
login.welcome=&\#x041A;&\#x043E;&\#x043D;&\#x0441;&\#x043E;&\#x043B;&\#x044C; H2
result.1row=1 &\#x0440;&\#x044F;&\#x0434;&\#x043E;&\#x043A;
result.autoCommitOff=&\#x0410;&\#x0432;&\#x0442;&\#x043E;&\#x0437;&\#x0431;&\#x0435;&\#x0440;&\#x0435;&\#x0436;&\#x0435;&\#x043D;&\#x043D;&\#x044F; &\#x0432;&\#x0438;&\#x043A;&\#x043B;&\#x044E;&\#x0447;&\#x0435;&\#x043D;&\#x0435;
result.autoCommitOn=&\#x0410;&\#x0432;&\#x0442;&\#x043E;&\#x0437;&\#x0431;&\#x0435;&\#x0440;&\#x0435;&\#x0436;&\#x0435;&\#x043D;&\#x043D;&\#x044F; &\#x0432;&\#x043A;&\#x043B;&\#x044E;&\#x0447;&\#x0435;&\#x043D;&\#x0435;
result.maxrowsSet=&\#x0412;&\#x0441;&\#x0442;&\#x0430;&\#x043D;&\#x043E;&\#x0432;&\#x043B;&\#x0435;&\#x043D;&\#x043E; &\#x043C;&\#x0430;&\#x043A;&\#x0441;&\#x0438;&\#x043C;&\#x0430;&\#x043B;&\#x044C;&\#x043D;&\#x0443; &\#x043A;&\#x0456;&\#x043B;&\#x044C;&\#x043A;&\#x0456;&\#x0441;&\#x0442;&\#x044C; &\#x0440;&\#x044F;&\#x0434;&\#x043A;&\#x0456;&\#x0432;
result.noRows=&\#x043D;&\#x0435;&\#x043C;&\#x0430;&\#x0454; &\#x0440;&\#x044F;&\#x0434;&\#x043A;&\#x0456;&\#x0432;
result.noRunningStatement=&\#x0412; &\#x0434;&\#x0430;&\#x043D;&\#x0438;&\#x0439; &\#x043C;&\#x043E;&\#x043C;&\#x0435;&\#x043D;&\#x0442; &\#x043D;&\#x0435; &\#x0432;&\#x0438;&\#x043A;&\#x043E;&\#x043D;&\#x0443;&\#x0454;&\#x0442;&\#x044C;&\#x0441;&\#x044F; &\#x0436;&\#x043E;&\#x0434;&\#x0435;&\#x043D; &\#x0437;&\#x0430;&\#x043F;&\#x0438;&\#x0442;
result.rows=&\#x0440;&\#x044F;&\#x0434;&\#x043A;&\#x0456;&\#x0432;
result.statementWasCancelled=&\#x0417;&\#x0430;&\#x043F;&\#x0438;&\#x0442; &\#x0431;&\#x0443;&\#x043B;&\#x043E; &\#x0432;&\#x0456;&\#x0434;&\#x043C;&\#x0456;&\#x043D;&\#x0435;&\#x043D;&\#x043E;
result.updateCount=&\#x041A;&\#x0456;&\#x043B;&\#x044C;&\#x043A;&\#x0456;&\#x0441;&\#x0442;&\#x044C; &\#x0437;&\#x043C;&\#x0456;&\#x043D;&\#x0435;&\#x043D;&\#x0438;&\#x0445;
resultEdit.add=&\#x0414;&\#x043E;&\#x0434;&\#x0430;&\#x0442;&\#x0438;
resultEdit.cancel=&\#x0412;&\#x0456;&\#x0434;&\#x043C;&\#x0456;&\#x043D;&\#x0438;&\#x0442;&\#x0438;
resultEdit.delete=&\#x0412;&\#x0438;&\#x0434;&\#x0430;&\#x043B;&\#x0438;&\#x0442;&\#x0438;
resultEdit.edit=&\#x0420;&\#x0435;&\#x0434;&\#x0430;&\#x0433;&\#x0443;&\#x0432;&\#x0430;&\#x0442;&\#x0438;
resultEdit.editResult=&\#x0420;&\#x0435;&\#x0434;&\#x0430;&\#x0433;&\#x0443;&\#x0432;&\#x0430;&\#x0442;&\#x0438;
resultEdit.save=&\#x0417;&\#x0431;&\#x0435;&\#x0440;&\#x0435;&\#x0433;&\#x0442;&\#x0438;
toolbar.all=&\#x0412;&\#x0441;&\#x0456;
toolbar.autoCommit=&\#x0410;&\#x0432;&\#x0442;&\#x043E;&\#x0437;&\#x0431;&\#x0435;&\#x0440;&\#x0435;&\#x0436;&\#x0435;&\#x043D;&\#x043D;&\#x044F;
toolbar.autoComplete=&\#x0410;&\#x0432;&\#x0442;&\#x043E; &\#x0434;&\#x043E;&\#x043F;&\#x043E;&\#x0432;&\#x043D;&\#x0435;&\#x043D;&\#x043D;&\#x044F;
toolbar.autoComplete.full=&\#x041F;&\#x043E;&\#x0432;&\#x043D;&\#x0435;
toolbar.autoComplete.normal=&\#x041D;&\#x043E;&\#x0440;&\#x043C;&\#x0430;&\#x043B;&\#x044C;&\#x043D;&\#x0435;
toolbar.autoComplete.off=&\#x0412;&\#x0438;&\#x043A;&\#x043B;&\#x044E;&\#x0447;&\#x0435;&\#x043D;&\#x0435;
toolbar.cancelStatement=&\#x0412;&\#x0456;&\#x0434;&\#x043C;&\#x0456;&\#x043D;&\#x0438;&\#x0442;&\#x0438; &\#x043F;&\#x043E;&\#x0442;&\#x043E;&\#x0447;&\#x043D;&\#x0438;&\#x0439; &\#x0437;&\#x0430;&\#x043F;&\#x0438;&\#x0442;
toolbar.clear=&\#x041E;&\#x0447;&\#x0438;&\#x0441;&\#x0442;&\#x0438;&\#x0442;&\#x0438;
toolbar.commit=&\#x041F;&\#x0456;&\#x0434;&\#x0442;&\#x0432;&\#x0435;&\#x0440;&\#x0434;&\#x0438;&\#x0442;&\#x0438; &\#x0437;&\#x043C;&\#x0456;&\#x043D;&\#x0438;
toolbar.disconnect=&\#x0412;&\#x0456;&\#x0434;'&\#x0454;&\#x0434;&\#x043D;&\#x0430;&\#x0442;&\#x0438;&\#x0441;&\#x044C;
toolbar.history=&\#x046;&\#x0441;&\#x0442;&\#x043E;&\#x0440;&\#x0456;&\#x044F; &\#x043A;&\#x043E;&\#x043C;&\#x0430;&\#x043D;&\#x0434;
toolbar.maxRows=&\#x041C;&\#x0430;&\#x043A;&\#x0441;&\#x0438;&\#x043C;&\#x0430;&\#x043B;&\#x044C;&\#x043D;&\#x0430; &\#x043A;&\#x0456;&\#x043B;&\#x044C;&\#x043A;&\#x0456;&\#x0441;&\#x0442;&\#x044C; &\#x0440;&\#x044F;&\#x0434;&\#x043A;&\#x0456;&\#x0432;
toolbar.refresh=&\#x041E;&\#x043D;&\#x043E;&\#x0432;&\#x0438;&\#x0442;&\#x0438;
toolbar.rollback=&\#x0412;&\#x0435;&\#x0440;&\#x043D;&\#x0443;&\#x0442;&\#x0438; &\#x043D;&\#x0430;&\#x0437;&\#x0430;&\#x0434;
toolbar.run=&\#x0412;&\#x0438;&\#x043A;&\#x043E;&\#x043D;&\#x0430;&\#x0442;&\#x0438; (Ctrl+Enter)
toolbar.sqlStatement=SQL &\#x0437;&\#x0430;&\#x043F;&\#x0438;&\#x0442;
tree.admin=&\#x0410;&\#x0434;&\#x043C;&\#x0456;&\#x043D;
tree.current=&\#x041F;&\#x043E;&\#x0442;&\#x043E;&\#x0447;&\#x043D;&\#x0435; &\#x0437;&\#x043D;&\#x0430;&\#x0447;&\#x0435;&\#x043D;&\#x043D;&\#x044F;
tree.hashed=&\#x0425;&\#x0435;&\#x0448;&\#x043E;&\#x0432;&\#x0430;&\#x043D;&\#x0438;&\#x0439;
tree.increment=&\#x0417;&\#x0431;&\#x0456;&\#x043B;&\#x044C;&\#x0448;&\#x0438;&\#x0442;&\#x0438;
tree.indexes=&\#x046;&\#x043D;&\#x0434;&\#x0435;&\#x043A;&\#x0441;&\#x0438;
tree.nonUnique=&\#x041D;&\#x0435;&\#x0443;&\#x043D;&\#x0456;&\#x043A;&\#x0430;&\#x043B;&\#x044C;&\#x043D;&\#x0435;
tree.sequences=&\#x041F;&\#x043E;&\#x0441;&\#x043B;&\#x0456;&\#x0434;&\#x043E;&\#x0432;&\#x043D;&\#x043E;&\#x0441;&\#x0442;&\#x0456;
tree.unique=&\#x0423;&\#x043D;&\#x0456;&\#x043A;&\#x0430;&\#x043B;&\#x044C;&\#x043D;&\#x0435;
tree.users=&\#x041A;&\#x043E;&\#x0440;&\#x0438;&\#x0441;&\#x0442;&\#x0443;&\#x0432;&\#x0430;&\#x0447;&\#x0456;
......@@ -392,7 +392,7 @@ public class TableFilter implements ColumnResolver {
}
}
buff.append(table.getSQL());
if (alias != null && !table.getName().equals(alias)) {
if (alias != null) {
buff.append(' ');
buff.append(Parser.quoteIdentifier(alias));
}
......@@ -422,7 +422,7 @@ public class TableFilter implements ColumnResolver {
String condition = StringUtils.unEnclose(filterCondition.getSQL());
condition = StringUtils.quoteRemarkSQL(condition);
buff.append(condition);
buff.append("*/");
buff.append(" */");
}
return buff.toString();
}
......
......@@ -307,4 +307,15 @@ public class TableView extends Table {
return owner;
}
public static TableView createTempView(Session s, User owner, Query query) throws SQLException {
String tempViewName = s.getNextTempViewName();
Schema mainSchema = s.getDatabase().getSchema(Constants.SCHEMA_MAIN);
String querySQL = query.getPlanSQL();
TableView v = new TableView(mainSchema, 0, tempViewName, querySQL, query.getParameters(), null, s,
false);
v.setOwner(owner);
v.setTemporary(true);
return v;
}
}
......@@ -56,13 +56,13 @@ public class DataType {
public int defaultDisplaySize;
public boolean hidden;
public int memory;
// for operations that include different types, convert both to the higher order
public int order;
// JDK 1.3 compatibility: Types.BOOLEAN
public static final int TYPE_BOOLEAN = 16;
// JDK 1.3 compatibility: Types.DATALINK
public static final int TYPE_DATALINK = 70;
......@@ -74,7 +74,7 @@ public class DataType {
if (TYPE_DATALINK != Types.DATALINK) {
new Exception("Types.DATALINK: " + Types.DATALINK).printStackTrace();
}
//#endif
add(Value.NULL, Types.NULL, "Null",
new DataType(),
......@@ -558,6 +558,8 @@ public class DataType {
return Value.CLOB;
case Types.NULL:
return Value.NULL;
case Types.ARRAY:
return Value.ARRAY;
default:
throw Message.getSQLException(ErrorCode.UNKNOWN_DATA_TYPE_1, ""+sqlType);
}
......
......@@ -10,21 +10,45 @@ import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import org.h2.message.Message;
import org.h2.result.LocalResult;
import org.h2.tools.SimpleResultSet;
import org.h2.util.MathUtils;
public class ValueResultSet extends Value {
private final ResultSet result;
private ValueResultSet(ResultSet rs) {
this.result = rs;
}
public static ValueResultSet get(ResultSet rs) throws SQLException {
ValueResultSet val = new ValueResultSet(rs);
return val;
}
public static ValueResultSet getCopy(LocalResult rs, int maxrows) throws SQLException {
int columnCount = rs.getVisibleColumnCount();
SimpleResultSet simple = new SimpleResultSet();
ValueResultSet val = new ValueResultSet(simple);
for (int i = 0; i < columnCount; i++) {
String name = rs.getColumnName(i);
int sqlType = DataType.convertTypeToSQLType(rs.getColumnType(i));
int precision = MathUtils.convertLongToInt(rs.getColumnPrecision(i));
int scale = rs.getColumnScale(i);
simple.addColumn(name, sqlType, precision, scale);
}
rs.reset();
for (int i = 0; i < maxrows && rs.next(); i++) {
Object[] list = new Object[columnCount];
for (int j = 0; j < columnCount; j++) {
list[j] = rs.currentRow()[j].getObject();
}
simple.addRow(list);
}
return val;
}
public static ValueResultSet getCopy(ResultSet rs, int maxrows) throws SQLException {
ResultSetMetaData meta = rs.getMetaData();
int columnCount = meta.getColumnCount();
......@@ -97,7 +121,7 @@ public class ValueResultSet extends Value {
public Object getObject() throws SQLException {
return result;
}
public ResultSet getResultSet() {
return result;
}
......@@ -108,6 +132,6 @@ public class ValueResultSet extends Value {
public String getSQL() {
return "";
}
}
}
......@@ -104,7 +104,7 @@ import org.h2.tools.Server;
import org.h2.util.StringUtils;
/**
* The main test application. JUnit is not used because loops are easier to write in
* The main test application. JUnit is not used because loops are easier to write in
* regular java applications (most tests are ran multiple times using different settings).
*/
public class TestAll {
......@@ -117,7 +117,7 @@ public class TestAll {
/*
Random test:
cd bin
del *.db
start cmd /k "java -cp .;%H2DRIVERS% org.h2.test.TestAll join >testJoin.txt"
......@@ -142,18 +142,42 @@ java org.h2.test.TestAll timer
private Server server;
public boolean cache2Q;
public static void main(String[] args) throws Exception {
long time = System.currentTimeMillis();
TestAll test = new TestAll();
test.printSystem();
test.printSystem();
/*
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
write more tests for the command line tools
Changelog:
Certain setting in the Server didn't work (see bug...)
avoid creating thousands of trace.db files
......@@ -161,21 +185,10 @@ Known Problems:
link to history page, bug page
Add a link to the google code bug page
History:
implement & test: checkpoint commits running transactions
test DbStarter
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;
----
A file is sent although the Japanese translation has not been completed yet.
----
......@@ -183,17 +196,17 @@ A file is sent although the Japanese translation has not been completed yet.
At startup, when corrupted, say if LOG=0 was used before
slow:
select ta.attname, ia.attnum, ic.relname
from pg_catalog.pg_attribute ta, pg_catalog.pg_attribute ia, pg_catalog.pg_class ic, pg_catalog.pg_index i, pg_catalog.pg_namespace n
where ic.relname = 'dummy_pkey'
AND n.nspname = ''
AND ic.oid = i.indexrelid
AND n.oid = ic.relnamespace
AND ia.attrelid = i.indexrelid
AND ta.attrelid = i.indrelid
AND ta.attnum = i.indkey[ia.attnum-1]
AND (NOT ta.attisdropped)
AND (NOT ia.attisdropped)
select ta.attname, ia.attnum, ic.relname
from pg_catalog.pg_attribute ta, pg_catalog.pg_attribute ia, pg_catalog.pg_class ic, pg_catalog.pg_index i, pg_catalog.pg_namespace n
where ic.relname = 'dummy_pkey'
AND n.nspname = ''
AND ic.oid = i.indexrelid
AND n.oid = ic.relnamespace
AND ia.attrelid = i.indexrelid
AND ta.attrelid = i.indrelid
AND ta.attnum = i.indkey[ia.attnum-1]
AND (NOT ta.attisdropped)
AND (NOT ia.attisdropped)
order by ia.attnum;
DROP TABLE IF EXISTS TEST;
......@@ -229,7 +242,7 @@ move Products that Work with H2 > Comparison
move Performance Tuning > Advanced Topics
testHalt
java org.h2.test.TestAll halt
java org.h2.test.TestAll halt
timer test
......@@ -237,18 +250,18 @@ java.lang.Exception: query was too quick; result: 0 time:968
at org.h2.test.TestBase.logError(TestBase.java:220)
at org.h2.test.db.TestCases$1.run(TestCases.java:170)
at java.lang.Thread.run(Thread.java:595)
ftp server: problem with multithreading?
h2\src\docsrc\html\images\SQLInjection.txt
send http://thecodist.com/fiche/thecodist/article/sql-injections-how-not-to-get-stuck to JavaWorld, TheServerSide,
send http://thecodist.com/fiche/thecodist/article/sql-injections-how-not-to-get-stuck to JavaWorld, TheServerSide,
Send SQL Injection solution proposal to PostgreSQL, MySQL, Derby, HSQLDB,...
Convert SQL-injection-2.txt to html document, include SQLInjection.java sample
MySQL, PostgreSQL
READ_TEXT(fileName String) returning a CLOB.
I am not sure if this will read the CLOB in memory however.
READ_TEXT(fileName String) returning a CLOB.
I am not sure if this will read the CLOB in memory however.
Improve LOB in directories performance
......@@ -270,8 +283,8 @@ translated .pdf
write tests using the PostgreSQL JDBC driver
*/
*/
// run TestHalt
// GroovyServlet
......@@ -292,13 +305,13 @@ write tests using the PostgreSQL JDBC driver
// long running test with the same database
// repeatable test with a very big database (making backups of the database files)
/*
Features of H2
- Case insensitive string data type
- GROUP_CONCAT aggregate, User defined aggregates
*/
*/
if (args.length > 0) {
if ("crash".equals(args[0])) {
new TestCrashAPI().runTest(test);
......@@ -331,7 +344,7 @@ Features of H2
}
void runTests() throws Exception {
// TODO test set lock_mode=0, 1; max_trace_file_size; modes; collation; assert
// TODO test shutdown immediately
......@@ -353,7 +366,7 @@ Features of H2
// big = true;
// memory = false;
//
testQuick();
testCombination();
......@@ -405,7 +418,7 @@ Features of H2
logMode = 1;
cipher = null;
mvcc = false;
cache2Q = false;
cache2Q = false;
testAll();
diskUndo = false;
......@@ -420,9 +433,9 @@ Features of H2
logMode = 1;
cipher = null;
mvcc = false;
cache2Q = false;
cache2Q = false;
testAll();
big = false;
smallLog = false;
networked = false;
......@@ -437,8 +450,8 @@ Features of H2
throttle = 0;
cipher = null;
mvcc = false;
cache2Q = false;
testAll();
cache2Q = false;
testAll();
diskUndo = true;
smallLog = false;
......@@ -452,7 +465,7 @@ Features of H2
throttle = 1;
cipher = "XTEA";
mvcc = false;
cache2Q = false;
cache2Q = false;
testAll();
diskUndo = false;
......@@ -470,7 +483,7 @@ Features of H2
throttle = 0;
cipher = null;
mvcc = false;
cache2Q = false;
cache2Q = false;
testAll();
big = true;
......@@ -487,9 +500,9 @@ Features of H2
throttle = 0;
cipher = null;
mvcc = false;
cache2Q = true;
cache2Q = true;
testAll();
big = true;
smallLog = false;
networked = true;
......@@ -504,19 +517,19 @@ Features of H2
throttle = 0;
cipher = "AES";
mvcc = false;
cache2Q = false;
cache2Q = false;
testAll();
smallLog = big = networked = memory = ssl = textStorage = diskResult = deleteIndex = traceSystemOut = false;
traceLevelFile = throttle = 0;
logMode = 1;
cipher = null;
mvcc = true;
cache2Q = false;
cache2Q = false;
testAll();
}
void testAll() throws Exception {
DeleteDbFiles.execute(TestBase.baseDir, null, true);
testDatabase();
......@@ -553,7 +566,7 @@ Features of H2
void testDatabase() throws Exception {
System.out.println("test big:"+big+" net:"+networked+" cipher:"+cipher+" memory:"+memory+" log:"+logMode+" diskResult:"+diskResult + " mvcc:" + mvcc);
beforeTest();
// int testMvcc;
// mvcc = true;
......
......@@ -23,7 +23,7 @@ public class TestBigResult extends TestBase {
testOrderGroup();
testLimitBufferedResult();
}
private void testLargeUpdateDelete() throws Exception {
deleteDb("bigResult");
Connection conn = getConnection("bigResult");
......
--- special grammar and test cases ---------------------------------------------------------------------------------------------
select count(*) from system_range(1, 2) where x in(1, 1, 1);
> COUNT(*)
> --------
> 1
> rows: 1
create table person(id bigint auto_increment, name varchar(100));
> ok
insert into person(name) values ('a'), ('b'), ('c');
> update count: 3
select * from person order by id;
> ID NAME
> -- ----
> 1 a
> 2 b
> 3 c
> rows (ordered): 3
select * from person order by id limit 2;
> ID NAME
> -- ----
> 1 a
> 2 b
> rows (ordered): 2
select * from person order by id limit 2 offset 1;
> ID NAME
> -- ----
> 2 b
> 3 c
> rows (ordered): 2
select * from person order by id limit 2147483647 offset 1;
> ID NAME
> -- ----
> 2 b
> 3 c
> rows (ordered): 2
select * from person order by id limit 2147483647-1 offset 1;
> ID NAME
> -- ----
> 2 b
> 3 c
> rows (ordered): 2
select * from person order by id limit 2147483647-1 offset 2;
> ID NAME
> -- ----
> 3 c
> rows (ordered): 1
select * from person order by id limit 2147483647-2 offset 2;
> ID NAME
> -- ----
> 3 c
> rows (ordered): 1
drop table person;
> ok
CREATE TABLE TEST(ID INTEGER NOT NULL, ID2 INTEGER DEFAULT 0);
> ok
......@@ -157,8 +220,8 @@ insert into test values(1), (2), (3);
explain select * from test where id in(1, 2, null);
> PLAN
> -------------------------------------------------------------------------------------------------------
> SELECT TEST.ID FROM PUBLIC.TEST /* PUBLIC.PRIMARY_KEY_1: ID >= 1 AND ID <= 2 */ WHERE ID IN(1, 2, NULL)
> --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
> SELECT TEST.ID FROM PUBLIC.TEST /* PUBLIC.TEST_TABLE_SCAN */ /* WHERE TRUE */ INNER JOIN TABLE_DISTINCT(TEMP_VIEW_8_X INTEGER=(1, 2, NULL)) TEMP_VIEW_9 /* PUBLIC."" */ ON ID = TEMP_VIEW_9.TEMP_VIEW_8_X WHERE TRUE
> rows: 1
drop table test;
......@@ -1878,8 +1941,8 @@ select * from test t1 where id in(id);
explain select * from test t1 where id in(select id from test);
> PLAN
> -------------------------------------------------------------------------------------------------------------------------------------------
> SELECT T1.ID, T1.NAME FROM PUBLIC.TEST T1 /* PUBLIC.TEST_TABLE_SCAN */ WHERE ID IN(SELECT ID FROM PUBLIC.TEST /* PUBLIC.TEST_TABLE_SCAN */)
> ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
> SELECT T1.ID, T1.NAME FROM PUBLIC.TEST T1 /* PUBLIC.TEST_TABLE_SCAN */ /* WHERE TRUE */ INNER JOIN (SELECT DISTINCT ID AS TEMP_VIEW_58_X FROM PUBLIC.TEST /* PUBLIC.TEST_TABLE_SCAN */) TEMP_VIEW_59 /* SELECT DISTINCT ID AS TEMP_VIEW_58_X FROM PUBLIC.TEST /++ PUBLIC.TEST_TABLE_SCAN ++/ */ ON ID = TEMP_VIEW_59.TEMP_VIEW_58_X WHERE TRUE
> rows: 1
select * from test t1 where id in(select id from test);
......@@ -1891,8 +1954,8 @@ select * from test t1 where id in(select id from test);
explain select * from test t1 where id in(1, select max(id) from test);
> PLAN
> -----------------------------------------------------------------------------------------------------------
> SELECT T1.ID, T1.NAME FROM PUBLIC.TEST T1 /* PUBLIC.PRIMARY_KEY_1: ID >= 1 AND ID <= 2 */ WHERE ID IN(1, 2)
> ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
> SELECT T1.ID, T1.NAME FROM PUBLIC.TEST T1 /* PUBLIC.TEST_TABLE_SCAN */ /* WHERE TRUE */ INNER JOIN TABLE_DISTINCT(TEMP_VIEW_66_X INTEGER=(1, 2)) TEMP_VIEW_67 /* PUBLIC."" */ ON ID = TEMP_VIEW_67.TEMP_VIEW_66_X WHERE TRUE
> rows: 1
select * from test t1 where id in(1, select max(id) from test);
......@@ -2005,8 +2068,8 @@ explain select * from one natural join two left join two three on
one.id=three.id left join one four on two.id=four.id where three.val
is null or three.val>=DATE'2006-07-01';
> PLAN
> -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
> SELECT ONE.ID, TWO.ID, TWO.VAL, THREE.ID, THREE.VAL, FOUR.ID FROM PUBLIC.ONE /* PUBLIC.ONE_TABLE_SCAN */ INNER JOIN PUBLIC.TWO /* PUBLIC.PRIMARY_KEY_2: ID = PUBLIC.ONE.ID AND ID = PUBLIC.ONE.ID */ /* WHERE PUBLIC.ONE.ID = PUBLIC.TWO.ID*/ LEFT OUTER JOIN PUBLIC.TWO THREE /* PUBLIC.PRIMARY_KEY_2: ID = ONE.ID */ ON ONE.ID = THREE.ID LEFT OUTER JOIN PUBLIC.ONE FOUR /* PUBLIC.PRIMARY_KEY_1: ID = TWO.ID */ ON TWO.ID = FOUR.ID WHERE (PUBLIC.ONE.ID = PUBLIC.TWO.ID) AND ((THREE.VAL IS NULL) OR (THREE.VAL >= DATE '2006-07-01'))
> --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
> SELECT ONE.ID, TWO.ID, TWO.VAL, THREE.ID, THREE.VAL, FOUR.ID FROM PUBLIC.ONE /* PUBLIC.ONE_TABLE_SCAN */ INNER JOIN PUBLIC.TWO /* PUBLIC.PRIMARY_KEY_2: ID = PUBLIC.ONE.ID AND ID = PUBLIC.ONE.ID */ /* WHERE PUBLIC.ONE.ID = PUBLIC.TWO.ID */ LEFT OUTER JOIN PUBLIC.TWO THREE /* PUBLIC.PRIMARY_KEY_2: ID = ONE.ID */ ON ONE.ID = THREE.ID LEFT OUTER JOIN PUBLIC.ONE FOUR /* PUBLIC.PRIMARY_KEY_1: ID = TWO.ID */ ON TWO.ID = FOUR.ID WHERE (PUBLIC.ONE.ID = PUBLIC.TWO.ID) AND ((THREE.VAL IS NULL) OR (THREE.VAL >= DATE '2006-07-01'))
> rows: 1
-- Query #4: same as #3, but the joins have been manually re-ordered
......@@ -2074,8 +2137,8 @@ inner join test2 on test1.id=test2.id left
outer join test3 on test2.id=test3.id
where test3.id is null;
> PLAN
> -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
> SELECT TEST1.ID, TEST2.ID, TEST3.ID FROM PUBLIC.TEST1 /* PUBLIC.TEST1_TABLE_SCAN */ INNER JOIN PUBLIC.TEST2 /* PUBLIC.PRIMARY_KEY_2: ID = TEST1.ID AND ID = TEST1.ID */ /* WHERE TEST1.ID = TEST2.ID*/ LEFT OUTER JOIN PUBLIC.TEST3 /* PUBLIC.PRIMARY_KEY_3: ID = TEST2.ID */ ON TEST2.ID = TEST3.ID WHERE (TEST3.ID IS NULL) AND (TEST1.ID = TEST2.ID)
> --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
> SELECT TEST1.ID, TEST2.ID, TEST3.ID FROM PUBLIC.TEST1 /* PUBLIC.TEST1_TABLE_SCAN */ INNER JOIN PUBLIC.TEST2 /* PUBLIC.PRIMARY_KEY_2: ID = TEST1.ID AND ID = TEST1.ID */ /* WHERE TEST1.ID = TEST2.ID */ LEFT OUTER JOIN PUBLIC.TEST3 /* PUBLIC.PRIMARY_KEY_3: ID = TEST2.ID */ ON TEST2.ID = TEST3.ID WHERE (TEST3.ID IS NULL) AND (TEST1.ID = TEST2.ID)
> rows: 1
insert into test1 select x from system_range(2, 1000);
......@@ -3827,20 +3890,20 @@ insert into b select id+10, p+10 from b;
explain select * from b b0, b b1, b b2 where b1.p = b0.id and b2.p = b1.id and b0.id=10;
> PLAN
> --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
> SELECT B0.ID, B0.P, B1.ID, B1.P, B2.ID, B2.P FROM PUBLIC.B B0 /* PUBLIC.PRIMARY_KEY_1: ID = 10 */ /* WHERE B0.ID = 10*/ INNER JOIN PUBLIC.B B1 /* PUBLIC.BP: P = B0.ID */ /* WHERE B1.P = B0.ID*/ INNER JOIN PUBLIC.B B2 /* PUBLIC.BP: P = B1.ID */ WHERE (B0.ID = 10) AND ((B1.P = B0.ID) AND (B2.P = B1.ID))
> ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
> SELECT B0.ID, B0.P, B1.ID, B1.P, B2.ID, B2.P FROM PUBLIC.B B0 /* PUBLIC.PRIMARY_KEY_1: ID = 10 */ /* WHERE B0.ID = 10 */ INNER JOIN PUBLIC.B B1 /* PUBLIC.BP: P = B0.ID */ /* WHERE B1.P = B0.ID */ INNER JOIN PUBLIC.B B2 /* PUBLIC.BP: P = B1.ID */ WHERE (B0.ID = 10) AND ((B1.P = B0.ID) AND (B2.P = B1.ID))
> rows: 1
explain select * from b b0, b b1, b b2, b b3 where b1.p = b0.id and b2.p = b1.id and b3.p = b2.id and b0.id=10;
> PLAN
> --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
> SELECT B0.ID, B0.P, B1.ID, B1.P, B2.ID, B2.P, B3.ID, B3.P FROM PUBLIC.B B0 /* PUBLIC.PRIMARY_KEY_1: ID = 10 */ /* WHERE B0.ID = 10*/ INNER JOIN PUBLIC.B B1 /* PUBLIC.BP: P = B0.ID */ /* WHERE B1.P = B0.ID*/ INNER JOIN PUBLIC.B B2 /* PUBLIC.BP: P = B1.ID */ /* WHERE B2.P = B1.ID*/ INNER JOIN PUBLIC.B B3 /* PUBLIC.BP: P = B2.ID */ WHERE (B0.ID = 10) AND ((B3.P = B2.ID) AND ((B1.P = B0.ID) AND (B2.P = B1.ID)))
> -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
> SELECT B0.ID, B0.P, B1.ID, B1.P, B2.ID, B2.P, B3.ID, B3.P FROM PUBLIC.B B0 /* PUBLIC.PRIMARY_KEY_1: ID = 10 */ /* WHERE B0.ID = 10 */ INNER JOIN PUBLIC.B B1 /* PUBLIC.BP: P = B0.ID */ /* WHERE B1.P = B0.ID */ INNER JOIN PUBLIC.B B2 /* PUBLIC.BP: P = B1.ID */ /* WHERE B2.P = B1.ID */ INNER JOIN PUBLIC.B B3 /* PUBLIC.BP: P = B2.ID */ WHERE (B0.ID = 10) AND ((B3.P = B2.ID) AND ((B1.P = B0.ID) AND (B2.P = B1.ID)))
> rows: 1
explain select * from b b0, b b1, b b2, b b3, b b4 where b1.p = b0.id and b2.p = b1.id and b3.p = b2.id and b4.p = b3.id and b0.id=10;
> PLAN
> --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
> SELECT B0.ID, B0.P, B1.ID, B1.P, B2.ID, B2.P, B3.ID, B3.P, B4.ID, B4.P FROM PUBLIC.B B0 /* PUBLIC.PRIMARY_KEY_1: ID = 10 */ /* WHERE B0.ID = 10*/ INNER JOIN PUBLIC.B B1 /* PUBLIC.BP: P = B0.ID */ /* WHERE B1.P = B0.ID*/ INNER JOIN PUBLIC.B B2 /* PUBLIC.BP: P = B1.ID */ /* WHERE B2.P = B1.ID*/ INNER JOIN PUBLIC.B B3 /* PUBLIC.BP: P = B2.ID */ /* WHERE B3.P = B2.ID*/ INNER JOIN PUBLIC.B B4 /* PUBLIC.BP: P = B3.ID */ WHERE (B0.ID = 10) AND ((B4.P = B3.ID) AND ((B3.P = B2.ID) AND ((B1.P = B0.ID) AND (B2.P = B1.ID))))
> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
> SELECT B0.ID, B0.P, B1.ID, B1.P, B2.ID, B2.P, B3.ID, B3.P, B4.ID, B4.P FROM PUBLIC.B B0 /* PUBLIC.PRIMARY_KEY_1: ID = 10 */ /* WHERE B0.ID = 10 */ INNER JOIN PUBLIC.B B1 /* PUBLIC.BP: P = B0.ID */ /* WHERE B1.P = B0.ID */ INNER JOIN PUBLIC.B B2 /* PUBLIC.BP: P = B1.ID */ /* WHERE B2.P = B1.ID */ INNER JOIN PUBLIC.B B3 /* PUBLIC.BP: P = B2.ID */ /* WHERE B3.P = B2.ID */ INNER JOIN PUBLIC.B B4 /* PUBLIC.BP: P = B3.ID */ WHERE (B0.ID = 10) AND ((B4.P = B3.ID) AND ((B3.P = B2.ID) AND ((B1.P = B0.ID) AND (B2.P = B1.ID))))
> rows: 1
analyze;
......@@ -3848,8 +3911,8 @@ analyze;
explain select * from b b0, b b1, b b2, b b3, b b4 where b1.p = b0.id and b2.p = b1.id and b3.p = b2.id and b4.p = b3.id and b0.id=10;
> PLAN
> --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
> SELECT B0.ID, B0.P, B1.ID, B1.P, B2.ID, B2.P, B3.ID, B3.P, B4.ID, B4.P FROM PUBLIC.B B0 /* PUBLIC.PRIMARY_KEY_1: ID = 10 */ /* WHERE B0.ID = 10*/ INNER JOIN PUBLIC.B B1 /* PUBLIC.BP: P = B0.ID */ /* WHERE B1.P = B0.ID*/ INNER JOIN PUBLIC.B B2 /* PUBLIC.BP: P = B1.ID */ /* WHERE B2.P = B1.ID*/ INNER JOIN PUBLIC.B B3 /* PUBLIC.BP: P = B2.ID */ /* WHERE B3.P = B2.ID*/ INNER JOIN PUBLIC.B B4 /* PUBLIC.BP: P = B3.ID */ WHERE (B0.ID = 10) AND ((B4.P = B3.ID) AND ((B3.P = B2.ID) AND ((B1.P = B0.ID) AND (B2.P = B1.ID))))
> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
> SELECT B0.ID, B0.P, B1.ID, B1.P, B2.ID, B2.P, B3.ID, B3.P, B4.ID, B4.P FROM PUBLIC.B B0 /* PUBLIC.PRIMARY_KEY_1: ID = 10 */ /* WHERE B0.ID = 10 */ INNER JOIN PUBLIC.B B1 /* PUBLIC.BP: P = B0.ID */ /* WHERE B1.P = B0.ID */ INNER JOIN PUBLIC.B B2 /* PUBLIC.BP: P = B1.ID */ /* WHERE B2.P = B1.ID */ INNER JOIN PUBLIC.B B3 /* PUBLIC.BP: P = B2.ID */ /* WHERE B3.P = B2.ID */ INNER JOIN PUBLIC.B B4 /* PUBLIC.BP: P = B3.ID */ WHERE (B0.ID = 10) AND ((B4.P = B3.ID) AND ((B3.P = B2.ID) AND ((B1.P = B0.ID) AND (B2.P = B1.ID))))
> rows: 1
drop table if exists b;
......@@ -3917,8 +3980,8 @@ EXPLAIN SELECT A.X FROM O B, O A, O F, O D, O C, O E, O G, O H, O I, O J
WHERE 1=J.X and J.Y=I.X AND I.Y=H.X AND H.Y=G.X AND G.Y=F.X AND F.Y=E.X
AND E.Y=D.X AND D.Y=C.X AND C.Y=B.X AND B.Y=A.X;
> PLAN
> ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
> SELECT A.X FROM PUBLIC.O J /* PUBLIC.PRIMARY_KEY_1: X = 1 */ /* WHERE 1 = J.X*/ INNER JOIN PUBLIC.O I /* PUBLIC.PRIMARY_KEY_1: X = J.Y */ /* WHERE J.Y = I.X*/ INNER JOIN PUBLIC.O H /* PUBLIC.PRIMARY_KEY_1: X = I.Y */ /* WHERE I.Y = H.X*/ INNER JOIN PUBLIC.O G /* PUBLIC.PRIMARY_KEY_1: X = H.Y */ /* WHERE H.Y = G.X*/ INNER JOIN PUBLIC.O F /* PUBLIC.PRIMARY_KEY_1: X = G.Y */ /* WHERE G.Y = F.X*/ INNER JOIN PUBLIC.O E /* PUBLIC.PRIMARY_KEY_1: X = F.Y */ /* WHERE F.Y = E.X*/ INNER JOIN PUBLIC.O D /* PUBLIC.PRIMARY_KEY_1: X = E.Y */ /* WHERE E.Y = D.X*/ INNER JOIN PUBLIC.O C /* PUBLIC.PRIMARY_KEY_1: X = D.Y */ /* WHERE D.Y = C.X*/ INNER JOIN PUBLIC.O B /* PUBLIC.PRIMARY_KEY_1: X = C.Y */ /* WHERE C.Y = B.X*/ INNER JOIN PUBLIC.O A /* PUBLIC.PRIMARY_KEY_1: X = B.Y */ WHERE (B.Y = A.X) AND ((C.Y = B.X) AND ((D.Y = C.X) AND ((E.Y = D.X) AND ((F.Y = E.X) AND ((G.Y = F.X) AND ((H.Y = G.X) AND ((I.Y = H.X) AND ((1 = J.X) AND (J.Y = I.X)))))))))
> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
> SELECT A.X FROM PUBLIC.O J /* PUBLIC.PRIMARY_KEY_1: X = 1 */ /* WHERE 1 = J.X */ INNER JOIN PUBLIC.O I /* PUBLIC.PRIMARY_KEY_1: X = J.Y */ /* WHERE J.Y = I.X */ INNER JOIN PUBLIC.O H /* PUBLIC.PRIMARY_KEY_1: X = I.Y */ /* WHERE I.Y = H.X */ INNER JOIN PUBLIC.O G /* PUBLIC.PRIMARY_KEY_1: X = H.Y */ /* WHERE H.Y = G.X */ INNER JOIN PUBLIC.O F /* PUBLIC.PRIMARY_KEY_1: X = G.Y */ /* WHERE G.Y = F.X */ INNER JOIN PUBLIC.O E /* PUBLIC.PRIMARY_KEY_1: X = F.Y */ /* WHERE F.Y = E.X */ INNER JOIN PUBLIC.O D /* PUBLIC.PRIMARY_KEY_1: X = E.Y */ /* WHERE E.Y = D.X */ INNER JOIN PUBLIC.O C /* PUBLIC.PRIMARY_KEY_1: X = D.Y */ /* WHERE D.Y = C.X */ INNER JOIN PUBLIC.O B /* PUBLIC.PRIMARY_KEY_1: X = C.Y */ /* WHERE C.Y = B.X */ INNER JOIN PUBLIC.O A /* PUBLIC.PRIMARY_KEY_1: X = B.Y */ WHERE (B.Y = A.X) AND ((C.Y = B.X) AND ((D.Y = C.X) AND ((E.Y = D.X) AND ((F.Y = E.X) AND ((G.Y = F.X) AND ((H.Y = G.X) AND ((I.Y = H.X) AND ((1 = J.X) AND (J.Y = I.X)))))))))
> rows: 1
DROP TABLE O;
......@@ -3948,8 +4011,8 @@ EXPLAIN SELECT COUNT(*) FROM PARENT, CHILD A, CHILD B, CHILD C, CHILD D, CHILD E
WHERE AID=A.ID AND BID=B.ID AND CID=C.ID
AND DID=D.ID AND EID=E.ID AND FID=F.ID AND GID=G.ID AND HID=H.ID;
> PLAN
> ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
> SELECT COUNT(*) FROM PUBLIC.PARENT /* PUBLIC.PARENT_TABLE_SCAN */ INNER JOIN PUBLIC.CHILD A /* PUBLIC.PRIMARY_KEY_2: ID = AID */ /* WHERE AID = A.ID*/ INNER JOIN PUBLIC.CHILD B /* PUBLIC.PRIMARY_KEY_2: ID = BID */ /* WHERE BID = B.ID*/ INNER JOIN PUBLIC.CHILD C /* PUBLIC.PRIMARY_KEY_2: ID = CID */ /* WHERE CID = C.ID*/ INNER JOIN PUBLIC.CHILD D /* PUBLIC.PRIMARY_KEY_2: ID = DID */ /* WHERE DID = D.ID*/ INNER JOIN PUBLIC.CHILD E /* PUBLIC.PRIMARY_KEY_2: ID = EID */ /* WHERE EID = E.ID*/ INNER JOIN PUBLIC.CHILD F /* PUBLIC.PRIMARY_KEY_2: ID = FID */ /* WHERE FID = F.ID*/ INNER JOIN PUBLIC.CHILD G /* PUBLIC.PRIMARY_KEY_2: ID = GID */ /* WHERE GID = G.ID*/ INNER JOIN PUBLIC.CHILD H /* PUBLIC.PRIMARY_KEY_2: ID = HID */ WHERE (HID = H.ID) AND ((GID = G.ID) AND ((FID = F.ID) AND ((EID = E.ID) AND ((DID = D.ID) AND ((CID = C.ID) AND ((AID = A.ID) AND (BID = B.ID)))))))
> ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
> SELECT COUNT(*) FROM PUBLIC.PARENT /* PUBLIC.PARENT_TABLE_SCAN */ INNER JOIN PUBLIC.CHILD A /* PUBLIC.PRIMARY_KEY_2: ID = AID */ /* WHERE AID = A.ID */ INNER JOIN PUBLIC.CHILD B /* PUBLIC.PRIMARY_KEY_2: ID = BID */ /* WHERE BID = B.ID */ INNER JOIN PUBLIC.CHILD C /* PUBLIC.PRIMARY_KEY_2: ID = CID */ /* WHERE CID = C.ID */ INNER JOIN PUBLIC.CHILD D /* PUBLIC.PRIMARY_KEY_2: ID = DID */ /* WHERE DID = D.ID */ INNER JOIN PUBLIC.CHILD E /* PUBLIC.PRIMARY_KEY_2: ID = EID */ /* WHERE EID = E.ID */ INNER JOIN PUBLIC.CHILD F /* PUBLIC.PRIMARY_KEY_2: ID = FID */ /* WHERE FID = F.ID */ INNER JOIN PUBLIC.CHILD G /* PUBLIC.PRIMARY_KEY_2: ID = GID */ /* WHERE GID = G.ID */ INNER JOIN PUBLIC.CHILD H /* PUBLIC.PRIMARY_KEY_2: ID = HID */ WHERE (HID = H.ID) AND ((GID = G.ID) AND ((FID = F.ID) AND ((EID = E.ID) AND ((DID = D.ID) AND ((CID = C.ID) AND ((AID = A.ID) AND (BID = B.ID)))))))
> rows: 1
CREATE TABLE FAMILY(ID INT PRIMARY KEY, PARENTID INT);
......@@ -3962,8 +4025,8 @@ EXPLAIN SELECT COUNT(*) FROM CHILD A, CHILD B, FAMILY, CHILD C, CHILD D, PARENT,
WHERE FAMILY.ID=1 AND FAMILY.PARENTID=PARENT.ID
AND AID=A.ID AND BID=B.ID AND CID=C.ID AND DID=D.ID AND EID=E.ID AND FID=F.ID AND GID=G.ID;
> PLAN
> ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
> SELECT COUNT(*) FROM PUBLIC.FAMILY /* PUBLIC.PRIMARY_KEY_3: ID = 1 */ /* WHERE FAMILY.ID = 1*/ INNER JOIN PUBLIC.PARENT /* PUBLIC.PRIMARY_KEY_1: ID = FAMILY.PARENTID */ /* WHERE FAMILY.PARENTID = PARENT.ID*/ INNER JOIN PUBLIC.CHILD A /* PUBLIC.PRIMARY_KEY_2: ID = AID */ /* WHERE AID = A.ID*/ INNER JOIN PUBLIC.CHILD B /* PUBLIC.PRIMARY_KEY_2: ID = BID */ /* WHERE BID = B.ID*/ INNER JOIN PUBLIC.CHILD C /* PUBLIC.PRIMARY_KEY_2: ID = CID */ /* WHERE CID = C.ID*/ INNER JOIN PUBLIC.CHILD D /* PUBLIC.PRIMARY_KEY_2: ID = DID */ /* WHERE DID = D.ID*/ INNER JOIN PUBLIC.CHILD E /* PUBLIC.PRIMARY_KEY_2: ID = EID */ /* WHERE EID = E.ID*/ INNER JOIN PUBLIC.CHILD F /* PUBLIC.PRIMARY_KEY_2: ID = FID */ /* WHERE FID = F.ID*/ INNER JOIN PUBLIC.CHILD G /* PUBLIC.PRIMARY_KEY_2: ID = GID */ WHERE (GID = G.ID) AND ((FID = F.ID) AND ((EID = E.ID) AND ((DID = D.ID) AND ((CID = C.ID) AND ((BID = B.ID) AND ((AID = A.ID) AND ((FAMILY.ID = 1) AND (FAMILY.PARENTID = PARENT.ID))))))))
> -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
> SELECT COUNT(*) FROM PUBLIC.FAMILY /* PUBLIC.PRIMARY_KEY_3: ID = 1 */ /* WHERE FAMILY.ID = 1 */ INNER JOIN PUBLIC.PARENT /* PUBLIC.PRIMARY_KEY_1: ID = FAMILY.PARENTID */ /* WHERE FAMILY.PARENTID = PARENT.ID */ INNER JOIN PUBLIC.CHILD A /* PUBLIC.PRIMARY_KEY_2: ID = AID */ /* WHERE AID = A.ID */ INNER JOIN PUBLIC.CHILD B /* PUBLIC.PRIMARY_KEY_2: ID = BID */ /* WHERE BID = B.ID */ INNER JOIN PUBLIC.CHILD C /* PUBLIC.PRIMARY_KEY_2: ID = CID */ /* WHERE CID = C.ID */ INNER JOIN PUBLIC.CHILD D /* PUBLIC.PRIMARY_KEY_2: ID = DID */ /* WHERE DID = D.ID */ INNER JOIN PUBLIC.CHILD E /* PUBLIC.PRIMARY_KEY_2: ID = EID */ /* WHERE EID = E.ID */ INNER JOIN PUBLIC.CHILD F /* PUBLIC.PRIMARY_KEY_2: ID = FID */ /* WHERE FID = F.ID */ INNER JOIN PUBLIC.CHILD G /* PUBLIC.PRIMARY_KEY_2: ID = GID */ WHERE (GID = G.ID) AND ((FID = F.ID) AND ((EID = E.ID) AND ((DID = D.ID) AND ((CID = C.ID) AND ((BID = B.ID) AND ((AID = A.ID) AND ((FAMILY.ID = 1) AND (FAMILY.PARENTID = PARENT.ID))))))))
> rows: 1
DROP TABLE FAMILY;
......@@ -4771,20 +4834,20 @@ EXPLAIN PLAN FOR SELECT NAME, COUNT(*) FROM TEST GROUP BY NAME HAVING COUNT(*) >
EXPLAIN PLAN FOR SELECT * FROM test t1 inner join test t2 on t1.id=t2.id and t2.name is not null where t1.id=1;
> PLAN
> -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
> SELECT T1.ID, T1.NAME, T2.ID, T2.NAME FROM PUBLIC.TEST T1 /* PUBLIC.PRIMARY_KEY_1: ID = 1 */ /* WHERE T1.ID = 1*/ INNER JOIN PUBLIC.TEST T2 /* PUBLIC.PRIMARY_KEY_1: ID = T1.ID AND ID = T1.ID */ WHERE (T1.ID = 1) AND ((T2.NAME IS NOT NULL) AND (T1.ID = T2.ID))
> --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
> SELECT T1.ID, T1.NAME, T2.ID, T2.NAME FROM PUBLIC.TEST T1 /* PUBLIC.PRIMARY_KEY_1: ID = 1 */ /* WHERE T1.ID = 1 */ INNER JOIN PUBLIC.TEST T2 /* PUBLIC.PRIMARY_KEY_1: ID = T1.ID AND ID = T1.ID */ WHERE (T1.ID = 1) AND ((T2.NAME IS NOT NULL) AND (T1.ID = T2.ID))
> rows: 1
EXPLAIN PLAN FOR SELECT * FROM test t1 left outer join test t2 on t1.id=t2.id and t2.name is not null where t1.id=1;
> PLAN
> ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
> SELECT T1.ID, T1.NAME, T2.ID, T2.NAME FROM PUBLIC.TEST T1 /* PUBLIC.PRIMARY_KEY_1: ID = 1 */ /* WHERE T1.ID = 1*/ LEFT OUTER JOIN PUBLIC.TEST T2 /* PUBLIC.PRIMARY_KEY_1: ID = T1.ID */ ON (T2.NAME IS NOT NULL) AND (T1.ID = T2.ID) WHERE T1.ID = 1
> -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
> SELECT T1.ID, T1.NAME, T2.ID, T2.NAME FROM PUBLIC.TEST T1 /* PUBLIC.PRIMARY_KEY_1: ID = 1 */ /* WHERE T1.ID = 1 */ LEFT OUTER JOIN PUBLIC.TEST T2 /* PUBLIC.PRIMARY_KEY_1: ID = T1.ID */ ON (T2.NAME IS NOT NULL) AND (T1.ID = T2.ID) WHERE T1.ID = 1
> rows: 1
EXPLAIN PLAN FOR SELECT * FROM test t1 left outer join test t2 on t1.id=t2.id and t2.name is null where t1.id=1;
> PLAN
> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
> SELECT T1.ID, T1.NAME, T2.ID, T2.NAME FROM PUBLIC.TEST T1 /* PUBLIC.PRIMARY_KEY_1: ID = 1 */ /* WHERE T1.ID = 1*/ LEFT OUTER JOIN PUBLIC.TEST T2 /* PUBLIC.PRIMARY_KEY_1: ID = T1.ID */ ON (T2.NAME IS NULL) AND (T1.ID = T2.ID) WHERE T1.ID = 1
> -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
> SELECT T1.ID, T1.NAME, T2.ID, T2.NAME FROM PUBLIC.TEST T1 /* PUBLIC.PRIMARY_KEY_1: ID = 1 */ /* WHERE T1.ID = 1 */ LEFT OUTER JOIN PUBLIC.TEST T2 /* PUBLIC.PRIMARY_KEY_1: ID = T1.ID */ ON (T2.NAME IS NULL) AND (T1.ID = T2.ID) WHERE T1.ID = 1
> rows: 1
EXPLAIN PLAN FOR SELECT * FROM TEST T1 WHERE EXISTS(SELECT * FROM TEST T2 WHERE T1.ID-1 = T2.ID);
......@@ -4795,14 +4858,14 @@ EXPLAIN PLAN FOR SELECT * FROM TEST T1 WHERE EXISTS(SELECT * FROM TEST T2 WHERE
EXPLAIN PLAN FOR SELECT * FROM TEST T1 WHERE ID IN(1, 2);
> PLAN
> -----------------------------------------------------------------------------------------------------------
> SELECT T1.ID, T1.NAME FROM PUBLIC.TEST T1 /* PUBLIC.PRIMARY_KEY_1: ID >= 1 AND ID <= 2 */ WHERE ID IN(1, 2)
> --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
> SELECT T1.ID, T1.NAME FROM PUBLIC.TEST T1 /* PUBLIC.TEST_TABLE_SCAN */ /* WHERE TRUE */ INNER JOIN TABLE_DISTINCT(TEMP_VIEW_103_X INTEGER=(1, 2)) TEMP_VIEW_104 /* PUBLIC."" */ ON ID = TEMP_VIEW_104.TEMP_VIEW_103_X WHERE TRUE
> rows: 1
EXPLAIN PLAN FOR SELECT * FROM TEST T1 WHERE ID IN(SELECT ID FROM TEST);
> PLAN
> -------------------------------------------------------------------------------------------------------------------------------------------
> SELECT T1.ID, T1.NAME FROM PUBLIC.TEST T1 /* PUBLIC.TEST_TABLE_SCAN */ WHERE ID IN(SELECT ID FROM PUBLIC.TEST /* PUBLIC.TEST_TABLE_SCAN */)
> ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
> SELECT T1.ID, T1.NAME FROM PUBLIC.TEST T1 /* PUBLIC.TEST_TABLE_SCAN */ /* WHERE TRUE */ INNER JOIN (SELECT DISTINCT ID AS TEMP_VIEW_107_X FROM PUBLIC.TEST /* PUBLIC.TEST_TABLE_SCAN */) TEMP_VIEW_108 /* SELECT DISTINCT ID AS TEMP_VIEW_107_X FROM PUBLIC.TEST /++ PUBLIC.TEST_TABLE_SCAN ++/ */ ON ID = TEMP_VIEW_108.TEMP_VIEW_107_X WHERE TRUE
> rows: 1
EXPLAIN PLAN FOR SELECT * FROM TEST T1 WHERE ID NOT IN(SELECT ID FROM TEST);
......@@ -5455,8 +5518,8 @@ select c.*, i.*, l.* from customer c natural join invoice i natural join INVOICE
explain select c.*, i.*, l.* from customer c natural join invoice i natural join INVOICE_LINE l;
> PLAN
> -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
> SELECT C.CUSTOMERID, C.CUSTOMER_NAME, I.CUSTOMERID, I.INVOICEID, I.INVOICE_TEXT, L.LINE_ID, L.INVOICEID, L.CUSTOMERID, L.LINE_TEXT FROM PUBLIC.CUSTOMER C /* PUBLIC.CUSTOMER_TABLE_SCAN */ INNER JOIN PUBLIC.INVOICE I /* PUBLIC.INVOICE_TABLE_SCAN */ /* WHERE PUBLIC.C.CUSTOMERID = PUBLIC.I.CUSTOMERID*/ INNER JOIN PUBLIC.INVOICE_LINE L /* PUBLIC.INVOICE_LINE_TABLE_SCAN */ WHERE (PUBLIC.C.CUSTOMERID = PUBLIC.I.CUSTOMERID) AND ((PUBLIC.I.CUSTOMERID = PUBLIC.L.CUSTOMERID) AND (PUBLIC.I.INVOICEID = PUBLIC.L.INVOICEID))
> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
> SELECT C.CUSTOMERID, C.CUSTOMER_NAME, I.CUSTOMERID, I.INVOICEID, I.INVOICE_TEXT, L.LINE_ID, L.INVOICEID, L.CUSTOMERID, L.LINE_TEXT FROM PUBLIC.CUSTOMER C /* PUBLIC.CUSTOMER_TABLE_SCAN */ INNER JOIN PUBLIC.INVOICE I /* PUBLIC.INVOICE_TABLE_SCAN */ /* WHERE PUBLIC.C.CUSTOMERID = PUBLIC.I.CUSTOMERID */ INNER JOIN PUBLIC.INVOICE_LINE L /* PUBLIC.INVOICE_LINE_TABLE_SCAN */ WHERE (PUBLIC.C.CUSTOMERID = PUBLIC.I.CUSTOMERID) AND ((PUBLIC.I.CUSTOMERID = PUBLIC.L.CUSTOMERID) AND (PUBLIC.I.INVOICEID = PUBLIC.L.INVOICEID))
> rows: 1
drop table customer;
......
......@@ -27,7 +27,9 @@ import org.h2.tools.Server;
import org.h2.util.Resources;
public class TestTools extends TestBase {
private Server server;
public void test() throws Exception {
deleteDb("utils");
testServerMain();
......@@ -41,20 +43,20 @@ public class TestTools extends TestBase {
testBackupRestore();
testRecover();
}
private void testServerMain() throws Exception {
String result;
Connection conn;
org.h2.Driver.load();
result = runServer(new String[]{"-?"}, 1);
check(result.indexOf("[options]") >= 0);
check(result.indexOf("Unknown option") < 0);
result = runServer(new String[]{"-xy"}, 1);
check(result.indexOf("[options]") >= 0);
check(result.indexOf("Unknown option") >= 0);
result = runServer(new String[]{"-tcp", "-tcpAllowOthers", "false", "-tcpPort", "9001", "-tcpPassword", "abc"}, 0);
check(result.indexOf("tcp://") >= 0);
check(result.indexOf(":9001") >= 0);
......@@ -64,29 +66,50 @@ public class TestTools extends TestBase {
conn.close();
result = runServer(new String[]{"-tcpShutdown", "tcp://localhost:9001", "-tcpPassword", "abc", "-tcpShutdownForce", "true"}, 0);
check(result.indexOf("Shutting down") >= 0);
result = runServer(new String[]{"-tcp", "-tcpAllowOthers", "true", "-tcpPort", "9001", "-tcpPassword", "def", "-tcpSSL", "true"}, 0);
result = runServer(new String[]{"-tcp", "-tcpAllowOthers", "true", "-tcpPort", "9001", "-tcpPassword", "abcdef", "-tcpSSL", "true"}, 0);
check(result.indexOf("ssl://") >= 0);
check(result.indexOf(":9001") >= 0);
check(result.indexOf("others can") >= 0);
check(result.indexOf("[options]") < 0);
conn = DriverManager.getConnection("jdbc:h2:ssl://localhost:9001/mem:", "sa", "sa");
conn.close();
result = runServer(new String[]{"-tcpShutdown", "ssl://localhost:9001", "-tcpPassword", "def", "-tcpShutdownForce", "false"}, 0);
result = runServer(new String[]{"-tcpShutdown", "ssl://localhost:9001", "-tcpPassword", "abcdef", "-tcpShutdownForce", "false"}, 0);
check(result.indexOf("Shutting down") >= 0);
result = runServer(new String[]{
"-web", "-webPort", "9002", "-webAllowOthers", "true", "-webSSL", "true",
"-pg", "-pgAllowOthers", "true", "-pgPort", "9003",
"-ftp", "-ftpPort", "9004", "-ftpDir", ".", "-ftpRead", "guest", "-ftpWrite", "sa", "-ftpWritePassword", "sa", "-ftpTask", "true",
"-tcp", "-tcpAllowOthers", "true", "-tcpPort", "9005", "-tcpPassword", "abc"}, 0);
Server stop = server;
check(result.indexOf("https://") >= 0);
check(result.indexOf(":9002") >= 0);
check(result.indexOf("pg://") >= 0);
check(result.indexOf(":9003") >= 0);
check(result.indexOf("others can") >= 0);
check(result.indexOf("only local") < 0);
check(result.indexOf("ftp://") >= 0);
check(result.indexOf(":9004") >= 0);
check(result.indexOf("tcp://") >= 0);
check(result.indexOf(":9005") >= 0);
result = runServer(new String[]{"-tcpShutdown", "tcp://localhost:9005", "-tcpPassword", "abc", "-tcpShutdownForce", "true"}, 0);
check(result.indexOf("Shutting down") >= 0);
stop.shutdown();
}
private String runServer(String[] args, int exitCode) throws Exception {
ByteArrayOutputStream buff = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(buff);
int gotCode = new Server().run(args, ps);
server = new Server();
int gotCode = server.run(args, ps);
check(exitCode, gotCode);
ps.flush();
String s = new String(buff.toByteArray());
return s;
}
private void testConvertTraceFile() throws Exception {
deleteDb("toolsConvertTraceFile");
Class.forName("org.h2.Driver");
......@@ -96,7 +119,7 @@ public class TestTools extends TestBase {
stat.execute("create table test(id int primary key, name varchar)");
stat.execute("insert into test values(1, 'Hello')");
conn.close();
ConvertTraceFile.main(new String[]{"-traceFile", baseDir + "/toolsConvertTraceFile.trace.db", "-javaClass", baseDir + "/Test", "-script", baseDir + "/test.sql"});
new File(baseDir + "/Test.java").delete();
......@@ -108,13 +131,13 @@ public class TestTools extends TestBase {
deleteDb("toolsConvertTraceFile");
Player.main(new String[]{baseDir + "/test.trace.db"});
testTraceFile(url);
deleteDb("toolsConvertTraceFile");
RunScript.main(new String[]{"-url", url, "-user", "sa", "-script", baseDir + "/test.sql"});
testTraceFile(url);
}
private void testTraceFile(String url) throws Exception {
Connection conn;
Recover.main(new String[]{"-removePassword", "-log", "false", "-dir", baseDir, "-db", "toolsConvertTraceFile"});
......@@ -147,7 +170,7 @@ public class TestTools extends TestBase {
check("Hello", rs.getString(2));
conn.close();
}
private void testRecover() throws Exception {
Class.forName("org.h2.Driver");
String url = "jdbc:h2:" + baseDir + "/toolsRecover";
......@@ -160,7 +183,7 @@ public class TestTools extends TestBase {
rs.next();
byte[] b1 = rs.getBytes(3);
String s1 = rs.getString(4);
conn.close();
Recover.main(new String[]{"-dir", baseDir, "-db", "toolsRecover"});
deleteDb("toolsRecover");
......@@ -257,6 +280,7 @@ public class TestTools extends TestBase {
private void testServer() throws Exception {
Connection conn;
deleteDb("test");
Server server = Server.createTcpServer(new String[] { "-ifExists", "false", "-baseDir", baseDir }).start();
conn = DriverManager.getConnection("jdbc:h2:tcp://localhost/test", "sa", "");
conn.close();
......
/*
* Copyright 2004-2007 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.tools.i18n;
public class AutoTranslate {
}
......@@ -13,10 +13,19 @@ import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.Stack;
import java.util.Map.Entry;
import org.h2.server.web.PageParser;
import org.h2.tools.doc.XMLParser;
import org.h2.util.FileUtils;
......@@ -24,13 +33,10 @@ import org.h2.util.IOUtils;
import org.h2.util.SortedProperties;
import org.h2.util.StringUtils;
//import com.google.api.translate.Language;
//import com.google.api.translate.Translate;
public class PrepareTranslation {
private static final String MAIN_LANGUAGE = "en";
private static final String DELETED_PREFIX = "~";
private static final boolean AUTO_TRANSLATE = false;
private static final boolean AUTO_TRANSLATE = true;
public static void main(String[] args) throws Exception {
new PrepareTranslation().run(args);
......@@ -55,7 +61,7 @@ public class PrepareTranslation {
// create the translated documentation
buildHtml("src/docsrc/text", "docs/html", "en");
// buildHtml("src/docsrc/text", "docs/html", "de");
buildHtml("src/docsrc/text", "docs/html", "de");
buildHtml("src/docsrc/text", "docs/html", "ja");
// convert the properties files back to utf8 text files, including the
......@@ -414,6 +420,7 @@ public class PrepareTranslation {
oldTranslations.setProperty(m, t);
}
}
HashSet toTranslate = new HashSet();
// add missing keys, using # and the value from the main file
Iterator it = main.keySet().iterator();
while (it.hasNext()) {
......@@ -422,11 +429,10 @@ public class PrepareTranslation {
if (!p.containsKey(key)) {
String t = oldTranslations.getProperty(now);
if (t == null) {
System.out.println(trans.getName() + ": key " + key
+ " not found in translation file; added dummy # 'translation'");
t = "#" + autoTranslate(now, language);
toTranslate.add(key);
} else {
p.put(key, t);
}
p.put(key, t);
} else {
String t = p.getProperty(key);
String last = base.getProperty(key);
......@@ -440,19 +446,42 @@ public class PrepareTranslation {
} else if (last != null && !last.equals(now)) {
t = oldTranslations.getProperty(now);
if (t == null) {
// main data changed since the last run: review
// translation
// main data changed since the last run: review translation
System.out.println(trans.getName() + ": key " + key + " changed, please review; last=" + last
+ " now=" + now);
String old = p.getProperty(key);
t = "#" + autoTranslate(now, language) + " #" + old;
// String old = p.getProperty(key);
toTranslate.add(key);
} else {
p.put(key, t);
}
p.put(key, t);
}
}
}
// remove keys that don't exist in the main file (deleted or typo in the
// key)
Map autoTranslated = new HashMap();
if (AUTO_TRANSLATE) {
HashSet set = new HashSet();
for (it = toTranslate.iterator(); it.hasNext();) {
String key = (String) it.next();
String now = main.getProperty(key);
set.add(now);
}
if ("de".equals(language)) {
autoTranslated = autoTranslate(set, "en", language);
}
}
for (it = toTranslate.iterator(); it.hasNext();) {
String key = (String) it.next();
String now = main.getProperty(key);
String t;
if (AUTO_TRANSLATE) {
t = "#" + autoTranslated.get(now);
} else {
System.out.println(trans.getName() + ": key " + key + " not found in translation file; added dummy # 'translation'");
t = "#" + now;
}
p.put(key, t);
}
// remove keys that don't exist in the main file (deleted or typo in the key)
it = new ArrayList(p.keySet()).iterator();
while (it.hasNext()) {
String key = (String) it.next();
......@@ -471,26 +500,87 @@ public class PrepareTranslation {
}
PropertiesToUTF8.storeProperties(p, trans.getAbsolutePath());
}
private Map autoTranslate(Set toTranslate, String sourceLanguage, String targetLanguage) {
HashMap results = new HashMap();
if (toTranslate.size() == 0) {
return results;
}
int maxLength = 1500;
int minSeparator = 100000;
HashMap keyMap = new HashMap(toTranslate.size());
StringBuffer buff = new StringBuffer(maxLength);
// TODO make sure these numbers don't occur in the original text
int separator = minSeparator;
for (Iterator it = toTranslate.iterator(); it.hasNext();) {
String original = (String) it.next();
if (original != null) {
original = original.trim();
if (buff.length() + original.length() > maxLength) {
System.out.println("remaining: " + (toTranslate.size() - separator + minSeparator));
translateChunk(buff, separator, sourceLanguage, targetLanguage, keyMap, results);
}
keyMap.put(new Integer(separator), original);
buff.append(separator);
buff.append(' ');
buff.append(original);
buff.append(' ');
separator++;
}
}
translateChunk(buff, separator, sourceLanguage, targetLanguage, keyMap, results);
return results;
}
private String autoTranslate(String original, String language) {
if (original == null || original.trim().length() == 0) {
return original;
private void translateChunk(StringBuffer buff, int separator, String source, String target, HashMap keyMap, HashMap results) {
buff.append(separator);
String original = buff.toString();
String translation = "";
try {
translation = translate(original, source, target);
System.out.println("original: " + original);
System.out.println("translation: " + translation);
} catch (Throwable e) {
System.out.println("Exception translating [" + original + "]: " + e);
e.printStackTrace();
}
String translation = original;
if (!AUTO_TRANSLATE) {
return "#" + translation;
for (Iterator it = keyMap.entrySet().iterator(); it.hasNext();) {
Entry entry = (Entry) it.next();
separator = ((Integer) entry.getKey()).intValue();
String o = (String) entry.getValue();
String startSeparator = String.valueOf(separator);
int start = translation.indexOf(startSeparator);
int end = translation.indexOf(String.valueOf(separator + 1));
if (start < 0 || end < 0) {
System.out.println("No translation for " + o);
results.put(o, "#" + o);
} else {
String t = translation.substring(start + startSeparator.length(), end);
t = t.trim();
results.put(o, t);
}
}
// if ("de".equals(language)) {
// try {
// Thread.sleep(5000);
// translation = Translate.translate(original, Language.ENGLISH, Language.GERMAN);
// System.out.println("original: " + original);
// System.out.println("translation: " + translation);
// } catch (Throwable e) {
// System.out.println("Exception translating [" + original + "]: " + e);
// // e.printStackTrace();
// }
// }
return "#" + translation;
keyMap.clear();
buff.setLength(0);
}
/**
* Translate the text using Google
*/
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");
start = result.indexOf('>', start) + 1;
int end = result.indexOf("</div>", start);
return result.substring(start, end);
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论