add setting aggregate_functions_null_for_empty

This commit is contained in:
feng lv 2020-10-18 20:18:31 +08:00
parent 6dc5cb166f
commit 5254a5ded7
4 changed files with 65 additions and 1 deletions

View File

@ -400,7 +400,8 @@ class IColumn;
M(Bool, optimize_trivial_insert_select, true, "Optimize trivial 'INSERT INTO table SELECT ... FROM TABLES' query", 0) \
M(Bool, allow_experimental_database_atomic, true, "Obsolete setting, does nothing. Will be removed after 2021-02-12", 0) \
M(Bool, allow_non_metadata_alters, true, "Allow to execute alters which affects not only tables metadata, but also data on disk", 0) \
M(Bool, enable_global_with_statement, false, "Propagate WITH statements to UNION queries and all subqueries", 0)
M(Bool, enable_global_with_statement, false, "Propagate WITH statements to UNION queries and all subqueries", 0) \
M(Bool, aggregate_functions_null_for_empty, false, "Rewrite all aggregate functions in a query, adding -OrNull suffix to them", 0)
// End of COMMON_SETTINGS
// Please add settings related to formats into the FORMAT_FACTORY_SETTINGS below.

View File

@ -31,6 +31,7 @@
#include <IO/WriteHelpers.h>
#include <Storages/IStorage.h>
#include <AggregateFunctions/AggregateFunctionFactory.h>
namespace DB
{
@ -110,6 +111,25 @@ struct CustomizeFunctionsSuffixData
char ifDistinct[] = "ifdistinct";
using CustomizeIfDistinctVisitor = InDepthNodeVisitor<OneTypeMatcher<CustomizeFunctionsSuffixData<ifDistinct>>, true>;
/// Used to rewrite all aggregate functions to add -OrNull suffix to them if setting `aggregate_functions_null_for_empty` is set.
struct CustomizeAggregateFunctionsSuffixData
{
using TypeToVisit = ASTFunction;
const String & customized_func_suffix;
void visit(ASTFunction & func, ASTPtr &)
{
if (AggregateFunctionFactory::instance().isAggregateFunctionName(func.name)
&& !endsWith(func.name, customized_func_suffix))
{
func.name = func.name + customized_func_suffix;
}
}
};
using CustomizeAggregateFunctionsOrNullVisitor = InDepthNodeVisitor<OneTypeMatcher<CustomizeAggregateFunctionsSuffixData>, true>;
/// Translate qualified names such as db.table.column, table.column, table_alias.column to names' normal form.
/// Expand asterisks and qualified asterisks with column names.
/// There would be columns in normal form & column aliases after translation. Column & column alias would be normalized in QueryNormalizer.
@ -692,6 +712,13 @@ void TreeRewriter::normalize(ASTPtr & query, Aliases & aliases, const Settings &
CustomizeGlobalNotInVisitor(data_global_not_null_in).visit(query);
}
// Rewrite all aggregate functions to add -OrNull suffix to them
if (settings.aggregate_functions_null_for_empty)
{
CustomizeAggregateFunctionsOrNullVisitor::Data data_or_null{"OrNull"};
CustomizeAggregateFunctionsOrNullVisitor(data_or_null).visit(query);
}
/// Creates a dictionary `aliases`: alias -> ASTPtr
QueryAliasesVisitor(aliases).visit(query);

View File

@ -0,0 +1,8 @@
0
\N
\N
\N
45
45
45
45

View File

@ -0,0 +1,28 @@
DROP TABLE IF EXISTS defaults;
CREATE TABLE defaults
(
n Int8
)ENGINE = Memory();
SELECT sum(n) FROM defaults;
SELECT sumOrNull(n) FROM defaults;
SET aggregate_functions_null_for_empty=1;
SELECT sum(n) FROM defaults;
SELECT sumOrNull(n) FROM defaults;
INSERT INTO defaults SELECT * FROM numbers(10);
SET aggregate_functions_null_for_empty=0;
SELECT sum(n) FROM defaults;
SELECT sumOrNull(n) FROM defaults;
SET aggregate_functions_null_for_empty=1;
SELECT sum(n) FROM defaults;
SELECT sumOrNull(n) FROM defaults;
DROP TABLE defaults;