This commit is contained in:
Antonio Andelic 2023-03-17 08:08:07 +00:00
parent 3210331480
commit d6efe7fc21
8 changed files with 164 additions and 41 deletions

View File

@ -9,11 +9,11 @@
using namespace DB; using namespace DB;
static ComparisonGraph getGraph(const String & query) static ComparisonGraph<> getGraph(const String & query)
{ {
ParserExpressionList parser(false); ParserExpressionList parser(false);
ASTPtr ast = parseQuery(parser, query, 0, 0); ASTPtr ast = parseQuery(parser, query, 0, 0);
return ComparisonGraph(ast->children); return ComparisonGraph<>(ast->children);
} }
TEST(ComparisonGraph, Bounds) TEST(ComparisonGraph, Bounds)
@ -47,8 +47,8 @@ TEST(ComparisonGraph, Bounds)
auto x = std::make_shared<ASTIdentifier>("x"); auto x = std::make_shared<ASTIdentifier>("x");
auto y = std::make_shared<ASTIdentifier>("y"); auto y = std::make_shared<ASTIdentifier>("y");
ASSERT_EQ(graph.compare(x, y), ComparisonGraph::CompareResult::LESS); ASSERT_EQ(graph.compare(x, y), ComparisonGraphCompareResult::LESS);
ASSERT_EQ(graph.compare(y, x), ComparisonGraph::CompareResult::GREATER); ASSERT_EQ(graph.compare(y, x), ComparisonGraphCompareResult::GREATER);
} }
} }
@ -93,7 +93,7 @@ TEST(ComparisonGraph, Components)
TEST(ComparisonGraph, Compare) TEST(ComparisonGraph, Compare)
{ {
using CompareResult = ComparisonGraph::CompareResult; using enum ComparisonGraphCompareResult;
{ {
String query = "a >= b, c >= b"; String query = "a >= b, c >= b";
@ -102,7 +102,7 @@ TEST(ComparisonGraph, Compare)
auto a = std::make_shared<ASTIdentifier>("a"); auto a = std::make_shared<ASTIdentifier>("a");
auto c = std::make_shared<ASTIdentifier>("c"); auto c = std::make_shared<ASTIdentifier>("c");
ASSERT_EQ(graph.compare(a, c), CompareResult::UNKNOWN); ASSERT_EQ(graph.compare(a, c), UNKNOWN);
} }
{ {
@ -113,9 +113,9 @@ TEST(ComparisonGraph, Compare)
auto b = std::make_shared<ASTIdentifier>("b"); auto b = std::make_shared<ASTIdentifier>("b");
auto c = std::make_shared<ASTIdentifier>("c"); auto c = std::make_shared<ASTIdentifier>("c");
ASSERT_EQ(graph.compare(a, c), CompareResult::GREATER); ASSERT_EQ(graph.compare(a, c), GREATER);
ASSERT_EQ(graph.compare(a, b), CompareResult::GREATER_OR_EQUAL); ASSERT_EQ(graph.compare(a, b), GREATER_OR_EQUAL);
ASSERT_EQ(graph.compare(b, c), CompareResult::GREATER); ASSERT_EQ(graph.compare(b, c), GREATER);
} }
{ {
@ -126,9 +126,9 @@ TEST(ComparisonGraph, Compare)
auto b = std::make_shared<ASTIdentifier>("b"); auto b = std::make_shared<ASTIdentifier>("b");
auto c = std::make_shared<ASTIdentifier>("c"); auto c = std::make_shared<ASTIdentifier>("c");
ASSERT_EQ(graph.compare(a, b), CompareResult::NOT_EQUAL); ASSERT_EQ(graph.compare(a, b), NOT_EQUAL);
ASSERT_EQ(graph.compare(a, c), CompareResult::GREATER); ASSERT_EQ(graph.compare(a, c), GREATER);
ASSERT_EQ(graph.compare(b, c), CompareResult::UNKNOWN); ASSERT_EQ(graph.compare(b, c), UNKNOWN);
} }
{ {
@ -154,17 +154,17 @@ TEST(ComparisonGraph, Compare)
auto lit_3 = std::make_shared<ASTLiteral>(3u); auto lit_3 = std::make_shared<ASTLiteral>(3u);
auto lit_4 = std::make_shared<ASTLiteral>(4u); auto lit_4 = std::make_shared<ASTLiteral>(4u);
ASSERT_EQ(graph.compare(lit_3, a), CompareResult::LESS_OR_EQUAL); ASSERT_EQ(graph.compare(lit_3, a), LESS_OR_EQUAL);
ASSERT_FALSE(graph.isAlwaysCompare(CompareResult::LESS, lit_3, a)); ASSERT_FALSE(graph.isAlwaysCompare(LESS, lit_3, a));
ASSERT_TRUE(graph.isAlwaysCompare(CompareResult::LESS, lit_2, a)); ASSERT_TRUE(graph.isAlwaysCompare(LESS, lit_2, a));
ASSERT_EQ(graph.compare(b, lit_2), CompareResult::GREATER); ASSERT_EQ(graph.compare(b, lit_2), GREATER);
ASSERT_EQ(graph.compare(b, lit_3), CompareResult::GREATER); ASSERT_EQ(graph.compare(b, lit_3), GREATER);
ASSERT_EQ(graph.compare(b, lit_4), CompareResult::UNKNOWN); ASSERT_EQ(graph.compare(b, lit_4), UNKNOWN);
ASSERT_EQ(graph.compare(d, lit_2), CompareResult::GREATER); ASSERT_EQ(graph.compare(d, lit_2), GREATER);
ASSERT_EQ(graph.compare(d, lit_3), CompareResult::GREATER_OR_EQUAL); ASSERT_EQ(graph.compare(d, lit_3), GREATER_OR_EQUAL);
ASSERT_EQ(graph.compare(d, lit_4), CompareResult::UNKNOWN); ASSERT_EQ(graph.compare(d, lit_4), UNKNOWN);
} }
{ {
@ -176,8 +176,8 @@ TEST(ComparisonGraph, Compare)
auto lit_3 = std::make_shared<ASTLiteral>(3); auto lit_3 = std::make_shared<ASTLiteral>(3);
auto lit_15 = std::make_shared<ASTLiteral>(15); auto lit_15 = std::make_shared<ASTLiteral>(15);
ASSERT_EQ(graph.compare(a, lit_8), CompareResult::UNKNOWN); ASSERT_EQ(graph.compare(a, lit_8), UNKNOWN);
ASSERT_EQ(graph.compare(a, lit_3), CompareResult::GREATER); ASSERT_EQ(graph.compare(a, lit_3), GREATER);
ASSERT_EQ(graph.compare(a, lit_15), CompareResult::LESS); ASSERT_EQ(graph.compare(a, lit_15), LESS);
} }
} }

