Merge remote-tracking branch 'upstream/master'

This commit is contained in:
alesapin 2018-07-23 20:15:48 +03:00
commit 68309b75a8
5 changed files with 53 additions and 13 deletions

View File

@ -18,6 +18,9 @@ public:
DataTypes transformArguments(const DataTypes & arguments) const override 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; DataTypes nested_arguments;
for (const auto & type : arguments) for (const auto & type : arguments)
{ {

View File

@ -377,6 +377,7 @@ namespace ErrorCodes
extern const int CANNOT_STAT = 400; extern const int CANNOT_STAT = 400;
extern const int FEATURE_IS_NOT_ENABLED_AT_BUILD_TIME = 401; extern const int FEATURE_IS_NOT_ENABLED_AT_BUILD_TIME = 401;
extern const int CANNOT_IOSETUP = 402; extern const int CANNOT_IOSETUP = 402;
extern const int INVALID_JOIN_ON_EXPRESSION = 403;
extern const int KEEPER_EXCEPTION = 999; extern const int KEEPER_EXCEPTION = 999;

View File

@ -1011,10 +1011,11 @@ public:
DataTypePtr observed_type0 = removeNullable(array_type->getNestedType()); DataTypePtr observed_type0 = removeNullable(array_type->getNestedType());
DataTypePtr observed_type1 = removeNullable(arguments[1]); 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)) && !observed_type0->equals(*observed_type1))
throw Exception("Types of array and 2nd argument of function " 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() + ".", + arguments[0]->getName() + " and " + arguments[1]->getName() + ".",
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
} }

View File

@ -61,6 +61,7 @@
#include <DataTypes/DataTypeFunction.h> #include <DataTypes/DataTypeFunction.h>
#include <Functions/FunctionsMiscellaneous.h> #include <Functions/FunctionsMiscellaneous.h>
#include <DataTypes/DataTypeTuple.h> #include <DataTypes/DataTypeTuple.h>
#include <Parsers/queryToString.h>
namespace DB namespace DB
@ -89,6 +90,7 @@ namespace ErrorCodes
extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH; extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH;
extern const int CONDITIONAL_TREE_PARENT_NOT_FOUND; extern const int CONDITIONAL_TREE_PARENT_NOT_FOUND;
extern const int TYPE_MISMATCH; 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); 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) if (table_join.using_expression_list)
{ {
auto & keys = typeid_cast<ASTExpressionList &>(*table_join.using_expression_list); auto & keys = typeid_cast<ASTExpressionList &>(*table_join.using_expression_list);
for (const auto & key : keys.children) 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())) add_name_to_join_keys(join_key_names_left, key->getColumnName(), "in USING list");
join_key_names_left.push_back(key->getColumnName()); add_name_to_join_keys(join_key_names_right, key->getAliasOrColumnName(), "in USING list");
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);
} }
} }
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())) for (const auto i : ext::range(0, nested_result_sample.columns()))
{ {

View File

@ -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 medianTimingWeightedArray([CAST( 0 AS Int8)],arrayPopBack([CAST( 0 AS Int8)]));
SELECT quantilesDeterministicArray([CAST( 0 AS Int8)],arrayPopBack([CAST( 0 AS Int32)])); SELECT quantilesDeterministicArray([CAST( 0 AS Int8)],arrayPopBack([CAST( 0 AS Int32)]));
SELECT maxIntersections([], []) SELECT maxIntersections([], []);
SELECT sumMap([], []) SELECT sumMap([], []);
SELECT countArray();