[Refactor](function) Reconstruct default logic for const args. (#17830)

This commit is contained in:
ZhaoChangle
2023-03-17 11:13:13 +08:00
committed by GitHub
parent 5d3de05976
commit b95cd7eca2
6 changed files with 63 additions and 71 deletions

View File

@ -128,8 +128,8 @@ NullPresence get_null_presence(const Block& block, const ColumnNumbers& args) {
return res;
}
bool allArgumentsAreConstants(const Block& block, const ColumnNumbers& args) {
for (auto arg : args) {
bool all_arguments_are_constant(const Block& block, const ColumnNumbers& args) {
for (const auto& arg : args) {
if (!is_column_const(*block.get_by_position(arg).column)) {
return false;
}
@ -138,53 +138,51 @@ bool allArgumentsAreConstants(const Block& block, const ColumnNumbers& args) {
}
} // namespace
inline Status PreparedFunctionImpl::_execute_skipped_constant_deal(
FunctionContext* context, Block& block, const ColumnNumbers& args, size_t result,
size_t input_rows_count, bool dry_run) {
bool executed = false;
RETURN_IF_ERROR(default_implementation_for_nulls(context, block, args, result, input_rows_count,
dry_run, &executed));
if (executed) {
return Status::OK();
}
if (dry_run) {
return execute_impl_dry_run(context, block, args, result, input_rows_count);
} else {
return execute_impl(context, block, args, result, input_rows_count);
}
}
Status PreparedFunctionImpl::default_implementation_for_constant_arguments(
FunctionContext* context, Block& block, const ColumnNumbers& args, size_t result,
size_t input_rows_count, bool dry_run, bool* executed) {
*executed = false;
ColumnNumbers arguments_to_remain_constants = get_arguments_that_are_always_constant();
ColumnNumbers args_expect_const = get_arguments_that_are_always_constant();
/// Check that these arguments are really constant.
for (auto arg_num : arguments_to_remain_constants) {
// Check that these arguments are really constant.
for (auto arg_num : args_expect_const) {
if (arg_num < args.size() &&
!is_column_const(*block.get_by_position(args[arg_num]).column)) {
return Status::RuntimeError("Argument at index {} for function {} must be constant",
arg_num, get_name());
return Status::InvalidArgument("Argument at index {} for function {} must be constant",
arg_num, get_name());
}
}
if (args.empty() || !use_default_implementation_for_constants() ||
!allArgumentsAreConstants(block, args)) {
!all_arguments_are_constant(block, args)) {
return Status::OK();
}
// now all columns is const.
Block temporary_block;
bool have_converted_columns = false;
size_t arguments_size = args.size();
for (size_t arg_num = 0; arg_num < arguments_size; ++arg_num) {
const ColumnWithTypeAndName& column = block.get_by_position(args[arg_num]);
if (arguments_to_remain_constants.end() != std::find(arguments_to_remain_constants.begin(),
arguments_to_remain_constants.end(),
arg_num)) {
temporary_block.insert({column.column->clone_resized(1), column.type, column.name});
} else {
have_converted_columns = true;
temporary_block.insert(
{assert_cast<const ColumnConst*>(column.column.get())->get_data_column_ptr(),
column.type, column.name});
}
}
/** When using default implementation for constants, the function requires at least one argument
* not in "arguments_to_remain_constants" set. Otherwise we get infinite recursion.
*/
if (!have_converted_columns) {
return Status::RuntimeError(
"Number of arguments for function {} doesn't match: the function "
"requires more arguments",
get_name());
temporary_block.insert(
{assert_cast<const ColumnConst*>(column.column.get())->get_data_column_ptr(),
column.type, column.name});
}
temporary_block.insert(block.get_by_position(result));
@ -194,9 +192,9 @@ Status PreparedFunctionImpl::default_implementation_for_constant_arguments(
temporary_argument_numbers[i] = i;
}
RETURN_IF_ERROR(execute_without_low_cardinality_columns(
context, temporary_block, temporary_argument_numbers, arguments_size,
temporary_block.rows(), dry_run));
RETURN_IF_ERROR(_execute_skipped_constant_deal(context, temporary_block,
temporary_argument_numbers, arguments_size,
temporary_block.rows(), dry_run));
ColumnPtr result_column;
/// extremely rare case, when we have function with completely const arguments
@ -248,21 +246,14 @@ Status PreparedFunctionImpl::execute_without_low_cardinality_columns(
FunctionContext* context, Block& block, const ColumnNumbers& args, size_t result,
size_t input_rows_count, bool dry_run) {
bool executed = false;
RETURN_IF_ERROR(default_implementation_for_constant_arguments(
context, block, args, result, input_rows_count, dry_run, &executed));
if (executed) {
return Status::OK();
}
RETURN_IF_ERROR(default_implementation_for_nulls(context, block, args, result, input_rows_count,
dry_run, &executed));
if (executed) {
return Status::OK();
}
if (dry_run)
return execute_impl_dry_run(context, block, args, result, input_rows_count);
else
return execute_impl(context, block, args, result, input_rows_count);
return _execute_skipped_constant_deal(context, block, args, result, input_rows_count, dry_run);
}
Status PreparedFunctionImpl::execute(FunctionContext* context, Block& block,