Skip to content

Commit fb34acb

Browse files
authored
Support second and third parameter of read_object are not constant (#16967)
1 parent cb18a95 commit fb34acb

File tree

7 files changed

+363
-54
lines changed

7 files changed

+363
-54
lines changed

integration-test/src/test/java/org/apache/iotdb/relational/it/query/object/IoTDBObjectQueryIT2.java renamed to integration-test/src/test/java/org/apache/iotdb/relational/it/query/object/IoTDBObjectQuery2IT.java

Lines changed: 56 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343

4444
@RunWith(IoTDBTestRunner.class)
4545
@Category({TableLocalStandaloneIT.class, TableClusterIT.class})
46-
public class IoTDBObjectQueryIT2 {
46+
public class IoTDBObjectQuery2IT {
4747

4848
private static final String DATABASE_NAME = "test";
4949

@@ -116,6 +116,7 @@ public void testReadObject() throws IoTDBConnectionException, StatementExecution
116116
Binary blob = iterator.getBlob(1);
117117
Assert.assertArrayEquals(expected, blob.getValues());
118118
}
119+
sessionDataSet.close();
119120

120121
sessionDataSet =
121122
session.executeQueryStatement(
@@ -126,6 +127,7 @@ public void testReadObject() throws IoTDBConnectionException, StatementExecution
126127
Binary blob = iterator.getBlob(1);
127128
Assert.assertArrayEquals(expected, blob.getValues());
128129
}
130+
sessionDataSet.close();
129131

130132
sessionDataSet =
131133
session.executeQueryStatement(
@@ -136,6 +138,7 @@ public void testReadObject() throws IoTDBConnectionException, StatementExecution
136138
Binary blob = iterator.getBlob(1);
137139
Assert.assertArrayEquals(expected, blob.getValues());
138140
}
141+
sessionDataSet.close();
139142

140143
sessionDataSet =
141144
session.executeQueryStatement(
@@ -145,6 +148,7 @@ public void testReadObject() throws IoTDBConnectionException, StatementExecution
145148
long count = iterator.getLong(1);
146149
Assert.assertEquals(10, count);
147150
}
151+
sessionDataSet.close();
148152

149153
// read_object are not pushed down. Read remote files
150154
sessionDataSet =
@@ -156,6 +160,7 @@ public void testReadObject() throws IoTDBConnectionException, StatementExecution
156160
Binary blob = iterator.getBlob(1);
157161
Assert.assertArrayEquals(expected, blob.getValues());
158162
}
163+
sessionDataSet.close();
159164
}
160165
}
161166

@@ -172,6 +177,8 @@ public void testFunctionAndClauses()
172177
while (iterator.next()) {
173178
Assert.assertEquals(4, iterator.getLong(1));
174179
}
180+
sessionDataSet.close();
181+
175182
sessionDataSet =
176183
session.executeQueryStatement(
177184
"select count(s8), first(s8), last(s8), first_by(s8, time), last_by(s8, time) from table1 where device = 'd1' and cast(s8 as string) = '(Object) 4 B' and try_cast(s8 as string) = '(Object) 4 B'");
@@ -183,12 +190,14 @@ public void testFunctionAndClauses()
183190
Assert.assertEquals("(Object) 4 B", iterator.getString(4));
184191
Assert.assertEquals("(Object) 4 B", iterator.getString(5));
185192
}
193+
sessionDataSet.close();
186194

187195
sessionDataSet = session.executeQueryStatement("select coalesce(s9, s8) from table1");
188196
iterator = sessionDataSet.iterator();
189197
while (iterator.next()) {
190198
Assert.assertEquals("(Object) 4 B", iterator.getString(1));
191199
}
200+
sessionDataSet.close();
192201

