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

--no commit message

--no commit message
上级 a55cd699
...@@ -155,13 +155,6 @@ ...@@ -155,13 +155,6 @@
<echo message="Run ant codeswitchJdk... first."/> <echo message="Run ant codeswitchJdk... first."/>
</target> </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"> <target name="docs" depends="clean,javadoc,compile">
<copy todir="docs"> <copy todir="docs">
<fileset dir="src/docsrc" includes="index.html"/> <fileset dir="src/docsrc" includes="index.html"/>
......
...@@ -833,19 +833,13 @@ public class Parser { ...@@ -833,19 +833,13 @@ public class Parser {
if (readIf("(")) { if (readIf("(")) {
if (isToken("SELECT") || isToken("FROM")) { if (isToken("SELECT") || isToken("FROM")) {
Query query = parseSelect(); Query query = parseSelect();
String querySQL = query.getSQL();
Session s; Session s;
if (prepared != null && prepared instanceof CreateView) { if (prepared != null && prepared instanceof CreateView) {
s = database.getSystemSession(); s = database.getSystemSession();
} else { } else {
s = session; s = session;
} }
String tempViewName = s.getNextTempViewName(); table = TableView.createTempView(s, session.getUser(), query);
TableView v = new TableView(mainSchema, 0, tempViewName, querySQL, query.getParameters(), null, s,
false);
v.setOwner(session.getUser());
v.setTemporary(true);
table = v;
read(")"); read(")");
} else { } else {
TableFilter top = readTableFilter(fromOuter); TableFilter top = readTableFilter(fromOuter);
...@@ -1148,9 +1142,9 @@ public class Parser { ...@@ -1148,9 +1142,9 @@ public class Parser {
for (int j = 0; j < joinCols.length; j++) { for (int j = 0; j < joinCols.length; j++) {
String joinColumnName = joinCols[j].getName(); String joinColumnName = joinCols[j].getName();
if (tableColumnName.equals(joinColumnName)) { if (tableColumnName.equals(joinColumnName)) {
Expression tableExpr = new ExpressionColumn(database, currentSelect, tableSchema, last Expression tableExpr = new ExpressionColumn(database, tableSchema, last
.getTableAlias(), tableColumnName); .getTableAlias(), tableColumnName);
Expression joinExpr = new ExpressionColumn(database, currentSelect, joinSchema, join Expression joinExpr = new ExpressionColumn(database, joinSchema, join
.getTableAlias(), joinColumnName); .getTableAlias(), joinColumnName);
Expression equal = new Comparison(session, Comparison.EQUAL, tableExpr, joinExpr); Expression equal = new Comparison(session, Comparison.EQUAL, tableExpr, joinExpr);
if (on == null) { if (on == null) {
...@@ -1955,11 +1949,11 @@ public class Parser { ...@@ -1955,11 +1949,11 @@ public class Parser {
return expr; return expr;
} }
name = readColumnIdentifier(); 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 { private Expression readTerm() throws SQLException {
...@@ -2014,7 +2008,7 @@ public class Parser { ...@@ -2014,7 +2008,7 @@ public class Parser {
} else if (readIf(".")) { } else if (readIf(".")) {
r = readTermObjectDot(name); r = readTermObjectDot(name);
} else { } else {
r = new ExpressionColumn(database, currentSelect, null, null, name); r = new ExpressionColumn(database, null, null, name);
} }
} else { } else {
read(); read();
...@@ -2046,7 +2040,7 @@ public class Parser { ...@@ -2046,7 +2040,7 @@ public class Parser {
} else if (readIf("DATE")) { } else if (readIf("DATE")) {
r = readFunctionWithoutParameters("CURRENT_DATE"); r = readFunctionWithoutParameters("CURRENT_DATE");
} else { } else {
r = new ExpressionColumn(database, currentSelect, null, null, name); r = new ExpressionColumn(database, null, null, name);
} }
} else if ("NEXT".equals(name) && readIf("VALUE")) { } else if ("NEXT".equals(name) && readIf("VALUE")) {
read("FOR"); read("FOR");
...@@ -2070,7 +2064,7 @@ public class Parser { ...@@ -2070,7 +2064,7 @@ public class Parser {
read(); read();
r = ValueExpression.get(ValueString.get(text)); r = ValueExpression.get(ValueString.get(text));
} else { } else {
r = new ExpressionColumn(database, currentSelect, null, null, name); r = new ExpressionColumn(database, null, null, name);
} }
} }
break; break;
......
...@@ -46,7 +46,7 @@ public class Call extends Prepared { ...@@ -46,7 +46,7 @@ public class Call extends Prepared {
for (int i = 0; i < list.length; i++) { for (int i = 0; i < list.length; i++) {
Value e = list[i]; Value e = list[i];
Column col = new Column("C" + (i + 1), e.getType(), e.getPrecision(), e.getScale(), e.getDisplaySize()); 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); LocalResult result = new LocalResult(session, expr, list.length);
result.addRow(list); result.addRow(list);
......
...@@ -43,7 +43,7 @@ public class ExplainPlan extends Prepared { ...@@ -43,7 +43,7 @@ public class ExplainPlan extends Prepared {
// TODO rights: are rights required for explain? // TODO rights: are rights required for explain?
ObjectArray expressions = new ObjectArray(); ObjectArray expressions = new ObjectArray();
Column column = new Column("PLAN", Value.STRING); 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); expressions.add(expr);
result = new LocalResult(session, expressions, 1); result = new LocalResult(session, expressions, 1);
if (maxrows >= 0) { if (maxrows >= 0) {
......
...@@ -248,6 +248,7 @@ public abstract class Query extends Prepared { ...@@ -248,6 +248,7 @@ public abstract class Query extends Prepared {
public abstract void setEvaluatable(TableFilter tableFilter, boolean b); public abstract void setEvaluatable(TableFilter tableFilter, boolean b);
public abstract void addGlobalCondition(Expression expr, int columnId, int comparisonType) throws SQLException; public abstract void addGlobalCondition(Expression expr, int columnId, int comparisonType) throws SQLException;
public abstract void setDistinct(boolean b); public abstract void setDistinct(boolean b);
public abstract String getFirstColumnAlias(Session session);
public void setSampleSize(int sampleSize) { public void setSampleSize(int sampleSize) {
this.sampleSize = sampleSize; this.sampleSize = sampleSize;
......
...@@ -108,7 +108,7 @@ public class ScriptCommand extends ScriptBase { ...@@ -108,7 +108,7 @@ public class ScriptCommand extends ScriptBase {
private LocalResult createResult() { private LocalResult createResult() {
ObjectArray cols = new ObjectArray(); 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); return new LocalResult(session, cols, 1);
} }
......
...@@ -10,6 +10,7 @@ import java.util.HashSet; ...@@ -10,6 +10,7 @@ import java.util.HashSet;
import org.h2.constant.ErrorCode; import org.h2.constant.ErrorCode;
import org.h2.constant.SysProperties; import org.h2.constant.SysProperties;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.expression.Alias;
import org.h2.expression.Comparison; import org.h2.expression.Comparison;
import org.h2.expression.ConditionAndOr; import org.h2.expression.ConditionAndOr;
import org.h2.expression.Expression; import org.h2.expression.Expression;
...@@ -270,8 +271,9 @@ public class Select extends Query { ...@@ -270,8 +271,9 @@ public class Select extends Query {
return null; 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) { 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(); limitRows += offset.getValue(session).getInt();
} }
int rowNumber = 0; int rowNumber = 0;
...@@ -386,7 +388,7 @@ public class Select extends Query { ...@@ -386,7 +388,7 @@ public class Select extends Query {
Column[] columns = t.getColumns(); Column[] columns = t.getColumns();
for (int j = 0; j < columns.length; j++) { for (int j = 0; j < columns.length; j++) {
Column c = columns[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); expressions.add(i++, ec);
} }
i--; i--;
...@@ -425,8 +427,8 @@ public class Select extends Query { ...@@ -425,8 +427,8 @@ public class Select extends Query {
havingIndex = -1; havingIndex = -1;
} }
// first visible columns, then order by, then having, and then group by // first visible columns, then order by, then having,
// at the end // and group by at the end
if (group != null) { if (group != null) {
groupIndex = new int[group.size()]; groupIndex = new int[group.size()];
for (int i = 0; i < group.size(); i++) { for (int i = 0; i < group.size(); i++) {
...@@ -486,6 +488,9 @@ public class Select extends Query { ...@@ -486,6 +488,9 @@ public class Select extends Query {
} }
if (condition != null) { if (condition != null) {
condition = condition.optimize(session); condition = condition.optimize(session);
if (SysProperties.OPTIMIZE_IN_JOIN) {
condition = condition.optimizeInJoin(session, this);
}
for (int j = 0; j < filters.size(); j++) { for (int j = 0; j < filters.size(); j++) {
TableFilter f = (TableFilter) filters.get(j); TableFilter f = (TableFilter) filters.get(j);
condition.createIndexConditions(session, f); condition.createIndexConditions(session, f);
...@@ -777,4 +782,20 @@ public class Select extends Query { ...@@ -777,4 +782,20 @@ public class Select extends Query {
return isEverything(ExpressionVisitor.READONLY); 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();
}
} }
...@@ -207,7 +207,7 @@ public class SelectUnion extends Query { ...@@ -207,7 +207,7 @@ public class SelectUnion extends Query {
int scale = Math.max(l.getScale(), r.getScale()); int scale = Math.max(l.getScale(), r.getScale());
int displaySize = Math.max(l.getDisplaySize(), r.getDisplaySize()); int displaySize = Math.max(l.getDisplaySize(), r.getDisplaySize());
Column col = new Column(l.getAlias(), type, prec, scale, displaySize); 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); expressions.add(e);
} }
if (orderList != null) { if (orderList != null) {
...@@ -332,4 +332,8 @@ public class SelectUnion extends Query { ...@@ -332,4 +332,8 @@ public class SelectUnion extends Query {
right.updateAggregate(session); right.updateAggregate(session);
} }
public String getFirstColumnAlias(Session session) {
return null;
}
} }
...@@ -27,6 +27,10 @@ public class SysProperties { ...@@ -27,6 +27,10 @@ public class SysProperties {
public static final boolean OPTIMIZE_EVALUATABLE_SUBQUERIES = getBooleanSetting("h2.optimizeEvaluatableSubqueries", true); public static final boolean OPTIMIZE_EVALUATABLE_SUBQUERIES = getBooleanSetting("h2.optimizeEvaluatableSubqueries", true);
public static final boolean OPTIMIZE_IN = getBooleanSetting("h2.optimizeIn", 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_MIN_MAX = getBooleanSetting("h2.optimizeMinMax", true);
public static final boolean OPTIMIZE_SUBQUERY_CACHE = getBooleanSetting("h2.optimizeSubqueryCache", true); public static final boolean OPTIMIZE_SUBQUERY_CACHE = getBooleanSetting("h2.optimizeSubqueryCache", true);
public static final boolean OPTIMIZE_NOT = getBooleanSetting("h2.optimizeNot", true); public static final boolean OPTIMIZE_NOT = getBooleanSetting("h2.optimizeNot", true);
......
...@@ -6,6 +6,7 @@ package org.h2.expression; ...@@ -6,6 +6,7 @@ package org.h2.expression;
import java.sql.SQLException; import java.sql.SQLException;
import org.h2.command.dml.Select;
import org.h2.constant.SysProperties; import org.h2.constant.SysProperties;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.message.Message; import org.h2.message.Message;
...@@ -20,9 +21,6 @@ import org.h2.value.ValueNull; ...@@ -20,9 +21,6 @@ import org.h2.value.ValueNull;
*/ */
public class ConditionAndOr extends Condition { 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; public static final int AND = 0, OR = 1;
private final int andOrType; private final int andOrType;
...@@ -222,4 +220,19 @@ public class ConditionAndOr extends Condition { ...@@ -222,4 +220,19 @@ public class ConditionAndOr extends Condition {
return left.getCost() + right.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; ...@@ -6,12 +6,16 @@ package org.h2.expression;
import java.sql.SQLException; import java.sql.SQLException;
import org.h2.command.dml.Select;
import org.h2.constant.SysProperties; import org.h2.constant.SysProperties;
import org.h2.engine.Constants;
import org.h2.engine.Database; import org.h2.engine.Database;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.index.IndexCondition; import org.h2.index.IndexCondition;
import org.h2.schema.Schema;
import org.h2.table.Column; import org.h2.table.Column;
import org.h2.table.ColumnResolver; import org.h2.table.ColumnResolver;
import org.h2.table.FunctionTable;
import org.h2.table.TableFilter; import org.h2.table.TableFilter;
import org.h2.util.ObjectArray; import org.h2.util.ObjectArray;
import org.h2.value.CompareMode; import org.h2.value.CompareMode;
...@@ -200,4 +204,36 @@ public class ConditionIn extends Condition { ...@@ -200,4 +204,36 @@ public class ConditionIn extends Condition {
return cost; 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; ...@@ -7,6 +7,7 @@ package org.h2.expression;
import java.sql.SQLException; import java.sql.SQLException;
import org.h2.command.dml.Query; import org.h2.command.dml.Query;
import org.h2.command.dml.Select;
import org.h2.constant.ErrorCode; import org.h2.constant.ErrorCode;
import org.h2.engine.Database; import org.h2.engine.Database;
import org.h2.engine.Session; import org.h2.engine.Session;
...@@ -14,6 +15,7 @@ import org.h2.message.Message; ...@@ -14,6 +15,7 @@ import org.h2.message.Message;
import org.h2.result.LocalResult; import org.h2.result.LocalResult;
import org.h2.table.ColumnResolver; import org.h2.table.ColumnResolver;
import org.h2.table.TableFilter; import org.h2.table.TableFilter;
import org.h2.table.TableView;
import org.h2.value.Value; import org.h2.value.Value;
import org.h2.value.ValueBoolean; import org.h2.value.ValueBoolean;
import org.h2.value.ValueNull; import org.h2.value.ValueNull;
...@@ -122,4 +124,26 @@ public class ConditionInSelect extends Condition { ...@@ -122,4 +124,26 @@ public class ConditionInSelect extends Condition {
return left.getCost() + 10 + (int) (10 * query.getCost()); 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; ...@@ -6,6 +6,7 @@ package org.h2.expression;
import java.sql.SQLException; import java.sql.SQLException;
import org.h2.command.dml.Select;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.table.Column; import org.h2.table.Column;
import org.h2.table.ColumnResolver; import org.h2.table.ColumnResolver;
...@@ -103,4 +104,12 @@ public abstract class Expression { ...@@ -103,4 +104,12 @@ public abstract class Expression {
addedToFilter = true; 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 { ...@@ -32,12 +32,12 @@ public class ExpressionColumn extends Expression {
private Column column; private Column column;
private boolean evaluatable; private boolean evaluatable;
public ExpressionColumn(Database database, Select select, Column column) { public ExpressionColumn(Database database, Column column) {
this.database = database; this.database = database;
this.column = column; 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.database = database;
this.schemaName = schemaName; this.schemaName = schemaName;
this.tableAlias = tableAlias; this.tableAlias = tableAlias;
......
...@@ -21,6 +21,7 @@ import org.h2.engine.Database; ...@@ -21,6 +21,7 @@ import org.h2.engine.Database;
import org.h2.engine.Mode; import org.h2.engine.Mode;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.message.Message; import org.h2.message.Message;
import org.h2.result.LocalResult;
import org.h2.schema.Sequence; import org.h2.schema.Sequence;
import org.h2.security.BlockCipher; import org.h2.security.BlockCipher;
import org.h2.security.CipherFactory; import org.h2.security.CipherFactory;
...@@ -31,14 +32,12 @@ import org.h2.table.LinkSchema; ...@@ -31,14 +32,12 @@ import org.h2.table.LinkSchema;
import org.h2.table.TableFilter; import org.h2.table.TableFilter;
import org.h2.tools.CompressTool; import org.h2.tools.CompressTool;
import org.h2.tools.Csv; import org.h2.tools.Csv;
import org.h2.tools.SimpleResultSet;
import org.h2.util.ObjectUtils;
import org.h2.util.MathUtils; import org.h2.util.MathUtils;
import org.h2.util.MemoryUtils; import org.h2.util.MemoryUtils;
import org.h2.util.ObjectArray; import org.h2.util.ObjectArray;
import org.h2.util.ObjectUtils;
import org.h2.util.RandomUtils; import org.h2.util.RandomUtils;
import org.h2.util.StringUtils; import org.h2.util.StringUtils;
import org.h2.value.DataType;
import org.h2.value.Value; import org.h2.value.Value;
import org.h2.value.ValueArray; import org.h2.value.ValueArray;
import org.h2.value.ValueBoolean; import org.h2.value.ValueBoolean;
...@@ -85,7 +84,7 @@ public class Function extends Expression implements FunctionCall { ...@@ -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, 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, 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, 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; private static final int VAR_ARGS = -1;
...@@ -286,6 +285,7 @@ public class Function extends Expression implements FunctionCall { ...@@ -286,6 +285,7 @@ public class Function extends Expression implements FunctionCall {
addFunction("ARRAY_LENGTH", ARRAY_LENGTH, 1, Value.INT); addFunction("ARRAY_LENGTH", ARRAY_LENGTH, 1, Value.INT);
addFunction("LINK_SCHEMA", LINK_SCHEMA, 6, Value.RESULT_SET); addFunction("LINK_SCHEMA", LINK_SCHEMA, 6, Value.RESULT_SET);
addFunctionWithNull("TABLE", TABLE, VAR_ARGS, 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("LEAST", LEAST, VAR_ARGS, Value.NULL);
addFunctionWithNull("GREATEST", GREATEST, VAR_ARGS, Value.NULL); addFunctionWithNull("GREATEST", GREATEST, VAR_ARGS, Value.NULL);
} }
...@@ -817,7 +817,9 @@ public class Function extends Expression implements FunctionCall { ...@@ -817,7 +817,9 @@ public class Function extends Expression implements FunctionCall {
return ValueResultSet.get(rs); return ValueResultSet.get(rs);
} }
case TABLE: case TABLE:
return getTable(session, args, false); return getTable(session, args, false, false);
case TABLE_DISTINCT:
return getTable(session, args, false, true);
case CSVWRITE: { case CSVWRITE: {
session.getUser().checkAdmin(); session.getUser().checkAdmin();
Connection conn = session.createConnection(false); Connection conn = session.createConnection(false);
...@@ -1266,6 +1268,7 @@ public class Function extends Expression implements FunctionCall { ...@@ -1266,6 +1268,7 @@ public class Function extends Expression implements FunctionCall {
case COALESCE: case COALESCE:
case CSVREAD: case CSVREAD:
case TABLE: case TABLE:
case TABLE_DISTINCT:
case LEAST: case LEAST:
case GREATEST: case GREATEST:
min = 1; min = 1;
...@@ -1529,6 +1532,7 @@ public class Function extends Expression implements FunctionCall { ...@@ -1529,6 +1532,7 @@ public class Function extends Expression implements FunctionCall {
buff.append(args[1].getSQL()); buff.append(args[1].getSQL());
break; break;
} }
case TABLE_DISTINCT:
case TABLE: { case TABLE: {
for (int i = 0; i < args.length; i++) { for (int i = 0; i < args.length; i++) {
if (i > 0) { if (i > 0) {
...@@ -1597,7 +1601,10 @@ public class Function extends Expression implements FunctionCall { ...@@ -1597,7 +1601,10 @@ public class Function extends Expression implements FunctionCall {
return vr; return vr;
} }
case TABLE: { case TABLE: {
return getTable(session, args, true); return getTable(session, args, true, false);
}
case TABLE_DISTINCT: {
return getTable(session, args, true, true);
} }
default: default:
break; break;
...@@ -1648,19 +1655,21 @@ public class Function extends Expression implements FunctionCall { ...@@ -1648,19 +1655,21 @@ public class Function extends Expression implements FunctionCall {
return cost; return cost;
} }
public ValueResultSet getTable(Session session, Expression[] args, boolean onlyColumnList) throws SQLException { public ValueResultSet getTable(Session session, Expression[] args, boolean onlyColumnList, boolean distinct) throws SQLException {
SimpleResultSet rs = new SimpleResultSet();
int len = columnList.length; int len = columnList.length;
Expression[] header = new Expression[len];
Database db = session.getDatabase();
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
Column c = columnList[i]; Column c = columnList[i];
String columnName = c.getName(); ExpressionColumn col = new ExpressionColumn(db, c);
int dataType = DataType.convertTypeToSQLType(c.getType()); header[i] = col;
int precision = MathUtils.convertLongToInt(c.getPrecision()); }
int scale = c.getScale(); LocalResult result = new LocalResult(session, header, len);
rs.addColumn(columnName, dataType, precision, scale); if (distinct) {
result.setDistinct();
} }
if (!onlyColumnList) { if (!onlyColumnList) {
Value[][] list = new Value[args.length][]; Value[][] list = new Value[len][];
int rowCount = 0; int rowCount = 0;
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
Value v = args[i].getValue(session); Value v = args[i].getValue(session);
...@@ -1674,7 +1683,7 @@ public class Function extends Expression implements FunctionCall { ...@@ -1674,7 +1683,7 @@ public class Function extends Expression implements FunctionCall {
} }
} }
for (int row = 0; row < rowCount; row++) { for (int row = 0; row < rowCount; row++) {
Object[] r = new Object[len]; Value[] r = new Value[len];
for (int j = 0; j < len; j++) { for (int j = 0; j < len; j++) {
Value[] l = list[j]; Value[] l = list[j];
Value v; Value v;
...@@ -1687,12 +1696,13 @@ public class Function extends Expression implements FunctionCall { ...@@ -1687,12 +1696,13 @@ public class Function extends Expression implements FunctionCall {
v = v.convertPrecision(c.getPrecision()); v = v.convertPrecision(c.getPrecision());
v = v.convertScale(true, c.getScale()); 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; return vr;
} }
......
...@@ -2724,9 +2724,9 @@ CALL SESSION_ID() ...@@ -2724,9 +2724,9 @@ CALL SESSION_ID()
" "
"Functions (System)","TABLE"," "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')) SELECT * FROM TABLE(ID INT=(1, 2), NAME VARCHAR=('Hello', 'World'))
" "
......
...@@ -55,7 +55,7 @@ public class LocalResult implements ResultInterface { ...@@ -55,7 +55,7 @@ public class LocalResult implements ResultInterface {
int scale = meta.getScale(i + 1); int scale = meta.getScale(i + 1);
int displaySize = meta.getColumnDisplaySize(i + 1); int displaySize = meta.getColumnDisplaySize(i + 1);
Column col = new Column(name, type, precision, scale, displaySize); 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); cols.add(expr);
} }
LocalResult result = new LocalResult(session, cols, columnCount); LocalResult result = new LocalResult(session, cols, columnCount);
...@@ -108,7 +108,17 @@ public class LocalResult implements ResultInterface { ...@@ -108,7 +108,17 @@ public class LocalResult implements ResultInterface {
return updateCount; 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; this.session = session;
if (session == null) { if (session == null) {
this.maxMemoryRows = Integer.MAX_VALUE; this.maxMemoryRows = Integer.MAX_VALUE;
...@@ -118,9 +128,8 @@ public class LocalResult implements ResultInterface { ...@@ -118,9 +128,8 @@ public class LocalResult implements ResultInterface {
rows = new ObjectArray(); rows = new ObjectArray();
this.visibleColumnCount = visibleColumnCount; this.visibleColumnCount = visibleColumnCount;
rowId = -1; rowId = -1;
this.expressions = new Expression[cols.size()]; this.expressions = expressions;
cols.toArray(expressions); this.displaySizes = new int[expressions.length];
this.displaySizes = new int[cols.size()];
} }
public void setSortOrder(SortOrder sort) { public void setSortOrder(SortOrder sort) {
...@@ -128,9 +137,8 @@ public class LocalResult implements ResultInterface { ...@@ -128,9 +137,8 @@ public class LocalResult implements ResultInterface {
} }
public void setDistinct() { public void setDistinct() {
// TODO big result sets: how to buffer distinct result sets? maybe do // TODO big result sets: how to buffer distinct result sets?
// the // maybe remove duplicates when sorting each block, and when merging
// distinct when sorting each block, and final merging
distinctRows = new ValueHashMap(session.getDatabase()); distinctRows = new ValueHashMap(session.getDatabase());
} }
......
...@@ -55,6 +55,7 @@ public class WebServer implements Service { ...@@ -55,6 +55,7 @@ public class WebServer implements Service {
{ "pt_BR", "Portugu\u00eas (Brasil)"}, { "pt_BR", "Portugu\u00eas (Brasil)"},
{ "pt_PT", "Portugu\u00eas (Europeu)"}, { "pt_PT", "Portugu\u00eas (Europeu)"},
{ "ru", "\u0440\u0443\u0441\u0441\u043a\u0438\u0439"}, { "ru", "\u0440\u0443\u0441\u0441\u043a\u0438\u0439"},
{ "uk", "\u0423\u043A\u0440\u0430\u0457\u043D\u0441\u044C\u043A\u0430"},
{ "zh_CN", "\u4E2D\u6587"}, { "zh_CN", "\u4E2D\u6587"},
}; };
...@@ -76,6 +77,8 @@ public class WebServer implements Service { ...@@ -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")); String lang = new java.util.Locale("hu").getDisplayLanguage(new java.util.Locale("hu"));
java.util.Locale.CHINESE.getDisplayLanguage( java.util.Locale.CHINESE.getDisplayLanguage(
java.util.Locale.CHINESE); 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 { ...@@ -392,7 +392,7 @@ public class TableFilter implements ColumnResolver {
} }
} }
buff.append(table.getSQL()); buff.append(table.getSQL());
if (alias != null && !table.getName().equals(alias)) { if (alias != null) {
buff.append(' '); buff.append(' ');
buff.append(Parser.quoteIdentifier(alias)); buff.append(Parser.quoteIdentifier(alias));
} }
...@@ -422,7 +422,7 @@ public class TableFilter implements ColumnResolver { ...@@ -422,7 +422,7 @@ public class TableFilter implements ColumnResolver {
String condition = StringUtils.unEnclose(filterCondition.getSQL()); String condition = StringUtils.unEnclose(filterCondition.getSQL());
condition = StringUtils.quoteRemarkSQL(condition); condition = StringUtils.quoteRemarkSQL(condition);
buff.append(condition); buff.append(condition);
buff.append("*/"); buff.append(" */");
} }
return buff.toString(); return buff.toString();
} }
......
...@@ -307,4 +307,15 @@ public class TableView extends Table { ...@@ -307,4 +307,15 @@ public class TableView extends Table {
return owner; 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;
}
} }
...@@ -558,6 +558,8 @@ public class DataType { ...@@ -558,6 +558,8 @@ public class DataType {
return Value.CLOB; return Value.CLOB;
case Types.NULL: case Types.NULL:
return Value.NULL; return Value.NULL;
case Types.ARRAY:
return Value.ARRAY;
default: default:
throw Message.getSQLException(ErrorCode.UNKNOWN_DATA_TYPE_1, ""+sqlType); throw Message.getSQLException(ErrorCode.UNKNOWN_DATA_TYPE_1, ""+sqlType);
} }
......
...@@ -10,7 +10,9 @@ import java.sql.ResultSetMetaData; ...@@ -10,7 +10,9 @@ import java.sql.ResultSetMetaData;
import java.sql.SQLException; import java.sql.SQLException;
import org.h2.message.Message; import org.h2.message.Message;
import org.h2.result.LocalResult;
import org.h2.tools.SimpleResultSet; import org.h2.tools.SimpleResultSet;
import org.h2.util.MathUtils;
public class ValueResultSet extends Value { public class ValueResultSet extends Value {
...@@ -25,6 +27,28 @@ public class ValueResultSet extends Value { ...@@ -25,6 +27,28 @@ public class ValueResultSet extends Value {
return val; 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 { public static ValueResultSet getCopy(ResultSet rs, int maxrows) throws SQLException {
ResultSetMetaData meta = rs.getMetaData(); ResultSetMetaData meta = rs.getMetaData();
int columnCount = meta.getColumnCount(); int columnCount = meta.getColumnCount();
......
...@@ -150,10 +150,34 @@ java org.h2.test.TestAll timer ...@@ -150,10 +150,34 @@ java org.h2.test.TestAll timer
/* /*
create table test(id int, name varchar);
insert into test select x, '' from system_range(1, 10000);
-- fast
update test set name = 'y' where cast(id as varchar) like '1%';
-- slow
update test set name = 'x' where id in (select x from system_range(1, 10000) where cast(x as varchar) like '1%');
drop table test;
Optimize IN(...), IN(select), ID=? OR ID=?: create temp table and use join
Bug:
H2 1.0.62 (2007-11-25) has regressed on this query. Parser syntax error is returned (query is OK for derby, oracle, and earlier H2 versions).
SELECT COUNT(*) FROM (
SELECT TT.id,TT.table_name FROM (
SELECT DISTINCT id, table_name FROM information_schema.tables WHERE id=-8 UNION SELECT DISTINCT id, table_name FROM information_schema.tables WHERE id=-8) AS TT
) AS AWR WHERE AWR.id=-8
Remove the final predicate and the query parses & runs fine:
SELECT COUNT(*) FROM (
SELECT TT.id,TT.table_name FROM (
SELECT DISTINCT id, table_name FROM information_schema.tables WHERE id=-8 UNION SELECT DISTINCT id, table_name FROM information_schema.tables WHERE id=-8) AS TT
) AS AWR
write more tests for the command line tools 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 avoid creating thousands of trace.db files
...@@ -161,21 +185,10 @@ Known Problems: ...@@ -161,21 +185,10 @@ Known Problems:
link to history page, bug page link to history page, bug page
Add a link to the google code bug page Add a link to the google code bug page
History:
implement & test: checkpoint commits running transactions implement & test: checkpoint commits running transactions
test DbStarter 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. A file is sent although the Japanese translation has not been completed yet.
---- ----
......
--- special grammar and test cases --------------------------------------------------------------------------------------------- --- 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); CREATE TABLE TEST(ID INTEGER NOT NULL, ID2 INTEGER DEFAULT 0);
> ok > ok
...@@ -157,8 +220,8 @@ insert into test values(1), (2), (3); ...@@ -157,8 +220,8 @@ insert into test values(1), (2), (3);
explain select * from test where id in(1, 2, null); explain select * from test where id in(1, 2, null);
> PLAN > 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 > rows: 1
drop table test; drop table test;
...@@ -1878,8 +1941,8 @@ select * from test t1 where id in(id); ...@@ -1878,8 +1941,8 @@ select * from test t1 where id in(id);
explain select * from test t1 where id in(select id from test); explain select * from test t1 where id in(select id from test);
> PLAN > 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 > rows: 1
select * from test t1 where id in(select id from test); 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); ...@@ -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); explain select * from test t1 where id in(1, select max(id) from test);
> PLAN > 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 > rows: 1
select * from test t1 where id in(1, select max(id) from test); 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 ...@@ -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 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'; is null or three.val>=DATE'2006-07-01';
> PLAN > 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 > rows: 1
-- Query #4: same as #3, but the joins have been manually re-ordered -- 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 ...@@ -2074,8 +2137,8 @@ inner join test2 on test1.id=test2.id left
outer join test3 on test2.id=test3.id outer join test3 on test2.id=test3.id
where test3.id is null; where test3.id is null;
> PLAN > 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 > rows: 1
insert into test1 select x from system_range(2, 1000); insert into test1 select x from system_range(2, 1000);
...@@ -3827,20 +3890,20 @@ insert into b select id+10, p+10 from b; ...@@ -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; explain select * from b b0, b b1, b b2 where b1.p = b0.id and b2.p = b1.id and b0.id=10;
> PLAN > 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 > 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; 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 > 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 > 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; 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 > 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 > rows: 1
analyze; analyze;
...@@ -3848,8 +3911,8 @@ 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; 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 > 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 > rows: 1
drop table if exists b; 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 ...@@ -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 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; AND E.Y=D.X AND D.Y=C.X AND C.Y=B.X AND B.Y=A.X;
> PLAN > 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 > rows: 1
DROP TABLE O; DROP TABLE O;
...@@ -3948,8 +4011,8 @@ EXPLAIN SELECT COUNT(*) FROM PARENT, CHILD A, CHILD B, CHILD C, CHILD D, CHILD E ...@@ -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 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; AND DID=D.ID AND EID=E.ID AND FID=F.ID AND GID=G.ID AND HID=H.ID;
> PLAN > 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 > rows: 1
CREATE TABLE FAMILY(ID INT PRIMARY KEY, PARENTID INT); 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, ...@@ -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 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; 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 > 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 > rows: 1
DROP TABLE FAMILY; DROP TABLE FAMILY;
...@@ -4771,20 +4834,20 @@ EXPLAIN PLAN FOR SELECT NAME, COUNT(*) FROM TEST GROUP BY NAME HAVING COUNT(*) > ...@@ -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; 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 > 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 > 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; 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 > 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 > 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; 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 > 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 > rows: 1
EXPLAIN PLAN FOR SELECT * FROM TEST T1 WHERE EXISTS(SELECT * FROM TEST T2 WHERE T1.ID-1 = T2.ID); 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 ...@@ -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); EXPLAIN PLAN FOR SELECT * FROM TEST T1 WHERE ID IN(1, 2);
> PLAN > 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 > rows: 1
EXPLAIN PLAN FOR SELECT * FROM TEST T1 WHERE ID IN(SELECT ID FROM TEST); EXPLAIN PLAN FOR SELECT * FROM TEST T1 WHERE ID IN(SELECT ID FROM TEST);
> PLAN > 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 > rows: 1
EXPLAIN PLAN FOR SELECT * FROM TEST T1 WHERE ID NOT IN(SELECT ID FROM TEST); 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 ...@@ -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; explain select c.*, i.*, l.* from customer c natural join invoice i natural join INVOICE_LINE l;
> PLAN > 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 > rows: 1
drop table customer; drop table customer;
......
...@@ -28,6 +28,8 @@ import org.h2.util.Resources; ...@@ -28,6 +28,8 @@ import org.h2.util.Resources;
public class TestTools extends TestBase { public class TestTools extends TestBase {
private Server server;
public void test() throws Exception { public void test() throws Exception {
deleteDb("utils"); deleteDb("utils");
testServerMain(); testServerMain();
...@@ -65,22 +67,43 @@ public class TestTools extends TestBase { ...@@ -65,22 +67,43 @@ public class TestTools extends TestBase {
result = runServer(new String[]{"-tcpShutdown", "tcp://localhost:9001", "-tcpPassword", "abc", "-tcpShutdownForce", "true"}, 0); result = runServer(new String[]{"-tcpShutdown", "tcp://localhost:9001", "-tcpPassword", "abc", "-tcpShutdownForce", "true"}, 0);
check(result.indexOf("Shutting down") >= 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("ssl://") >= 0);
check(result.indexOf(":9001") >= 0); check(result.indexOf(":9001") >= 0);
check(result.indexOf("others can") >= 0); check(result.indexOf("others can") >= 0);
check(result.indexOf("[options]") < 0); check(result.indexOf("[options]") < 0);
conn = DriverManager.getConnection("jdbc:h2:ssl://localhost:9001/mem:", "sa", "sa"); conn = DriverManager.getConnection("jdbc:h2:ssl://localhost:9001/mem:", "sa", "sa");
conn.close(); 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); 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 { private String runServer(String[] args, int exitCode) throws Exception {
ByteArrayOutputStream buff = new ByteArrayOutputStream(); ByteArrayOutputStream buff = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(buff); PrintStream ps = new PrintStream(buff);
int gotCode = new Server().run(args, ps); server = new Server();
int gotCode = server.run(args, ps);
check(exitCode, gotCode); check(exitCode, gotCode);
ps.flush(); ps.flush();
String s = new String(buff.toByteArray()); String s = new String(buff.toByteArray());
...@@ -257,6 +280,7 @@ public class TestTools extends TestBase { ...@@ -257,6 +280,7 @@ public class TestTools extends TestBase {
private void testServer() throws Exception { private void testServer() throws Exception {
Connection conn; Connection conn;
deleteDb("test");
Server server = Server.createTcpServer(new String[] { "-ifExists", "false", "-baseDir", baseDir }).start(); Server server = Server.createTcpServer(new String[] { "-ifExists", "false", "-baseDir", baseDir }).start();
conn = DriverManager.getConnection("jdbc:h2:tcp://localhost/test", "sa", ""); conn = DriverManager.getConnection("jdbc:h2:tcp://localhost/test", "sa", "");
conn.close(); 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; ...@@ -13,10 +13,19 @@ import java.io.IOException;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.OutputStreamWriter; import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.Set;
import java.util.Stack; import java.util.Stack;
import java.util.Map.Entry;
import org.h2.server.web.PageParser; import org.h2.server.web.PageParser;
import org.h2.tools.doc.XMLParser; import org.h2.tools.doc.XMLParser;
import org.h2.util.FileUtils; import org.h2.util.FileUtils;
...@@ -24,13 +33,10 @@ import org.h2.util.IOUtils; ...@@ -24,13 +33,10 @@ import org.h2.util.IOUtils;
import org.h2.util.SortedProperties; import org.h2.util.SortedProperties;
import org.h2.util.StringUtils; import org.h2.util.StringUtils;
//import com.google.api.translate.Language;
//import com.google.api.translate.Translate;
public class PrepareTranslation { public class PrepareTranslation {
private static final String MAIN_LANGUAGE = "en"; private static final String MAIN_LANGUAGE = "en";
private static final String DELETED_PREFIX = "~"; 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 { public static void main(String[] args) throws Exception {
new PrepareTranslation().run(args); new PrepareTranslation().run(args);
...@@ -55,7 +61,7 @@ public class PrepareTranslation { ...@@ -55,7 +61,7 @@ public class PrepareTranslation {
// create the translated documentation // create the translated documentation
buildHtml("src/docsrc/text", "docs/html", "en"); 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"); buildHtml("src/docsrc/text", "docs/html", "ja");
// convert the properties files back to utf8 text files, including the // convert the properties files back to utf8 text files, including the
...@@ -414,6 +420,7 @@ public class PrepareTranslation { ...@@ -414,6 +420,7 @@ public class PrepareTranslation {
oldTranslations.setProperty(m, t); oldTranslations.setProperty(m, t);
} }
} }
HashSet toTranslate = new HashSet();
// add missing keys, using # and the value from the main file // add missing keys, using # and the value from the main file
Iterator it = main.keySet().iterator(); Iterator it = main.keySet().iterator();
while (it.hasNext()) { while (it.hasNext()) {
...@@ -422,11 +429,10 @@ public class PrepareTranslation { ...@@ -422,11 +429,10 @@ public class PrepareTranslation {
if (!p.containsKey(key)) { if (!p.containsKey(key)) {
String t = oldTranslations.getProperty(now); String t = oldTranslations.getProperty(now);
if (t == null) { if (t == null) {
System.out.println(trans.getName() + ": key " + key toTranslate.add(key);
+ " not found in translation file; added dummy # 'translation'"); } else {
t = "#" + autoTranslate(now, language);
}
p.put(key, t); p.put(key, t);
}
} else { } else {
String t = p.getProperty(key); String t = p.getProperty(key);
String last = base.getProperty(key); String last = base.getProperty(key);
...@@ -440,19 +446,42 @@ public class PrepareTranslation { ...@@ -440,19 +446,42 @@ public class PrepareTranslation {
} else if (last != null && !last.equals(now)) { } else if (last != null && !last.equals(now)) {
t = oldTranslations.getProperty(now); t = oldTranslations.getProperty(now);
if (t == null) { if (t == null) {
// main data changed since the last run: review // main data changed since the last run: review translation
// translation
System.out.println(trans.getName() + ": key " + key + " changed, please review; last=" + last System.out.println(trans.getName() + ": key " + key + " changed, please review; last=" + last
+ " now=" + now); + " now=" + now);
String old = p.getProperty(key); // String old = p.getProperty(key);
t = "#" + autoTranslate(now, language) + " #" + old; 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(); it = new ArrayList(p.keySet()).iterator();
while (it.hasNext()) { while (it.hasNext()) {
String key = (String) it.next(); String key = (String) it.next();
...@@ -472,25 +501,86 @@ public class PrepareTranslation { ...@@ -472,25 +501,86 @@ public class PrepareTranslation {
PropertiesToUTF8.storeProperties(p, trans.getAbsolutePath()); PropertiesToUTF8.storeProperties(p, trans.getAbsolutePath());
} }
private String autoTranslate(String original, String language) { private Map autoTranslate(Set toTranslate, String sourceLanguage, String targetLanguage) {
if (original == null || original.trim().length() == 0) { HashMap results = new HashMap();
return original; if (toTranslate.size() == 0) {
} return results;
String translation = original; }
if (!AUTO_TRANSLATE) { int maxLength = 1500;
return "#" + translation; int minSeparator = 100000;
} HashMap keyMap = new HashMap(toTranslate.size());
// if ("de".equals(language)) { StringBuffer buff = new StringBuffer(maxLength);
// try { // TODO make sure these numbers don't occur in the original text
// Thread.sleep(5000); int separator = minSeparator;
// translation = Translate.translate(original, Language.ENGLISH, Language.GERMAN); for (Iterator it = toTranslate.iterator(); it.hasNext();) {
// System.out.println("original: " + original); String original = (String) it.next();
// System.out.println("translation: " + translation); if (original != null) {
// } catch (Throwable e) { original = original.trim();
// System.out.println("Exception translating [" + original + "]: " + e); if (buff.length() + original.length() > maxLength) {
// // e.printStackTrace(); System.out.println("remaining: " + (toTranslate.size() - separator + minSeparator));
// } translateChunk(buff, separator, sourceLanguage, targetLanguage, keyMap, results);
// } }
return "#" + translation; 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 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();
}
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);
}
}
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 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论