Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions be/src/exprs/function/uniform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "core/block/block.h"
#include "core/block/column_numbers.h"
#include "core/column/column.h"
#include "core/column/column_execute_util.h"
#include "core/column/column_vector.h"
#include "core/data_type/data_type_number.h" // IWYU pragma: keep
#include "core/data_type/primitive_type.h"
Expand Down Expand Up @@ -73,12 +74,12 @@ struct UniformIntImpl {
"uniform's min should be less than max, but got [{}, {})", min, max);
}

// Get gen column (seed values)
const auto& gen_column = block.get_by_position(arguments[2]).column;
auto gen_column =
ColumnView<TYPE_BIGINT>::create(block.get_by_position(arguments[2]).column);

for (int i = 0; i < input_rows_count; i++) {
// Use gen value as seed for each row
auto seed = (*gen_column)[i].get<TYPE_BIGINT>();
auto seed = gen_column.value_at(i);
std::mt19937_64 generator(seed);
std::uniform_int_distribution<int64_t> distribution(min, max);
res_data[i] = distribution(generator);
Expand Down Expand Up @@ -122,11 +123,12 @@ struct UniformDoubleImpl {
}

// Get gen column (seed values)
const auto& gen_column = block.get_by_position(arguments[2]).column;
auto gen_column =
ColumnView<TYPE_BIGINT>::create(block.get_by_position(arguments[2]).column);

for (int i = 0; i < input_rows_count; i++) {
// Use gen value as seed for each row
auto seed = (*gen_column)[i].get<TYPE_BIGINT>();
auto seed = gen_column.value_at(i);
std::mt19937_64 generator(seed);
std::uniform_real_distribution<double> distribution(min, max);
res_data[i] = distribution(generator);
Expand Down Expand Up @@ -157,6 +159,8 @@ class FunctionUniform : public IFunction {
return Impl::get_variadic_argument_types();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This override makes the default all-constant path keep min/max as ColumnConst but unwrap the seed argument to its nested data column. In PreparedFunctionImpl::default_implementation_for_constant_arguments, temporary_block.rows() is then taken from the first column, so for a row-producing query such as a classic-planner path that reaches BE with uniform(1, 100, 1), the temp block has min as ColumnConst(size = input_rows_count) and seed as ColumnInt64(size = 1). execute_impl loops input_rows_count rows and ColumnView treats the unwrapped seed as non-const, so value_at(1) and later read past the one-row seed column.

Nereids currently rejects a literal seed, but this BE function is also the execution boundary for non-Nereids/classic and BE constant-fold paths, and this PR specifically changes BE constant handling. Please either enforce the third argument must not be constant at BE execution/open time or disable/adjust the default constant-argument path so the seed remains a correctly sized ColumnConst rather than a one-row nested column.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This override makes the default all-constant path keep min/max as ColumnConst but unwrap the seed argument to its nested data column. In PreparedFunctionImpl::default_implementation_for_constant_arguments, temporary_block.rows() is then taken from the first column, so for a row-producing query such as a classic-planner path that reaches BE with uniform(1, 100, 1), the temp block has min as ColumnConst(size = input_rows_count) and seed as ColumnInt64(size = 1). execute_impl loops input_rows_count rows and ColumnView treats the unwrapped seed as non-const, so value_at(1) and later read past the one-row seed column.

Nereids currently rejects a literal seed, but this BE function is also the execution boundary for non-Nereids/classic and BE constant-fold paths, and this PR specifically changes BE constant handling. Please either enforce the third argument must not be constant at BE execution/open time or disable/adjust the default constant-argument path so the seed remains a correctly sized ColumnConst rather than a one-row nested column.

某个设计上的问题,目前的be的执行框架,在执行的时候,一个函数/表达式 返回会返回column const,或者非column const (有一些函数会根据runtime的value来直接返回一个column const 的column

}

ColumnNumbers get_arguments_that_are_always_constant() const override { return {0, 1}; }

Status open(FunctionContext* context, FunctionContext::FunctionStateScope scope) override {
// init_function_context do set_constant_cols for FRAGMENT_LOCAL scope
if (scope == FunctionContext::FRAGMENT_LOCAL) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ suite("nereids_scalar_fn_U") {

def result = sql """select uniform(1, 100, random()*10000) from numbers("number" = "10");"""
assertTrue(result.size() == 10)
def doubleResult = sql """select uniform(1.23, 100.100, random()*10000) from numbers("number" = "10");"""
assertTrue(doubleResult.size() == 10)
test {
sql """select uniform(100, 1, random()*10000) from numbers("number" = "10");"""
exception "uniform's min should be less than max"
Expand Down
Loading