193202
// MATCH_RECOGNIZE
194203
Assert.assertThrows(
@@ -209,6 +218,7 @@ public void testFunctionAndClauses()
209218
while (iterator.next()) {
210219
Assert.assertEquals("(Object) 4 B", iterator.getString(1));
211220
}
221+
sessionDataSet.close();
212222

213223
// WHERE
214224
session.executeQueryStatement(
@@ -217,71 +227,90 @@ public void testFunctionAndClauses()
217227
while (iterator.next()) {
218228
Assert.assertEquals("(Object) 4 B", iterator.getString(2));
219229
}
230+
sessionDataSet.close();
220231

221232
// GROUP BY
222233
Assert.assertThrows(
223234
StatementExecutionException.class,
224-
() -> session.executeNonQueryStatement("select count(*) from table1 group by s8"));
235+
() -> session.executeQueryStatement("select count(*) from table1 group by s8"));
225236

226237
// ORDER BY
227238
Assert.assertThrows(
228239
StatementExecutionException.class,
229-
() -> session.executeNonQueryStatement("select count(*) from table1 order by s8"));
240+
() -> session.executeQueryStatement("select count(*) from table1 order by s8"));
230241

231242
// FILL
232-
Assert.assertThrows(
233-
StatementExecutionException.class,
234-
() ->
235-
session.executeNonQueryStatement(
236-
"select time, s8 from table1 where device = 'd10' fill method linear"));
237-
session.executeQueryStatement(
238-
"select time, s8 from table1 where device = 'd10' fill method previous");
243+
sessionDataSet =
244+
session.executeQueryStatement(
245+
"select time, s8 from table1 where device = 'd10' fill method linear");
246+
sessionDataSet.close();
247+
248+
sessionDataSet =
249+
session.executeQueryStatement(
250+
"select time, s8 from table1 where device = 'd10' fill method previous");
239251
iterator = sessionDataSet.iterator();
240252
while (iterator.next()) {
241253
Assert.assertEquals("(Object) 4 B", iterator.getString(2));
242254
}
255+
sessionDataSet.close();
243256

244257
// HAVING
245-
session.executeQueryStatement(
246-
"select device, count(s8) from table1 group by device having count(s8) > 0");
258+
sessionDataSet =
259+
session.executeQueryStatement(
260+
"select device, count(s8) from table1 group by device having count(s8) > 0");
247261
iterator = sessionDataSet.iterator();
248262
while (iterator.next()) {
249263
long count = iterator.getLong(2);
250264
Assert.assertEquals(10, count);
251265
}
266+
sessionDataSet.close();
252267

