Unverified 提交 9c29e2d9 authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov 提交者: GitHub

Merge pull request #1574 from katzyn/misc

Fix ROWNUM() in non-select commands and assorted minor changes in Condition implementations
......@@ -21,6 +21,10 @@ Change Log
<h2>Next Version (unreleased)</h2>
<ul>
<li>Issue #1573: DELETE FROM w/ ROWNUM and subquery
</li>
<li>PR #1571: Optimizing ConditionAndOr queries
</li>
<li>Issue #1565: SOME / ANY conflict
</li>
<li>PR #1564: Refactor Expression implementations
......
......@@ -2620,6 +2620,7 @@ public class Parser {
Select command = new Select(session);
int start = lastParseIndex;
Select oldSelect = currentSelect;
Prepared oldPrepared = currentPrepared;
currentSelect = command;
currentPrepared = command;
if (fromFirst) {
......@@ -2676,6 +2677,7 @@ public class Parser {
}
command.setParameterList(parameters);
currentSelect = oldSelect;
currentPrepared = oldPrepared;
setSQL(command, "SELECT", start);
return command;
}
......
......@@ -111,7 +111,7 @@ public class Alias extends Expression {
@Override
public String getTableName() {
if (aliasColumnName) {
return super.getTableName();
return null;
}
return expr.getTableName();
}
......@@ -119,7 +119,7 @@ public class Alias extends Expression {
@Override
public String getColumnName() {
if (!(expr instanceof ExpressionColumn) || aliasColumnName) {
return super.getColumnName();
return alias;
}
return expr.getColumnName();
}
......
......@@ -6,7 +6,6 @@
package org.h2.expression.condition;
import java.util.ArrayList;
import java.util.Arrays;
import org.h2.api.ErrorCode;
import org.h2.engine.Database;
import org.h2.engine.Session;
......@@ -575,25 +574,27 @@ public class Comparison extends Condition {
}
} else {
// a=b OR a=c
Database db = session.getDatabase();
if (rc && r2c && l.equals(l2)) {
return new ConditionIn(db, left,
new ArrayList<>(Arrays.asList(right, other.right)));
return getConditionIn(session, left, right, other.right);
} else if (rc && l2c && l.equals(r2)) {
return new ConditionIn(db, left,
new ArrayList<>(Arrays.asList(right, other.left)));
return getConditionIn(session, left, right, other.left);
} else if (lc && r2c && r.equals(l2)) {
return new ConditionIn(db, right,
new ArrayList<>(Arrays.asList(left, other.right)));
return getConditionIn(session, right, left, other.right);
} else if (lc && l2c && r.equals(r2)) {
return new ConditionIn(db, right,
new ArrayList<>(Arrays.asList(left, other.left)));
return getConditionIn(session, right, left, other.left);
}
}
}
return null;
}
private static ConditionIn getConditionIn(Session session, Expression left, Expression value1, Expression value2) {
ArrayList<Expression> right = new ArrayList<>(2);
right.add(value1);
right.add(value2);
return new ConditionIn(session.getDatabase(), left, right);
}
@Override
public int getSubexpressionCount() {
return compareType == IS_NULL || compareType == IS_NOT_NULL ? 1 : 2;
......
......@@ -319,25 +319,30 @@ public class ConditionAndOr extends Condition {
* @param right the second condition
* @return null or the third condition
*/
private Expression optimizeConditionAndOr(ConditionAndOr left, ConditionAndOr right) {
private static Expression optimizeConditionAndOr(ConditionAndOr left, ConditionAndOr right) {
if (left.andOrType != AND || right.andOrType != AND) {
return null;
}
Expression commonExpressionLeft = left.getSubexpression(0);
Expression commonExpressionRight = left.getSubexpression(1);
Expression leftLeft = left.getSubexpression(0), leftRight = left.getSubexpression(1);
Expression rightLeft = right.getSubexpression(0), rightRight = right.getSubexpression(1);
String leftLeftSQL = leftLeft.getSQL(), rightLeftSQL = rightLeft.getSQL();
Expression combinedExpression;
if (left.getSubexpression(0).getSQL().equals(right.getSubexpression(0).getSQL())) {
combinedExpression = new ConditionAndOr(OR, left.getSubexpression(1), right.getSubexpression(1));
return new ConditionAndOr(AND, commonExpressionLeft, combinedExpression);
} else if (left.getSubexpression(0).getSQL().equals(right.getSubexpression(1).getSQL())) {
combinedExpression = new ConditionAndOr(OR, left.getSubexpression(1), right.getSubexpression(0));
return new ConditionAndOr(AND, commonExpressionLeft, combinedExpression);
} else if (left.getSubexpression(1).getSQL().equals(right.getSubexpression(0).getSQL())) {
combinedExpression = new ConditionAndOr(OR, left.getSubexpression(0), right.getSubexpression(1));
return new ConditionAndOr(AND, commonExpressionRight, combinedExpression);
} else if (left.getSubexpression(1).getSQL().equals(right.getSubexpression(1).getSQL())) {
combinedExpression = new ConditionAndOr(OR, left.getSubexpression(0), right.getSubexpression(0));
return new ConditionAndOr(AND, commonExpressionRight, combinedExpression);
if (leftLeftSQL.equals(rightLeftSQL)) {
combinedExpression = new ConditionAndOr(OR, leftRight, rightRight);
return new ConditionAndOr(AND, leftLeft, combinedExpression);
}
String rightRightSQL = rightRight.getSQL();
if (leftLeftSQL.equals(rightRightSQL)) {
combinedExpression = new ConditionAndOr(OR, leftRight, rightLeft);
return new ConditionAndOr(AND, leftLeft, combinedExpression);
}
String leftRightSQL = leftRight.getSQL();
if (leftRightSQL.equals(rightLeftSQL)) {
combinedExpression = new ConditionAndOr(OR, leftLeft, rightRight);
return new ConditionAndOr(AND, leftRight, combinedExpression);
} else if (leftRightSQL.equals(rightRightSQL)) {
combinedExpression = new ConditionAndOr(OR, leftLeft, rightLeft);
return new ConditionAndOr(AND, leftRight, combinedExpression);
}
return null;
}
......
......@@ -31,7 +31,6 @@ public class ConditionIn extends Condition {
private final Database database;
private Expression left;
private final ArrayList<Expression> valueList;
private int queryLevel;
/**
* Create a new IN(..) condition.
......@@ -53,8 +52,6 @@ public class ConditionIn extends Condition {
if (l == ValueNull.INSTANCE) {
return l;
}
boolean result = false;
boolean hasNull = false;
int size = valueList.size();
if (size == 1) {
Expression e = valueList.get(0);
......@@ -62,6 +59,8 @@ public class ConditionIn extends Condition {
return ConditionInParameter.getValue(database, l, e.getValue(session));
}
}
boolean result = false;
boolean hasNull = false;
for (int i = 0; i < size; i++) {
Expression e = valueList.get(i);
Value r = e.getValue(session);
......@@ -86,7 +85,6 @@ public class ConditionIn extends Condition {
for (Expression e : valueList) {
e.mapColumns(resolver, level, state);
}
this.queryLevel = Math.max(level, this.queryLevel);
}
@Override
......
......@@ -33,7 +33,6 @@ import org.h2.value.ValueNull;
public class ConditionInConstantSet extends Condition {
private Expression left;
private int queryLevel;
private final ArrayList<Expression> valueList;
private final TreeSet<Value> valueSet;
private final int type;
......@@ -87,7 +86,6 @@ public class ConditionInConstantSet extends Condition {
@Override
public void mapColumns(ColumnResolver resolver, int level, int state) {
left.mapColumns(resolver, level, state);
this.queryLevel = Math.max(level, this.queryLevel);
}
@Override
......
......@@ -33,7 +33,6 @@ public class ConditionInSelect extends Condition {
private final Query query;
private final boolean all;
private final int compareType;
private int queryLevel;
public ConditionInSelect(Database database, Expression left, Query query,
boolean all, int compareType) {
......@@ -110,7 +109,6 @@ public class ConditionInSelect extends Condition {
public void mapColumns(ColumnResolver resolver, int level, int state) {
left.mapColumns(resolver, level, state);
query.mapColumns(resolver, level + 1);
this.queryLevel = Math.max(level, this.queryLevel);
}
@Override
......
......@@ -154,7 +154,7 @@ public class TestScript extends TestDb {
"dropDomain", "dropIndex", "dropSchema", "truncateTable" }) {
testScript("ddl/" + s + ".sql");
}
for (String s : new String[] { "error_reporting", "insertIgnore", "merge", "mergeUsing", "replace",
for (String s : new String[] { "delete", "error_reporting", "insertIgnore", "merge", "mergeUsing", "replace",
"script", "select", "show", "with" }) {
testScript("dml/" + s + ".sql");
}
......
-- Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0,
-- and the EPL 1.0 (http://h2database.com/html/license.html).
-- Initial Developer: H2 Group
--
CREATE TABLE TEST(ID INT);
> ok
INSERT INTO TEST VALUES (1), (2), (3);
> update count: 3
DELETE FROM TEST WHERE EXISTS (SELECT X FROM SYSTEM_RANGE(1, 3) WHERE X = ID) AND ROWNUM() = 1;
> update count: 1
SELECT ID FROM TEST;
> ID
> --
> 2
> 3
> rows: 2
DROP TABLE TEST;
> ok
......@@ -10,7 +10,6 @@ import org.h2.test.TestBase;
import org.h2.test.TestDb;
import java.io.File;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
......
......@@ -803,3 +803,4 @@ discard enhancements nolock surefire logarithm
qualification opportunity jumping exploited unacceptable vrs duplicated
queryparser tokenized freeze factorings recompilation unenclosed rfe dsync
econd irst bcef ordinality nord unnest
analyst occupation distributive josaph aor engineer sajeewa isuru randil kevin doctor businessman artist ashan
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论