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

--no commit message

--no commit message
上级 a55cd699
......@@ -155,13 +155,6 @@
<echo message="Run ant codeswitchJdk... first."/>
</target>
<target name="createPatch" depends="clean">
<delete file="../h2-patch.*"/>
<tar destfile="../h2-patch.tar" basedir="." includes="src/**/*.java,build.xml"/>
<bzip2 destfile="../h2-patch.tar.bz2" src="../h2-patch.tar"/>
<delete file="../h2-patch.tar"/>
</target>
<target name="docs" depends="clean,javadoc,compile">
<copy todir="docs">
<fileset dir="src/docsrc" includes="index.html"/>
......
......@@ -833,19 +833,13 @@ public class Parser {
if (readIf("(")) {
if (isToken("SELECT") || isToken("FROM")) {
Query query = parseSelect();
String querySQL = query.getSQL();
Session s;
if (prepared != null && prepared instanceof CreateView) {
s = database.getSystemSession();
} else {
s = session;
}
String tempViewName = s.getNextTempViewName();
TableView v = new TableView(mainSchema, 0, tempViewName, querySQL, query.getParameters(), null, s,
false);
v.setOwner(session.getUser());
v.setTemporary(true);
table = v;
table = TableView.createTempView(s, session.getUser(), query);
read(")");
} else {
TableFilter top = readTableFilter(fromOuter);
......@@ -1148,9 +1142,9 @@ public class Parser {
for (int j = 0; j < joinCols.length; j++) {
String joinColumnName = joinCols[j].getName();
if (tableColumnName.equals(joinColumnName)) {
Expression tableExpr = new ExpressionColumn(database, currentSelect, tableSchema, last
Expression tableExpr = new ExpressionColumn(database, tableSchema, last
.getTableAlias(), tableColumnName);
Expression joinExpr = new ExpressionColumn(database, currentSelect, joinSchema, join
Expression joinExpr = new ExpressionColumn(database, joinSchema, join
.getTableAlias(), joinColumnName);
Expression equal = new Comparison(session, Comparison.EQUAL, tableExpr, joinExpr);
if (on == null) {
......@@ -1955,11 +1949,11 @@ public class Parser {
return expr;
}
name = readColumnIdentifier();
return new ExpressionColumn(database, currentSelect, schemaName, objectName, name);
return new ExpressionColumn(database, schemaName, objectName, name);
}
return new ExpressionColumn(database, currentSelect, schemaName, objectName, name);
return new ExpressionColumn(database, schemaName, objectName, name);
}
return new ExpressionColumn(database, currentSelect, null, objectName, name);
return new ExpressionColumn(database, null, objectName, name);
}
private Expression readTerm() throws SQLException {
......@@ -2014,7 +2008,7 @@ public class Parser {
} else if (readIf(".")) {
r = readTermObjectDot(name);
} else {
r = new ExpressionColumn(database, currentSelect, null, null, name);
r = new ExpressionColumn(database, null, null, name);
}
} else {
read();
......@@ -2046,7 +2040,7 @@ public class Parser {
} else if (readIf("DATE")) {
r = readFunctionWithoutParameters("CURRENT_DATE");
} else {
r = new ExpressionColumn(database, currentSelect, null, null, name);
r = new ExpressionColumn(database, null, null, name);
}
} else if ("NEXT".equals(name) && readIf("VALUE")) {
read("FOR");
......@@ -2070,7 +2064,7 @@ public class Parser {
read();
r = ValueExpression.get(ValueString.get(text));
} else {
r = new ExpressionColumn(database, currentSelect, null, null, name);
r = new ExpressionColumn(database, null, null, name);
}
}
break;
......
......@@ -46,7 +46,7 @@ public class Call extends Prepared {
for (int i = 0; i < list.length; i++) {
Value e = list[i];
Column col = new Column("C" + (i + 1), e.getType(), e.getPrecision(), e.getScale(), e.getDisplaySize());
expr.add(new ExpressionColumn(session.getDatabase(), null, col));
expr.add(new ExpressionColumn(session.getDatabase(), col));
}
LocalResult result = new LocalResult(session, expr, list.length);
result.addRow(list);
......
......@@ -43,7 +43,7 @@ public class ExplainPlan extends Prepared {
// TODO rights: are rights required for explain?
ObjectArray expressions = new ObjectArray();
Column column = new Column("PLAN", Value.STRING);
ExpressionColumn expr = new ExpressionColumn(session.getDatabase(), null, column);
ExpressionColumn expr = new ExpressionColumn(session.getDatabase(), column);
expressions.add(expr);
result = new LocalResult(session, expressions, 1);
if (maxrows >= 0) {
......
......@@ -248,6 +248,7 @@ public abstract class Query extends Prepared {
public abstract void setEvaluatable(TableFilter tableFilter, boolean b);
public abstract void addGlobalCondition(Expression expr, int columnId, int comparisonType) throws SQLException;
public abstract void setDistinct(boolean b);
public abstract String getFirstColumnAlias(Session session);
public void setSampleSize(int sampleSize) {
this.sampleSize = sampleSize;
......
......@@ -108,7 +108,7 @@ public class ScriptCommand extends ScriptBase {
private LocalResult createResult() {
ObjectArray cols = new ObjectArray();
cols.add(new ExpressionColumn(session.getDatabase(), null, new Column("SCRIPT", Value.STRING)));
cols.add(new ExpressionColumn(session.getDatabase(), new Column("SCRIPT", Value.STRING)));
return new LocalResult(session, cols, 1);
}
......
......@@ -10,6 +10,7 @@ import java.util.HashSet;
import org.h2.constant.ErrorCode;
import org.h2.constant.SysProperties;
import org.h2.engine.Session;
import org.h2.expression.Alias;
import org.h2.expression.Comparison;
import org.h2.expression.ConditionAndOr;
import org.h2.expression.Expression;
......@@ -270,8 +271,9 @@ public class Select extends Query {
return null;
}
private void queryFlat(int columnCount, LocalResult result, int limitRows) throws SQLException {
private void queryFlat(int columnCount, LocalResult result, long limitRows) throws SQLException {
if (limitRows != 0 && offset != null) {
// limitRows must be long, otherwise we get an int overflow if limitRows is at or near Integer.MAX_VALUE
limitRows += offset.getValue(session).getInt();
}
int rowNumber = 0;
......@@ -386,7 +388,7 @@ public class Select extends Query {
Column[] columns = t.getColumns();
for (int j = 0; j < columns.length; j++) {
Column c = columns[j];
ExpressionColumn ec = new ExpressionColumn(session.getDatabase(), this, null, alias, c.getName());
ExpressionColumn ec = new ExpressionColumn(session.getDatabase(), null, alias, c.getName());
expressions.add(i++, ec);
}
i--;
......@@ -425,8 +427,8 @@ public class Select extends Query {
havingIndex = -1;
}
// first visible columns, then order by, then having, and then group by
// at the end
// first visible columns, then order by, then having,
// and group by at the end
if (group != null) {
groupIndex = new int[group.size()];
for (int i = 0; i < group.size(); i++) {
......@@ -486,6 +488,9 @@ public class Select extends Query {
}
if (condition != null) {
condition = condition.optimize(session);
if (SysProperties.OPTIMIZE_IN_JOIN) {
condition = condition.optimizeInJoin(session, this);
}
for (int j = 0; j < filters.size(); j++) {
TableFilter f = (TableFilter) filters.get(j);
condition.createIndexConditions(session, f);
......@@ -777,4 +782,20 @@ public class Select extends Query {
return isEverything(ExpressionVisitor.READONLY);
}
public String getFirstColumnAlias(Session session) {
if (SysProperties.CHECK) {
if (visibleColumnCount > 1) {
throw Message.getInternalError("" + visibleColumnCount);
}
}
Expression expr = (Expression) expressions.get(0);
if (expr instanceof Alias) {
return expr.getAlias();
} else {
expr = new Alias(expr, session.getNextTempViewName() + "_X");
expressions.set(0, expr);
}
return expr.getAlias();
}
}
......@@ -207,7 +207,7 @@ public class SelectUnion extends Query {
int scale = Math.max(l.getScale(), r.getScale());
int displaySize = Math.max(l.getDisplaySize(), r.getDisplaySize());
Column col = new Column(l.getAlias(), type, prec, scale, displaySize);
Expression e = new ExpressionColumn(session.getDatabase(), null, col);
Expression e = new ExpressionColumn(session.getDatabase(), col);
expressions.add(e);
}
if (orderList != null) {
......@@ -332,4 +332,8 @@ public class SelectUnion extends Query {
right.updateAggregate(session);
}
public String getFirstColumnAlias(Session session) {
return null;
}
}
......@@ -27,6 +27,10 @@ public class SysProperties {
public static final boolean OPTIMIZE_EVALUATABLE_SUBQUERIES = getBooleanSetting("h2.optimizeEvaluatableSubqueries", true);
public static final boolean OPTIMIZE_IN = getBooleanSetting("h2.optimizeIn", true);
private int testing;
public static final boolean OPTIMIZE_IN_JOIN = getBooleanSetting("h2.optimizeInJoin", true);
public static final boolean OPTIMIZE_MIN_MAX = getBooleanSetting("h2.optimizeMinMax", true);
public static final boolean OPTIMIZE_SUBQUERY_CACHE = getBooleanSetting("h2.optimizeSubqueryCache", true);
public static final boolean OPTIMIZE_NOT = getBooleanSetting("h2.optimizeNot", true);
......
......@@ -6,6 +6,7 @@ package org.h2.expression;
import java.sql.SQLException;
import org.h2.command.dml.Select;
import org.h2.constant.SysProperties;
import org.h2.engine.Session;
import org.h2.message.Message;
......@@ -20,9 +21,6 @@ import org.h2.value.ValueNull;
*/
public class ConditionAndOr extends Condition {
// TODO optimization: we could extend (ID=1 AND ID=B) to (ID=1 AND ID=B AND
// B=1)
public static final int AND = 0, OR = 1;
private final int andOrType;
......@@ -222,4 +220,19 @@ public class ConditionAndOr extends Condition {
return left.getCost() + right.getCost();
}
public Expression optimizeInJoin(Session session, Select select) throws SQLException {
if (andOrType == AND) {
Expression l = left.optimizeInJoin(session, select);
Expression r = right.optimizeInJoin(session, select);
if (l != left || r != right) {
left = l;
right = r;
// only optimize again if there was some change
// otherwise some expressions are 'over-optimized'
return optimize(session);
}
}
return this;
}
}
......@@ -6,12 +6,16 @@ package org.h2.expression;
import java.sql.SQLException;
import org.h2.command.dml.Select;
import org.h2.constant.SysProperties;
import org.h2.engine.Constants;
import org.h2.engine.Database;
import org.h2.engine.Session;
import org.h2.index.IndexCondition;
import org.h2.schema.Schema;
import org.h2.table.Column;
import org.h2.table.ColumnResolver;
import org.h2.table.FunctionTable;
import org.h2.table.TableFilter;
import org.h2.util.ObjectArray;
import org.h2.value.CompareMode;
......@@ -200,4 +204,36 @@ public class ConditionIn extends Condition {
return cost;
}
public Expression optimizeInJoin(Session session, Select select) throws SQLException {
if (!areAllValues(ExpressionVisitor.get(ExpressionVisitor.EVALUATABLE))) {
return this;
}
Database db = session.getDatabase();
Schema mainSchema = db.getSchema(Constants.SCHEMA_MAIN);
Function function = Function.getFunction(database, "TABLE_DISTINCT");
Expression[] array = new Expression[values.size()];
for (int i = 0; i < values.size(); i++) {
Expression e = (Expression) values.get(i);
array[i] = e;
}
ExpressionList list = new ExpressionList(array);
function.setParameter(0, list);
function.doneWithParameters();
ObjectArray columns = new ObjectArray();
int dataType = left.getType();
String columnName = session.getNextTempViewName() + "_X";
Column col = new Column(columnName, dataType);
columns.add(col);
function.setColumns(columns);
FunctionTable table = new FunctionTable(mainSchema, session, function);
String viewName = session.getNextTempViewName();
TableFilter filter = new TableFilter(session, table, viewName, false, select);
select.addTableFilter(filter, true);
ExpressionColumn column = new ExpressionColumn(db, null, viewName, columnName);
Comparison on = new Comparison(session, Comparison.EQUAL, left, column);
on.mapColumns(filter, 0);
filter.addFilterCondition(on, true);
return ValueExpression.get(ValueBoolean.get(true));
}
}
......@@ -7,6 +7,7 @@ package org.h2.expression;
import java.sql.SQLException;
import org.h2.command.dml.Query;
import org.h2.command.dml.Select;
import org.h2.constant.ErrorCode;
import org.h2.engine.Database;
import org.h2.engine.Session;
......@@ -14,6 +15,7 @@ import org.h2.message.Message;
import org.h2.result.LocalResult;
import org.h2.table.ColumnResolver;
import org.h2.table.TableFilter;
import org.h2.table.TableView;
import org.h2.value.Value;
import org.h2.value.ValueBoolean;
import org.h2.value.ValueNull;
......@@ -122,4 +124,26 @@ public class ConditionInSelect extends Condition {
return left.getCost() + 10 + (int) (10 * query.getCost());
}
public Expression optimizeInJoin(Session session, Select select) throws SQLException {
if (all || compareType != Comparison.EQUAL) {
return this;
}
if (!query.isEverything(ExpressionVisitor.EVALUATABLE)) {
return this;
}
String alias = query.getFirstColumnAlias(session);
query.setDistinct(true);
if (alias == null) {
return this;
}
TableView view = TableView.createTempView(session, session.getUser(), query);
TableFilter filter = new TableFilter(session, view, view.getName(), false, select);
select.addTableFilter(filter, true);
ExpressionColumn column = new ExpressionColumn(session.getDatabase(), null, view.getName(), alias);
Comparison on = new Comparison(session, Comparison.EQUAL, left, column);
on.mapColumns(filter, 0);
filter.addFilterCondition(on, true);
return ValueExpression.get(ValueBoolean.get(true));
}
}
......@@ -6,6 +6,7 @@ package org.h2.expression;
import java.sql.SQLException;
import org.h2.command.dml.Select;
import org.h2.engine.Session;
import org.h2.table.Column;
import org.h2.table.ColumnResolver;
......@@ -103,4 +104,12 @@ public abstract class Expression {
addedToFilter = true;
}
}
public String toString() {
return getSQL();
}
public Expression optimizeInJoin(Session session, Select select) throws SQLException {
return this;
}
}
......@@ -32,12 +32,12 @@ public class ExpressionColumn extends Expression {
private Column column;
private boolean evaluatable;
public ExpressionColumn(Database database, Select select, Column column) {
public ExpressionColumn(Database database, Column column) {
this.database = database;
this.column = column;
}
public ExpressionColumn(Database database, Select select, String schemaName, String tableAlias, String columnName) {
public ExpressionColumn(Database database, String schemaName, String tableAlias, String columnName) {
this.database = database;
this.schemaName = schemaName;
this.tableAlias = tableAlias;
......
......@@ -21,6 +21,7 @@ import org.h2.engine.Database;
import org.h2.engine.Mode;
import org.h2.engine.Session;
import org.h2.message.Message;
import org.h2.result.LocalResult;
import org.h2.schema.Sequence;
import org.h2.security.BlockCipher;
import org.h2.security.CipherFactory;
......@@ -31,14 +32,12 @@ import org.h2.table.LinkSchema;
import org.h2.table.TableFilter;
import org.h2.tools.CompressTool;
import org.h2.tools.Csv;
import org.h2.tools.SimpleResultSet;
import org.h2.util.ObjectUtils;
import org.h2.util.MathUtils;
import org.h2.util.MemoryUtils;
import org.h2.util.ObjectArray;
import org.h2.util.ObjectUtils;
import org.h2.util.RandomUtils;
import org.h2.util.StringUtils;
import org.h2.value.DataType;
import org.h2.value.Value;
import org.h2.value.ValueArray;
import org.h2.value.ValueBoolean;
......@@ -85,7 +84,7 @@ public class Function extends Expression implements FunctionCall {
public static final int IFNULL = 200, CASEWHEN = 201, CONVERT = 202, CAST = 203, COALESCE = 204, NULLIF = 205,
CASE = 206, NEXTVAL = 207, CURRVAL = 208, ARRAY_GET = 209, CSVREAD = 210, CSVWRITE = 211,
MEMORY_FREE = 212, MEMORY_USED = 213, LOCK_MODE = 214, SCHEMA = 215, SESSION_ID = 216, ARRAY_LENGTH = 217,
LINK_SCHEMA = 218, TABLE = 219, LEAST = 220, GREATEST = 221;
LINK_SCHEMA = 218, TABLE = 219, LEAST = 220, GREATEST = 221, TABLE_DISTINCT = 222;
private static final int VAR_ARGS = -1;
......@@ -286,6 +285,7 @@ public class Function extends Expression implements FunctionCall {
addFunction("ARRAY_LENGTH", ARRAY_LENGTH, 1, Value.INT);
addFunction("LINK_SCHEMA", LINK_SCHEMA, 6, Value.RESULT_SET);
addFunctionWithNull("TABLE", TABLE, VAR_ARGS, Value.RESULT_SET);
addFunctionWithNull("TABLE_DISTINCT", TABLE_DISTINCT, VAR_ARGS, Value.RESULT_SET);
addFunctionWithNull("LEAST", LEAST, VAR_ARGS, Value.NULL);
addFunctionWithNull("GREATEST", GREATEST, VAR_ARGS, Value.NULL);
}
......@@ -817,7 +817,9 @@ public class Function extends Expression implements FunctionCall {
return ValueResultSet.get(rs);
}
case TABLE:
return getTable(session, args, false);
return getTable(session, args, false, false);
case TABLE_DISTINCT:
return getTable(session, args, false, true);
case CSVWRITE: {
session.getUser().checkAdmin();
Connection conn = session.createConnection(false);
......@@ -1266,6 +1268,7 @@ public class Function extends Expression implements FunctionCall {
case COALESCE:
case CSVREAD:
case TABLE:
case TABLE_DISTINCT:
case LEAST:
case GREATEST:
min = 1;
......@@ -1529,6 +1532,7 @@ public class Function extends Expression implements FunctionCall {
buff.append(args[1].getSQL());
break;
}
case TABLE_DISTINCT:
case TABLE: {
for (int i = 0; i < args.length; i++) {
if (i > 0) {
......@@ -1597,7 +1601,10 @@ public class Function extends Expression implements FunctionCall {
return vr;
}
case TABLE: {
return getTable(session, args, true);
return getTable(session, args, true, false);
}
case TABLE_DISTINCT: {
return getTable(session, args, true, true);
}
default:
break;
......@@ -1648,19 +1655,21 @@ public class Function extends Expression implements FunctionCall {
return cost;
}
public ValueResultSet getTable(Session session, Expression[] args, boolean onlyColumnList) throws SQLException {
SimpleResultSet rs = new SimpleResultSet();
public ValueResultSet getTable(Session session, Expression[] args, boolean onlyColumnList, boolean distinct) throws SQLException {
int len = columnList.length;
Expression[] header = new Expression[len];
Database db = session.getDatabase();
for (int i = 0; i < len; i++) {
Column c = columnList[i];
String columnName = c.getName();
int dataType = DataType.convertTypeToSQLType(c.getType());
int precision = MathUtils.convertLongToInt(c.getPrecision());
int scale = c.getScale();
rs.addColumn(columnName, dataType, precision, scale);
ExpressionColumn col = new ExpressionColumn(db, c);
header[i] = col;
}
LocalResult result = new LocalResult(session, header, len);
if (distinct) {
result.setDistinct();
}
if (!onlyColumnList) {
Value[][] list = new Value[args.length][];
Value[][] list = new Value[len][];
int rowCount = 0;
for (int i = 0; i < len; i++) {
Value v = args[i].getValue(session);
......@@ -1674,7 +1683,7 @@ public class Function extends Expression implements FunctionCall {
}
}
for (int row = 0; row < rowCount; row++) {
Object[] r = new Object[len];
Value[] r = new Value[len];
for (int j = 0; j < len; j++) {
Value[] l = list[j];
Value v;
......@@ -1687,12 +1696,13 @@ public class Function extends Expression implements FunctionCall {
v = v.convertPrecision(c.getPrecision());
v = v.convertScale(true, c.getScale());
}
r[j] = v.getObject();
r[j] = v;
}
rs.addRow(r);
result.addRow(r);
}
}
ValueResultSet vr = ValueResultSet.get(rs);
result.done();
ValueResultSet vr = ValueResultSet.getCopy(result, Integer.MAX_VALUE);
return vr;
}
......
......@@ -2724,9 +2724,9 @@ CALL SESSION_ID()
"
"Functions (System)","TABLE","
TABLE( { name dataType = expression } [,..]): result set
TABLE|TABLE_DISTINCT( { name dataType = expression } [,..]): result set
","
Returns the result set.
Returns the result set. TABLE_DISTINCT removes duplicate rows.
","
SELECT * FROM TABLE(ID INT=(1, 2), NAME VARCHAR=('Hello', 'World'))
"
......
......@@ -55,7 +55,7 @@ public class LocalResult implements ResultInterface {
int scale = meta.getScale(i + 1);
int displaySize = meta.getColumnDisplaySize(i + 1);
Column col = new Column(name, type, precision, scale, displaySize);
Expression expr = new ExpressionColumn(db, null, col);
Expression expr = new ExpressionColumn(db, col);
cols.add(expr);
}
LocalResult result = new LocalResult(session, cols, columnCount);
......@@ -108,7 +108,17 @@ public class LocalResult implements ResultInterface {
return updateCount;
}
public LocalResult(Session session, ObjectArray cols, int visibleColumnCount) {
public LocalResult(Session session, ObjectArray expressionList, int visibleColumnCount) {
this(session, getList(expressionList), visibleColumnCount);
}
private static Expression[] getList(ObjectArray expressionList) {
Expression[] expressions = new Expression[expressionList.size()];
expressionList.toArray(expressions);
return expressions;
}
public LocalResult(Session session, Expression[] expressions, int visibleColumnCount) {
this.session = session;
if (session == null) {
this.maxMemoryRows = Integer.MAX_VALUE;
......@@ -118,9 +128,8 @@ public class LocalResult implements ResultInterface {
rows = new ObjectArray();
this.visibleColumnCount = visibleColumnCount;
rowId = -1;
this.expressions = new Expression[cols.size()];
cols.toArray(expressions);
this.displaySizes = new int[cols.size()];
this.expressions = expressions;
this.displaySizes = new int[expressions.length];
}
public void setSortOrder(SortOrder sort) {
......@@ -128,9 +137,8 @@ public class LocalResult implements ResultInterface {
}
public void setDistinct() {
// TODO big result sets: how to buffer distinct result sets? maybe do
// the
// distinct when sorting each block, and final merging
// TODO big result sets: how to buffer distinct result sets?
// maybe remove duplicates when sorting each block, and when merging
distinctRows = new ValueHashMap(session.getDatabase());
}
......
......@@ -55,6 +55,7 @@ public class WebServer implements Service {
{ "pt_BR", "Portugu\u00eas (Brasil)"},
{ "pt_PT", "Portugu\u00eas (Europeu)"},
{ "ru", "\u0440\u0443\u0441\u0441\u043a\u0438\u0439"},
{ "uk", "\u0423\u043A\u0440\u0430\u0457\u043D\u0441\u044C\u043A\u0430"},
{ "zh_CN", "\u4E2D\u6587"},
};
......@@ -76,6 +77,8 @@ public class WebServer implements Service {
};
/*
String[] list = Locale.getISOLanguages();
for(int i=0; i<list.length; i++) System.out.print(list[i] + " ");
String lang = new java.util.Locale("hu").getDisplayLanguage(new java.util.Locale("hu"));
java.util.Locale.CHINESE.getDisplayLanguage(
java.util.Locale.CHINESE);
......
......@@ -392,7 +392,7 @@ public class TableFilter implements ColumnResolver {
}
}
buff.append(table.getSQL());
if (alias != null && !table.getName().equals(alias)) {
if (alias != null) {
buff.append(' ');
buff.append(Parser.quoteIdentifier(alias));
}
......@@ -422,7 +422,7 @@ public class TableFilter implements ColumnResolver {
String condition = StringUtils.unEnclose(filterCondition.getSQL());
condition = StringUtils.quoteRemarkSQL(condition);
buff.append(condition);
buff.append("*/");
buff.append(" */");
}
return buff.toString();
}
......
......@@ -307,4 +307,15 @@ public class TableView extends Table {
return owner;
}
public static TableView createTempView(Session s, User owner, Query query) throws SQLException {
String tempViewName = s.getNextTempViewName();
Schema mainSchema = s.getDatabase().getSchema(Constants.SCHEMA_MAIN);
String querySQL = query.getPlanSQL();
TableView v = new TableView(mainSchema, 0, tempViewName, querySQL, query.getParameters(), null, s,
false);
v.setOwner(owner);
v.setTemporary(true);
return v;
}
}
......@@ -558,6 +558,8 @@ public class DataType {
return Value.CLOB;
case Types.NULL:
return Value.NULL;
case Types.ARRAY:
return Value.ARRAY;
default:
throw Message.getSQLException(ErrorCode.UNKNOWN_DATA_TYPE_1, ""+sqlType);
}
......
......@@ -10,7 +10,9 @@ import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import org.h2.message.Message;
import org.h2.result.LocalResult;
import org.h2.tools.SimpleResultSet;
import org.h2.util.MathUtils;
public class ValueResultSet extends Value {
......@@ -25,6 +27,28 @@ public class ValueResultSet extends Value {
return val;
}
public static ValueResultSet getCopy(LocalResult rs, int maxrows) throws SQLException {
int columnCount = rs.getVisibleColumnCount();
SimpleResultSet simple = new SimpleResultSet();
ValueResultSet val = new ValueResultSet(simple);
for (int i = 0; i < columnCount; i++) {
String name = rs.getColumnName(i);
int sqlType = DataType.convertTypeToSQLType(rs.getColumnType(i));
int precision = MathUtils.convertLongToInt(rs.getColumnPrecision(i));
int scale = rs.getColumnScale(i);
simple.addColumn(name, sqlType, precision, scale);
}
rs.reset();
for (int i = 0; i < maxrows && rs.next(); i++) {
Object[] list = new Object[columnCount];
for (int j = 0; j < columnCount; j++) {
list[j] = rs.currentRow()[j].getObject();
}
simple.addRow(list);
}
return val;
}
public static ValueResultSet getCopy(ResultSet rs, int maxrows) throws SQLException {
ResultSetMetaData meta = rs.getMetaData();
int columnCount = meta.getColumnCount();
......
......@@ -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
Changelog:
Certain setting in the Server didn't work (see bug...)
avoid creating thousands of trace.db files
......@@ -161,21 +185,10 @@ Known Problems:
link to history page, bug page
Add a link to the google code bug page
History:
implement & test: checkpoint commits running transactions
test DbStarter
create table test(id int, name varchar);
insert into test select x, '' from system_range(1, 10000);
-- fast
update test set name = 'y' where cast(id as varchar) like '1%';
-- slow
update test set name = 'x' where id in (select x from system_range(1, 10000) where cast(x as varchar) like '1%');
drop table test;
----
A file is sent although the Japanese translation has not been completed yet.
----
......
......@@ -28,6 +28,8 @@ import org.h2.util.Resources;
public class TestTools extends TestBase {
private Server server;
public void test() throws Exception {
deleteDb("utils");
testServerMain();
......@@ -65,22 +67,43 @@ public class TestTools extends TestBase {
result = runServer(new String[]{"-tcpShutdown", "tcp://localhost:9001", "-tcpPassword", "abc", "-tcpShutdownForce", "true"}, 0);
check(result.indexOf("Shutting down") >= 0);
result = runServer(new String[]{"-tcp", "-tcpAllowOthers", "true", "-tcpPort", "9001", "-tcpPassword", "def", "-tcpSSL", "true"}, 0);
result = runServer(new String[]{"-tcp", "-tcpAllowOthers", "true", "-tcpPort", "9001", "-tcpPassword", "abcdef", "-tcpSSL", "true"}, 0);
check(result.indexOf("ssl://") >= 0);
check(result.indexOf(":9001") >= 0);
check(result.indexOf("others can") >= 0);
check(result.indexOf("[options]") < 0);
conn = DriverManager.getConnection("jdbc:h2:ssl://localhost:9001/mem:", "sa", "sa");
conn.close();
result = runServer(new String[]{"-tcpShutdown", "ssl://localhost:9001", "-tcpPassword", "def", "-tcpShutdownForce", "false"}, 0);
result = runServer(new String[]{"-tcpShutdown", "ssl://localhost:9001", "-tcpPassword", "abcdef", "-tcpShutdownForce", "false"}, 0);
check(result.indexOf("Shutting down") >= 0);
result = runServer(new String[]{
"-web", "-webPort", "9002", "-webAllowOthers", "true", "-webSSL", "true",
"-pg", "-pgAllowOthers", "true", "-pgPort", "9003",
"-ftp", "-ftpPort", "9004", "-ftpDir", ".", "-ftpRead", "guest", "-ftpWrite", "sa", "-ftpWritePassword", "sa", "-ftpTask", "true",
"-tcp", "-tcpAllowOthers", "true", "-tcpPort", "9005", "-tcpPassword", "abc"}, 0);
Server stop = server;
check(result.indexOf("https://") >= 0);
check(result.indexOf(":9002") >= 0);
check(result.indexOf("pg://") >= 0);
check(result.indexOf(":9003") >= 0);
check(result.indexOf("others can") >= 0);
check(result.indexOf("only local") < 0);
check(result.indexOf("ftp://") >= 0);
check(result.indexOf(":9004") >= 0);
check(result.indexOf("tcp://") >= 0);
check(result.indexOf(":9005") >= 0);
result = runServer(new String[]{"-tcpShutdown", "tcp://localhost:9005", "-tcpPassword", "abc", "-tcpShutdownForce", "true"}, 0);
check(result.indexOf("Shutting down") >= 0);
stop.shutdown();
}
private String runServer(String[] args, int exitCode) throws Exception {
ByteArrayOutputStream buff = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(buff);
int gotCode = new Server().run(args, ps);
server = new Server();
int gotCode = server.run(args, ps);
check(exitCode, gotCode);
ps.flush();
String s = new String(buff.toByteArray());
......@@ -257,6 +280,7 @@ public class TestTools extends TestBase {
private void testServer() throws Exception {
Connection conn;
deleteDb("test");
Server server = Server.createTcpServer(new String[] { "-ifExists", "false", "-baseDir", baseDir }).start();
conn = DriverManager.getConnection("jdbc:h2:tcp://localhost/test", "sa", "");
conn.close();
......
/*
* Copyright 2004-2007 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.tools.i18n;
public class AutoTranslate {
}
......@@ -13,10 +13,19 @@ import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.Stack;
import java.util.Map.Entry;
import org.h2.server.web.PageParser;
import org.h2.tools.doc.XMLParser;
import org.h2.util.FileUtils;
......@@ -24,13 +33,10 @@ import org.h2.util.IOUtils;
import org.h2.util.SortedProperties;
import org.h2.util.StringUtils;
//import com.google.api.translate.Language;
//import com.google.api.translate.Translate;
public class PrepareTranslation {
private static final String MAIN_LANGUAGE = "en";
private static final String DELETED_PREFIX = "~";
private static final boolean AUTO_TRANSLATE = false;
private static final boolean AUTO_TRANSLATE = true;
public static void main(String[] args) throws Exception {
new PrepareTranslation().run(args);
......@@ -55,7 +61,7 @@ public class PrepareTranslation {
// create the translated documentation
buildHtml("src/docsrc/text", "docs/html", "en");
// buildHtml("src/docsrc/text", "docs/html", "de");
buildHtml("src/docsrc/text", "docs/html", "de");
buildHtml("src/docsrc/text", "docs/html", "ja");
// convert the properties files back to utf8 text files, including the
......@@ -414,6 +420,7 @@ public class PrepareTranslation {
oldTranslations.setProperty(m, t);
}
}
HashSet toTranslate = new HashSet();
// add missing keys, using # and the value from the main file
Iterator it = main.keySet().iterator();
while (it.hasNext()) {
......@@ -422,11 +429,10 @@ public class PrepareTranslation {
if (!p.containsKey(key)) {
String t = oldTranslations.getProperty(now);
if (t == null) {
System.out.println(trans.getName() + ": key " + key
+ " not found in translation file; added dummy # 'translation'");
t = "#" + autoTranslate(now, language);
}
toTranslate.add(key);
} else {
p.put(key, t);
}
} else {
String t = p.getProperty(key);
String last = base.getProperty(key);
......@@ -440,19 +446,42 @@ public class PrepareTranslation {
} else if (last != null && !last.equals(now)) {
t = oldTranslations.getProperty(now);
if (t == null) {
// main data changed since the last run: review
// translation
// main data changed since the last run: review translation
System.out.println(trans.getName() + ": key " + key + " changed, please review; last=" + last
+ " now=" + now);
String old = p.getProperty(key);
t = "#" + autoTranslate(now, language) + " #" + old;
}
// String old = p.getProperty(key);
toTranslate.add(key);
} else {
p.put(key, t);
}
}
}
// remove keys that don't exist in the main file (deleted or typo in the
// key)
}
Map autoTranslated = new HashMap();
if (AUTO_TRANSLATE) {
HashSet set = new HashSet();
for (it = toTranslate.iterator(); it.hasNext();) {
String key = (String) it.next();
String now = main.getProperty(key);
set.add(now);
}
if ("de".equals(language)) {
autoTranslated = autoTranslate(set, "en", language);
}
}
for (it = toTranslate.iterator(); it.hasNext();) {
String key = (String) it.next();
String now = main.getProperty(key);
String t;
if (AUTO_TRANSLATE) {
t = "#" + autoTranslated.get(now);
} else {
System.out.println(trans.getName() + ": key " + key + " not found in translation file; added dummy # 'translation'");
t = "#" + now;
}
p.put(key, t);
}
// remove keys that don't exist in the main file (deleted or typo in the key)
it = new ArrayList(p.keySet()).iterator();
while (it.hasNext()) {
String key = (String) it.next();
......@@ -472,25 +501,86 @@ public class PrepareTranslation {
PropertiesToUTF8.storeProperties(p, trans.getAbsolutePath());
}
private String autoTranslate(String original, String language) {
if (original == null || original.trim().length() == 0) {
return original;
}
String translation = original;
if (!AUTO_TRANSLATE) {
return "#" + translation;
}
// if ("de".equals(language)) {
// try {
// Thread.sleep(5000);
// translation = Translate.translate(original, Language.ENGLISH, Language.GERMAN);
// System.out.println("original: " + original);
// System.out.println("translation: " + translation);
// } catch (Throwable e) {
// System.out.println("Exception translating [" + original + "]: " + e);
// // e.printStackTrace();
// }
// }
return "#" + translation;
private Map autoTranslate(Set toTranslate, String sourceLanguage, String targetLanguage) {
HashMap results = new HashMap();
if (toTranslate.size() == 0) {
return results;
}
int maxLength = 1500;
int minSeparator = 100000;
HashMap keyMap = new HashMap(toTranslate.size());
StringBuffer buff = new StringBuffer(maxLength);
// TODO make sure these numbers don't occur in the original text
int separator = minSeparator;
for (Iterator it = toTranslate.iterator(); it.hasNext();) {
String original = (String) it.next();
if (original != null) {
original = original.trim();
if (buff.length() + original.length() > maxLength) {
System.out.println("remaining: " + (toTranslate.size() - separator + minSeparator));
translateChunk(buff, separator, sourceLanguage, targetLanguage, keyMap, results);
}
keyMap.put(new Integer(separator), original);
buff.append(separator);
buff.append(' ');
buff.append(original);
buff.append(' ');
separator++;
}
}
translateChunk(buff, separator, sourceLanguage, targetLanguage, keyMap, results);
return results;
}
private 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 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论