253268
// WINDOW
254269
Assert.assertThrows(
255270
StatementExecutionException.class,
256271
() ->
257-
session.executeNonQueryStatement(
272+
session.executeQueryStatement(
258273
"select *, nth_value(s8,2) over(partition by s8) from table1"));
259274
Assert.assertThrows(
260275
StatementExecutionException.class,
261276
() ->
262-
session.executeNonQueryStatement(
277+
session.executeQueryStatement(
263278
"select *, nth_value(s8,2) over(order by s8) from table1"));
264-
session.executeNonQueryStatement(
265-
"select *, nth_value(s8,2) over(partition by device) from table1");
266-
session.executeNonQueryStatement(
267-
"select *, lead(s8) over(partition by device order by time) from table1");
268-
session.executeNonQueryStatement(
269-
"select *, first_value(s8) over(partition by device) from table1");
270-
session.executeNonQueryStatement(
271-
"select *, last_value(s8) over(partition by device) from table1");
272-
session.executeNonQueryStatement(
273-
"select *, lag(s8) over(partition by device order by time) from table1");
279+
sessionDataSet =
280+
session.executeQueryStatement(
281+
"select *, nth_value(s8,2) over(partition by device) from table1");
282+
sessionDataSet.close();
283+
284+
sessionDataSet =
285+
session.executeQueryStatement(
286+
"select *, lead(s8) over(partition by device order by time) from table1");
287+
sessionDataSet.close();
288+
289+
sessionDataSet =
290+
session.executeQueryStatement(
291+
"select *, first_value(s8) over(partition by device) from table1");
292+
sessionDataSet.close();
293+
294+
sessionDataSet =
295+
session.executeQueryStatement(
296+
"select *, last_value(s8) over(partition by device) from table1");
297+
sessionDataSet.close();
298+
299+
sessionDataSet =
300+
session.executeQueryStatement(
301+
"select *, lag(s8) over(partition by device order by time) from table1");
302+
sessionDataSet.close();
274303

275304
// Table-value function
276305
Assert.assertThrows(
277306
StatementExecutionException.class,
278307
() ->
279-
session.executeNonQueryStatement(
308+
session.executeQueryStatement(
280309
"select * from session(data => table1 partition by s8, timecol => 'time', gap => 1ms)"));
281310
Assert.assertThrows(
282311
StatementExecutionException.class,
283312
() ->
284-
session.executeNonQueryStatement(
313+
session.executeQueryStatement(
285314
"select * from session(data => table1 order by s8, timecol => 'time', gap => 1ms)"));
286315
sessionDataSet =
287316
session.executeQueryStatement(
@@ -291,6 +320,7 @@ public void testFunctionAndClauses()
291320
String str = iterator.getString("s8");
292321
Assert.assertEquals("(Object) 4 B", str);
293322
}
323+
sessionDataSet.close();
294324
}
295325
}
296326
}

integration-test/src/test/java/org/apache/iotdb/relational/it/query/object/IoTDBObjectQueryIT.java

Lines changed: 86 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -62,15 +62,15 @@ public class IoTDBObjectQueryIT {
6262
new String[] {
6363
"CREATE DATABASE " + DATABASE_NAME,
6464
"USE " + DATABASE_NAME,
65-
"CREATE TABLE t1(device_id STRING TAG, o1 OBJECT, b1 BLOB, s1 STRING)",
66-
"INSERT INTO t1(time, device_id, b1, o1, s1) VALUES(1, 'd1', X'cafebabe01', to_object(true, 0, X'cafebabe01'), 'cafebabe01')",
67-
"INSERT INTO t1(time, device_id, b1, o1, s1) VALUES(2, 'd1', X'cafebabe0202', to_object(true, 0, X'cafebabe02'), 'cafebabe02')",
68-
"INSERT INTO t1(time, device_id, b1, o1, s1) VALUES(3, 'd1', X'cafebabe0303', to_object(true, 0, X'cafebabe03'), 'cafebabe03')",
69-
"INSERT INTO t1(time, device_id, b1, o1, s1) VALUES(4, 'd1', X'cafebabe04', to_object(true, 0, X'cafebabe04'), 'cafebabe04')",
70-
"INSERT INTO t1(time, device_id, b1, o1, s1) VALUES(1, 'd2', X'cafebade01', to_object(true, 0, X'cafebade01'), 'cafebade01')",
71-
"INSERT INTO t1(time, device_id, b1, o1, s1) VALUES(2, 'd2', X'cafebade0202', to_object(true, 0, X'cafebade02'), 'cafebade02')",
72-
"INSERT INTO t1(time, device_id, b1, o1, s1) VALUES(3, 'd2', X'cafebade0302', to_object(true, 0, X'cafebade03'), 'cafebade03')",
73-
"INSERT INTO t1(time, device_id, b1, o1, s1) VALUES(4, 'd2', X'cafebade04', to_object(true, 0, X'cafebade04'), 'cafebade04')",
65+
"CREATE TABLE t1(device_id STRING TAG, o1 OBJECT, b1 BLOB, s1 STRING, l1 INT64, l2 INT64)",
66+
"INSERT INTO t1(time, device_id, b1, o1, s1, l1, l2) VALUES(1, 'd1', X'cafebabe01', to_object(true, 0, X'cafebabe01'), 'cafebabe01', 0, 100)",
67+
"INSERT INTO t1(time, device_id, b1, o1, s1, l1, l2) VALUES(2, 'd1', X'cafebabe0202', to_object(true, 0, X'cafebabe02'), 'cafebabe02', 0, 100)",
68+
"INSERT INTO t1(time, device_id, b1, o1, s1, l1, l2) VALUES(3, 'd1', X'cafebabe0303', to_object(true, 0, X'cafebabe03'), 'cafebabe03', 0, 100)",
69+
"INSERT INTO t1(time, device_id, b1, o1, s1, l1, l2) VALUES(4, 'd1', X'cafebabe04', to_object(true, 0, X'cafebabe04'), 'cafebabe04', 0, 100)",
70+
"INSERT INTO t1(time, device_id, b1, o1, s1, l1, l2) VALUES(1, 'd2', X'cafebade01', to_object(true, 0, X'cafebade01'), 'cafebade01', 0, 100)",
71+
"INSERT INTO t1(time, device_id, b1, o1, s1, l1, l2) VALUES(2, 'd2', X'cafebade0202', to_object(true, 0, X'cafebade02'), 'cafebade02', 0, 100)",
72+
"INSERT INTO t1(time, device_id, b1, o1, s1, l1, l2) VALUES(3, 'd2', X'cafebade0302', to_object(true, 0, X'cafebade03'), 'cafebade03', 0, 100)",
73+
"INSERT INTO t1(time, device_id, b1, o1, s1, l1, l2) VALUES(4, 'd2', X'cafebade04', to_object(true, 0, X'cafebade04'), 'cafebade04', 0, 100)",
7474
"FLUSH",
7575
};
7676

@@ -134,6 +134,83 @@ public void jdbcTest() {
134134
}
135135
assertEquals(2, cnt);
136136
}
137+
138+
try (ResultSet resultSet =
139+
statement.executeQuery(
140+
"SELECT time, b1, READ_OBJECT(o1, 0, -1), s1 FROM t1 WHERE device_id = 'd2' AND READ_OBJECT(o1)=b1 ORDER BY time")) {
141+
int cnt = 0;
142+
String[] ans = {"0xcafebade01", "0xcafebade04"};
143+
while (resultSet.next()) {
144+
String s = resultSet.getString(3);
145+
assertEquals(ans[cnt], s);
146+
cnt++;
147+
}
148+
assertEquals(2, cnt);
149+
}
150+
151+
try (ResultSet resultSet =
152+
statement.executeQuery(
153+
"SELECT time, b1, READ_OBJECT(o1, l1), s1 FROM t1 WHERE device_id = 'd2' AND READ_OBJECT(o1)=b1 ORDER BY time")) {
154+
int cnt = 0;
155+
String[] ans = {"0xcafebade01", "0xcafebade04"};
156+
while (resultSet.next()) {
157+
String s = resultSet.getString(3);
158+
assertEquals(ans[cnt], s);
159+
cnt++;
160+
}
161+
assertEquals(2, cnt);
162+
}
163+
164+
try (ResultSet resultSet =
165+
statement.executeQuery(
166+
"SELECT time, b1, READ_OBJECT(o1, l1, l2), s1 FROM t1 WHERE device_id = 'd2' AND READ_OBJECT(o1)=b1 ORDER BY time")) {
167+
int cnt = 0;
168+
String[] ans = {"0xcafebade01", "0xcafebade04"};
169+
while (resultSet.next()) {
170+
String s = resultSet.getString(3);
171+
assertEquals(ans[cnt], s);
172+
cnt++;
173+
}
174+
assertEquals(2, cnt);
175+
}
176+
177+
try (ResultSet resultSet =
178+
statement.executeQuery(
179+
"SELECT time, b1, READ_OBJECT(o1, l1, -1), s1 FROM t1 WHERE device_id = 'd2' AND READ_OBJECT(o1)=b1 ORDER BY time")) {
180+
int cnt = 0;
181+
String[] ans = {"0xcafebade01", "0xcafebade04"};
182+
while (resultSet.next()) {
183+
String s = resultSet.getString(3);
184+
assertEquals(ans[cnt], s);
185+
cnt++;
186+
}
187+
assertEquals(2, cnt);
188+
}
189+
190+
try (ResultSet resultSet =
191+
statement.executeQuery(
192+
"SELECT time, b1, READ_OBJECT(o1, 0, l2), s1 FROM t1 WHERE device_id = 'd2' AND READ_OBJECT(o1)=b1 ORDER BY time")) {
193+
int cnt = 0;
194+
String[] ans = {"0xcafebade01", "0xcafebade04"};
195+
while (resultSet.next()) {
196+
String s = resultSet.getString(3);
197+
assertEquals(ans[cnt], s);
198+
cnt++;
199+
}
200+
assertEquals(2, cnt);
201+
}
202+
203+
try (ResultSet resultSet =
204+
statement.executeQuery(
205+
"SELECT time, b1, o1, s1 FROM t1 WHERE device_id = 'd1' FILL METHOD LINEAR")) {
206+
int cnt = 0;
207+
while (resultSet.next()) {
208+
cnt++;
209+
String s = resultSet.getString(3);
210+
assertEquals("(Object) 5 B", s);
211+
}
212+
assertEquals(4, cnt);
213+
}
137214
}
138215
} catch (SQLException e) {
139216
e.printStackTrace();

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/relational/ColumnTransformerBuilder.java

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@
8585
import org.apache.iotdb.db.queryengine.transformation.dag.column.binary.CompareNonEqualColumnTransformer;
8686
import org.apache.iotdb.db.queryengine.transformation.dag.column.binary.HmacColumnTransformer;
8787
import org.apache.iotdb.db.queryengine.transformation.dag.column.binary.Like2ColumnTransformer;
88+
import org.apache.iotdb.db.queryengine.transformation.dag.column.binary.ReadObject2ColumnTransformer;
8889
import org.apache.iotdb.db.queryengine.transformation.dag.column.binary.factory.HmacStrategiesFactory;
8990
import org.apache.iotdb.db.queryengine.transformation.dag.column.leaf.ConstantColumnTransformer;
9091
import org.apache.iotdb.db.queryengine.transformation.dag.column.leaf.IdentityColumnTransformer;
@@ -105,6 +106,7 @@
105106
import org.apache.iotdb.db.queryengine.transformation.dag.column.ternary.BetweenColumnTransformer;
106107
import org.apache.iotdb.db.queryengine.transformation.dag.column.ternary.Like3ColumnTransformer;
107108
import org.apache.iotdb.db.queryengine.transformation.dag.column.ternary.LpadColumnTransformer;
109+
import org.apache.iotdb.db.queryengine.transformation.dag.column.ternary.ReadObject3ColumnTransformer;
108110
import org.apache.iotdb.db.queryengine.transformation.dag.column.ternary.RpadColumnTransformer;
109111
import org.apache.iotdb.db.queryengine.transformation.dag.column.udf.UserDefineScalarFunctionTransformer;
110112
import org.apache.iotdb.db.queryengine.transformation.dag.column.unary.IsNullColumnTransformer;
@@ -1467,21 +1469,31 @@ private ColumnTransformer getFunctionColumnTransformer(
14671469
if (children.size() == 1) {
14681470
return new ReadObjectColumnTransformer(BLOB, first, context.fragmentInstanceContext);
14691471
} else if (children.size() == 2) {
1470-
return new ReadObjectColumnTransformer(
1471-
BLOB,
1472-
((LongLiteral) children.get(1)).getParsedValue(),
1473-
first,
1474-
context.fragmentInstanceContext);
1472+
Expression offset = children.get(1);
1473+
if (isLongLiteral(offset)) {
1474+
return new ReadObjectColumnTransformer(
1475+
BLOB,
1476+
((LongLiteral) children.get(1)).getParsedValue(),
1477+
first,
1478+
context.fragmentInstanceContext);
1479+
} else {
1480+
return new ReadObject2ColumnTransformer(
1481+
BLOB, first, this.process(offset, context), context.fragmentInstanceContext);
1482+
}
14751483
} else {
1476-
long offset = ((LongLiteral) children.get(1)).getParsedValue();
1477-
long length = ((LongLiteral) children.get(2)).getParsedValue();
1478-
checkArgument(offset >= 0 && length >= 0);
1479-
return new ReadObjectColumnTransformer(
1480-
BLOB,
1481-
((LongLiteral) children.get(1)).getParsedValue(),
1482-
((LongLiteral) children.get(2)).getParsedValue(),
1483-
first,
1484-
context.fragmentInstanceContext);
1484+
if (isLongLiteral(children.get(1)) && isLongLiteral(children.get(2))) {
1485+
long offset = ((LongLiteral) children.get(1)).getParsedValue();
1486+
long length = ((LongLiteral) children.get(2)).getParsedValue();
1487+
return new ReadObjectColumnTransformer(
1488+
BLOB, offset, length, first, context.fragmentInstanceContext);
1489+
} else {
1490+
return new ReadObject3ColumnTransformer(
1491+
BLOB,
1492+
first,
1493+
this.process(children.get(1), context),
1494+
this.process(children.get(2), context),
1495+
context.fragmentInstanceContext);
1496+
}
14851497
}
14861498
} else {
14871499
// user defined function

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/OperatorTreeGenerator.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1494,6 +1494,7 @@ public static ILinearFill[] getLinearFill(int inputColumns, List<TSDataType> inp
14941494
case TEXT:
14951495
case STRING:
14961496
case BLOB:
1497+
case OBJECT:
14971498
linearFill[i] = IDENTITY_LINEAR_FILL;
14981499
break;
14991500
default:

0 commit comments

Comments
 (0)