fix tests

This commit is contained in:
chertus 2019-03-12 16:17:17 +03:00
parent 114e55c956
commit b76e3ad1c4
2 changed files with 43 additions and 14 deletions

View File

@ -1,4 +1,6 @@
#include <Common/typeid_cast.h> #include <Common/typeid_cast.h>
#include <Functions/FunctionsComparison.h>
#include <Functions/FunctionsLogical.h>
#include <Interpreters/CrossToInnerJoinVisitor.h> #include <Interpreters/CrossToInnerJoinVisitor.h>
#include <Interpreters/DatabaseAndTableWithAlias.h> #include <Interpreters/DatabaseAndTableWithAlias.h>
#include <Interpreters/IdentifierSemantic.h> #include <Interpreters/IdentifierSemantic.h>
@ -29,6 +31,8 @@ struct JoinedTable
DatabaseAndTableWithAlias table; DatabaseAndTableWithAlias table;
ASTTablesInSelectQueryElement * element = nullptr; ASTTablesInSelectQueryElement * element = nullptr;
ASTTableJoin * join = nullptr; ASTTableJoin * join = nullptr;
ASTPtr array_join = nullptr;
bool has_using = false;
JoinedTable(ASTPtr table_element) JoinedTable(ASTPtr table_element)
{ {
@ -47,11 +51,16 @@ struct JoinedTable
} }
if (join->using_expression_list) if (join->using_expression_list)
throw Exception("Multiple CROSS/COMMA JOIN do not support USING", ErrorCodes::NOT_IMPLEMENTED); has_using = true;
} }
auto & expr = typeid_cast<const ASTTableExpression &>(*element->table_expression); if (element->table_expression)
table = DatabaseAndTableWithAlias(expr); {
auto & expr = typeid_cast<const ASTTableExpression &>(*element->table_expression);
table = DatabaseAndTableWithAlias(expr);
}
array_join = element->array_join;
} }
void rewriteCommaToCross() void rewriteCommaToCross()
@ -63,6 +72,16 @@ struct JoinedTable
bool canAttachOnExpression() const { return join && !join->on_expression; } bool canAttachOnExpression() const { return join && !join->on_expression; }
}; };
bool isComparison(const String & name)
{
return name == NameEquals::name ||
name == NameNotEquals::name ||
name == NameLess::name ||
name == NameGreater::name ||
name == NameLessOrEquals::name ||
name == NameGreaterOrEquals::name;
}
/// It checks if where expression could be moved to JOIN ON expression partially or entirely. /// It checks if where expression could be moved to JOIN ON expression partially or entirely.
class CheckExpressionVisitorData class CheckExpressionVisitorData
{ {
@ -79,7 +98,7 @@ public:
if (!ands_only) if (!ands_only)
return; return;
if (node.name == "and") if (node.name == NameAnd::name)
{ {
if (!node.arguments || node.arguments->children.empty()) if (!node.arguments || node.arguments->children.empty())
throw Exception("Logical error: function requires argiment", ErrorCodes::LOGICAL_ERROR); throw Exception("Logical error: function requires argiment", ErrorCodes::LOGICAL_ERROR);
@ -92,11 +111,15 @@ public:
ands_only = false; ands_only = false;
} }
} }
else if (node.name == "equals") else if (node.name == NameEquals::name)
{ {
if (size_t min_table = canMoveEqualsToJoinOn(node)) if (size_t min_table = canMoveEqualsToJoinOn(node))
asts_to_join_on[min_table].push_back(ast); asts_to_join_on[min_table].push_back(ast);
} }
else if (isComparison(node.name))
{
/// leave other comparisons as is
}
else else
{ {
ands_only = false; ands_only = false;
@ -122,7 +145,7 @@ public:
for (auto & ast : expressions) for (auto & ast : expressions)
arguments.emplace_back(ast->clone()); arguments.emplace_back(ast->clone());
return makeASTFunction("and", std::move(arguments)); return makeASTFunction(NameAnd::name, std::move(arguments));
} }
private: private:
@ -202,8 +225,14 @@ bool getTables(ASTSelectQuery & select, std::vector<JoinedTable> & joined_tables
for (auto & child : tables->children) for (auto & child : tables->children)
{ {
joined_tables.emplace_back(JoinedTable(child)); joined_tables.emplace_back(JoinedTable(child));
JoinedTable & t = joined_tables.back();
if (t.array_join)
return false;
if (ASTTableJoin * join = joined_tables.back().join) if (num_tables > 2 && t.has_using)
throw Exception("Multiple CROSS/COMMA JOIN do not support USING", ErrorCodes::NOT_IMPLEMENTED);
if (ASTTableJoin * join = t.join)
if (join->kind == ASTTableJoin::Kind::Comma) if (join->kind == ASTTableJoin::Kind::Comma)
++num_comma; ++num_comma;
} }

View File

@ -57,25 +57,25 @@ comma nullable
2 2 1 2 2 2 1 2
cross cross
SELECT \n a, \n b, \n t2.a, \n t2.b\nFROM t1 \nCROSS JOIN t2 \nWHERE a = t2.a SELECT \n a, \n b, \n t2.a, \n t2.b\nFROM t1 \nCROSS JOIN t2 \nWHERE a = t2.a
SELECT *\nFROM t1 \nALL INNER JOIN t2 ON t1.a = t2.a SELECT \n a, \n b, \n t2.a, \n t2.b\nFROM t1 \nALL INNER JOIN t2 ON a = t2.a\nWHERE a = t2.a
cross nullable cross nullable
SELECT \n a, \n b, \n t2.a, \n t2.b\nFROM t1 \n, t2 \nWHERE a = t2.a SELECT \n a, \n b, \n t2.a, \n t2.b\nFROM t1 \n, t2 \nWHERE a = t2.a
SELECT *\nFROM t1 \nALL INNER JOIN t2 ON t1.a = t2.a SELECT \n a, \n b, \n t2.a, \n t2.b\nFROM t1 \nALL INNER JOIN t2 ON a = t2.a\nWHERE a = t2.a
cross nullable vs not nullable cross nullable vs not nullable
SELECT \n a, \n b, \n t2.a, \n t2.b\nFROM t1 \nCROSS JOIN t2 \nWHERE a = t2.b SELECT \n a, \n b, \n t2.a, \n t2.b\nFROM t1 \nCROSS JOIN t2 \nWHERE a = t2.b
SELECT *\nFROM t1 \nALL INNER JOIN t2 ON t1.a = t2.b SELECT \n a, \n b, \n t2.a, \n t2.b\nFROM t1 \nALL INNER JOIN t2 ON a = t2.b\nWHERE a = t2.b
cross self cross self
SELECT \n a, \n b, \n y.a, \n y.b\nFROM t1 AS x \nCROSS JOIN t1 AS y \nWHERE (a = y.a) AND (b = y.b) SELECT \n a, \n b, \n y.a, \n y.b\nFROM t1 AS x \nCROSS JOIN t1 AS y \nWHERE (a = y.a) AND (b = y.b)
SELECT *\nFROM t1 AS x \nALL INNER JOIN t1 AS y ON (x.a = y.a) AND (x.b = y.b) SELECT \n a, \n b, \n y.a, \n y.b\nFROM t1 AS x \nALL INNER JOIN t1 AS y ON (a = y.a) AND (b = y.b)\nWHERE (a = y.a) AND (b = y.b)
cross one table expr cross one table expr
SELECT \n a, \n b, \n t2.a, \n t2.b\nFROM t1 \nCROSS JOIN t2 \nWHERE a = b SELECT \n a, \n b, \n t2.a, \n t2.b\nFROM t1 \nCROSS JOIN t2 \nWHERE a = b
SELECT \n a, \n b, \n t2.a, \n t2.b\nFROM t1 \nCROSS JOIN t2 \nWHERE a = b SELECT \n a, \n b, \n t2.a, \n t2.b\nFROM t1 \nCROSS JOIN t2 \nWHERE a = b
cross multiple ands cross multiple ands
SELECT \n a, \n b, \n t2.a, \n t2.b\nFROM t1 \nCROSS JOIN t2 \nWHERE (a = t2.a) AND (b = t2.b) SELECT \n a, \n b, \n t2.a, \n t2.b\nFROM t1 \nCROSS JOIN t2 \nWHERE (a = t2.a) AND (b = t2.b)
SELECT *\nFROM t1 \nALL INNER JOIN t2 ON (t1.a = t2.a) AND (t1.b = t2.b) SELECT \n a, \n b, \n t2.a, \n t2.b\nFROM t1 \nALL INNER JOIN t2 ON (a = t2.a) AND (b = t2.b)\nWHERE (a = t2.a) AND (b = t2.b)
cross and inside and cross and inside and
SELECT \n a, \n b, \n t2.a, \n t2.b\nFROM t1 \nCROSS JOIN t2 \nWHERE (a = t2.a) AND ((a = t2.a) AND ((a = t2.a) AND (b = t2.b))) SELECT \n a, \n b, \n t2.a, \n t2.b\nFROM t1 \nCROSS JOIN t2 \nWHERE (a = t2.a) AND ((a = t2.a) AND ((a = t2.a) AND (b = t2.b)))
SELECT *\nFROM t1 \nALL INNER JOIN t2 ON (t1.a = t2.a) AND (t1.a = t2.a) AND (t1.a = t2.a) AND (t1.b = t2.b) SELECT \n a, \n b, \n t2.a, \n t2.b\nFROM t1 \nALL INNER JOIN t2 ON (a = t2.a) AND (a = t2.a) AND (a = t2.a) AND (b = t2.b)\nWHERE (a = t2.a) AND ((a = t2.a) AND ((a = t2.a) AND (b = t2.b)))
cross split conjunction cross split conjunction
SELECT \n a, \n b, \n t2.a, \n t2.b\nFROM t1 \nCROSS JOIN t2 \nWHERE (a = t2.a) AND (b = t2.b) AND (a >= 1) AND (t2.b > 0) SELECT \n a, \n b, \n t2.a, \n t2.b\nFROM t1 \nCROSS JOIN t2 \nWHERE (a = t2.a) AND (b = t2.b) AND (a >= 1) AND (t2.b > 0)
SELECT *\nFROM t1 \nALL INNER JOIN t2 ON (t1.a = t2.a) AND (t1.b = t2.b)\nWHERE (t1.a = t2.a) AND (t1.b = t2.b) AND (t1.a >= 1) AND (t2.b > 0) SELECT \n a, \n b, \n t2.a, \n t2.b\nFROM t1 \nALL INNER JOIN t2 ON (a = t2.a) AND (b = t2.b)\nWHERE (a = t2.a) AND (b = t2.b) AND (a >= 1) AND (t2.b > 0)