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 <Functions/FunctionsComparison.h>
#include <Functions/FunctionsLogical.h>
#include <Interpreters/CrossToInnerJoinVisitor.h>
#include <Interpreters/DatabaseAndTableWithAlias.h>
#include <Interpreters/IdentifierSemantic.h>
@ -29,6 +31,8 @@ struct JoinedTable
DatabaseAndTableWithAlias table;
ASTTablesInSelectQueryElement * element = nullptr;
ASTTableJoin * join = nullptr;
ASTPtr array_join = nullptr;
bool has_using = false;
JoinedTable(ASTPtr table_element)
{
@ -47,13 +51,18 @@ struct JoinedTable
}
if (join->using_expression_list)
throw Exception("Multiple CROSS/COMMA JOIN do not support USING", ErrorCodes::NOT_IMPLEMENTED);
has_using = true;
}
if (element->table_expression)
{
auto & expr = typeid_cast<const ASTTableExpression &>(*element->table_expression);
table = DatabaseAndTableWithAlias(expr);
}
array_join = element->array_join;
}
void rewriteCommaToCross()
{
if (join)
@ -63,6 +72,16 @@ struct JoinedTable
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.
class CheckExpressionVisitorData
{
@ -79,7 +98,7 @@ public:
if (!ands_only)
return;
if (node.name == "and")
if (node.name == NameAnd::name)
{
if (!node.arguments || node.arguments->children.empty())
throw Exception("Logical error: function requires argiment", ErrorCodes::LOGICAL_ERROR);
@ -92,11 +111,15 @@ public:
ands_only = false;
}
}
else if (node.name == "equals")
else if (node.name == NameEquals::name)
{
if (size_t min_table = canMoveEqualsToJoinOn(node))
asts_to_join_on[min_table].push_back(ast);
}
else if (isComparison(node.name))
{
/// leave other comparisons as is
}
else
{
ands_only = false;
@ -122,7 +145,7 @@ public:
for (auto & ast : expressions)
arguments.emplace_back(ast->clone());
return makeASTFunction("and", std::move(arguments));
return makeASTFunction(NameAnd::name, std::move(arguments));
}
private:
@ -202,8 +225,14 @@ bool getTables(ASTSelectQuery & select, std::vector<JoinedTable> & joined_tables
for (auto & child : tables->children)
{
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)
++num_comma;
}

View File

@ -57,25 +57,25 @@ comma nullable
2 2 1 2
cross
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
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
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
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
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
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
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
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)