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

Merge pull request #1612 from katzyn/row

Improve javadoc, documentation, tests and some code for row values
...@@ -2542,11 +2542,13 @@ START WITH 1 ...@@ -2542,11 +2542,13 @@ START WITH 1
"Other Grammar","Set clause list"," "Other Grammar","Set clause list","
{ { columnName = { DEFAULT | expression } } [,...] } { { columnName = { DEFAULT | expression } } [,...] }
| { ( columnName [,...] ) = ( select ) } | { ( columnName [,...] ) = {rowValueExpression|(select)} }
"," ","
List of SET clauses. List of SET clauses.
"," ","
NAME = 'Test', VALUE = 2 NAME = 'Test', VALUE = 2
(A, B) = (1, 2)
(A, B) = (SELECT X, Y FROM OTHER T2 WHERE T1.ID = T2.ID)
" "
"Other Grammar","String"," "Other Grammar","String","
...@@ -5211,11 +5213,13 @@ SELECT X, SET(@I, IFNULL(@I, 0)+X) RUNNING_TOTAL FROM SYSTEM_RANGE(1, 10) ...@@ -5211,11 +5213,13 @@ SELECT X, SET(@I, IFNULL(@I, 0)+X) RUNNING_TOTAL FROM SYSTEM_RANGE(1, 10)
" "
"Functions (System)","TABLE"," "Functions (System)","TABLE","
{ TABLE | TABLE_DISTINCT } ( { name dataType = expression } [,...] ) { TABLE | TABLE_DISTINCT }
( { name dataType = array|rowValueExpression } [,...] )
"," ","
Returns the result set. TABLE_DISTINCT removes duplicate rows. Returns the result set. TABLE_DISTINCT removes duplicate rows.
"," ","
SELECT * FROM TABLE(ID INT=(1, 2), NAME VARCHAR=('Hello', 'World')) SELECT * FROM TABLE(VALUE INT = ARRAY[1, 2]);
SELECT * FROM TABLE(ID INT=(1, 2), NAME VARCHAR=('Hello', 'World'));
" "
"Functions (System)","TRANSACTION_ID"," "Functions (System)","TRANSACTION_ID","
......
...@@ -21,6 +21,8 @@ Change Log ...@@ -21,6 +21,8 @@ Change Log
<h2>Next Version (unreleased)</h2> <h2>Next Version (unreleased)</h2>
<ul> <ul>
<li>Issue #1608: ARRAY and row value expression should not be the same
</li>
<li>Issue #1606: Quantified comparison predicate doesn't work correctly on primary key column <li>Issue #1606: Quantified comparison predicate doesn't work correctly on primary key column
</li> </li>
<li>Issue #1057: Very slow execution with subquery and connection parameter LAZY_QUERY_EXECUTION=1 <li>Issue #1057: Very slow execution with subquery and connection parameter LAZY_QUERY_EXECUTION=1
......
...@@ -428,12 +428,9 @@ public class Database implements DataHandler { ...@@ -428,12 +428,9 @@ public class Database implements DataHandler {
* Compare two values with the current comparison mode. The values may have * Compare two values with the current comparison mode. The values may have
* different data types including NULL. * different data types including NULL.
* *
* @param v the other value
* @param databaseMode the database mode
* @param compareMode the compare mode
* @param a the first value * @param a the first value
* @param b the second value * @param b the second value
* @param forEquality perform only check for equality (= or <>) * @param forEquality perform only check for equality (= or &lt;&gt;)
* @return 0 if both values are equal, -1 if the first value is smaller, 1 * @return 0 if both values are equal, -1 if the first value is smaller, 1
* if the second value is larger, {@link Integer#MIN_VALUE} if order * if the second value is larger, {@link Integer#MIN_VALUE} if order
* is not defined due to NULL comparison * is not defined due to NULL comparison
......
...@@ -61,16 +61,15 @@ import org.h2.util.Utils; ...@@ -61,16 +61,15 @@ import org.h2.util.Utils;
import org.h2.value.DataType; import org.h2.value.DataType;
import org.h2.value.ExtTypeInfo; import org.h2.value.ExtTypeInfo;
import org.h2.value.Value; import org.h2.value.Value;
import org.h2.value.ValueArray;
import org.h2.value.ValueBoolean; import org.h2.value.ValueBoolean;
import org.h2.value.ValueBytes; import org.h2.value.ValueBytes;
import org.h2.value.ValueCollectionBase;
import org.h2.value.ValueDate; import org.h2.value.ValueDate;
import org.h2.value.ValueDouble; import org.h2.value.ValueDouble;
import org.h2.value.ValueInt; import org.h2.value.ValueInt;
import org.h2.value.ValueLong; import org.h2.value.ValueLong;
import org.h2.value.ValueNull; import org.h2.value.ValueNull;
import org.h2.value.ValueResultSet; import org.h2.value.ValueResultSet;
import org.h2.value.ValueRow;
import org.h2.value.ValueString; import org.h2.value.ValueString;
import org.h2.value.ValueTime; import org.h2.value.ValueTime;
import org.h2.value.ValueTimestamp; import org.h2.value.ValueTimestamp;
...@@ -1092,13 +1091,11 @@ public class Function extends Expression implements FunctionCall { ...@@ -1092,13 +1091,11 @@ public class Function extends Expression implements FunctionCall {
return result; return result;
} }
private Value[] getArray(Value v0) { private static Value[] getArray(Value v0) {
int t = v0.getType(); int t = v0.getType();
Value[] list; Value[] list;
if (t == Value.ARRAY) { if (t == Value.ARRAY || t == Value.ROW) {
list = ((ValueArray) v0).getList(); list = ((ValueCollectionBase) v0).getList();
} else if (t == Value.ROW) {
list = ((ValueRow) v0).getList();
} else { } else {
list = null; list = null;
} }
......
...@@ -16,7 +16,7 @@ import org.h2.message.DbException; ...@@ -16,7 +16,7 @@ import org.h2.message.DbException;
import org.h2.result.LocalResult; import org.h2.result.LocalResult;
import org.h2.table.Column; import org.h2.table.Column;
import org.h2.value.Value; import org.h2.value.Value;
import org.h2.value.ValueArray; import org.h2.value.ValueCollectionBase;
import org.h2.value.ValueInt; import org.h2.value.ValueInt;
import org.h2.value.ValueNull; import org.h2.value.ValueNull;
import org.h2.value.ValueResultSet; import org.h2.value.ValueResultSet;
...@@ -105,8 +105,11 @@ public class TableFunction extends Function { ...@@ -105,8 +105,11 @@ public class TableFunction extends Function {
if (v == ValueNull.INSTANCE) { if (v == ValueNull.INSTANCE) {
list[i] = new Value[0]; list[i] = new Value[0];
} else { } else {
ValueArray array = (ValueArray) v.convertTo(Value.ARRAY); int type = v.getType();
Value[] l = array.getList(); if (type != Value.ARRAY && type != Value.ROW) {
v = v.convertTo(Value.ARRAY);
}
Value[] l = ((ValueCollectionBase) v).getList();
list[i] = l; list[i] = l;
rows = Math.max(rows, l.length); rows = Math.max(rows, l.length);
} }
......
...@@ -61,10 +61,6 @@ public class ValueArray extends ValueCollectionBase { ...@@ -61,10 +61,6 @@ public class ValueArray extends ValueCollectionBase {
return (ValueArray) EMPTY; return (ValueArray) EMPTY;
} }
public Value[] getList() {
return values;
}
@Override @Override
public int getType() { public int getType() {
return Value.ARRAY; return Value.ARRAY;
......
...@@ -14,7 +14,7 @@ import org.h2.util.MathUtils; ...@@ -14,7 +14,7 @@ import org.h2.util.MathUtils;
/** /**
* Base class for ARRAY and ROW values. * Base class for ARRAY and ROW values.
*/ */
abstract class ValueCollectionBase extends Value { public abstract class ValueCollectionBase extends Value {
final Value[] values; final Value[] values;
...@@ -24,6 +24,10 @@ abstract class ValueCollectionBase extends Value { ...@@ -24,6 +24,10 @@ abstract class ValueCollectionBase extends Value {
this.values = values; this.values = values;
} }
public Value[] getList() {
return values;
}
@Override @Override
public int hashCode() { public int hashCode() {
if (hash != 0) { if (hash != 0) {
......
...@@ -47,10 +47,6 @@ public class ValueRow extends ValueCollectionBase { ...@@ -47,10 +47,6 @@ public class ValueRow extends ValueCollectionBase {
return (ValueRow) EMPTY; return (ValueRow) EMPTY;
} }
public Value[] getList() {
return values;
}
@Override @Override
public int getType() { public int getType() {
return Value.ROW; return Value.ROW;
......
...@@ -440,7 +440,7 @@ public class TestFunctions extends TestDb implements AggregateFunction { ...@@ -440,7 +440,7 @@ public class TestFunctions extends TestDb implements AggregateFunction {
stat.execute("create alias dynamic deterministic for \"" + stat.execute("create alias dynamic deterministic for \"" +
getClass().getName() + ".dynamic\""); getClass().getName() + ".dynamic\"");
setCount(0); setCount(0);
rs = stat.executeQuery("call dynamic(('a', 1))[1]"); rs = stat.executeQuery("call dynamic(ARRAY['a', 1])[1]");
rs.next(); rs.next();
String a = rs.getString(1); String a = rs.getString(1);
assertEquals("a1", a); assertEquals("a1", a);
......
...@@ -176,7 +176,7 @@ public class TestMetaData extends TestDb { ...@@ -176,7 +176,7 @@ public class TestMetaData extends TestDb {
Statement stat = conn.createStatement(); Statement stat = conn.createStatement();
stat.execute("create table a(x array)"); stat.execute("create table a(x array)");
stat.execute("insert into a values((1, 2))"); stat.execute("insert into a values(ARRAY[1, 2])");
rs = stat.executeQuery("SELECT x[1] FROM a"); rs = stat.executeQuery("SELECT x[1] FROM a");
ResultSetMetaData rsMeta = rs.getMetaData(); ResultSetMetaData rsMeta = rs.getMetaData();
assertEquals(Types.NULL, rsMeta.getColumnType(1)); assertEquals(Types.NULL, rsMeta.getColumnType(1));
......
...@@ -3,37 +3,37 @@ ...@@ -3,37 +3,37 @@
-- Initial Developer: H2 Group -- Initial Developer: H2 Group
-- --
select array_contains((4.0, 2.0, 2.0), 2.0); select array_contains(ARRAY[4.0, 2.0, 2.0], 2.0);
>> TRUE >> TRUE
select array_contains((4.0, 2.0, 2.0), 5.0); select array_contains(ARRAY[4.0, 2.0, 2.0], 5.0);
>> FALSE >> FALSE
select array_contains(('one', 'two'), 'one'); select array_contains(ARRAY['one', 'two'], 'one');
>> TRUE >> TRUE
select array_contains(('one', 'two'), 'xxx'); select array_contains(ARRAY['one', 'two'], 'xxx');
>> FALSE >> FALSE
select array_contains(('one', 'two'), null); select array_contains(ARRAY['one', 'two'], null);
>> FALSE >> FALSE
select array_contains((null, 'two'), null); select array_contains(ARRAY[null, 'two'], null);
>> TRUE >> TRUE
select array_contains(null, 'one'); select array_contains(null, 'one');
>> null >> null
select array_contains(((1, 2), (3, 4)), (1, 2)); select array_contains(ARRAY[ARRAY[1, 2], ARRAY[3, 4]], ARRAY[1, 2]);
>> TRUE >> TRUE
select array_contains(((1, 2), (3, 4)), (5, 6)); select array_contains(ARRAY[ARRAY[1, 2], ARRAY[3, 4]], ARRAY[5, 6]);
>> FALSE >> FALSE
CREATE TABLE TEST (ID INT PRIMARY KEY AUTO_INCREMENT, A ARRAY); CREATE TABLE TEST (ID INT PRIMARY KEY AUTO_INCREMENT, A ARRAY);
> ok > ok
INSERT INTO TEST (A) VALUES ((1L, 2L)), ((3L, 4L)); INSERT INTO TEST (A) VALUES (ARRAY[1L, 2L]), (ARRAY[3L, 4L]);
> update count: 2 > update count: 2
SELECT ID, ARRAY_CONTAINS(A, 1L), ARRAY_CONTAINS(A, 2L), ARRAY_CONTAINS(A, 3L), ARRAY_CONTAINS(A, 4L) FROM TEST; SELECT ID, ARRAY_CONTAINS(A, 1L), ARRAY_CONTAINS(A, 2L), ARRAY_CONTAINS(A, 3L), ARRAY_CONTAINS(A, 4L) FROM TEST;
......
...@@ -34,6 +34,9 @@ drop table test; ...@@ -34,6 +34,9 @@ drop table test;
explain select * from table(id int = (1, 2), name varchar=('Hello', 'World')); explain select * from table(id int = (1, 2), name varchar=('Hello', 'World'));
>> SELECT TABLE.ID, TABLE.NAME FROM TABLE(ID INT=ROW (1, 2), NAME VARCHAR=ROW ('Hello', 'World')) /* function */ >> SELECT TABLE.ID, TABLE.NAME FROM TABLE(ID INT=ROW (1, 2), NAME VARCHAR=ROW ('Hello', 'World')) /* function */
explain select * from table(id int = ARRAY[1, 2], name varchar=ARRAY['Hello', 'World']);
>> SELECT TABLE.ID, TABLE.NAME FROM TABLE(ID INT=ARRAY [1, 2], NAME VARCHAR=ARRAY ['Hello', 'World']) /* function */
select * from table(id int=(1, 2), name varchar=('Hello', 'World')) x order by id; select * from table(id int=(1, 2), name varchar=('Hello', 'World')) x order by id;
> ID NAME > ID NAME
> -- ----- > -- -----
......
...@@ -1395,7 +1395,7 @@ drop table test; ...@@ -1395,7 +1395,7 @@ drop table test;
create table test(id int primary key, data array); create table test(id int primary key, data array);
> ok > ok
insert into test values(1, (1, 1)), (2, (1, 2)), (3, (1, 1, 1)); insert into test values(1, ARRAY[1, 1]), (2, ARRAY[1, 2]), (3, ARRAY[1, 1, 1]);
> update count: 3 > update count: 3
select * from test order by data; select * from test order by data;
...@@ -2011,10 +2011,10 @@ select (1, 2); ...@@ -2011,10 +2011,10 @@ select (1, 2);
create table array_test(x array); create table array_test(x array);
> ok > ok
insert into array_test values((1, 2, 3)), ((2, 3, 4)); insert into array_test values(ARRAY[1, 2, 3]), (ARRAY[2, 3, 4]);
> update count: 2 > update count: 2
select * from array_test where x = (1, 2, 3); select * from array_test where x = ARRAY[1, 2, 3];
> X > X
> --------- > ---------
> [1, 2, 3] > [1, 2, 3]
......
...@@ -41,7 +41,8 @@ public class TestKeywords extends TestBase { ...@@ -41,7 +41,8 @@ public class TestKeywords extends TestBase {
ClassReader r = new ClassReader(Parser.class.getResourceAsStream("Parser.class")); ClassReader r = new ClassReader(Parser.class.getResourceAsStream("Parser.class"));
r.accept(new ClassVisitor(Opcodes.ASM6) { r.accept(new ClassVisitor(Opcodes.ASM6) {
@Override @Override
public FieldVisitor visitField(int access, String name, String descriptor, String signature, Object value) { public FieldVisitor visitField(int access, String name, String descriptor, String signature,
Object value) {
add(set, value); add(set, value);
return null; return null;
} }
......
...@@ -804,4 +804,4 @@ qualification opportunity jumping exploited unacceptable vrs duplicated ...@@ -804,4 +804,4 @@ qualification opportunity jumping exploited unacceptable vrs duplicated
queryparser tokenized freeze factorings recompilation unenclosed rfe dsync queryparser tokenized freeze factorings recompilation unenclosed rfe dsync
econd irst bcef ordinality nord unnest econd irst bcef ordinality nord unnest
analyst occupation distributive josaph aor engineer sajeewa isuru randil kevin doctor businessman artist ashan analyst occupation distributive josaph aor engineer sajeewa isuru randil kevin doctor businessman artist ashan
corrupts splitted disruption unintentional octets preconditions predicates subq corrupts splitted disruption unintentional octets preconditions predicates subq objectweb insn opcodes
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论