mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-26 17:41:59 +00:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
68309b75a8
@ -18,6 +18,9 @@ public:
|
||||
|
||||
DataTypes transformArguments(const DataTypes & arguments) const override
|
||||
{
|
||||
if (0 == arguments.size())
|
||||
throw Exception("-Array aggregate functions require at least one argument", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
|
||||
|
||||
DataTypes nested_arguments;
|
||||
for (const auto & type : arguments)
|
||||
{
|
||||
|
@ -377,6 +377,7 @@ namespace ErrorCodes
|
||||
extern const int CANNOT_STAT = 400;
|
||||
extern const int FEATURE_IS_NOT_ENABLED_AT_BUILD_TIME = 401;
|
||||
extern const int CANNOT_IOSETUP = 402;
|
||||
extern const int INVALID_JOIN_ON_EXPRESSION = 403;
|
||||
|
||||
|
||||
extern const int KEEPER_EXCEPTION = 999;
|
||||
|
@ -1011,10 +1011,11 @@ public:
|
||||
DataTypePtr observed_type0 = removeNullable(array_type->getNestedType());
|
||||
DataTypePtr observed_type1 = removeNullable(arguments[1]);
|
||||
|
||||
if (!(observed_type0->isNumber() && observed_type1->isNumber())
|
||||
/// We also support arrays of Enum type (that are represented by number) to search numeric values.
|
||||
if (!(observed_type0->isValueRepresentedByNumber() && observed_type1->isNumber())
|
||||
&& !observed_type0->equals(*observed_type1))
|
||||
throw Exception("Types of array and 2nd argument of function "
|
||||
+ getName() + " must be identical up to nullability. Passed: "
|
||||
+ getName() + " must be identical up to nullability or numeric types or Enum and numeric type. Passed: "
|
||||
+ arguments[0]->getName() + " and " + arguments[1]->getName() + ".",
|
||||
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||
}
|
||||
|
@ -61,6 +61,7 @@
|
||||
#include <DataTypes/DataTypeFunction.h>
|
||||
#include <Functions/FunctionsMiscellaneous.h>
|
||||
#include <DataTypes/DataTypeTuple.h>
|
||||
#include <Parsers/queryToString.h>
|
||||
|
||||
|
||||
namespace DB
|
||||
@ -89,6 +90,7 @@ namespace ErrorCodes
|
||||
extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH;
|
||||
extern const int CONDITIONAL_TREE_PARENT_NOT_FOUND;
|
||||
extern const int TYPE_MISMATCH;
|
||||
extern const int INVALID_JOIN_ON_EXPRESSION;
|
||||
}
|
||||
|
||||
|
||||
@ -2856,22 +2858,53 @@ void ExpressionAnalyzer::collectJoinedColumns(NameSet & joined_columns, NamesAnd
|
||||
nested_result_sample = InterpreterSelectWithUnionQuery::getSampleBlock(subquery, context);
|
||||
}
|
||||
|
||||
auto add_name_to_join_keys = [](Names & join_keys, const String & name, const char * where)
|
||||
{
|
||||
if (join_keys.end() == std::find(join_keys.begin(), join_keys.end(), name))
|
||||
join_keys.push_back(name);
|
||||
else
|
||||
throw Exception("Duplicate column " + name + " " + where, ErrorCodes::DUPLICATE_COLUMN);
|
||||
};
|
||||
|
||||
if (table_join.using_expression_list)
|
||||
{
|
||||
auto & keys = typeid_cast<ASTExpressionList &>(*table_join.using_expression_list);
|
||||
for (const auto & key : keys.children)
|
||||
{
|
||||
if (join_key_names_left.end() == std::find(join_key_names_left.begin(), join_key_names_left.end(), key->getColumnName()))
|
||||
join_key_names_left.push_back(key->getColumnName());
|
||||
else
|
||||
throw Exception("Duplicate column " + key->getColumnName() + " in USING list", ErrorCodes::DUPLICATE_COLUMN);
|
||||
|
||||
if (join_key_names_right.end() == std::find(join_key_names_right.begin(), join_key_names_right.end(), key->getAliasOrColumnName()))
|
||||
join_key_names_right.push_back(key->getAliasOrColumnName());
|
||||
else
|
||||
throw Exception("Duplicate column " + key->getAliasOrColumnName() + " in USING list", ErrorCodes::DUPLICATE_COLUMN);
|
||||
add_name_to_join_keys(join_key_names_left, key->getColumnName(), "in USING list");
|
||||
add_name_to_join_keys(join_key_names_right, key->getAliasOrColumnName(), "in USING list");
|
||||
}
|
||||
}
|
||||
else if (table_join.on_expression)
|
||||
{
|
||||
const auto supported_syntax =
|
||||
"\nSupported syntax: JOIN ON [table.]column = [table.]column [AND [table.]column = [table.]column ...]";
|
||||
auto throwSyntaxException = [&](const String & msg)
|
||||
{
|
||||
throw Exception("Invalid expression for JOIN ON. " + msg + supported_syntax, ErrorCodes::INVALID_JOIN_ON_EXPRESSION);
|
||||
};
|
||||
|
||||
auto add_columns_from_equals_expr = [&](const ASTPtr & expr)
|
||||
{
|
||||
auto * func_equals = typeid_cast<const ASTFunction *>(expr.get());
|
||||
if (!func_equals || func_equals->name != "equals")
|
||||
throwSyntaxException("Expected equals expression, got " + queryToString(expr));
|
||||
|
||||
String left_name = func_equals->arguments->children.at(0)->getAliasOrColumnName();
|
||||
String right_name = func_equals->arguments->children.at(1)->getAliasOrColumnName();
|
||||
add_name_to_join_keys(join_key_names_left, left_name, "in JOIN ON expression for left table");
|
||||
add_name_to_join_keys(join_key_names_right, right_name, "in JOIN ON expression for right table");
|
||||
};
|
||||
|
||||
auto * func = typeid_cast<const ASTFunction *>(table_join.on_expression.get());
|
||||
if (func && func->name == "and")
|
||||
{
|
||||
for (auto expr : func->children)
|
||||
add_columns_from_equals_expr(expr);
|
||||
}
|
||||
else
|
||||
add_columns_from_equals_expr(table_join.on_expression);
|
||||
}
|
||||
|
||||
for (const auto i : ext::range(0, nested_result_sample.columns()))
|
||||
{
|
||||
|
@ -428,5 +428,7 @@ SELECT COVAR_SAMPArray([CAST( 0 AS Int8)],arrayPopBack([CAST( 0 AS Int8)]));
|
||||
SELECT medianTimingWeightedArray([CAST( 0 AS Int8)],arrayPopBack([CAST( 0 AS Int8)]));
|
||||
SELECT quantilesDeterministicArray([CAST( 0 AS Int8)],arrayPopBack([CAST( 0 AS Int32)]));
|
||||
|
||||
SELECT maxIntersections([], [])
|
||||
SELECT sumMap([], [])
|
||||
SELECT maxIntersections([], []);
|
||||
SELECT sumMap([], []);
|
||||
|
||||
SELECT countArray();
|
||||
|
Loading…
Reference in New Issue
Block a user