mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-24 00:22:29 +00:00
fix
This commit is contained in:
parent
36562fdbbb
commit
1d9096c9ac
@ -19,6 +19,11 @@ namespace ErrorCodes
|
||||
namespace
|
||||
{
|
||||
|
||||
bool isDeterminedIdentifier(JoinIdentifierPos pos)
|
||||
{
|
||||
return pos == JoinIdentifierPos::Left || pos == JoinIdentifierPos::Right;
|
||||
}
|
||||
|
||||
bool isLeftIdentifier(JoinIdentifierPos pos)
|
||||
{
|
||||
/// Unknown identifiers considered as left, we will try to process it on later stages
|
||||
@ -79,7 +84,7 @@ void CollectJoinOnKeysMatcher::Data::asofToJoinKeys()
|
||||
|
||||
void CollectJoinOnKeysMatcher::visit(const ASTIdentifier & ident, const ASTPtr & ast, CollectJoinOnKeysMatcher::Data & data)
|
||||
{
|
||||
if (auto expr_from_table = getTableForIdentifiers(ast, false, data); expr_from_table != JoinIdentifierPos::Unknown)
|
||||
if (auto expr_from_table = getTableForIdentifiers(ast, false, data); isDeterminedIdentifier(expr_from_table))
|
||||
data.analyzed_join.addJoinCondition(ast, isLeftIdentifier(expr_from_table));
|
||||
else
|
||||
throw Exception("Unexpected identifier '" + ident.name() + "' in JOIN ON section",
|
||||
@ -105,27 +110,26 @@ void CollectJoinOnKeysMatcher::visit(const ASTFunction & func, const ASTPtr & as
|
||||
ASTPtr left = func.arguments->children.at(0);
|
||||
ASTPtr right = func.arguments->children.at(1);
|
||||
auto table_numbers = getTableNumbers(left, right, data);
|
||||
|
||||
if (table_numbers.first == table_numbers.second)
|
||||
{
|
||||
if (table_numbers.first == JoinIdentifierPos::Unknown)
|
||||
throw Exception("Ambiguous column in expression '" + queryToString(ast) + "' in JOIN ON section",
|
||||
ErrorCodes::AMBIGUOUS_COLUMN_NAME);
|
||||
if (!isDeterminedIdentifier(table_numbers.first))
|
||||
throw Exception(ErrorCodes::AMBIGUOUS_COLUMN_NAME,
|
||||
"Ambiguous columns in expression '{}' in JOIN ON section", queryToString(ast));
|
||||
data.analyzed_join.addJoinCondition(ast, isLeftIdentifier(table_numbers.first));
|
||||
return;
|
||||
}
|
||||
if ((table_numbers.first == JoinIdentifierPos::Left && table_numbers.second == JoinIdentifierPos::Right) ||
|
||||
(table_numbers.first == JoinIdentifierPos::Right && table_numbers.second == JoinIdentifierPos::Left))
|
||||
|
||||
if ((isLeftIdentifier(table_numbers.first) && isRightIdentifier(table_numbers.second)) ||
|
||||
(isRightIdentifier(table_numbers.first) && isLeftIdentifier(table_numbers.second)))
|
||||
{
|
||||
data.addJoinKeys(left, right, table_numbers);
|
||||
return;
|
||||
}
|
||||
|
||||
throw Exception(ErrorCodes::AMBIGUOUS_COLUMN_NAME,
|
||||
"Cannot detect left and right JOIN keys. JOIN ON section is ambiguous for expression '{}'", queryToString(ast));
|
||||
}
|
||||
|
||||
|
||||
if (auto expr_from_table = getTableForIdentifiers(ast, false, data); expr_from_table != JoinIdentifierPos::Unknown)
|
||||
if (auto expr_from_table = getTableForIdentifiers(ast, false, data); isDeterminedIdentifier(expr_from_table))
|
||||
{
|
||||
data.analyzed_join.addJoinCondition(ast, isLeftIdentifier(expr_from_table));
|
||||
return;
|
||||
@ -208,7 +212,7 @@ JoinIdentifierPos CollectJoinOnKeysMatcher::getTableForIdentifiers(const ASTPtr
|
||||
std::vector<const ASTIdentifier *> identifiers;
|
||||
getIdentifiers(ast, identifiers);
|
||||
if (identifiers.empty())
|
||||
return JoinIdentifierPos::Unknown;
|
||||
return JoinIdentifierPos::Constant;
|
||||
|
||||
JoinIdentifierPos table_number = JoinIdentifierPos::Unknown;
|
||||
|
||||
|
@ -32,6 +32,8 @@ enum class JoinIdentifierPos
|
||||
Left,
|
||||
/// Right side of JOIN
|
||||
Right,
|
||||
/// Identifier is not a column, but for example a constant
|
||||
Constant,
|
||||
};
|
||||
|
||||
using JoinIdentifierPosPair = std::pair<JoinIdentifierPos, JoinIdentifierPos>;
|
||||
|
@ -62,7 +62,6 @@ namespace ErrorCodes
|
||||
extern const int EMPTY_LIST_OF_COLUMNS_QUERIED;
|
||||
extern const int EMPTY_NESTED_TABLE;
|
||||
extern const int EXPECTED_ALL_OR_ANY;
|
||||
extern const int INCOMPATIBLE_TYPE_OF_JOIN;
|
||||
extern const int INVALID_JOIN_ON_EXPRESSION;
|
||||
extern const int LOGICAL_ERROR;
|
||||
extern const int NOT_IMPLEMENTED;
|
||||
@ -792,8 +791,8 @@ void collectJoinedColumns(TableJoin & analyzed_join, ASTTableJoin & table_join,
|
||||
|
||||
if (any_keys_empty)
|
||||
throw DB::Exception(ErrorCodes::INVALID_JOIN_ON_EXPRESSION,
|
||||
"Cannot get JOIN keys from JOIN ON section: '{}'",
|
||||
queryToString(table_join.on_expression));
|
||||
"Cannot get JOIN keys from JOIN ON section: '{}', found keys: {}",
|
||||
queryToString(table_join.on_expression), TableJoin::formatClauses(analyzed_join.getClauses()));
|
||||
|
||||
if (is_asof)
|
||||
{
|
||||
|
@ -43,7 +43,7 @@ JOIN system.one AS y USING dummy;
|
||||
SELECT * FROM ( SELECT [toUInt32(dummy), toUInt32(dummy)] AS dummy FROM system.one ) AS x ARRAY JOIN dummy
|
||||
JOIN (select toInt32(dummy) as dummy from system.one ) AS y USING dummy;
|
||||
|
||||
SELECT dummy > 0, toTypeName(any(dummy)), any(toTypeName(dummy))
|
||||
SELECT dummy > 0, toTypeName(any(dummy)), any(toTypeName(dummy))
|
||||
FROM ( SELECT [toUInt32(dummy), toUInt32(dummy)] AS dummy FROM system.one ) AS x ARRAY JOIN dummy
|
||||
JOIN ( SELECT toInt32(dummy) AS dummy FROM system.one ) AS y USING dummy GROUP BY (dummy > 0);
|
||||
|
||||
|
@ -33,11 +33,10 @@ SELECT * FROM (SELECT key3 AS c, key1 AS a, key2 AS b FROM t1) AS t1 ALL INNER J
|
||||
SELECT * FROM (SELECT key3 AS c, key1 AS a, key2 AS b FROM t1) AS t1 ALL INNER JOIN tj ON t1.a = tj.key1 AND t1.b = tj.key2 AND t1.c = tj.key3 ORDER BY t1.a;
|
||||
SELECT * FROM (SELECT key3 AS c, key1 AS a, key2 AS b FROM t1) AS t1 ALL INNER JOIN tj ON t1.c = tj.key3 AND t1.a = tj.key1 AND t1.b = tj.key2 ORDER BY t1.a;
|
||||
|
||||
-- TODO (vdimir): uncomment after https://github.com/ClickHouse/ClickHouse/pull/44016
|
||||
-- SELECT * FROM t1 ALL INNER JOIN tj ON t1.key1 = tj.key1 AND t1.key3 = tj.key3 AND t1.key2 = tj.key2 AND 1; -- { serverError INCOMPATIBLE_TYPE_OF_JOIN }
|
||||
-- SELECT * FROM t1 ALL INNER JOIN tj ON t1.key1 = tj.key1 AND t1.key3 = tj.key3 AND t1.key2 = tj.key2 AND 0; -- { serverError INCOMPATIBLE_TYPE_OF_JOIN }
|
||||
-- SELECT * FROM t1 ALL INNER JOIN tj ON t1.key1 = tj.key1 AND t1.key3 = tj.key3 AND t1.key2 = tj.key2 AND 1 == 1; -- { serverError INCOMPATIBLE_TYPE_OF_JOIN }
|
||||
-- SELECT * FROM t1 ALL INNER JOIN tj ON t1.key1 = tj.key1 AND t1.key3 = tj.key3 AND t1.key2 = tj.key2 AND 1 > 1; -- { serverError INCOMPATIBLE_TYPE_OF_JOIN }
|
||||
SELECT * FROM t1 ALL INNER JOIN tj ON t1.key1 = tj.key1 AND t1.key3 = tj.key3 AND t1.key2 = tj.key2 AND 1; -- { serverError INCOMPATIBLE_TYPE_OF_JOIN }
|
||||
SELECT * FROM t1 ALL INNER JOIN tj ON t1.key1 = tj.key1 AND t1.key3 = tj.key3 AND t1.key2 = tj.key2 AND 0; -- { serverError INCOMPATIBLE_TYPE_OF_JOIN }
|
||||
SELECT * FROM t1 ALL INNER JOIN tj ON t1.key1 = tj.key1 AND t1.key3 = tj.key3 AND t1.key2 = tj.key2 AND 1 == 1; -- { serverError INCOMPATIBLE_TYPE_OF_JOIN }
|
||||
SELECT * FROM t1 ALL INNER JOIN tj ON t1.key1 = tj.key1 AND t1.key3 = tj.key3 AND t1.key2 = tj.key2 AND 1 > 1; -- { serverError INCOMPATIBLE_TYPE_OF_JOIN }
|
||||
|
||||
SELECT '--- incompatible ---';
|
||||
SELECT * FROM t1 ALL INNER JOIN tj ON 1; -- { serverError INCOMPATIBLE_TYPE_OF_JOIN }
|
||||
@ -46,6 +45,13 @@ SELECT * FROM t1 ALL INNER JOIN tj ON NULL; -- { serverError INCOMPATIBLE_TYPE_O
|
||||
SELECT * FROM t1 ALL INNER JOIN tj ON 1 == 1; -- { serverError INCOMPATIBLE_TYPE_OF_JOIN }
|
||||
SELECT * FROM t1 ALL INNER JOIN tj ON 1 != 1; -- { serverError INCOMPATIBLE_TYPE_OF_JOIN }
|
||||
|
||||
-- Here is another error code because equality is handled differently in CollectJoinOnKeysVisitor.
|
||||
-- We can change the error code, but it will become inconsistent for other cases
|
||||
-- where we actually expect AMBIGUOUS_COLUMN_NAME instead of INVALID_JOIN_ON_EXPRESSION.
|
||||
-- These checks will be more reliable after switching to a new analyzer.
|
||||
SELECT * FROM t1 ALL INNER JOIN tj ON 1 == 1; -- { serverError AMBIGUOUS_COLUMN_NAME }
|
||||
SELECT * FROM t1 ALL INNER JOIN tj ON 1 == 2; -- { serverError AMBIGUOUS_COLUMN_NAME }
|
||||
|
||||
SELECT * FROM t1 ALL INNER JOIN tj USING (key2, key3); -- { serverError INCOMPATIBLE_TYPE_OF_JOIN }
|
||||
SELECT * FROM t1 ALL INNER JOIN tj USING (key1, key2, attr) SETTINGS allow_experimental_analyzer = 0; -- { serverError INCOMPATIBLE_TYPE_OF_JOIN }
|
||||
SELECT * FROM t1 ALL INNER JOIN tj USING (key1, key2, attr) SETTINGS allow_experimental_analyzer = 1; -- { serverError UNKNOWN_IDENTIFIER }
|
||||
|
Loading…
Reference in New Issue
Block a user