Skip to content

Commit

Permalink
Merge pull request #10426 from Mytherin/nowpushdown
Browse files Browse the repository at this point in the history
Rework FunctionSideEffects to FunctionStability - allow NOW() to be pushed down
  • Loading branch information
Mytherin committed Feb 2, 2024
2 parents 2d496b8 + 8b0d956 commit d4ed7c7
Show file tree
Hide file tree
Showing 46 changed files with 380 additions and 146 deletions.
23 changes: 15 additions & 8 deletions extension/parquet/parquet_statistics.cpp
Expand Up @@ -208,11 +208,12 @@ Value ParquetStatisticsUtils::ConvertValue(const LogicalType &type,
}
case LogicalTypeId::TIMESTAMP:
case LogicalTypeId::TIMESTAMP_TZ: {
timestamp_t timestamp_value;
if (schema_ele.type == Type::INT96) {
if (stats.size() != sizeof(Int96)) {
throw InternalException("Incorrect stats size for type TIMESTAMP");
}
return Value::TIMESTAMP(ImpalaTimestampToTimestamp(Load<Int96>(stats_data)));
timestamp_value = ImpalaTimestampToTimestamp(Load<Int96>(stats_data));
} else {
D_ASSERT(schema_ele.type == Type::INT64);
if (stats.size() != sizeof(int64_t)) {
Expand All @@ -222,21 +223,25 @@ Value ParquetStatisticsUtils::ConvertValue(const LogicalType &type,
if (schema_ele.__isset.logicalType && schema_ele.logicalType.__isset.TIMESTAMP) {
// logical type
if (schema_ele.logicalType.TIMESTAMP.unit.__isset.MILLIS) {
return Value::TIMESTAMPMS(timestamp_t(val));
timestamp_value = Timestamp::FromEpochMs(val);
} else if (schema_ele.logicalType.TIMESTAMP.unit.__isset.NANOS) {
return Value::TIMESTAMPNS(timestamp_t(val));
timestamp_value = Timestamp::FromEpochNanoSeconds(val);
} else if (schema_ele.logicalType.TIMESTAMP.unit.__isset.MICROS) {
return Value::TIMESTAMP(timestamp_t(val));
timestamp_value = timestamp_t(val);
} else {
throw InternalException("Timestamp logicalType is set but unit is not defined");
}
}
if (schema_ele.converted_type == duckdb_parquet::format::ConvertedType::TIMESTAMP_MILLIS) {
return Value::TIMESTAMPMS(timestamp_t(val));
} else if (schema_ele.converted_type == duckdb_parquet::format::ConvertedType::TIMESTAMP_MILLIS) {
timestamp_value = Timestamp::FromEpochMs(val);
} else {
return Value::TIMESTAMP(timestamp_t(val));
timestamp_value = timestamp_t(val);
}
}
if (type.id() == LogicalTypeId::TIMESTAMP_TZ) {
return Value::TIMESTAMPTZ(timestamp_value);
} else {
return Value::TIMESTAMP(timestamp_value);
}
}
default:
throw InternalException("Unsupported type for stats %s", type.ToString());
Expand Down Expand Up @@ -298,7 +303,9 @@ unique_ptr<BaseStatistics> ParquetStatisticsUtils::TransformColumnStatistics(con
case LogicalTypeId::DOUBLE:
case LogicalTypeId::DATE:
case LogicalTypeId::TIME:
case LogicalTypeId::TIME_TZ:
case LogicalTypeId::TIMESTAMP:
case LogicalTypeId::TIMESTAMP_TZ:
case LogicalTypeId::TIMESTAMP_SEC:
case LogicalTypeId::TIMESTAMP_MS:
case LogicalTypeId::TIMESTAMP_NS:
Expand Down
2 changes: 1 addition & 1 deletion src/catalog/default/default_views.cpp
Expand Up @@ -38,7 +38,7 @@ static DefaultView internal_views[] = {
{"pg_catalog", "pg_index", "SELECT index_oid indexrelid, table_oid indrelid, 0 indnatts, 0 indnkeyatts, is_unique indisunique, is_primary indisprimary, false indisexclusion, true indimmediate, false indisclustered, true indisvalid, false indcheckxmin, true indisready, true indislive, false indisreplident, NULL::INT[] indkey, NULL::OID[] indcollation, NULL::OID[] indclass, NULL::INT[] indoption, expressions indexprs, NULL indpred FROM duckdb_indexes()"},
{"pg_catalog", "pg_indexes", "SELECT schema_name schemaname, table_name tablename, index_name indexname, NULL \"tablespace\", sql indexdef FROM duckdb_indexes()"},
{"pg_catalog", "pg_namespace", "SELECT oid, schema_name nspname, 0 nspowner, NULL nspacl FROM duckdb_schemas()"},
{"pg_catalog", "pg_proc", "SELECT f.function_oid oid, function_name proname, s.oid pronamespace, NULL proowner, NULL prolang, 0 procost, 0 prorows, varargs provariadic, 0 prosupport, CASE function_type WHEN 'aggregate' THEN 'a' ELSE 'f' END prokind, false prosecdef, false proleakproof, false proisstrict, function_type = 'table' proretset, CASE WHEN has_side_effects THEN 'v' ELSE 'i' END provolatile, 'u' proparallel, length(parameters) pronargs, 0 pronargdefaults, return_type prorettype, parameter_types proargtypes, NULL proallargtypes, NULL proargmodes, parameters proargnames, NULL proargdefaults, NULL protrftypes, NULL prosrc, NULL probin, macro_definition prosqlbody, NULL proconfig, NULL proacl, function_type = 'aggregate' proisagg, FROM duckdb_functions() f LEFT JOIN duckdb_schemas() s USING (database_name, schema_name)"},
{"pg_catalog", "pg_proc", "SELECT f.function_oid oid, function_name proname, s.oid pronamespace, NULL proowner, NULL prolang, 0 procost, 0 prorows, varargs provariadic, 0 prosupport, CASE function_type WHEN 'aggregate' THEN 'a' ELSE 'f' END prokind, false prosecdef, false proleakproof, false proisstrict, function_type = 'table' proretset, case (stability) when 'CONSISTENT' then 'i' when 'CONSISTENT_WITHIN_QUERY' then 's' when 'VOLATILE' then 'v' end provolatile, 'u' proparallel, length(parameters) pronargs, 0 pronargdefaults, return_type prorettype, parameter_types proargtypes, NULL proallargtypes, NULL proargmodes, parameters proargnames, NULL proargdefaults, NULL protrftypes, NULL prosrc, NULL probin, macro_definition prosqlbody, NULL proconfig, NULL proacl, function_type = 'aggregate' proisagg, FROM duckdb_functions() f LEFT JOIN duckdb_schemas() s USING (database_name, schema_name)"},
{"pg_catalog", "pg_sequence", "SELECT sequence_oid seqrelid, 0 seqtypid, start_value seqstart, increment_by seqincrement, max_value seqmax, min_value seqmin, 0 seqcache, cycle seqcycle FROM duckdb_sequences()"},
{"pg_catalog", "pg_sequences", "SELECT schema_name schemaname, sequence_name sequencename, 'duckdb' sequenceowner, 0 data_type, start_value, min_value, max_value, increment_by, cycle, 0 cache_size, last_value FROM duckdb_sequences()"},
{"pg_catalog", "pg_settings", "SELECT name, value setting, description short_desc, CASE WHEN input_type = 'VARCHAR' THEN 'string' WHEN input_type = 'BOOLEAN' THEN 'bool' WHEN input_type IN ('BIGINT', 'UBIGINT') THEN 'integer' ELSE input_type END vartype FROM duckdb_settings()"},
Expand Down
25 changes: 15 additions & 10 deletions src/common/enum_util.cpp
Expand Up @@ -2517,24 +2517,29 @@ FunctionNullHandling EnumUtil::FromString<FunctionNullHandling>(const char *valu
}

template<>
const char* EnumUtil::ToChars<FunctionSideEffects>(FunctionSideEffects value) {
const char* EnumUtil::ToChars<FunctionStability>(FunctionStability value) {
switch(value) {
case FunctionSideEffects::NO_SIDE_EFFECTS:
return "NO_SIDE_EFFECTS";
case FunctionSideEffects::HAS_SIDE_EFFECTS:
return "HAS_SIDE_EFFECTS";
case FunctionStability::CONSISTENT:
return "CONSISTENT";
case FunctionStability::VOLATILE:
return "VOLATILE";
case FunctionStability::CONSISTENT_WITHIN_QUERY:
return "CONSISTENT_WITHIN_QUERY";
default:
throw NotImplementedException(StringUtil::Format("Enum value: '%d' not implemented", value));
}
}

template<>
FunctionSideEffects EnumUtil::FromString<FunctionSideEffects>(const char *value) {
if (StringUtil::Equals(value, "NO_SIDE_EFFECTS")) {
return FunctionSideEffects::NO_SIDE_EFFECTS;
FunctionStability EnumUtil::FromString<FunctionStability>(const char *value) {
if (StringUtil::Equals(value, "CONSISTENT")) {
return FunctionStability::CONSISTENT;
}
if (StringUtil::Equals(value, "HAS_SIDE_EFFECTS")) {
return FunctionSideEffects::HAS_SIDE_EFFECTS;
if (StringUtil::Equals(value, "VOLATILE")) {
return FunctionStability::VOLATILE;
}
if (StringUtil::Equals(value, "CONSISTENT_WITHIN_QUERY")) {
return FunctionStability::CONSISTENT_WITHIN_QUERY;
}
throw NotImplementedException(StringUtil::Format("Enum value: '%s' not implemented", value));
}
Expand Down
2 changes: 1 addition & 1 deletion src/core_functions/lambda_functions.cpp
Expand Up @@ -366,7 +366,7 @@ void ExecuteLambda(DataChunk &args, ExpressionState &state, Vector &result) {

FUNCTION_FUNCTOR::AppendResult(result, lambda_vector, elem_cnt, result_entries, list_filter_info, execute_info);

if (info.is_all_constant && !info.has_side_effects) {
if (info.is_all_constant && !info.is_volatile) {
result.SetVectorType(VectorType::CONSTANT_VECTOR);
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/core_functions/scalar/date/current.cpp
Expand Up @@ -35,19 +35,19 @@ static void CurrentTimestampFunction(DataChunk &input, ExpressionState &state, V

ScalarFunction CurrentTimeFun::GetFunction() {
ScalarFunction current_time({}, LogicalType::TIME, CurrentTimeFunction);
current_time.side_effects = FunctionSideEffects::HAS_SIDE_EFFECTS;
current_time.stability = FunctionStability::CONSISTENT_WITHIN_QUERY;
return current_time;
}

ScalarFunction CurrentDateFun::GetFunction() {
ScalarFunction current_date({}, LogicalType::DATE, CurrentDateFunction);
current_date.side_effects = FunctionSideEffects::HAS_SIDE_EFFECTS;
current_date.stability = FunctionStability::CONSISTENT_WITHIN_QUERY;
return current_date;
}

ScalarFunction GetCurrentTimestampFun::GetFunction() {
ScalarFunction current_timestamp({}, LogicalType::TIMESTAMP_TZ, CurrentTimestampFunction);
current_timestamp.side_effects = FunctionSideEffects::HAS_SIDE_EFFECTS;
current_timestamp.stability = FunctionStability::CONSISTENT_WITHIN_QUERY;
return current_timestamp;
}

Expand Down
2 changes: 1 addition & 1 deletion src/core_functions/scalar/generic/error.cpp
Expand Up @@ -14,7 +14,7 @@ ScalarFunction ErrorFun::GetFunction() {
auto fun = ScalarFunction({LogicalType::VARCHAR}, LogicalType::SQLNULL,
ScalarFunction::UnaryFunction<string_t, int32_t, ErrorOperator>);
// Set the function with side effects to avoid the optimization.
fun.side_effects = FunctionSideEffects::HAS_SIDE_EFFECTS;
fun.stability = FunctionStability::VOLATILE;
return fun;
}

Expand Down
15 changes: 7 additions & 8 deletions src/core_functions/scalar/generic/least.cpp
Expand Up @@ -97,25 +97,24 @@ static void LeastGreatestFunction(DataChunk &args, ExpressionState &state, Vecto
template <typename T, class OP>
ScalarFunction GetLeastGreatestFunction(const LogicalType &type) {
return ScalarFunction({type}, type, LeastGreatestFunction<T, OP>, nullptr, nullptr, nullptr, nullptr, type,
FunctionSideEffects::NO_SIDE_EFFECTS, FunctionNullHandling::SPECIAL_HANDLING);
FunctionStability::CONSISTENT, FunctionNullHandling::SPECIAL_HANDLING);
}

template <class OP>
static ScalarFunctionSet GetLeastGreatestFunctions() {
ScalarFunctionSet fun_set;
fun_set.AddFunction(ScalarFunction({LogicalType::BIGINT}, LogicalType::BIGINT, LeastGreatestFunction<int64_t, OP>,
nullptr, nullptr, nullptr, nullptr, LogicalType::BIGINT,
FunctionSideEffects::NO_SIDE_EFFECTS, FunctionNullHandling::SPECIAL_HANDLING));
FunctionStability::CONSISTENT, FunctionNullHandling::SPECIAL_HANDLING));
fun_set.AddFunction(ScalarFunction(
{LogicalType::HUGEINT}, LogicalType::HUGEINT, LeastGreatestFunction<hugeint_t, OP>, nullptr, nullptr, nullptr,
nullptr, LogicalType::HUGEINT, FunctionSideEffects::NO_SIDE_EFFECTS, FunctionNullHandling::SPECIAL_HANDLING));
nullptr, LogicalType::HUGEINT, FunctionStability::CONSISTENT, FunctionNullHandling::SPECIAL_HANDLING));
fun_set.AddFunction(ScalarFunction({LogicalType::DOUBLE}, LogicalType::DOUBLE, LeastGreatestFunction<double, OP>,
nullptr, nullptr, nullptr, nullptr, LogicalType::DOUBLE,
FunctionSideEffects::NO_SIDE_EFFECTS, FunctionNullHandling::SPECIAL_HANDLING));
fun_set.AddFunction(ScalarFunction({LogicalType::VARCHAR}, LogicalType::VARCHAR,
LeastGreatestFunction<string_t, OP, true>, nullptr, nullptr, nullptr, nullptr,
LogicalType::VARCHAR, FunctionSideEffects::NO_SIDE_EFFECTS,
FunctionNullHandling::SPECIAL_HANDLING));
FunctionStability::CONSISTENT, FunctionNullHandling::SPECIAL_HANDLING));
fun_set.AddFunction(ScalarFunction(
{LogicalType::VARCHAR}, LogicalType::VARCHAR, LeastGreatestFunction<string_t, OP, true>, nullptr, nullptr,
nullptr, nullptr, LogicalType::VARCHAR, FunctionStability::CONSISTENT, FunctionNullHandling::SPECIAL_HANDLING));

fun_set.AddFunction(GetLeastGreatestFunction<timestamp_t, OP>(LogicalType::TIMESTAMP));
fun_set.AddFunction(GetLeastGreatestFunction<time_t, OP>(LogicalType::TIME));
Expand Down
2 changes: 1 addition & 1 deletion src/core_functions/scalar/generic/stats.cpp
Expand Up @@ -47,7 +47,7 @@ ScalarFunction StatsFun::GetFunction() {
ScalarFunction stats({LogicalType::ANY}, LogicalType::VARCHAR, StatsFunction, StatsBind, nullptr,
StatsPropagateStats);
stats.null_handling = FunctionNullHandling::SPECIAL_HANDLING;
stats.side_effects = FunctionSideEffects::HAS_SIDE_EFFECTS;
stats.stability = FunctionStability::VOLATILE;
return stats;
}

Expand Down
23 changes: 17 additions & 6 deletions src/core_functions/scalar/generic/system_functions.cpp
Expand Up @@ -76,29 +76,40 @@ static void VersionFunction(DataChunk &input, ExpressionState &state, Vector &re

ScalarFunction CurrentQueryFun::GetFunction() {
ScalarFunction current_query({}, LogicalType::VARCHAR, CurrentQueryFunction);
current_query.side_effects = FunctionSideEffects::HAS_SIDE_EFFECTS;
current_query.stability = FunctionStability::VOLATILE;
return current_query;
}

ScalarFunction CurrentSchemaFun::GetFunction() {
return ScalarFunction({}, LogicalType::VARCHAR, CurrentSchemaFunction);
ScalarFunction current_schema({}, LogicalType::VARCHAR, CurrentSchemaFunction);
current_schema.stability = FunctionStability::CONSISTENT_WITHIN_QUERY;
return current_schema;
}

ScalarFunction CurrentDatabaseFun::GetFunction() {
return ScalarFunction({}, LogicalType::VARCHAR, CurrentDatabaseFunction);
ScalarFunction current_database({}, LogicalType::VARCHAR, CurrentDatabaseFunction);
current_database.stability = FunctionStability::CONSISTENT_WITHIN_QUERY;
return current_database;
}

ScalarFunction CurrentSchemasFun::GetFunction() {
auto varchar_list_type = LogicalType::LIST(LogicalType::VARCHAR);
return ScalarFunction({LogicalType::BOOLEAN}, varchar_list_type, CurrentSchemasFunction);
ScalarFunction current_schemas({LogicalType::BOOLEAN}, varchar_list_type, CurrentSchemasFunction);
current_schemas.stability = FunctionStability::CONSISTENT_WITHIN_QUERY;
return current_schemas;
}

ScalarFunction InSearchPathFun::GetFunction() {
return ScalarFunction({LogicalType::VARCHAR, LogicalType::VARCHAR}, LogicalType::BOOLEAN, InSearchPathFunction);
ScalarFunction in_search_path({LogicalType::VARCHAR, LogicalType::VARCHAR}, LogicalType::BOOLEAN,
InSearchPathFunction);
in_search_path.stability = FunctionStability::CONSISTENT_WITHIN_QUERY;
return in_search_path;
}

ScalarFunction CurrentTransactionIdFun::GetFunction() {
return ScalarFunction({}, LogicalType::BIGINT, TransactionIdCurrent);
ScalarFunction txid_current({}, LogicalType::BIGINT, TransactionIdCurrent);
txid_current.stability = FunctionStability::CONSISTENT_WITHIN_QUERY;
return txid_current;
}

ScalarFunction VersionFun::GetFunction() {
Expand Down
2 changes: 1 addition & 1 deletion src/core_functions/scalar/list/list_reduce.cpp
Expand Up @@ -172,7 +172,7 @@ void LambdaFunctions::ListReduceFunction(duckdb::DataChunk &args, duckdb::Expres
loops++;
}

if (info.is_all_constant && !info.has_side_effects) {
if (info.is_all_constant && !info.is_volatile) {
info.result.SetVectorType(VectorType::CONSTANT_VECTOR);
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/core_functions/scalar/random/random.cpp
Expand Up @@ -36,7 +36,7 @@ static unique_ptr<FunctionLocalState> RandomInitLocalState(ExpressionState &stat
ScalarFunction RandomFun::GetFunction() {
ScalarFunction random("random", {}, LogicalType::DOUBLE, RandomFunction, nullptr, nullptr, nullptr,
RandomInitLocalState);
random.side_effects = FunctionSideEffects::HAS_SIDE_EFFECTS;
random.stability = FunctionStability::VOLATILE;
return random;
}

Expand All @@ -56,7 +56,7 @@ ScalarFunction UUIDFun::GetFunction() {
ScalarFunction uuid_function({}, LogicalType::UUID, GenerateUUIDFunction, nullptr, nullptr, nullptr,
RandomInitLocalState);
// generate a random uuid
uuid_function.side_effects = FunctionSideEffects::HAS_SIDE_EFFECTS;
uuid_function.stability = FunctionStability::VOLATILE;
return uuid_function;
}

Expand Down
2 changes: 1 addition & 1 deletion src/core_functions/scalar/random/setseed.cpp
Expand Up @@ -54,7 +54,7 @@ unique_ptr<FunctionData> SetSeedBind(ClientContext &context, ScalarFunction &bou

ScalarFunction SetseedFun::GetFunction() {
ScalarFunction setseed("setseed", {LogicalType::DOUBLE}, LogicalType::SQLNULL, SetSeedFunction, SetSeedBind);
setseed.side_effects = FunctionSideEffects::HAS_SIDE_EFFECTS;
setseed.stability = FunctionStability::VOLATILE;
return setseed;
}

Expand Down
26 changes: 12 additions & 14 deletions src/core_functions/scalar/string/parse_path.cpp
Expand Up @@ -293,7 +293,7 @@ static void ParsePathFunction(DataChunk &args, ExpressionState &state, Vector &r
ScalarFunctionSet ParseDirnameFun::GetFunctions() {
ScalarFunctionSet parse_dirname;
ScalarFunction func({LogicalType::VARCHAR}, LogicalType::VARCHAR, TrimPathFunction<true>, nullptr, nullptr, nullptr,
nullptr, LogicalType::INVALID, FunctionSideEffects::NO_SIDE_EFFECTS,
nullptr, LogicalType::INVALID, FunctionStability::CONSISTENT,
FunctionNullHandling::SPECIAL_HANDLING);
parse_dirname.AddFunction(func);
// separator options
Expand All @@ -305,7 +305,7 @@ ScalarFunctionSet ParseDirnameFun::GetFunctions() {
ScalarFunctionSet ParseDirpathFun::GetFunctions() {
ScalarFunctionSet parse_dirpath;
ScalarFunction func({LogicalType::VARCHAR}, LogicalType::VARCHAR, ParseDirpathFunction, nullptr, nullptr, nullptr,
nullptr, LogicalType::INVALID, FunctionSideEffects::NO_SIDE_EFFECTS,
nullptr, LogicalType::INVALID, FunctionStability::CONSISTENT,
FunctionNullHandling::SPECIAL_HANDLING);
parse_dirpath.AddFunction(func);
// separator options
Expand All @@ -316,20 +316,18 @@ ScalarFunctionSet ParseDirpathFun::GetFunctions() {

ScalarFunctionSet ParseFilenameFun::GetFunctions() {
ScalarFunctionSet parse_filename;
parse_filename.AddFunction(ScalarFunction({LogicalType::VARCHAR}, LogicalType::VARCHAR, TrimPathFunction<false>,
nullptr, nullptr, nullptr, nullptr, LogicalType::INVALID,
FunctionStability::CONSISTENT, FunctionNullHandling::SPECIAL_HANDLING));
parse_filename.AddFunction(ScalarFunction(
{LogicalType::VARCHAR}, LogicalType::VARCHAR, TrimPathFunction<false>, nullptr, nullptr, nullptr, nullptr,
LogicalType::INVALID, FunctionSideEffects::NO_SIDE_EFFECTS, FunctionNullHandling::SPECIAL_HANDLING));
parse_filename.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::VARCHAR}, LogicalType::VARCHAR,
TrimPathFunction<false>, nullptr, nullptr, nullptr, nullptr,
LogicalType::INVALID, FunctionSideEffects::NO_SIDE_EFFECTS,
FunctionNullHandling::SPECIAL_HANDLING));
parse_filename.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::BOOLEAN}, LogicalType::VARCHAR,
TrimPathFunction<false>, nullptr, nullptr, nullptr, nullptr,
LogicalType::INVALID, FunctionSideEffects::NO_SIDE_EFFECTS,
FunctionNullHandling::SPECIAL_HANDLING));
{LogicalType::VARCHAR, LogicalType::VARCHAR}, LogicalType::VARCHAR, TrimPathFunction<false>, nullptr, nullptr,
nullptr, nullptr, LogicalType::INVALID, FunctionStability::CONSISTENT, FunctionNullHandling::SPECIAL_HANDLING));
parse_filename.AddFunction(ScalarFunction(
{LogicalType::VARCHAR, LogicalType::BOOLEAN}, LogicalType::VARCHAR, TrimPathFunction<false>, nullptr, nullptr,
nullptr, nullptr, LogicalType::INVALID, FunctionStability::CONSISTENT, FunctionNullHandling::SPECIAL_HANDLING));
parse_filename.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::BOOLEAN, LogicalType::VARCHAR},
LogicalType::VARCHAR, TrimPathFunction<false>, nullptr, nullptr, nullptr,
nullptr, LogicalType::INVALID, FunctionSideEffects::NO_SIDE_EFFECTS,
nullptr, LogicalType::INVALID, FunctionStability::CONSISTENT,
FunctionNullHandling::SPECIAL_HANDLING));
return parse_filename;
}
Expand All @@ -338,7 +336,7 @@ ScalarFunctionSet ParsePathFun::GetFunctions() {
auto varchar_list_type = LogicalType::LIST(LogicalType::VARCHAR);
ScalarFunctionSet parse_path;
ScalarFunction func({LogicalType::VARCHAR}, varchar_list_type, ParsePathFunction, nullptr, nullptr, nullptr,
nullptr, LogicalType::INVALID, FunctionSideEffects::NO_SIDE_EFFECTS,
nullptr, LogicalType::INVALID, FunctionStability::CONSISTENT,
FunctionNullHandling::SPECIAL_HANDLING);
parse_path.AddFunction(func);
// separator options
Expand Down

0 comments on commit d4ed7c7

Please sign in to comment.