Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,30 @@ public void testCreateTimeseries1() {
}
}

@Test
public void testLimitZeroRejected() throws SQLException {
try (Connection connection = EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
Statement statement = connection.createStatement()) {
statement.execute("CREATE DATABASE " + DATABASE_NAME);
statement.execute("USE " + DATABASE_NAME);
statement.execute("CREATE TABLE table1(device STRING TAG, s1 INT32 FIELD)");

assertLimitZeroRejected(statement, "SELECT * FROM table1 LIMIT 0");
assertLimitZeroRejected(statement, "SELECT * FROM table1 ORDER BY time LIMIT 0");
}
}

private static void assertLimitZeroRejected(Statement statement, String sql) {
try {
statement.executeQuery(sql);
fail("Expected LIMIT 0 to be rejected");
} catch (SQLException e) {
assertTrue(
e.getMessage(),
e.getMessage().contains("LIMIT row count must be greater than 0 (actual value: 0)"));
}
}

@Ignore // TODO After last query supported
@Test
public void testLastQueryNonCached() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ public void test() throws Exception {
true);
// empty result
compareQueryResults(
session, "select * from view3 limit 1", "select * from table1 limit 0", true);
session, "select * from view3 limit 1", "select * from table1 where battery = 'b'", true);

// not exists
compareQueryResults(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import java.util.Collections;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

@RunWith(IoTDBTestRunner.class)
Expand Down Expand Up @@ -106,10 +107,14 @@ public void testDevice() throws SQLException {
"show devices from table0 where region_id < plant_id offset 0 limit 1"),
"region_id,plant_id,device_id,model,",
Collections.singleton("1,木兰,3,A,"));
TestUtils.assertResultSetEqual(
statement.executeQuery("show devices from table0 where region_id < plant_id limit 0"),
"region_id,plant_id,device_id,model,",
Collections.emptySet());
try {
statement.executeQuery("show devices from table0 where region_id < plant_id limit 0");
fail("Expected LIMIT 0 to be rejected");
} catch (SQLException e) {
assertTrue(
e.getMessage(),
e.getMessage().contains("LIMIT row count must be greater than 0 (actual value: 0)"));
}
TestUtils.assertResultSetEqual(
statement.executeQuery("count devices from table0 where region_id < plant_id"),
"count(devices),",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2261,8 +2261,9 @@ public final class DataNodeQueryMessages {
"Type %s is not orderable, and therefore cannot be used in ORDER BY: %s";
public static final String OFFSET_ROW_COUNT_MUST_BE_GREATER_OR_EQUAL_TO_0_ACTUAL_VALUE_S =
"OFFSET row count must be greater or equal to 0 (actual value: %s)";
public static final String LIMIT_ROW_COUNT_MUST_BE_GREATER_OR_EQUAL_TO_0_ACTUAL_VALUE_S =
"LIMIT row count must be greater or equal to 0 (actual value: %s)";
public static final String
EXCEPTION_LIMIT_ROW_COUNT_MUST_BE_GREATER_THAN_0_ACTUAL_VALUE_ARG_79F8F1A3 =
"LIMIT row count must be greater than 0 (actual value: %s)";
public static final String NON_CONSTANT_PARAMETER_VALUE_FOR_S_S =
"Non constant parameter value for %s: %s";
public static final String PARAMETER_VALUE_PROVIDED_FOR_S_IS_NULL_S =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2518,9 +2518,10 @@ public final class DataNodeQueryMessages {
public static final String OFFSET_ROW_COUNT_MUST_BE_GREATER_OR_EQUAL_TO_0_ACTUAL_VALUE_S =

"OFFSET 行数必须大于或等于 0(实际值:%s)";
public static final String LIMIT_ROW_COUNT_MUST_BE_GREATER_OR_EQUAL_TO_0_ACTUAL_VALUE_S =
public static final String
EXCEPTION_LIMIT_ROW_COUNT_MUST_BE_GREATER_THAN_0_ACTUAL_VALUE_ARG_79F8F1A3 =

"LIMIT 行数必须大于或等于 0(实际值:%s)";
"LIMIT 行数必须大于 0(实际值:%s)";
public static final String NON_CONSTANT_PARAMETER_VALUE_FOR_S_S =

"%s 的参数值不是常量:%s";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5058,11 +5058,11 @@ private boolean analyzeLimit(Limit node, Scope scope) {
}
rowCount.ifPresent(
count -> {
if (count < 0) {
if (count <= 0) {
throw new SemanticException(
String.format(
DataNodeQueryMessages
.LIMIT_ROW_COUNT_MUST_BE_GREATER_OR_EQUAL_TO_0_ACTUAL_VALUE_S,
.EXCEPTION_LIMIT_ROW_COUNT_MUST_BE_GREATER_THAN_0_ACTUAL_VALUE_ARG_79F8F1A3,
count));
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,15 @@ public static void setUp() {
IoTDBDescriptor.getInstance().getConfig().setDataNodeId(1);
}

@Test
public void testLimitZeroRejected() {
TestUtils.assertAnalyzeSemanticException(
"SELECT * FROM table1 LIMIT 0", "LIMIT row count must be greater than 0 (actual value: 0)");
TestUtils.assertAnalyzeSemanticException(
"SELECT * FROM table1 ORDER BY time LIMIT 0",
"LIMIT row count must be greater than 0 (actual value: 0)");
}

@Test
public void testMockQuery() throws OperatorNotFoundException {
final String sql =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,30 +19,19 @@

package org.apache.iotdb.db.queryengine.plan.relational.analyzer;

import org.apache.iotdb.db.queryengine.plan.relational.planner.PlanTester;

import org.junit.Test;

import static org.apache.iotdb.db.queryengine.plan.relational.planner.assertions.PlanAssert.assertPlan;
import static org.apache.iotdb.db.queryengine.plan.relational.planner.assertions.PlanMatchPattern.limit;
import static org.apache.iotdb.db.queryengine.plan.relational.planner.assertions.PlanMatchPattern.output;
import static org.apache.iotdb.db.queryengine.plan.relational.planner.assertions.PlanMatchPattern.tableScan;
import static org.apache.iotdb.db.queryengine.plan.relational.analyzer.TestUtils.assertAnalyzeSemanticException;

public class EvaluateEmptyIntersectTest {

@Test
public void EvaluateEmptyIntersectTest() {
// Normal case
assertPlan(
new PlanTester()
.createPlan(
"(select tag1 from t1 limit 0) intersect (select tag1 from t2) intersect (select tag1 from t3)"),
output((limit(0, tableScan("testdb.t1")))));

assertPlan(
new PlanTester()
.createPlan(
"(select tag1 from t1 ) intersect all (select tag1 from t2 limit 0) intersect all (select tag1 from t3)"),
output((limit(0, tableScan("testdb.t2")))));
assertAnalyzeSemanticException(
"(select tag1 from t1 limit 0) intersect (select tag1 from t2) intersect (select tag1 from t3)",
"LIMIT row count must be greater than 0 (actual value: 0)");
assertAnalyzeSemanticException(
"(select tag1 from t1) intersect all (select tag1 from t2 limit 0) intersect all (select tag1 from t3)",
"LIMIT row count must be greater than 0 (actual value: 0)");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,83 +19,39 @@

package org.apache.iotdb.db.queryengine.plan.relational.analyzer;

import org.apache.iotdb.db.queryengine.plan.relational.planner.PlanTester;

import org.junit.Test;

import static org.apache.iotdb.db.queryengine.plan.relational.planner.assertions.PlanAssert.assertPlan;
import static org.apache.iotdb.db.queryengine.plan.relational.planner.assertions.PlanMatchPattern.aggregation;
import static org.apache.iotdb.db.queryengine.plan.relational.planner.assertions.PlanMatchPattern.filter;
import static org.apache.iotdb.db.queryengine.plan.relational.planner.assertions.PlanMatchPattern.limit;
import static org.apache.iotdb.db.queryengine.plan.relational.planner.assertions.PlanMatchPattern.output;
import static org.apache.iotdb.db.queryengine.plan.relational.planner.assertions.PlanMatchPattern.project;
import static org.apache.iotdb.db.queryengine.plan.relational.planner.assertions.PlanMatchPattern.sort;
import static org.apache.iotdb.db.queryengine.plan.relational.planner.assertions.PlanMatchPattern.tableScan;
import static org.apache.iotdb.db.queryengine.plan.relational.planner.assertions.PlanMatchPattern.union;
import static org.apache.iotdb.db.queryengine.plan.relational.planner.assertions.PlanMatchPattern.window;
import static org.apache.iotdb.db.queryengine.plan.relational.analyzer.TestUtils.assertAnalyzeSemanticException;

public class RemoveEmptyExceptBranchesTest {

@Test
public void removeEmptyExceptBranchesTest1() {
// Normal case
assertPlan(
new PlanTester()
.createPlan(
"(select tag1 from t1 limit 0) except (select tag1 from t2) except (select tag1 from t3)"),
output((limit(0, tableScan("testdb.t1")))));

assertPlan(
new PlanTester()
.createPlan(
"(select tag1 from t1 limit 0) except all (select tag1 from t2) except all (select tag1 from t3)"),
output((limit(0, tableScan("testdb.t1")))));
assertAnalyzeSemanticException(
"(select tag1 from t1 limit 0) except (select tag1 from t2) except (select tag1 from t3)",
"LIMIT row count must be greater than 0 (actual value: 0)");
assertAnalyzeSemanticException(
"(select tag1 from t1 limit 0) except all (select tag1 from t2) except all (select tag1 from t3)",
"LIMIT row count must be greater than 0 (actual value: 0)");
}

@Test
public void removeEmptyExceptBranchesTest2() {
// Normal case
assertPlan(
new PlanTester()
.createPlan(
"(select tag1 from t1 ) except (select tag1 from t2 limit 0) except (select tag1 from t3 limit 0)"),
output(aggregation(tableScan("testdb.t1"))));

assertPlan(
new PlanTester()
.createPlan(
"(select tag1 from t1) except all (select tag1 from t2 limit 0) except all (select tag1 from t3 limit 0)"),
output((tableScan("testdb.t1"))));
assertAnalyzeSemanticException(
"(select tag1 from t1) except (select tag1 from t2 limit 0) except (select tag1 from t3 limit 0)",
"LIMIT row count must be greater than 0 (actual value: 0)");
assertAnalyzeSemanticException(
"(select tag1 from t1) except all (select tag1 from t2 limit 0) except all (select tag1 from t3 limit 0)",
"LIMIT row count must be greater than 0 (actual value: 0)");
}

@Test
public void removeEmptyExceptBranchesTest3() {
// Normal case
assertPlan(
new PlanTester()
.createPlan(
"(select tag1 from t1) except (select tag1 from t2) except (select tag1 from t3 limit 0)"),
output(
aggregation(
project(
filter(
aggregation(
union(
project(tableScan("testdb.t1")),
project(tableScan("testdb.t2")))))))));

assertPlan(
new PlanTester()
.createPlan(
"(select tag1 from t1) except all (select tag1 from t2 ) except all (select tag1 from t3 limit 0)"),
output(
project(
filter(
project(
window(
sort(
union(
project(tableScan("testdb.t1")),
project(tableScan("testdb.t2"))))))))));
assertAnalyzeSemanticException(
"(select tag1 from t1) except (select tag1 from t2) except (select tag1 from t3 limit 0)",
"LIMIT row count must be greater than 0 (actual value: 0)");
assertAnalyzeSemanticException(
"(select tag1 from t1) except all (select tag1 from t2) except all (select tag1 from t3 limit 0)",
"LIMIT row count must be greater than 0 (actual value: 0)");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import static org.apache.iotdb.db.queryengine.plan.relational.analyzer.TestUtils.QUERY_CONTEXT;
import static org.apache.iotdb.db.queryengine.plan.relational.analyzer.TestUtils.SESSION_INFO;
import static org.apache.iotdb.db.queryengine.plan.relational.analyzer.TestUtils.TEST_MATADATA;
import static org.apache.iotdb.db.queryengine.plan.relational.analyzer.TestUtils.assertAnalyzeSemanticException;
import static org.apache.iotdb.db.queryengine.plan.relational.planner.assertions.PlanAssert.assertPlan;
import static org.apache.iotdb.db.queryengine.plan.relational.planner.assertions.PlanMatchPattern.limit;
import static org.apache.iotdb.db.queryengine.plan.relational.planner.assertions.PlanMatchPattern.output;
Expand Down Expand Up @@ -128,31 +129,22 @@ public void pushTopKThroughUnionTest() {

@Test
public void removeEmptyUnionBranchesTest1() {
// Normal case
assertPlan(
new PlanTester()
.createPlan(
"(select tag1 from t1 limit 0) union all (select tag1 from t2) union all (select tag1 from t3)"),
output((union(tableScan("testdb.t2"), tableScan("testdb.t3")))));
assertAnalyzeSemanticException(
"(select tag1 from t1 limit 0) union all (select tag1 from t2) union all (select tag1 from t3)",
"LIMIT row count must be greater than 0 (actual value: 0)");
}

@Test
public void removeEmptyUnionBranchesTest2() {
// One non-empty branch
assertPlan(
new PlanTester()
.createPlan(
"(select tag1 from t1 limit 0) union all (select tag1 from t2 limit 0) union all (select tag1 from t3 limit 1)"),
output(limit(1, tableScan("testdb.t3"))));
assertAnalyzeSemanticException(
"(select tag1 from t1 limit 0) union all (select tag1 from t2 limit 0) union all (select tag1 from t3 limit 1)",
"LIMIT row count must be greater than 0 (actual value: 0)");
}

@Test
public void removeEmptyUnionBranchesTest3() {
// All branches are empty
assertPlan(
new PlanTester()
.createPlan(
"(select tag1 from t1 limit 0) union all (select tag1 from t2 limit 0) union all (select tag1 from t3 limit 0)"),
output(limit(0, tableScan("testdb.t1"))));
assertAnalyzeSemanticException(
"(select tag1 from t1 limit 0) union all (select tag1 from t2 limit 0) union all (select tag1 from t3 limit 0)",
"LIMIT row count must be greater than 0 (actual value: 0)");
}
}
Loading