View File

@ -38,8 +38,44 @@ WHERE (c > 100) OR (b > 100)
SELECT count() AS `count()` SELECT count() AS `count()`
FROM constraint_test_constants FROM constraint_test_constants
WHERE c > 100 WHERE c > 100
QUERY id: 0
PROJECTION COLUMNS
count() UInt64
PROJECTION
LIST id: 1, nodes: 1
FUNCTION id: 2, function_name: count, function_type: aggregate, result_type: UInt64
JOIN TREE
TABLE id: 3, table_name: default.constraint_test_constants
WHERE
FUNCTION id: 4, function_name: greater, function_type: ordinary, result_type: UInt8
ARGUMENTS
LIST id: 5, nodes: 2
COLUMN id: 6, column_name: c, result_type: Int64, source_id: 3
CONSTANT id: 7, constant_value: UInt64_100, constant_value_type: UInt8
SELECT count() AS `count()` SELECT count() AS `count()`
FROM constraint_test_constants FROM constraint_test_constants
WHERE c > 100 WHERE c > 100
QUERY id: 0
PROJECTION COLUMNS
count() UInt64
PROJECTION
LIST id: 1, nodes: 1
FUNCTION id: 2, function_name: count, function_type: aggregate, result_type: UInt64
JOIN TREE
TABLE id: 3, table_name: default.constraint_test_constants
WHERE
FUNCTION id: 4, function_name: greater, function_type: ordinary, result_type: UInt8
ARGUMENTS
LIST id: 5, nodes: 2
COLUMN id: 6, column_name: c, result_type: Int64, source_id: 3
CONSTANT id: 7, constant_value: UInt64_100, constant_value_type: UInt8
SELECT count() AS `count()` SELECT count() AS `count()`
FROM constraint_test_constants FROM constraint_test_constants
QUERY id: 0
PROJECTION COLUMNS
count() UInt64
PROJECTION
LIST id: 1, nodes: 1
FUNCTION id: 2, function_name: count, function_type: aggregate, result_type: UInt64
JOIN TREE
TABLE id: 3, table_name: default.constraint_test_constants

View File

