This is an automated email from the ASF dual-hosted git repository. lta pushed a commit to branch fix_bug_of_read_with_filter in repository https://gitbox.apache.org/repos/asf/incubator-iotdb.git
commit 2ab8498e6c04ca162a2218884ce5b9c8e939b565 Author: lta <[email protected]> AuthorDate: Sun Apr 7 22:32:16 2019 +0800 fix_bug_of_read_with_filter --- .../dataset/EngineDataSetWithTimeGenerator.java | 50 +++++++-- .../org/apache/iotdb/db/qp/QueryProcessorTest.java | 3 +- .../EngineDataSetWithTimeGeneratorTest.java | 123 +++++++++++++++++++++ 3 files changed, 163 insertions(+), 13 deletions(-) diff --git a/iotdb/src/main/java/org/apache/iotdb/db/query/dataset/EngineDataSetWithTimeGenerator.java b/iotdb/src/main/java/org/apache/iotdb/db/query/dataset/EngineDataSetWithTimeGenerator.java index cdaa0fb..e8ced51 100644 --- a/iotdb/src/main/java/org/apache/iotdb/db/query/dataset/EngineDataSetWithTimeGenerator.java +++ b/iotdb/src/main/java/org/apache/iotdb/db/query/dataset/EngineDataSetWithTimeGenerator.java @@ -34,6 +34,7 @@ public class EngineDataSetWithTimeGenerator extends QueryDataSet { private EngineTimeGenerator timeGenerator; private List<EngineReaderByTimeStamp> readers; + private RowRecord cachedRowRecord; /** * constructor of EngineDataSetWithTimeGenerator. @@ -52,24 +53,49 @@ public class EngineDataSetWithTimeGenerator extends QueryDataSet { @Override public boolean hasNext() throws IOException { - return timeGenerator.hasNext(); + if (cachedRowRecord != null) { + return true; + } + return cacheRowRecord(); } @Override public RowRecord next() throws IOException { - long timestamp = timeGenerator.next(); - RowRecord rowRecord = new RowRecord(timestamp); - for (int i = 0; i < readers.size(); i++) { - EngineReaderByTimeStamp reader = readers.get(i); - Object value = reader.getValueInTimestamp(timestamp); - if (value == null) { - rowRecord.addField(new Field(null)); - } else { - rowRecord.addField(getField(value, dataTypes.get(i))); - } + if (cachedRowRecord == null) { + cacheRowRecord(); } + RowRecord tempRecord = cachedRowRecord; + cachedRowRecord = null; + return tempRecord; + } - return rowRecord; + /** + * Cache row record + * + * @return if there has next row record. + */ + private boolean cacheRowRecord() throws IOException { + while (timeGenerator.hasNext()) { + boolean markNull = true; + long timestamp = timeGenerator.next(); + RowRecord rowRecord = new RowRecord(timestamp); + for (int i = 0; i < readers.size(); i++) { + EngineReaderByTimeStamp reader = readers.get(i); + Object value = reader.getValueInTimestamp(timestamp); + if (value == null) { + rowRecord.addField(new Field(null)); + } else { + markNull = false; + rowRecord.addField(getField(value, dataTypes.get(i))); + } + } + if (!markNull) { + cachedRowRecord = rowRecord; + return true; + } + } + cachedRowRecord = null; + return false; } private Field getField(Object value, TSDataType dataType) { diff --git a/iotdb/src/test/java/org/apache/iotdb/db/qp/QueryProcessorTest.java b/iotdb/src/test/java/org/apache/iotdb/db/qp/QueryProcessorTest.java index 489bd20..4145936 100644 --- a/iotdb/src/test/java/org/apache/iotdb/db/qp/QueryProcessorTest.java +++ b/iotdb/src/test/java/org/apache/iotdb/db/qp/QueryProcessorTest.java @@ -26,11 +26,12 @@ import org.apache.iotdb.db.exception.qp.QueryProcessorException; import org.apache.iotdb.db.qp.executor.OverflowQPExecutor; import org.apache.iotdb.db.qp.logical.Operator.OperatorType; import org.apache.iotdb.db.qp.physical.PhysicalPlan; +import org.apache.iotdb.db.qp.utils.MemIntQpExecutor; import org.junit.Test; public class QueryProcessorTest { - private QueryProcessor processor = new QueryProcessor(new OverflowQPExecutor()); + private QueryProcessor processor = new QueryProcessor(new MemIntQpExecutor()); @Test public void parseSQLToPhysicalPlan() diff --git a/iotdb/src/test/java/org/apache/iotdb/db/query/dataset/EngineDataSetWithTimeGeneratorTest.java b/iotdb/src/test/java/org/apache/iotdb/db/query/dataset/EngineDataSetWithTimeGeneratorTest.java new file mode 100644 index 0000000..6dec434 --- /dev/null +++ b/iotdb/src/test/java/org/apache/iotdb/db/query/dataset/EngineDataSetWithTimeGeneratorTest.java @@ -0,0 +1,123 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.iotdb.db.query.dataset; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import org.apache.iotdb.db.qp.QueryProcessor; +import org.apache.iotdb.db.qp.executor.OverflowQPExecutor; +import org.apache.iotdb.db.qp.executor.QueryProcessExecutor; +import org.apache.iotdb.db.qp.physical.crud.QueryPlan; +import org.apache.iotdb.db.utils.EnvironmentUtils; +import org.apache.iotdb.tsfile.read.query.dataset.QueryDataSet; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class EngineDataSetWithTimeGeneratorTest { + + private QueryProcessExecutor queryExecutor = new OverflowQPExecutor(); + private QueryProcessor processor = new QueryProcessor(queryExecutor); + private String[] sqls = { + "SET STORAGE GROUP TO root.vehicle", + "SET STORAGE GROUP TO root.test", + "CREATE TIMESERIES root.vehicle.d0.s0 WITH DATATYPE=INT32, ENCODING=RLE", + "CREATE TIMESERIES root.vehicle.d0.s1 WITH DATATYPE=TEXT, ENCODING=PLAIN", + "CREATE TIMESERIES root.test.d0.s0 WITH DATATYPE=INT32, ENCODING=RLE", + "CREATE TIMESERIES root.test.d0.s1 WITH DATATYPE=TEXT, ENCODING=PLAIN", + "insert into root.vehicle.d0(timestamp,s0) values(10,100)", + "insert into root.vehicle.d0(timestamp,s0,s1) values(12,101,'102')", + "insert into root.vehicle.d0(timestamp,s1) values(19,'103')", + "insert into root.vehicle.d0(timestamp,s0) values(20,1000)", + "insert into root.vehicle.d0(timestamp,s0,s1) values(22,1001,'1002')", + "insert into root.vehicle.d0(timestamp,s1) values(29,'1003')", + "insert into root.test.d0(timestamp,s0) values(10,106)", + "insert into root.test.d0(timestamp,s0,s1) values(14,107,'108')", + "insert into root.test.d0(timestamp,s1) values(16,'109')", + "insert into root.test.d0(timestamp,s0) values(30,1006)", + "insert into root.test.d0(timestamp,s0,s1) values(34,1007,'1008')", + "insert into root.test.d0(timestamp,s1) values(36,'1090')", + "insert into root.vehicle.d0(timestamp,s0) values(6,120)", + "insert into root.vehicle.d0(timestamp,s0,s1) values(38,121,'122')", + "insert into root.vehicle.d0(timestamp,s1) values(9,'123')", + "insert into root.vehicle.d0(timestamp,s0) values(16,128)", + "insert into root.vehicle.d0(timestamp,s0,s1) values(18,189,'198')", + "insert into root.vehicle.d0(timestamp,s1) values(99,'1234')", + "insert into root.test.d0(timestamp,s0) values(15,126)", + "insert into root.test.d0(timestamp,s0,s1) values(8,127,'128')", + "insert into root.test.d0(timestamp,s1) values(20,'129')", + "insert into root.test.d0(timestamp,s0) values(150,426)", + "insert into root.test.d0(timestamp,s0,s1) values(80,427,'528')", + "insert into root.test.d0(timestamp,s1) values(2,'1209')", + "insert into root.vehicle.d0(timestamp,s0) values(209,130)", + "insert into root.vehicle.d0(timestamp,s0,s1) values(206,131,'132')", + "insert into root.vehicle.d0(timestamp,s1) values(70,'33')", + "insert into root.test.d0(timestamp,s0) values(19,136)", + "insert into root.test.d0(timestamp,s0,s1) values(7,137,'138')", + "insert into root.test.d0(timestamp,s1) values(30,'139')", + "insert into root.test.d0(timestamp,s0) values(1900,1316)", + "insert into root.test.d0(timestamp,s0,s1) values(700,1307,'1038')", + "insert into root.test.d0(timestamp,s1) values(3000,'1309')"}; + + @Before + public void setUp() throws Exception { + EnvironmentUtils.envSetUp(); + for (String sql : sqls) { + queryExecutor.processNonQuery(processor.parseSQLToPhysicalPlan(sql)); + } + } + + @After + public void tearDown() throws Exception { + EnvironmentUtils.cleanEnv(); + } + + @Test + public void testHasNextAndNext() throws Exception { + QueryPlan queryPlan = (QueryPlan) processor + .parseSQLToPhysicalPlan("select test.d0.s1 from root where root.vehicle.d0.s0 > 100"); + QueryDataSet dataSet = queryExecutor.processQuery(queryPlan, EnvironmentUtils.TEST_QUERY_CONTEXT); + assertTrue(dataSet.hasNext()); + assertEquals("16\t109", dataSet.next().toString()); + assertTrue(dataSet.hasNext()); + assertEquals("20\t129", dataSet.next().toString()); + assertFalse(dataSet.hasNext()); + assertNull(dataSet.next()); + + queryPlan = (QueryPlan) processor + .parseSQLToPhysicalPlan("select vehicle.d0.s1 from root where root.vehicle.d0.s0 > 100"); + dataSet = queryExecutor.processQuery(queryPlan, EnvironmentUtils.TEST_QUERY_CONTEXT); + assertTrue(dataSet.hasNext()); + assertEquals("12\t102", dataSet.next().toString()); + assertTrue(dataSet.hasNext()); + assertEquals("18\t198", dataSet.next().toString()); + assertTrue(dataSet.hasNext()); + assertEquals("22\t1002", dataSet.next().toString()); + assertTrue(dataSet.hasNext()); + assertEquals("38\t122", dataSet.next().toString()); + assertTrue(dataSet.hasNext()); + assertEquals("206\t132", dataSet.next().toString()); + assertFalse(dataSet.hasNext()); + assertNull(dataSet.next()); + + } +} \ No newline at end of file
