Details
Description
There are few places in the string related built-in functions which check whether the input argument is constant per row:
TimestampVal TimestampFunctions::ToTimestamp(FunctionContext* context, const StringVal& date, const StringVal& fmt) { if (fmt.is_null || fmt.len == 0) { TimestampFunctions::ReportBadFormat(context, fmt, false); return TimestampVal::null(); } if (date.is_null || date.len == 0) return TimestampVal::null(); void* state = context->GetFunctionState(FunctionContext::THREAD_LOCAL); DateTimeFormatContext* dt_ctx = reinterpret_cast<DateTimeFormatContext*>(state); if (!context->IsArgConstant(1)) { dt_ctx->Reset(reinterpret_cast<const char*>(fmt.ptr), fmt.len); if (!TimestampParser::ParseFormatTokens(dt_ctx)) { ReportBadFormat(context, fmt, false); return TimestampVal::null(); } } const TimestampValue& tv = TimestampValue::Parse( reinterpret_cast<const char*>(date.ptr), date.len, *dt_ctx); TimestampVal tv_val; tv.ToTimestampVal(&tv_val); return tv_val; }
StringVal StringFunctions::BTrimString(FunctionContext* ctx, const StringVal& str, const StringVal& chars_to_trim) { if (str.is_null) return StringVal::null(); bitset<256>* unique_chars = reinterpret_cast<bitset<256>*>( ctx->GetFunctionState(FunctionContext::THREAD_LOCAL)); // When 'chars_to_trim' is unique for each element (e.g. when 'chars_to_trim' // is each element of a table column), we need to prepare a bitset of unique // characters here instead of using the bitset from function context. if (!ctx->IsArgConstant(1)) { unique_chars->reset(); DCHECK(chars_to_trim.len != 0 || chars_to_trim.is_null); for (int32_t i = 0; i < chars_to_trim.len; ++i) { unique_chars->set(static_cast<int>(chars_to_trim.ptr[i]), true); } } ... ...
it seems generally useful to extend FunctionContextImpl::GetConstFnAttr() to also return whether the i-th argument to a UDF is constant or not and then replace these calls with constants during codegen.