@ -98,8 +98,12 @@ SELECT count() FROM constraint_test_constants WHERE 11 <= a; ---> assumption ->
-- A AND NOT A -- A AND NOT A
EXPLAIN SYNTAX SELECT count() FROM constraint_test_constants WHERE (a > 100 OR b > 100 OR c > 100) AND (a <= 100 OR b > 100 OR c > 100); EXPLAIN SYNTAX SELECT count() FROM constraint_test_constants WHERE (a > 100 OR b > 100 OR c > 100) AND (a <= 100 OR b > 100 OR c > 100);
-- EXPLAIN QUERY TREE SELECT count() FROM constraint_test_constants WHERE (a > 100 OR b > 100 OR c > 100) AND (a <= 100 OR b > 100 OR c > 100); ---> the order of the generated checks is not consistent
EXPLAIN SYNTAX SELECT count() FROM constraint_test_constants WHERE (a > 100 OR b > 100 OR c > 100) AND (a <= 100 OR b > 100 OR c > 100) AND (NOT b > 100 OR c > 100); EXPLAIN SYNTAX SELECT count() FROM constraint_test_constants WHERE (a > 100 OR b > 100 OR c > 100) AND (a <= 100 OR b > 100 OR c > 100) AND (NOT b > 100 OR c > 100);
EXPLAIN QUERY TREE SELECT count() FROM constraint_test_constants WHERE (a > 100 OR b > 100 OR c > 100) AND (a <= 100 OR b > 100 OR c > 100) AND (NOT b > 100 OR c > 100);
EXPLAIN SYNTAX SELECT count() FROM constraint_test_constants WHERE (a > 100 OR b > 100 OR c > 100) AND (a <= 100 OR b > 100 OR c > 100) AND (NOT b > 100 OR c > 100) AND (c > 100); EXPLAIN SYNTAX SELECT count() FROM constraint_test_constants WHERE (a > 100 OR b > 100 OR c > 100) AND (a <= 100 OR b > 100 OR c > 100) AND (NOT b > 100 OR c > 100) AND (c > 100);
EXPLAIN QUERY TREE SELECT count() FROM constraint_test_constants WHERE (a > 100 OR b > 100 OR c > 100) AND (a <= 100 OR b > 100 OR c > 100) AND (NOT b > 100 OR c > 100) AND (c > 100);
EXPLAIN SYNTAX SELECT count() FROM constraint_test_constants WHERE (a > 100 OR b > 100 OR c > 100) AND (a <= 100 OR b > 100 OR c > 100) AND (NOT b > 100 OR c > 100) AND (c <= 100); EXPLAIN SYNTAX SELECT count() FROM constraint_test_constants WHERE (a > 100 OR b > 100 OR c > 100) AND (a <= 100 OR b > 100 OR c > 100) AND (NOT b > 100 OR c > 100) AND (c <= 100);
EXPLAIN QUERY TREE SELECT count() FROM constraint_test_constants WHERE (a > 100 OR b > 100 OR c > 100) AND (a <= 100 OR b > 100 OR c > 100) AND (NOT b > 100 OR c > 100) AND (c <= 100);
DROP TABLE constraint_test_constants; DROP TABLE constraint_test_constants;

View File

@ -1,14 +1,66 @@
SELECT count() SELECT count()
FROM t_constraints_where FROM t_constraints_where
WHERE 0 WHERE 0
QUERY id: 0
PROJECTION COLUMNS
count() UInt64
PROJECTION
LIST id: 1, nodes: 1
FUNCTION id: 2, function_name: count, function_type: aggregate, result_type: UInt64
JOIN TREE
TABLE id: 3, table_name: default.t_constraints_where
WHERE
CONSTANT id: 4, constant_value: UInt64_0, constant_value_type: UInt8
SELECT count() SELECT count()
FROM t_constraints_where FROM t_constraints_where
WHERE 0 WHERE 0
QUERY id: 0
PROJECTION COLUMNS
count() UInt64
PROJECTION
LIST id: 1, nodes: 1
FUNCTION id: 2, function_name: count, function_type: aggregate, result_type: UInt64
JOIN TREE
TABLE id: 3, table_name: default.t_constraints_where
WHERE
CONSTANT id: 4, constant_value: UInt64_0, constant_value_type: UInt8
SELECT count() SELECT count()
FROM t_constraints_where FROM t_constraints_where
WHERE 0 WHERE 0
QUERY id: 0
PROJECTION COLUMNS
count() UInt64
PROJECTION
LIST id: 1, nodes: 1
FUNCTION id: 2, function_name: count, function_type: aggregate, result_type: UInt64
JOIN TREE
TABLE id: 3, table_name: default.t_constraints_where
WHERE
CONSTANT id: 4, constant_value: UInt64_0, constant_value_type: UInt8
SELECT count() SELECT count()
FROM t_constraints_where FROM t_constraints_where
WHERE b < 8 WHERE b < 8
QUERY id: 0
PROJECTION COLUMNS
count() UInt64
PROJECTION
LIST id: 1, nodes: 1
FUNCTION id: 2, function_name: count, function_type: aggregate, result_type: UInt64
JOIN TREE
TABLE id: 3, table_name: default.t_constraints_where
WHERE
FUNCTION id: 4, function_name: less, function_type: ordinary, result_type: UInt8
ARGUMENTS
LIST id: 5, nodes: 2
COLUMN id: 6, column_name: b, result_type: UInt32, source_id: 3
CONSTANT id: 7, constant_value: UInt64_8, constant_value_type: UInt8
SELECT count() SELECT count()
FROM t_constraints_where FROM t_constraints_where
QUERY id: 0
PROJECTION COLUMNS
count() UInt64
PROJECTION
LIST id: 1, nodes: 1
FUNCTION id: 2, function_name: count, function_type: aggregate, result_type: UInt64
JOIN TREE
TABLE id: 3, table_name: default.t_constraints_where

