Rewrite arithmetic in aggregate functions optimisation (#11899)

This commit is contained in:
Artem Zuikov 2020-06-24 21:49:55 +03:00 committed by GitHub
parent 2ce2588770
commit 2391ac22b7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 446 additions and 293 deletions

View File

@ -363,7 +363,7 @@ struct Settings : public SettingsCollection<Settings>
M(SettingBool, optimize_trivial_count_query, true, "Process trivial 'SELECT count() FROM table' query from metadata.", 0) \
M(SettingUInt64, mutations_sync, 0, "Wait for synchronous execution of ALTER TABLE UPDATE/DELETE queries (mutations). 0 - execute asynchronously. 1 - wait current server. 2 - wait all replicas if they exist.", 0) \
M(SettingBool, optimize_move_functions_out_of_any, true, "Move functions out of aggregate functions 'any', 'anyLast'.", 0) \
M(SettingBool, optimize_arithmetic_operations_in_aggregate_functions, false, "Move arithmetic operations out of aggregation functions", 0) \
M(SettingBool, optimize_arithmetic_operations_in_aggregate_functions, true, "Move arithmetic operations out of aggregation functions", 0) \
M(SettingBool, optimize_duplicate_order_by_and_distinct, true, "Remove duplicate ORDER BY and DISTINCT if it's possible", 0) \
M(SettingBool, optimize_if_chain_to_miltiif, false, "Replace if(cond1, then1, if(cond2, ...)) chains to multiIf. Currently it's not beneficial for numeric types.", 0) \
M(SettingBool, allow_experimental_alter_materialized_view_structure, false, "Allow atomic alter on Materialized views. Work in progress.", 0) \

View File

@ -1,327 +1,159 @@
#include <unordered_set>
#include <Common/typeid_cast.h>
#include <Parsers/ASTLiteral.h>
#include <Parsers/ASTFunction.h>
#include <Interpreters/ArithmeticOperationsInAgrFuncOptimize.h>
#include <IO/WriteHelpers.h>
#include <Parsers/ASTSubquery.h>
#include <Parsers/ASTTablesInSelectQuery.h>
#include <Interpreters/ArithmeticOperationsInAgrFuncOptimize.h>
namespace DB
{
namespace ErrorCodes
{
extern const int LOGICAL_ERROR;
extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH;
extern const int UNEXPECTED_AST_STRUCTURE;
extern const int BAD_TYPE_OF_FIELD;
}
namespace
{
constexpr const char * min = "min";
constexpr const char * max = "max";
constexpr const char * mul = "multiply";
constexpr const char * plus = "plus";
constexpr const char * sum = "sum";
bool isConstantField(const Field & field)
const ASTFunction * getInternalFunction(const ASTFunction & func)
{
return field.getType() == Field::Types::Int64 ||
field.getType() == Field::Types::UInt64 ||
field.getType() == Field::Types::Int128 ||
field.getType() == Field::Types::UInt128;
if (func.arguments->children.size() == 1)
return func.arguments->children[0]->as<ASTFunction>();
return nullptr;
}
bool onlyConstsInside(const ASTFunction * func_node)
ASTPtr exchangeExtractFirstArgument(const String & func_name, const ASTFunction & child_func)
{
return !(func_node->arguments->children[0]->as<ASTFunction>()) &&
(func_node->arguments->children.size() == 2 &&
!(func_node->arguments->children[1]->as<ASTFunction>()));
ASTs new_child_args;
new_child_args.push_back(child_func.arguments->children[1]);
auto new_child = makeASTFunction(func_name, new_child_args);
ASTs new_args;
new_args.push_back(child_func.arguments->children[0]);
new_args.push_back(new_child);
return makeASTFunction(child_func.name, new_args);
}
bool inappropriateNameInside(const ASTFunction * func_node, const char * inter_func_name)
ASTPtr exchangeExtractSecondArgument(const String & func_name, const ASTFunction & child_func)
{
return (func_node->arguments->children[0]->as<ASTFunction>() &&
strcmp(inter_func_name, func_node->arguments->children[0]->as<ASTFunction>()->name.c_str()) != 0) ||
(func_node->arguments->children.size() == 2 &&
func_node->arguments->children[1]->as<ASTFunction>() &&
strcmp(inter_func_name, func_node->arguments->children[1]->as<ASTFunction>()->name.c_str()) != 0);
ASTs new_child_args;
new_child_args.push_back(child_func.arguments->children[0]);
auto new_child = makeASTFunction(func_name, new_child_args);
ASTs new_args;
new_args.push_back(new_child);
new_args.push_back(child_func.arguments->children[1]);
return makeASTFunction(child_func.name, new_args);
}
bool isInappropriate(const ASTPtr & node, const char * inter_func_name)
Field zeroField(const Field & value)
{
return !node->as<ASTFunction>() || (strcmp(inter_func_name, node->as<ASTFunction>()->name.c_str()) != 0);
}
ASTFunction * getInternalFunction(const ASTFunction * f_n)
{
const auto * function_args = f_n->arguments->as<ASTExpressionList>();
if (!function_args || function_args->children.size() != 1)
throw Exception("Wrong number of arguments for function " + f_n->name + "(" + toString(function_args->children.size()) + " instead of 1)",
ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
return f_n->arguments->children[0]->as<ASTFunction>();
}
ASTFunction * treeFiller(ASTFunction * old_tree, const ASTs & nodes_array, size_t size, const char * name, bool flag)
{
if (flag)
--size;
for (size_t i = 0; i < size; ++i)
switch (value.getType())
{
old_tree->arguments->children = {};
old_tree->arguments->children.push_back(nodes_array[i]);
old_tree->arguments->children.push_back(makeASTFunction(name));
old_tree = old_tree->arguments->children[1]->as<ASTFunction>();
}
return old_tree;
}
/// scalar values from the first level
std::pair<ASTs, ASTs> tryGetConst(const char * name, const ASTs & arguments)
{
ASTs const_num;
ASTs not_const;
for (const auto & arg : arguments)
{
if (const auto * literal = arg->as<ASTLiteral>())
{
if (isConstantField(literal->value))
const_num.push_back(arg);
else
not_const.push_back(arg);
}
else
not_const.push_back(arg);
case Field::Types::UInt64: return UInt64(0);
case Field::Types::Int64: return Int64(0);
case Field::Types::Float64: return Float64(0);
case Field::Types::UInt128: return UInt128(0);
case Field::Types::Int128: return Int128(0);
default:
break;
}
if ((strcmp(name, plus) == 0 || strcmp(name, mul) == 0) && const_num.size() + not_const.size() != 2)
throw Exception("Wrong number of arguments for function 'plus' or 'multiply' (" + toString(const_num.size() + not_const.size()) + " instead of 2)",
ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
return {const_num, not_const};
throw Exception("Unexpected literal type in function", ErrorCodes::BAD_TYPE_OF_FIELD);
}
std::pair<ASTs, ASTs> findAllConsts(const ASTFunction * func_node, const char * inter_func_name)
const String & changeNameIfNeeded(const String & func_name, const String & child_name, const ASTLiteral & literal)
{
if (func_node->arguments->children.empty())
static const std::unordered_map<String, std::unordered_set<String>> matches = {
{ "min", { "multiply", "divide" } },
{ "max", { "multiply", "divide" } }
};
static const std::unordered_map<String, String> swap_to = {
{ "min", "max" },
{ "max", "min" }
};
if (literal.value < zeroField(literal.value) && matches.count(func_name) && matches.find(func_name)->second.count(child_name))
return swap_to.find(func_name)->second;
return func_name;
}
ASTPtr tryExchangeFunctions(const ASTFunction & func)
{
static const std::unordered_map<String, std::unordered_set<String>> supported = {
{ "sum", { "multiply", "divide" } },
{ "min", { "multiply", "divide", "plus", "minus" } },
{ "max", { "multiply", "divide", "plus", "minus" } }
};
const ASTFunction * child_func = getInternalFunction(func);
if (!child_func || !child_func->arguments || child_func->arguments->children.size() != 2 ||
!supported.count(func.name) || !supported.find(func.name)->second.count(child_func->name))
return {};
/// Cannot rewrite function with alias cause alias could become undefined
if (!func.tryGetAlias().empty() || !child_func->tryGetAlias().empty())
return {};
const auto & child_func_args = child_func->arguments->children;
const auto * first_literal = child_func_args[0]->as<ASTLiteral>();
const auto * second_literal = child_func_args[1]->as<ASTLiteral>();
ASTPtr optimized_ast;
if (first_literal && !second_literal)
{
if (strcmp(func_node->name.c_str(), plus) == 0 || strcmp(func_node->name.c_str(), mul) == 0)
throw Exception("Wrong number of arguments for function" + func_node->name + "(0 instead of 2)",
ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
else
/// It's possible to rewrite 'sum(1/n)' with 'sum(1) * div(1/n)' but we lose accuracy. Ignored.
if (child_func->name == "divide")
return {};
}
if (onlyConstsInside(func_node))
return tryGetConst(func_node->name.c_str(), func_node->arguments->children);
else if (inappropriateNameInside(func_node, inter_func_name))
const String & new_name = changeNameIfNeeded(func.name, child_func->name, *first_literal);
optimized_ast = exchangeExtractFirstArgument(new_name, *child_func);
}
else if (second_literal) /// second or both are consts
{
bool first_child_is_const = func_node->arguments->children[0]->as<ASTLiteral>() &&
isConstantField(func_node->arguments->children[0]->as<ASTLiteral>()->value);
bool second_child_is_const = func_node->arguments->children.size() == 2 &&
func_node->arguments->children[1]->as<ASTLiteral>() &&
isConstantField(func_node->arguments->children[1]->as<ASTLiteral>()->value);
if (first_child_is_const)
return {{func_node->arguments->children[0]}, {func_node->arguments->children[1]}};
else if (second_child_is_const)
return {{func_node->arguments->children[1]}, {func_node->arguments->children[0]}};
if (isInappropriate(func_node->arguments->children[0], inter_func_name)
&& isInappropriate(func_node->arguments->children[1], inter_func_name))
{
return {{}, {func_node->arguments->children[0], func_node->arguments->children[1]}};
}
else if (isInappropriate(func_node->arguments->children[0], inter_func_name))
{
std::pair<ASTs, ASTs> ans = findAllConsts(func_node->arguments->children[1]->as<ASTFunction>(), inter_func_name);
ans.second.push_back(func_node->arguments->children[0]);
return ans;
}
std::pair<ASTs, ASTs> ans = findAllConsts(func_node->arguments->children[0]->as<ASTFunction>(), inter_func_name);
ans.second.push_back(func_node->arguments->children[1]);
return ans;
const String & new_name = changeNameIfNeeded(func.name, child_func->name, *second_literal);
optimized_ast = exchangeExtractSecondArgument(new_name, *child_func);
}
std::pair<ASTs, ASTs> fl = tryGetConst(func_node->name.c_str(), func_node->arguments->children);
ASTs first_lvl_consts = fl.first;
ASTs first_lvl_not_consts = fl.second;
if (first_lvl_not_consts.empty() || !first_lvl_not_consts[0]->as<ASTFunction>())
return {first_lvl_consts, first_lvl_not_consts};
std::pair<ASTs, ASTs> ans = findAllConsts(first_lvl_not_consts[0]->as<ASTFunction>(), inter_func_name);
ASTs all_consts = ans.first;
ASTs all_not_consts = ans.second;
if (first_lvl_consts.size() == 1)
{
if (!first_lvl_not_consts[0]->as<ASTFunction>())
all_not_consts.push_back(first_lvl_not_consts[0]);
all_consts.push_back(first_lvl_consts[0]);
}
else if (first_lvl_consts.empty())
{
/// if node is inappropriate to go into it, we just add this node to all_not_consts vector
bool first_node_inappropriate_to_go_into = isInappropriate(first_lvl_not_consts[0], inter_func_name);
bool second_node_inappropriate_to_go_into = first_lvl_not_consts.size() == 2 &&
isInappropriate(first_lvl_not_consts[1], inter_func_name);
if (first_node_inappropriate_to_go_into)
all_not_consts.push_back(first_lvl_not_consts[0]);
if (second_node_inappropriate_to_go_into)
all_not_consts.push_back(first_lvl_not_consts[1]);
}
else
throw Exception("did not expect that", ErrorCodes::UNEXPECTED_AST_STRUCTURE);
return {all_consts, all_not_consts};
return optimized_ast;
}
/// rebuilds tree, all scalar values now outside the main func
void buildTree(ASTFunction * cur_node, const char * func_name, const char * intro_func, const std::pair<ASTs, ASTs> & tree_comp)
}
void ArithmeticOperationsInAgrFuncMatcher::visit(const ASTFunction & func, ASTPtr & ast, Data & data)
{
ASTs cons_val = tree_comp.first;
ASTs non_cons = tree_comp.second;
bool not_const_empty = non_cons.empty();
cur_node->name = intro_func;
cur_node = treeFiller(cur_node, cons_val, cons_val.size(), intro_func, not_const_empty);
cur_node->name = func_name;
if (non_cons.empty())
cur_node->arguments->children.push_back(cons_val[cons_val.size() - 1]);
else if (non_cons.size() == 1)
cur_node->arguments->children.push_back(non_cons[0]);
else
if (auto exchanged_funcs = tryExchangeFunctions(func))
{
cur_node->arguments->children.push_back(makeASTFunction(intro_func));
cur_node = cur_node->arguments->children[0]->as<ASTFunction>();
cur_node = treeFiller(cur_node, non_cons, non_cons.size() - 2, intro_func, not_const_empty);
cur_node->arguments->children = {non_cons[non_cons.size() - 2], non_cons[non_cons.size() - 1]};
ast = exchanged_funcs;
/// Main visitor is bottom-up. This is top-down part.
/// We've found an aggregate function an now move it down through others: sum(mul(mul)) -> mul(mul(sum)).
/// It's not dangerous cause main visitor already has visited this part of tree.
auto & expression_list = ast->children[0];
visit(expression_list->children[0], data);
}
}
void sumOptimize(ASTFunction * f_n)
void ArithmeticOperationsInAgrFuncMatcher::visit(ASTPtr & ast, Data & data)
{
const auto * function_args = f_n->arguments->as<ASTExpressionList>();
if (!function_args || function_args->children.size() != 1)
throw Exception("Wrong number of arguments for function 'sum' (" + toString(function_args->children.size()) + " instead of 1)",
ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
ASTFunction * inter_node = getInternalFunction(f_n);
if (inter_node && inter_node->name == mul)
{
std::pair<ASTs, ASTs> nodes = findAllConsts(f_n, mul);
if (nodes.first.empty())
return;
buildTree(f_n, sum, mul, nodes);
}
if (const auto * function_node = ast->as<ASTFunction>())
visit(*function_node, ast, data);
}
void minOptimize(ASTFunction * f_n)
bool ArithmeticOperationsInAgrFuncMatcher::needChildVisit(const ASTPtr & node, const ASTPtr &)
{
ASTFunction * inter_node = getInternalFunction(f_n);
if (inter_node && inter_node->name == mul)
{
int sign = 1;
std::pair<ASTs, ASTs> nodes = findAllConsts(f_n, mul);
if (nodes.first.empty())
return;
for (const auto & arg : nodes.first)
{
Int128 num = applyVisitor(FieldVisitorConvertToNumber<Int128>(), arg->as<ASTLiteral>()->value);
/// if multiplication is negative, min function becomes max
if ((arg->as<ASTLiteral>()->value.getType() == Field::Types::Int64 ||
arg->as<ASTLiteral>()->value.getType() == Field::Types::Int128) && num < static_cast<Int128>(0))
sign *= -1;
}
if (sign == -1)
buildTree(f_n, max, mul, nodes);
else
buildTree(f_n, min, mul, nodes);
}
else if (inter_node && inter_node->name == plus)
{
std::pair<ASTs, ASTs> nodes = findAllConsts(f_n, plus);
buildTree(f_n, min, plus, nodes);
}
}
void maxOptimize(ASTFunction * f_n)
{
ASTFunction * inter_node = getInternalFunction(f_n);
if (inter_node && inter_node->name == mul)
{
int sign = 1;
std::pair<ASTs, ASTs> nodes = findAllConsts(f_n, mul);
if (nodes.first.empty())
return;
for (const auto & arg: nodes.first)
{
Int128 num = applyVisitor(FieldVisitorConvertToNumber<Int128>(), arg->as<ASTLiteral>()->value);
/// if multiplication is negative, max function becomes min
if ((arg->as<ASTLiteral>()->value.getType() == Field::Types::Int64 ||
arg->as<ASTLiteral>()->value.getType() == Field::Types::Int128) && num < static_cast<Int128>(0))
sign *= -1;
}
if (sign == -1)
buildTree(f_n, min, mul, nodes);
else
buildTree(f_n, max, mul, nodes);
}
else if (inter_node && inter_node->name == plus)
{
std::pair<ASTs, ASTs> nodes = findAllConsts(f_n, plus);
buildTree(f_n, max, plus, nodes);
}
}
}
/// optimize for min, max, sum is ready, ToDo: groupBitAnd, groupBitOr, groupBitXor
void ArithmeticOperationsInAgrFuncMatcher::visit(ASTFunction * function_node, Data data)
{
data = {};
if (function_node->name == sum)
sumOptimize(function_node);
else if (function_node->name == min)
minOptimize(function_node);
else if (function_node->name == max)
maxOptimize(function_node);
}
void ArithmeticOperationsInAgrFuncMatcher::visit(const ASTPtr & current_ast, Data data)
{
if (!current_ast)
return;
if (auto * function_node = current_ast->as<ASTFunction>())
visit(function_node, data);
}
bool ArithmeticOperationsInAgrFuncMatcher::needChildVisit(const ASTPtr & node, const ASTPtr & child)
{
if (!child)
throw Exception("AST item should not have nullptr in children", ErrorCodes::LOGICAL_ERROR);
return !(node->as<ASTTableExpression>() || node->as<ASTArrayJoin>());
return !node->as<ASTSubquery>() && !node->as<ASTTableExpression>();
}
}

View File

@ -6,17 +6,24 @@
namespace DB
{
/// It converts some arithmetic. Optimization due to the linearity property of some aggregate functions.
/// Function collects const and not const nodes and rebuilds old tree.
/// Extract constant arguments out of aggregate functions from child functions
/// 'sum(a * 2)' -> 'sum(a) * 2'
/// Rewrites: sum([multiply|divide]) -> [multiply|divide](sum)
/// [min|max]([multiply|divide|plus|minus]) -> [multiply|divide|plus|minus]([min|max])
/// TODO: groupBitAnd, groupBitOr, groupBitXor
/// TODO: better constant detection: f(const) is not detected as const.
/// TODO: 'f((2 * n) * n)' -> '2 * f(n * n)'
class ArithmeticOperationsInAgrFuncMatcher
{
public:
struct Data {};
static void visit(const ASTPtr & ast, Data data);
static void visit(ASTFunction *, Data data);
static bool needChildVisit(const ASTPtr & node, const ASTPtr & child);
static void visit(ASTPtr & ast, Data & data);
static void visit(const ASTFunction &, ASTPtr & ast, Data & data);
static bool needChildVisit(const ASTPtr & node, const ASTPtr & child);
};
using ArithmeticOperationsInAgrFuncVisitor = InDepthNodeVisitor<ArithmeticOperationsInAgrFuncMatcher, true>;
using ArithmeticOperationsInAgrFuncVisitor = InDepthNodeVisitor<ArithmeticOperationsInAgrFuncMatcher, false>;
}

View File

@ -555,14 +555,11 @@ void optimizeIf(ASTPtr & query, Aliases & aliases, bool if_chain_to_miltiif)
OptimizeIfChainsVisitor().visit(query);
}
void optimizeArithmeticOperationsInAgr(ASTPtr & query, bool optimize_arithmetic_operations_in_agr_func)
void optimizeAggregationFunctions(ASTPtr & query)
{
if (optimize_arithmetic_operations_in_agr_func)
{
/// Removing arithmetic operations from functions
ArithmeticOperationsInAgrFuncVisitor::Data data = {};
ArithmeticOperationsInAgrFuncVisitor(data).visit(query);
}
/// Move arithmetic operations out of aggregation functions
ArithmeticOperationsInAgrFuncVisitor::Data data;
ArithmeticOperationsInAgrFuncVisitor(data).visit(query);
}
void optimizeAnyInput(ASTPtr & query)
@ -952,7 +949,8 @@ SyntaxAnalyzerResultPtr SyntaxAnalyzer::analyzeSelect(
optimizeIf(query, result.aliases, settings.optimize_if_chain_to_miltiif);
/// Move arithmetic operations out of aggregation functions
optimizeArithmeticOperationsInAgr(query, settings.optimize_arithmetic_operations_in_aggregate_functions);
if (settings.optimize_arithmetic_operations_in_aggregate_functions)
optimizeAggregationFunctions(query);
/// Push the predicate expression down to the subqueries.
result.rewrite_subqueries = PredicateExpressionsOptimizer(context, tables_with_columns, settings).optimize(*select_query);

View File

@ -1,6 +1,150 @@
SELECT \n sum(n + 1),\n sum(1 + n),\n sum(n - 1),\n sum(1 - n)\nFROM \n(\n SELECT number AS n\n FROM numbers(10)\n)
SELECT \n sum(n) * 2,\n 2 * sum(n),\n sum(n) / 2,\n sum(1 / n)\nFROM \n(\n SELECT number AS n\n FROM numbers(10)\n)
SELECT \n min(n) + 1,\n 1 + min(n),\n min(n) - 1,\n 1 - min(n)\nFROM \n(\n SELECT number AS n\n FROM numbers(10)\n)
SELECT \n min(n) * 2,\n 2 * min(n),\n min(n) / 2,\n min(1 / n)\nFROM \n(\n SELECT number AS n\n FROM numbers(10)\n)
SELECT \n max(n) + 1,\n 1 + max(n),\n max(n) - 1,\n 1 - max(n)\nFROM \n(\n SELECT number AS n\n FROM numbers(10)\n)
SELECT \n max(n) * 2,\n 2 * max(n),\n max(n) / 2,\n max(1 / n)\nFROM \n(\n SELECT number AS n\n FROM numbers(10)\n)
SELECT \n sum(n + -1),\n sum(-1 + n),\n sum(n - -1),\n sum(-1 - n)\nFROM \n(\n SELECT number AS n\n FROM numbers(10)\n)
SELECT \n sum(n) * -2,\n -2 * sum(n),\n sum(n) / -2,\n sum(-1 / n)\nFROM \n(\n SELECT number AS n\n FROM numbers(10)\n)
SELECT \n min(n) + -1,\n -1 + min(n),\n min(n) - -1,\n -1 - min(n)\nFROM \n(\n SELECT number AS n\n FROM numbers(10)\n)
SELECT \n max(n) * -2,\n -2 * max(n),\n max(n) / -2,\n min(-1 / n)\nFROM \n(\n SELECT number AS n\n FROM numbers(10)\n)
SELECT \n max(n) + -1,\n -1 + max(n),\n max(n) - -1,\n -1 - max(n)\nFROM \n(\n SELECT number AS n\n FROM numbers(10)\n)
SELECT \n min(n) * -2,\n -2 * min(n),\n min(n) / -2,\n max(-1 / n)\nFROM \n(\n SELECT number AS n\n FROM numbers(10)\n)
SELECT \n sum(abs(2) + 1),\n sum(abs(2) + n),\n sum(n - abs(2)),\n sum(1 - abs(2))\nFROM \n(\n SELECT number AS n\n FROM numbers(10)\n)
SELECT \n sum(abs(2)) * 2,\n sum(abs(2) * n),\n sum(n / abs(2)),\n sum(1 / abs(2))\nFROM \n(\n SELECT number AS n\n FROM numbers(10)\n)
SELECT \n min(abs(2)) + 1,\n min(abs(2) + n),\n min(n - abs(2)),\n 1 - min(abs(2))\nFROM \n(\n SELECT number AS n\n FROM numbers(10)\n)
SELECT \n min(abs(2)) * 2,\n min(abs(2) * n),\n min(n / abs(2)),\n min(1 / abs(2))\nFROM \n(\n SELECT number AS n\n FROM numbers(10)\n)
SELECT \n max(abs(2)) + 1,\n max(abs(2) + n),\n max(n - abs(2)),\n 1 - max(abs(2))\nFROM \n(\n SELECT number AS n\n FROM numbers(10)\n)
SELECT \n max(abs(2)) * 2,\n max(abs(2) * n),\n max(n / abs(2)),\n max(1 / abs(2))\nFROM \n(\n SELECT number AS n\n FROM numbers(10)\n)
SELECT \n sum(abs(n) + 1),\n sum(abs(n) + n),\n sum(n - abs(n)),\n sum(1 - abs(n))\nFROM \n(\n SELECT number AS n\n FROM numbers(10)\n)
SELECT \n sum(abs(n)) * 2,\n sum(abs(n) * n),\n sum(n / abs(n)),\n sum(1 / abs(n))\nFROM \n(\n SELECT number AS n\n FROM numbers(10)\n)
SELECT \n min(abs(n)) + 1,\n min(abs(n) + n),\n min(n - abs(n)),\n 1 - min(abs(n))\nFROM \n(\n SELECT number AS n\n FROM numbers(10)\n)
SELECT \n min(abs(n)) * 2,\n min(abs(n) * n),\n min(n / abs(n)),\n min(1 / abs(n))\nFROM \n(\n SELECT number AS n\n FROM numbers(10)\n)
SELECT \n max(abs(n)) + 1,\n max(abs(n) + n),\n max(n - abs(n)),\n 1 - max(abs(n))\nFROM \n(\n SELECT number AS n\n FROM numbers(10)\n)
SELECT \n max(abs(n)) * 2,\n max(abs(n) * n),\n max(n / abs(n)),\n max(1 / abs(n))\nFROM \n(\n SELECT number AS n\n FROM numbers(10)\n)
SELECT \n sum((n * n) + 1),\n sum(1 + (n * n)),\n sum((n * n) - 1),\n sum(1 - (n * n))\nFROM \n(\n SELECT number AS n\n FROM numbers(10)\n)
SELECT \n sum(n * n) * 2,\n sum((2 * n) * n),\n sum(n * n) / 2,\n sum((1 / n) * n)\nFROM \n(\n SELECT number AS n\n FROM numbers(10)\n)
SELECT \n min(n * n) + 1,\n 1 + min(n * n),\n min(n * n) - 1,\n 1 - min(n * n)\nFROM \n(\n SELECT number AS n\n FROM numbers(10)\n)
SELECT \n min(n * n) * 2,\n min((2 * n) * n),\n min(n * n) / 2,\n min((1 / n) * n)\nFROM \n(\n SELECT number AS n\n FROM numbers(10)\n)
SELECT \n max(n * n) + 1,\n 1 + max(n * n),\n max(n * n) - 1,\n 1 - max(n * n)\nFROM \n(\n SELECT number AS n\n FROM numbers(10)\n)
SELECT \n max(n * n) * 2,\n max((2 * n) * n),\n max(n * n) / 2,\n max((1 / n) * n)\nFROM \n(\n SELECT number AS n\n FROM numbers(10)\n)
SELECT \n sum((1 + n) + 1),\n sum((1 + 1) + n),\n sum((1 + n) - 1),\n sum((1 + 1) - n)\nFROM \n(\n SELECT number AS n\n FROM numbers(10)\n)
SELECT \n sum(1 + (n * 2)),\n sum(1 + (2 * n)),\n sum(1 + (n / 2)),\n sum(1 + (1 / n))\nFROM \n(\n SELECT number AS n\n FROM numbers(10)\n)
SELECT \n (1 + min(n)) + 1,\n min((1 + 1) + n),\n (1 + min(n)) - 1,\n min((1 + 1) - n)\nFROM \n(\n SELECT number AS n\n FROM numbers(10)\n)
SELECT \n 1 + min(n * 2),\n 1 + min(2 * n),\n 1 + min(n / 2),\n 1 + min(1 / n)\nFROM \n(\n SELECT number AS n\n FROM numbers(10)\n)
SELECT \n (1 + max(n)) + 1,\n max((1 + 1) + n),\n (1 + max(n)) - 1,\n max((1 + 1) - n)\nFROM \n(\n SELECT number AS n\n FROM numbers(10)\n)
SELECT \n 1 + max(n * 2),\n 1 + max(2 * n),\n 1 + max(n / 2),\n 1 + max(1 / n)\nFROM \n(\n SELECT number AS n\n FROM numbers(10)\n)
SELECT \n sum((n + -1) + -1),\n sum((-1 + n) + -1),\n sum((n - -1) + -1),\n sum((-1 - n) + -1)\nFROM \n(\n SELECT number AS n\n FROM numbers(10)\n)
SELECT \n (sum(n) * -2) * -1,\n (-2 * sum(n)) * -1,\n (sum(n) / -2) / -1,\n sum(-1 / n) / -1\nFROM \n(\n SELECT number AS n\n FROM numbers(10)\n)
SELECT \n (min(n) + -1) + -1,\n (-1 + min(n)) + -1,\n (min(n) - -1) + -1,\n (-1 - min(n)) + -1\nFROM \n(\n SELECT number AS n\n FROM numbers(10)\n)
SELECT \n (min(n) * -2) * -1,\n (-2 * min(n)) * -1,\n (min(n) / -2) / -1,\n max(-1 / n) / -1\nFROM \n(\n SELECT number AS n\n FROM numbers(10)\n)
SELECT \n (max(n) + -1) + -1,\n (-1 + max(n)) + -1,\n (max(n) - -1) + -1,\n (-1 - max(n)) + -1\nFROM \n(\n SELECT number AS n\n FROM numbers(10)\n)
SELECT \n (max(n) * -2) * -1,\n (-2 * max(n)) * -1,\n (max(n) / -2) / -1,\n min(-1 / n) / -1\nFROM \n(\n SELECT number AS n\n FROM numbers(10)\n)
SELECT ((sum(n + 1) + sum(1 + n)) + sum(n - 1)) + sum(1 - n)\nFROM \n(\n SELECT number AS n\n FROM numbers(10)\n)
SELECT (((sum(n) * 2) + (2 * sum(n))) + (sum(n) / 2)) + sum(1 / n)\nFROM \n(\n SELECT number AS n\n FROM numbers(10)\n)
SELECT (((min(n) + 1) + (1 + min(n))) + (min(n) - 1)) + (1 - min(n))\nFROM \n(\n SELECT number AS n\n FROM numbers(10)\n)
SELECT (((min(n) * 2) + (2 * min(n))) + (min(n) / 2)) + min(1 / n)\nFROM \n(\n SELECT number AS n\n FROM numbers(10)\n)
SELECT (((max(n) + 1) + (1 + max(n))) + (max(n) - 1)) + (1 - max(n))\nFROM \n(\n SELECT number AS n\n FROM numbers(10)\n)
SELECT (((max(n) * 2) + (2 * max(n))) + (max(n) / 2)) + max(1 / n)\nFROM \n(\n SELECT number AS n\n FROM numbers(10)\n)
55 55 35 -35
90 90 22.5 inf
1 1 -1 1
0 0 0 0.1111111111111111
10 10 8 -8
18 18 4.5 inf
35 35 55 -55
-90 -90 -22.5 -inf
-1 -1 1 -1
-18 -18 -4.5 -inf
8 8 10 -10
0 0 -0 -0.1111111111111111
30 65 25 -10
40 90 22.5 5
3 2 -2 -1
4 0 0 0.5
3 11 7 -1
4 18 4.5 0.5
55 90 0 -35
90 285 nan inf
1 0 0 1
0 0 nan 0.1111111111111111
10 18 0 -8
18 81 nan inf
295 295 275 -275
570 570 142.5 nan
1 1 -1 1
0 0 0 nan
82 82 80 -80
162 162 40.5 nan
65 65 45 -25
100 100 32.5 inf
2 2 0 -7
1 1 1 1.1111111111111112
11 11 9 2
19 19 5.5 inf
25 25 45 -65
90 90 22.5 inf
-2 -2 0 -2
0 0 0 0.1111111111111111
7 7 9 -11
18 18 4.5 inf
110
inf
2
0.1111111111111111
20
inf
-15444
68.62157087543459
243
55 55 35 -35
90 90 22.5 inf
1 1 -1 -8
0 0 0 0.1111111111111111
10 10 8 1
18 18 4.5 inf
35 35 55 -55
-90 -90 -22.5 -inf
-1 -1 1 -10
-18 -18 -4.5 -inf
8 8 10 -1
0 0 -0 -0.1111111111111111
30 65 25 -10
40 90 22.5 5
3 2 -2 -1
4 0 0 0.5
3 11 7 -1
4 18 4.5 0.5
55 90 0 -35
90 285 nan inf
1 0 0 -8
0 0 nan 0.1111111111111111
10 18 0 1
18 81 nan inf
295 295 275 -275
570 570 142.5 nan
1 1 -1 -80
0 0 0 nan
82 82 80 1
162 162 40.5 nan
65 65 45 -25
100 100 32.5 inf
2 2 0 -7
1 1 1 1.1111111111111112
11 11 9 2
19 19 5.5 inf
25 25 45 -65
90 90 22.5 inf
-2 -2 0 -11
0 0 0 0.1111111111111111
7 7 9 -2
18 18 4.5 inf
110
inf
-7
0.1111111111111111
29
inf
-15444
68.62157087543459
243

View File

@ -1,10 +1,182 @@
set optimize_arithmetic_operations_in_aggregate_functions = 1;
SET enable_debug_queries = 1;
SET optimize_arithmetic_operations_in_aggregate_functions = 1;
ANALYZE SELECT sum(n + 1), sum(1 + n), sum(n - 1), sum(1 - n) FROM (SELECT number n FROM numbers(10));
ANALYZE SELECT sum(n * 2), sum(2 * n), sum(n / 2), sum(1 / n) FROM (SELECT number n FROM numbers(10));
ANALYZE SELECT min(n + 1), min(1 + n), min(n - 1), min(1 - n) FROM (SELECT number n FROM numbers(10));
ANALYZE SELECT min(n * 2), min(2 * n), min(n / 2), min(1 / n) FROM (SELECT number n FROM numbers(10));
ANALYZE SELECT max(n + 1), max(1 + n), max(n - 1), max(1 - n) FROM (SELECT number n FROM numbers(10));
ANALYZE SELECT max(n * 2), max(2 * n), max(n / 2), max(1 / n) FROM (SELECT number n FROM numbers(10));
ANALYZE SELECT sum(n + -1), sum(-1 + n), sum(n - -1), sum(-1 - n) FROM (SELECT number n FROM numbers(10));
ANALYZE SELECT sum(n * -2), sum(-2 * n), sum(n / -2), sum(-1 / n) FROM (SELECT number n FROM numbers(10));
ANALYZE SELECT min(n + -1), min(-1 + n), min(n - -1), min(-1 - n) FROM (SELECT number n FROM numbers(10));
ANALYZE SELECT min(n * -2), min(-2 * n), min(n / -2), min(-1 / n) FROM (SELECT number n FROM numbers(10));
ANALYZE SELECT max(n + -1), max(-1 + n), max(n - -1), max(-1 - n) FROM (SELECT number n FROM numbers(10));
ANALYZE SELECT max(n * -2), max(-2 * n), max(n / -2), max(-1 / n) FROM (SELECT number n FROM numbers(10));
ANALYZE SELECT sum(abs(2) + 1), sum(abs(2) + n), sum(n - abs(2)), sum(1 - abs(2)) FROM (SELECT number n FROM numbers(10));
ANALYZE SELECT sum(abs(2) * 2), sum(abs(2) * n), sum(n / abs(2)), sum(1 / abs(2)) FROM (SELECT number n FROM numbers(10));
ANALYZE SELECT min(abs(2) + 1), min(abs(2) + n), min(n - abs(2)), min(1 - abs(2)) FROM (SELECT number n FROM numbers(10));
ANALYZE SELECT min(abs(2) * 2), min(abs(2) * n), min(n / abs(2)), min(1 / abs(2)) FROM (SELECT number n FROM numbers(10));
ANALYZE SELECT max(abs(2) + 1), max(abs(2) + n), max(n - abs(2)), max(1 - abs(2)) FROM (SELECT number n FROM numbers(10));
ANALYZE SELECT max(abs(2) * 2), max(abs(2) * n), max(n / abs(2)), max(1 / abs(2)) FROM (SELECT number n FROM numbers(10));
ANALYZE SELECT sum(abs(n) + 1), sum(abs(n) + n), sum(n - abs(n)), sum(1 - abs(n)) FROM (SELECT number n FROM numbers(10));
ANALYZE SELECT sum(abs(n) * 2), sum(abs(n) * n), sum(n / abs(n)), sum(1 / abs(n)) FROM (SELECT number n FROM numbers(10));
ANALYZE SELECT min(abs(n) + 1), min(abs(n) + n), min(n - abs(n)), min(1 - abs(n)) FROM (SELECT number n FROM numbers(10));
ANALYZE SELECT min(abs(n) * 2), min(abs(n) * n), min(n / abs(n)), min(1 / abs(n)) FROM (SELECT number n FROM numbers(10));
ANALYZE SELECT max(abs(n) + 1), max(abs(n) + n), max(n - abs(n)), max(1 - abs(n)) FROM (SELECT number n FROM numbers(10));
ANALYZE SELECT max(abs(n) * 2), max(abs(n) * n), max(n / abs(n)), max(1 / abs(n)) FROM (SELECT number n FROM numbers(10));
ANALYZE SELECT sum(n*n + 1), sum(1 + n*n), sum(n*n - 1), sum(1 - n*n) FROM (SELECT number n FROM numbers(10));
ANALYZE SELECT sum(n*n * 2), sum(2 * n*n), sum(n*n / 2), sum(1 / n*n) FROM (SELECT number n FROM numbers(10));
ANALYZE SELECT min(n*n + 1), min(1 + n*n), min(n*n - 1), min(1 - n*n) FROM (SELECT number n FROM numbers(10));
ANALYZE SELECT min(n*n * 2), min(2 * n*n), min(n*n / 2), min(1 / n*n) FROM (SELECT number n FROM numbers(10));
ANALYZE SELECT max(n*n + 1), max(1 + n*n), max(n*n - 1), max(1 - n*n) FROM (SELECT number n FROM numbers(10));
ANALYZE SELECT max(n*n * 2), max(2 * n*n), max(n*n / 2), max(1 / n*n) FROM (SELECT number n FROM numbers(10));
ANALYZE SELECT sum(1 + n + 1), sum(1 + 1 + n), sum(1 + n - 1), sum(1 + 1 - n) FROM (SELECT number n FROM numbers(10));
ANALYZE SELECT sum(1 + n * 2), sum(1 + 2 * n), sum(1 + n / 2), sum(1 + 1 / n) FROM (SELECT number n FROM numbers(10));
ANALYZE SELECT min(1 + n + 1), min(1 + 1 + n), min(1 + n - 1), min(1 + 1 - n) FROM (SELECT number n FROM numbers(10));
ANALYZE SELECT min(1 + n * 2), min(1 + 2 * n), min(1 + n / 2), min(1 + 1 / n) FROM (SELECT number n FROM numbers(10));
ANALYZE SELECT max(1 + n + 1), max(1 + 1 + n), max(1 + n - 1), max(1 + 1 - n) FROM (SELECT number n FROM numbers(10));
ANALYZE SELECT max(1 + n * 2), max(1 + 2 * n), max(1 + n / 2), max(1 + 1 / n) FROM (SELECT number n FROM numbers(10));
ANALYZE SELECT sum(n + -1 + -1), sum(-1 + n + -1), sum(n - -1 + -1), sum(-1 - n + -1) FROM (SELECT number n FROM numbers(10));
ANALYZE SELECT sum(n * -2 * -1), sum(-2 * n * -1), sum(n / -2 / -1), sum(-1 / n / -1) FROM (SELECT number n FROM numbers(10));
ANALYZE SELECT min(n + -1 + -1), min(-1 + n + -1), min(n - -1 + -1), min(-1 - n + -1) FROM (SELECT number n FROM numbers(10));
ANALYZE SELECT min(n * -2 * -1), min(-2 * n * -1), min(n / -2 / -1), min(-1 / n / -1) FROM (SELECT number n FROM numbers(10));
ANALYZE SELECT max(n + -1 + -1), max(-1 + n + -1), max(n - -1 + -1), max(-1 - n + -1) FROM (SELECT number n FROM numbers(10));
ANALYZE SELECT max(n * -2 * -1), max(-2 * n * -1), max(n / -2 / -1), max(-1 / n / -1) FROM (SELECT number n FROM numbers(10));
ANALYZE SELECT sum(n + 1) + sum(1 + n) + sum(n - 1) + sum(1 - n) FROM (SELECT number n FROM numbers(10));
ANALYZE SELECT sum(n * 2) + sum(2 * n) + sum(n / 2) + sum(1 / n) FROM (SELECT number n FROM numbers(10));
ANALYZE SELECT min(n + 1) + min(1 + n) + min(n - 1) + min(1 - n) FROM (SELECT number n FROM numbers(10));
ANALYZE SELECT min(n * 2) + min(2 * n) + min(n / 2) + min(1 / n) FROM (SELECT number n FROM numbers(10));
ANALYZE SELECT max(n + 1) + max(1 + n) + max(n - 1) + max(1 - n) FROM (SELECT number n FROM numbers(10));
ANALYZE SELECT max(n * 2) + max(2 * n) + max(n / 2) + max(1 / n) FROM (SELECT number n FROM numbers(10));
SELECT sum(n + 1), sum(1 + n), sum(n - 1), sum(1 - n) FROM (SELECT number n FROM numbers(10));
SELECT sum(n * 2), sum(2 * n), sum(n / 2), sum(1 / n) FROM (SELECT number n FROM numbers(10));
SELECT min(n + 1), min(1 + n), min(n - 1), min(1 - n) FROM (SELECT number n FROM numbers(10));
SELECT min(n * 2), min(2 * n), min(n / 2), min(1 / n) FROM (SELECT number n FROM numbers(10));
SELECT max(n + 1), max(1 + n), max(n - 1), max(1 - n) FROM (SELECT number n FROM numbers(10));
SELECT max(n * 2), max(2 * n), max(n / 2), max(1 / n) FROM (SELECT number n FROM numbers(10));
SELECT sum(n + -1), sum(-1 + n), sum(n - -1), sum(-1 - n) FROM (SELECT number n FROM numbers(10));
SELECT sum(n * -2), sum(-2 * n), sum(n / -2), sum(-1 / n) FROM (SELECT number n FROM numbers(10));
SELECT min(n + -1), min(-1 + n), min(n - -1), min(-1 - n) FROM (SELECT number n FROM numbers(10));
SELECT min(n * -2), min(-2 * n), min(n / -2), min(-1 / n) FROM (SELECT number n FROM numbers(10));
SELECT max(n + -1), max(-1 + n), max(n - -1), max(-1 - n) FROM (SELECT number n FROM numbers(10));
SELECT max(n * -2), max(-2 * n), max(n / -2), max(-1 / n) FROM (SELECT number n FROM numbers(10));
SELECT sum(abs(2) + 1), sum(abs(2) + n), sum(n - abs(2)), sum(1 - abs(2)) FROM (SELECT number n FROM numbers(10));
SELECT sum(abs(2) * 2), sum(abs(2) * n), sum(n / abs(2)), sum(1 / abs(2)) FROM (SELECT number n FROM numbers(10));
SELECT min(abs(2) + 1), min(abs(2) + n), min(n - abs(2)), min(1 - abs(2)) FROM (SELECT number n FROM numbers(10));
SELECT min(abs(2) * 2), min(abs(2) * n), min(n / abs(2)), min(1 / abs(2)) FROM (SELECT number n FROM numbers(10));
SELECT max(abs(2) + 1), max(abs(2) + n), max(n - abs(2)), max(1 - abs(2)) FROM (SELECT number n FROM numbers(10));
SELECT max(abs(2) * 2), max(abs(2) * n), max(n / abs(2)), max(1 / abs(2)) FROM (SELECT number n FROM numbers(10));
SELECT sum(abs(n) + 1), sum(abs(n) + n), sum(n - abs(n)), sum(1 - abs(n)) FROM (SELECT number n FROM numbers(10));
SELECT sum(abs(n) * 2), sum(abs(n) * n), sum(n / abs(n)), sum(1 / abs(n)) FROM (SELECT number n FROM numbers(10));
SELECT min(abs(n) + 1), min(abs(n) + n), min(n - abs(n)), min(1 - abs(n)) FROM (SELECT number n FROM numbers(10));
SELECT min(abs(n) * 2), min(abs(n) * n), min(n / abs(n)), min(1 / abs(n)) FROM (SELECT number n FROM numbers(10));
SELECT max(abs(n) + 1), max(abs(n) + n), max(n - abs(n)), max(1 - abs(n)) FROM (SELECT number n FROM numbers(10));
SELECT max(abs(n) * 2), max(abs(n) * n), max(n / abs(n)), max(1 / abs(n)) FROM (SELECT number n FROM numbers(10));
SELECT sum(n*n + 1), sum(1 + n*n), sum(n*n - 1), sum(1 - n*n) FROM (SELECT number n FROM numbers(10));
SELECT sum(n*n * 2), sum(2 * n*n), sum(n*n / 2), sum(1 / n*n) FROM (SELECT number n FROM numbers(10));
SELECT min(n*n + 1), min(1 + n*n), min(n*n - 1), min(1 - n*n) FROM (SELECT number n FROM numbers(10));
SELECT min(n*n * 2), min(2 * n*n), min(n*n / 2), min(1 / n*n) FROM (SELECT number n FROM numbers(10));
SELECT max(n*n + 1), max(1 + n*n), max(n*n - 1), max(1 - n*n) FROM (SELECT number n FROM numbers(10));
SELECT max(n*n * 2), max(2 * n*n), max(n*n / 2), max(1 / n*n) FROM (SELECT number n FROM numbers(10));
SELECT sum(1 + n + 1), sum(1 + 1 + n), sum(1 + n - 1), sum(1 + 1 - n) FROM (SELECT number n FROM numbers(10));
SELECT sum(1 + n * 2), sum(1 + 2 * n), sum(1 + n / 2), sum(1 + 1 / n) FROM (SELECT number n FROM numbers(10));
SELECT min(1 + n + 1), min(1 + 1 + n), min(1 + n - 1), min(1 + 1 - n) FROM (SELECT number n FROM numbers(10));
SELECT min(1 + n * 2), min(1 + 2 * n), min(1 + n / 2), min(1 + 1 / n) FROM (SELECT number n FROM numbers(10));
SELECT max(1 + n + 1), max(1 + 1 + n), max(1 + n - 1), max(1 + 1 - n) FROM (SELECT number n FROM numbers(10));
SELECT max(1 + n * 2), max(1 + 2 * n), max(1 + n / 2), max(1 + 1 / n) FROM (SELECT number n FROM numbers(10));
SELECT sum(n + -1 + -1), sum(-1 + n + -1), sum(n - -1 + -1), sum(-1 - n + -1) FROM (SELECT number n FROM numbers(10));
SELECT sum(n * -2 * -1), sum(-2 * n * -1), sum(n / -2 / -1), sum(-1 / n / -1) FROM (SELECT number n FROM numbers(10));
SELECT min(n + -1 + -1), min(-1 + n + -1), min(n - -1 + -1), min(-1 - n + -1) FROM (SELECT number n FROM numbers(10));
SELECT min(n * -2 * -1), min(-2 * n * -1), min(n / -2 / -1), min(-1 / n / -1) FROM (SELECT number n FROM numbers(10));
SELECT max(n + -1 + -1), max(-1 + n + -1), max(n - -1 + -1), max(-1 - n + -1) FROM (SELECT number n FROM numbers(10));
SELECT max(n * -2 * -1), max(-2 * n * -1), max(n / -2 / -1), max(-1 / n / -1) FROM (SELECT number n FROM numbers(10));
SELECT sum(n + 1) + sum(1 + n) + sum(n - 1) + sum(1 - n) FROM (SELECT number n FROM numbers(10));
SELECT sum(n * 2) + sum(2 * n) + sum(n / 2) + sum(1 / n) FROM (SELECT number n FROM numbers(10));
SELECT min(n + 1) + min(1 + n) + min(n - 1) + min(1 - n) FROM (SELECT number n FROM numbers(10));
SELECT min(n * 2) + min(2 * n) + min(n / 2) + min(1 / n) FROM (SELECT number n FROM numbers(10));
SELECT max(n + 1) + max(1 + n) + max(n - 1) + max(1 - n) FROM (SELECT number n FROM numbers(10));
SELECT max(n * 2) + max(2 * n) + max(n / 2) + max(1 / n) FROM (SELECT number n FROM numbers(10));
SELECT sum(number * -3) + min(2 * number * -3) - max(-1 * -2 * number * -3) FROM numbers(100);
SELECT max(log(2) * number) FROM numbers(100);
SELECT round(max(log(2) * 3 * sin(0.3) * number * 4)) FROM numbers(100);
set optimize_arithmetic_operations_in_aggregate_functions = 0;
SET optimize_arithmetic_operations_in_aggregate_functions = 0;
SELECT sum(n + 1), sum(1 + n), sum(n - 1), sum(1 - n) FROM (SELECT number n FROM numbers(10));
SELECT sum(n * 2), sum(2 * n), sum(n / 2), sum(1 / n) FROM (SELECT number n FROM numbers(10));
SELECT min(n + 1), min(1 + n), min(n - 1), min(1 - n) FROM (SELECT number n FROM numbers(10));
SELECT min(n * 2), min(2 * n), min(n / 2), min(1 / n) FROM (SELECT number n FROM numbers(10));
SELECT max(n + 1), max(1 + n), max(n - 1), max(1 - n) FROM (SELECT number n FROM numbers(10));
SELECT max(n * 2), max(2 * n), max(n / 2), max(1 / n) FROM (SELECT number n FROM numbers(10));
SELECT sum(n + -1), sum(-1 + n), sum(n - -1), sum(-1 - n) FROM (SELECT number n FROM numbers(10));
SELECT sum(n * -2), sum(-2 * n), sum(n / -2), sum(-1 / n) FROM (SELECT number n FROM numbers(10));
SELECT min(n + -1), min(-1 + n), min(n - -1), min(-1 - n) FROM (SELECT number n FROM numbers(10));
SELECT min(n * -2), min(-2 * n), min(n / -2), min(-1 / n) FROM (SELECT number n FROM numbers(10));
SELECT max(n + -1), max(-1 + n), max(n - -1), max(-1 - n) FROM (SELECT number n FROM numbers(10));
SELECT max(n * -2), max(-2 * n), max(n / -2), max(-1 / n) FROM (SELECT number n FROM numbers(10));
SELECT sum(abs(2) + 1), sum(abs(2) + n), sum(n - abs(2)), sum(1 - abs(2)) FROM (SELECT number n FROM numbers(10));
SELECT sum(abs(2) * 2), sum(abs(2) * n), sum(n / abs(2)), sum(1 / abs(2)) FROM (SELECT number n FROM numbers(10));
SELECT min(abs(2) + 1), min(abs(2) + n), min(n - abs(2)), min(1 - abs(2)) FROM (SELECT number n FROM numbers(10));
SELECT min(abs(2) * 2), min(abs(2) * n), min(n / abs(2)), min(1 / abs(2)) FROM (SELECT number n FROM numbers(10));
SELECT max(abs(2) + 1), max(abs(2) + n), max(n - abs(2)), max(1 - abs(2)) FROM (SELECT number n FROM numbers(10));
SELECT max(abs(2) * 2), max(abs(2) * n), max(n / abs(2)), max(1 / abs(2)) FROM (SELECT number n FROM numbers(10));
SELECT sum(abs(n) + 1), sum(abs(n) + n), sum(n - abs(n)), sum(1 - abs(n)) FROM (SELECT number n FROM numbers(10));
SELECT sum(abs(n) * 2), sum(abs(n) * n), sum(n / abs(n)), sum(1 / abs(n)) FROM (SELECT number n FROM numbers(10));
SELECT min(abs(n) + 1), min(abs(n) + n), min(n - abs(n)), min(1 - abs(n)) FROM (SELECT number n FROM numbers(10));
SELECT min(abs(n) * 2), min(abs(n) * n), min(n / abs(n)), min(1 / abs(n)) FROM (SELECT number n FROM numbers(10));
SELECT max(abs(n) + 1), max(abs(n) + n), max(n - abs(n)), max(1 - abs(n)) FROM (SELECT number n FROM numbers(10));
SELECT max(abs(n) * 2), max(abs(n) * n), max(n / abs(n)), max(1 / abs(n)) FROM (SELECT number n FROM numbers(10));
SELECT sum(n*n + 1), sum(1 + n*n), sum(n*n - 1), sum(1 - n*n) FROM (SELECT number n FROM numbers(10));
SELECT sum(n*n * 2), sum(2 * n*n), sum(n*n / 2), sum(1 / n*n) FROM (SELECT number n FROM numbers(10));
SELECT min(n*n + 1), min(1 + n*n), min(n*n - 1), min(1 - n*n) FROM (SELECT number n FROM numbers(10));
SELECT min(n*n * 2), min(2 * n*n), min(n*n / 2), min(1 / n*n) FROM (SELECT number n FROM numbers(10));
SELECT max(n*n + 1), max(1 + n*n), max(n*n - 1), max(1 - n*n) FROM (SELECT number n FROM numbers(10));
SELECT max(n*n * 2), max(2 * n*n), max(n*n / 2), max(1 / n*n) FROM (SELECT number n FROM numbers(10));
SELECT sum(1 + n + 1), sum(1 + 1 + n), sum(1 + n - 1), sum(1 + 1 - n) FROM (SELECT number n FROM numbers(10));
SELECT sum(1 + n * 2), sum(1 + 2 * n), sum(1 + n / 2), sum(1 + 1 / n) FROM (SELECT number n FROM numbers(10));
SELECT min(1 + n + 1), min(1 + 1 + n), min(1 + n - 1), min(1 + 1 - n) FROM (SELECT number n FROM numbers(10));
SELECT min(1 + n * 2), min(1 + 2 * n), min(1 + n / 2), min(1 + 1 / n) FROM (SELECT number n FROM numbers(10));
SELECT max(1 + n + 1), max(1 + 1 + n), max(1 + n - 1), max(1 + 1 - n) FROM (SELECT number n FROM numbers(10));
SELECT max(1 + n * 2), max(1 + 2 * n), max(1 + n / 2), max(1 + 1 / n) FROM (SELECT number n FROM numbers(10));
SELECT sum(n + -1 + -1), sum(-1 + n + -1), sum(n - -1 + -1), sum(-1 - n + -1) FROM (SELECT number n FROM numbers(10));
SELECT sum(n * -2 * -1), sum(-2 * n * -1), sum(n / -2 / -1), sum(-1 / n / -1) FROM (SELECT number n FROM numbers(10));
SELECT min(n + -1 + -1), min(-1 + n + -1), min(n - -1 + -1), min(-1 - n + -1) FROM (SELECT number n FROM numbers(10));
SELECT min(n * -2 * -1), min(-2 * n * -1), min(n / -2 / -1), min(-1 / n / -1) FROM (SELECT number n FROM numbers(10));
SELECT max(n + -1 + -1), max(-1 + n + -1), max(n - -1 + -1), max(-1 - n + -1) FROM (SELECT number n FROM numbers(10));
SELECT max(n * -2 * -1), max(-2 * n * -1), max(n / -2 / -1), max(-1 / n / -1) FROM (SELECT number n FROM numbers(10));
SELECT sum(n + 1) + sum(1 + n) + sum(n - 1) + sum(1 - n) FROM (SELECT number n FROM numbers(10));
SELECT sum(n * 2) + sum(2 * n) + sum(n / 2) + sum(1 / n) FROM (SELECT number n FROM numbers(10));
SELECT min(n + 1) + min(1 + n) + min(n - 1) + min(1 - n) FROM (SELECT number n FROM numbers(10));
SELECT min(n * 2) + min(2 * n) + min(n / 2) + min(1 / n) FROM (SELECT number n FROM numbers(10));
SELECT max(n + 1) + max(1 + n) + max(n - 1) + max(1 - n) FROM (SELECT number n FROM numbers(10));
SELECT max(n * 2) + max(2 * n) + max(n / 2) + max(1 / n) FROM (SELECT number n FROM numbers(10));
SELECT sum(number * -3) + min(2 * number * -3) - max(-1 * -2 * number * -3) FROM numbers(100);
SELECT max(log(2) * number) FROM numbers(100);