View File

@ -8,9 +8,13 @@ CREATE TABLE t_constraints_where(a UInt32, b UInt32, CONSTRAINT c1 ASSUME b >= 5
INSERT INTO t_constraints_where VALUES (1, 7); INSERT INTO t_constraints_where VALUES (1, 7);
EXPLAIN SYNTAX SELECT count() FROM t_constraints_where WHERE b > 15; -- assumption -> 0 EXPLAIN SYNTAX SELECT count() FROM t_constraints_where WHERE b > 15; -- assumption -> 0
EXPLAIN QUERY TREE SELECT count() FROM t_constraints_where WHERE b > 15; -- assumption -> 0
EXPLAIN SYNTAX SELECT count() FROM t_constraints_where WHERE b = 20; -- assumption -> 0 EXPLAIN SYNTAX SELECT count() FROM t_constraints_where WHERE b = 20; -- assumption -> 0
EXPLAIN QUERY TREE SELECT count() FROM t_constraints_where WHERE b = 20; -- assumption -> 0
EXPLAIN SYNTAX SELECT count() FROM t_constraints_where WHERE b < 2; -- assumption -> 0 EXPLAIN SYNTAX SELECT count() FROM t_constraints_where WHERE b < 2; -- assumption -> 0
EXPLAIN QUERY TREE SELECT count() FROM t_constraints_where WHERE b < 2; -- assumption -> 0
EXPLAIN SYNTAX SELECT count() FROM t_constraints_where WHERE b > 20 OR b < 8; -- assumption -> remove (b < 20) EXPLAIN SYNTAX SELECT count() FROM t_constraints_where WHERE b > 20 OR b < 8; -- assumption -> remove (b < 20)
EXPLAIN QUERY TREE SELECT count() FROM t_constraints_where WHERE b > 20 OR b < 8; -- assumption -> remove (b < 20)
DROP TABLE t_constraints_where; DROP TABLE t_constraints_where;
@ -19,5 +23,6 @@ CREATE TABLE t_constraints_where(a UInt32, b UInt32, CONSTRAINT c1 ASSUME b < 10
INSERT INTO t_constraints_where VALUES (1, 7); INSERT INTO t_constraints_where VALUES (1, 7);
EXPLAIN SYNTAX SELECT count() FROM t_constraints_where WHERE b = 1 OR b < 18 OR b > 5; -- assumption -> (b < 20) -> 0; EXPLAIN SYNTAX SELECT count() FROM t_constraints_where WHERE b = 1 OR b < 18 OR b > 5; -- assumption -> (b < 20) -> 0;
EXPLAIN QUERY TREE SELECT count() FROM t_constraints_where WHERE b = 1 OR b < 18 OR b > 5; -- assumption -> (b < 20) -> 0;
DROP TABLE t_constraints_where; DROP TABLE t_constraints_where;

View File

@ -2,14 +2,22 @@ SELECT i AS i
FROM index_append_test_test FROM index_append_test_test
PREWHERE a = 0 PREWHERE a = 0
WHERE (a = 0) AND indexHint((i + 40) > 0) WHERE (a = 0) AND indexHint((i + 40) > 0)
SETTINGS convert_query_to_cnf = 1, optimize_using_constraints = 1, optimize_move_to_prewhere = 1, optimize_substitute_columns = 1, optimize_append_index = 1
1
SELECT i AS i SELECT i AS i
FROM index_append_test_test FROM index_append_test_test
PREWHERE a < 0 PREWHERE a < 0
SETTINGS convert_query_to_cnf = 1, optimize_using_constraints = 1, optimize_move_to_prewhere = 1, optimize_substitute_columns = 1, optimize_append_index = 1
0
SELECT i AS i SELECT i AS i
FROM index_append_test_test FROM index_append_test_test
PREWHERE a >= 0 PREWHERE a >= 0
WHERE (a >= 0) AND indexHint((i + 40) > 0) WHERE (a >= 0) AND indexHint((i + 40) > 0)
SETTINGS convert_query_to_cnf = 1, optimize_using_constraints = 1, optimize_move_to_prewhere = 1, optimize_substitute_columns = 1, optimize_append_index = 1
1
SELECT i AS i SELECT i AS i
FROM index_append_test_test FROM index_append_test_test
PREWHERE (2 * b) < 100 PREWHERE (2 * b) < 100
WHERE ((2 * b) < 100) AND indexHint(i < 100) WHERE ((2 * b) < 100) AND indexHint(i < 100)
SETTINGS convert_query_to_cnf = 1, optimize_using_constraints = 1, optimize_move_to_prewhere = 1, optimize_substitute_columns = 1, optimize_append_index = 1
1

View File

@ -0,0 +1,35 @@
#!/usr/bin/env bash
CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
# shellcheck source=../shell_config.sh
. "$CURDIR"/../shell_config.sh
# We should have correct env vars from shell_config.sh to run this test
$CLICKHOUSE_CLIENT --query "DROP TABLE IF EXISTS index_append_test_test;"
$CLICKHOUSE_CLIENT --query "CREATE TABLE index_append_test_test (i Int64, a UInt32, b UInt64, CONSTRAINT c1 ASSUME i <= 2 * b AND i + 40 > a) ENGINE = MergeTree() ORDER BY i;"
$CLICKHOUSE_CLIENT --query "INSERT INTO index_append_test_test VALUES (1, 10, 1), (2, 20, 2);"
function run_with_settings()
{
query="$1 SETTINGS convert_query_to_cnf = 1\
, optimize_using_constraints = 1\
, optimize_move_to_prewhere = 1\
, optimize_substitute_columns = 1\
, optimize_append_index = 1"
$CLICKHOUSE_CLIENT --query="$query"
}
run_with_settings "EXPLAIN SYNTAX SELECT i FROM index_append_test_test WHERE a = 0"
run_with_settings "EXPLAIN QUERY TREE SELECT i FROM index_append_test_test WHERE a = 0" | grep -Fac "indexHint"
run_with_settings "EXPLAIN SYNTAX SELECT i FROM index_append_test_test WHERE a < 0"
run_with_settings "EXPLAIN QUERY TREE SELECT i FROM index_append_test_test WHERE a < 0" | grep -Fac "indexHint"
run_with_settings "EXPLAIN SYNTAX SELECT i FROM index_append_test_test WHERE a >= 0"
run_with_settings "EXPLAIN QUERY TREE SELECT i FROM index_append_test_test WHERE a >= 0" | grep -Fac "indexHint"
run_with_settings "EXPLAIN SYNTAX SELECT i FROM index_append_test_test WHERE 2 * b < 100"
run_with_settings "EXPLAIN QUERY TREE SELECT i FROM index_append_test_test WHERE 2 * b < 100" | grep -Fac "indexHint"
$CLICKHOUSE_CLIENT --query "DROP TABLE index_append_test_test;"

View File

@ -1,17 +0,0 @@
SET convert_query_to_cnf = 1;
SET optimize_using_constraints = 1;
SET optimize_move_to_prewhere = 1;
SET optimize_substitute_columns = 1;
SET optimize_append_index = 1;
DROP TABLE IF EXISTS index_append_test_test;
CREATE TABLE index_append_test_test (i Int64, a UInt32, b UInt64, CONSTRAINT c1 ASSUME i <= 2 * b AND i + 40 > a) ENGINE = MergeTree() ORDER BY i;
INSERT INTO index_append_test_test VALUES (1, 10, 1), (2, 20, 2);
EXPLAIN SYNTAX SELECT i FROM index_append_test_test WHERE a = 0;
EXPLAIN SYNTAX SELECT i FROM index_append_test_test WHERE a < 0;
EXPLAIN SYNTAX SELECT i FROM index_append_test_test WHERE a >= 0;
EXPLAIN SYNTAX SELECT i FROM index_append_test_test WHERE 2 * b < 100;
DROP TABLE index_append_test_test;