Skip to content
Open
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 2 additions & 0 deletions src/duckdb/extension/core_functions/function_list.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ static const StaticFunctionDefinition core_functions[] = {
DUCKDB_SCALAR_FUNCTION_SET(GenerateSeriesFun),
DUCKDB_SCALAR_FUNCTION(GetBitFun),
DUCKDB_SCALAR_FUNCTION(GetCurrentTimestampFun),
DUCKDB_SCALAR_FUNCTION(GetTypeFun),
DUCKDB_SCALAR_FUNCTION_SET_ALIAS(GradeUpFun),
DUCKDB_SCALAR_FUNCTION_SET(GreatestFun),
DUCKDB_SCALAR_FUNCTION_SET(GreatestCommonDivisorFun),
Expand Down Expand Up @@ -266,6 +267,7 @@ static const StaticFunctionDefinition core_functions[] = {
DUCKDB_SCALAR_FUNCTION_SET(MakeTimestampFun),
DUCKDB_SCALAR_FUNCTION_SET(MakeTimestampMsFun),
DUCKDB_SCALAR_FUNCTION_SET(MakeTimestampNsFun),
DUCKDB_SCALAR_FUNCTION(MakeTypeFun),
DUCKDB_SCALAR_FUNCTION_SET(MapFun),
DUCKDB_SCALAR_FUNCTION(MapConcatFun),
DUCKDB_SCALAR_FUNCTION(MapEntriesFun),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,26 @@ struct TypeOfFun {
static ScalarFunction GetFunction();
};

struct GetTypeFun {
static constexpr const char *Name = "get_type";
static constexpr const char *Parameters = "expression";
static constexpr const char *Description = "Returns the type of the result of the expression";
static constexpr const char *Example = "get_type('abc')";
static constexpr const char *Categories = "";

static ScalarFunction GetFunction();
};

struct MakeTypeFun {
static constexpr const char *Name = "make_type";
static constexpr const char *Parameters = "name,...";
static constexpr const char *Description = "Construct a type from its name and optional parameters";
static constexpr const char *Example = "make_type('DECIMAL', 10, 2)";
static constexpr const char *Categories = "";

static ScalarFunction GetFunction();
};

struct CanCastImplicitlyFun {
static constexpr const char *Name = "can_cast_implicitly";
static constexpr const char *Parameters = "source_type,target_type";
Expand Down
16 changes: 10 additions & 6 deletions src/duckdb/extension/core_functions/lambda_functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#include "duckdb/planner/expression/bound_function_expression.hpp"
#include "duckdb/planner/expression/bound_cast_expression.hpp"
#include "duckdb/planner/expression/bound_lambda_expression.hpp"

namespace duckdb {

Expand All @@ -22,10 +23,11 @@ struct LambdaExecuteInfo {

// get the input types for the input chunk
vector<LogicalType> input_types;

input_types.push_back(child_vector.GetType());
if (has_index) {
input_types.push_back(LogicalType::BIGINT);
}
input_types.push_back(child_vector.GetType());
for (idx_t i = 1; i < args.ColumnCount(); i++) {
input_types.push_back(args.data[i].GetType());
}
Expand Down Expand Up @@ -152,8 +154,9 @@ struct ListFilterFunctor {

// slice the input chunk's corresponding vector to get the new lists
// and append them to the result
idx_t source_list_idx = execute_info.has_index ? 1 : 0;
Vector result_lists(execute_info.input_chunk.data[source_list_idx], sel, count);

// The first vector in the input chunk is always the list vector
Vector result_lists(execute_info.input_chunk.data[0], sel, count);
ListVector::Append(result, result_lists, count, 0);
}
};
Expand Down Expand Up @@ -190,8 +193,8 @@ static void ExecuteExpression(const idx_t elem_cnt, const LambdaFunctions::Colum

// reference the child vector (and the index vector)
if (info.has_index) {
info.input_chunk.data[0].Reference(index_vector);
info.input_chunk.data[1].Reference(slice);
info.input_chunk.data[0].Reference(slice);
info.input_chunk.data[1].Reference(index_vector);
} else {
info.input_chunk.data[0].Reference(slice);
}
Expand Down Expand Up @@ -247,7 +250,8 @@ LogicalType LambdaFunctions::DetermineListChildType(const LogicalType &child_typ
} else if (child_type.id() == LogicalTypeId::LIST) {
return ListType::GetChildType(child_type);
}
throw InternalException("The first argument must be a list or array type");

throw BinderException("Invalid LIST argument during lambda function binding!");
}

return child_type;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -517,7 +517,8 @@ unique_ptr<BaseStatistics> DateTruncStatistics(vector<BaseStatistics> &child_sta
auto result = NumericStats::CreateEmpty(min_value.type());
NumericStats::SetMin(result, min_value);
NumericStats::SetMax(result, max_value);
result.CopyValidity(child_stats[0]);

result.CombineValidity(child_stats[0], child_stats[1]);
return result.ToUnique();
}

Expand Down
121 changes: 121 additions & 0 deletions src/duckdb/extension/core_functions/scalar/generic/type_functions.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
#include "core_functions/scalar/generic_functions.hpp"
#include "duckdb/planner/expression/bound_constant_expression.hpp"
#include "duckdb/planner/expression/bound_function_expression.hpp"
#include "duckdb/parser/expression/constant_expression.hpp"
#include "duckdb/planner/binder.hpp"
#include "duckdb/parser/expression/type_expression.hpp"
#include "duckdb/execution/expression_executor.hpp"

namespace duckdb {

//----------------------------------------------------------------------------------------------------------------------
// typeof function
//----------------------------------------------------------------------------------------------------------------------

static void TypeOfFunction(DataChunk &args, ExpressionState &state, Vector &result) {
Value v(args.data[0].GetType().ToString());
result.Reference(v);
}

static unique_ptr<Expression> BindTypeOfFunctionExpression(FunctionBindExpressionInput &input) {
auto &return_type = input.children[0]->return_type;
if (return_type.id() == LogicalTypeId::UNKNOWN || return_type.id() == LogicalTypeId::SQLNULL) {
// parameter - unknown return type
return nullptr;
}
// emit a constant expression
return make_uniq<BoundConstantExpression>(Value(return_type.ToString()));
}

ScalarFunction TypeOfFun::GetFunction() {
auto fun = ScalarFunction({LogicalType::ANY}, LogicalType::VARCHAR, TypeOfFunction);
fun.SetNullHandling(FunctionNullHandling::SPECIAL_HANDLING);
fun.SetBindExpressionCallback(BindTypeOfFunctionExpression);
return fun;
}

//----------------------------------------------------------------------------------------------------------------------
// get_type function
//----------------------------------------------------------------------------------------------------------------------
// This is like "typeof", except returns LogicalType::TYPE instead of VARCHAR

static void GetTypeFunction(DataChunk &args, ExpressionState &state, Vector &result) {
auto v = Value::TYPE(args.data[0].GetType());
result.Reference(v);
}

static unique_ptr<Expression> BindGetTypeFunctionExpression(FunctionBindExpressionInput &input) {
auto &return_type = input.children[0]->return_type;
if (return_type.id() == LogicalTypeId::UNKNOWN || return_type.id() == LogicalTypeId::SQLNULL) {
// parameter - unknown return type
return nullptr;
}
// emit a constant expression
return make_uniq<BoundConstantExpression>(Value::TYPE(return_type));
}

ScalarFunction GetTypeFun::GetFunction() {
auto fun = ScalarFunction({LogicalType::ANY}, LogicalType::VARCHAR, GetTypeFunction);
fun.SetNullHandling(FunctionNullHandling::SPECIAL_HANDLING);
fun.SetBindExpressionCallback(BindGetTypeFunctionExpression);
return fun;
}

//----------------------------------------------------------------------------------------------------------------------
// make_type function
//----------------------------------------------------------------------------------------------------------------------
static void MakeTypeFunction(DataChunk &args, ExpressionState &state, Vector &result) {
throw InvalidInputException("make_type function can only be used in constant expressions");
}

static unique_ptr<Expression> BindMakeTypeFunctionExpression(FunctionBindExpressionInput &input) {
vector<pair<string, Value>> args;

// Evaluate all arguments to constant values
for (auto &child : input.children) {
string name = child->alias;
if (!child->IsFoldable()) {
throw BinderException("make_type function arguments must be constant expressions");
}
auto val = ExpressionExecutor::EvaluateScalar(input.context, *child);
args.emplace_back(name, val);
}

if (args.empty()) {
throw BinderException("make_type function requires at least one argument");
}

if (args.front().second.type() != LogicalType::VARCHAR) {
throw BinderException("make_type function first argument must be the type name as VARCHAR");
}

vector<unique_ptr<ParsedExpression>> type_args;
for (idx_t i = 1; i < args.size(); i++) {
auto &arg = args[i];
auto result = make_uniq<ConstantExpression>(arg.second);
result->SetAlias(arg.first);

type_args.push_back(std::move(result));
}

auto type_name = args.front().second.GetValue<string>();
auto qualified_name = QualifiedName::Parse(type_name);

auto unbound_type = LogicalType::UNBOUND(make_uniq<TypeExpression>(qualified_name.catalog, qualified_name.schema,
qualified_name.name, std::move(type_args)));

// Bind the unbound type
auto binder = Binder::CreateBinder(input.context);
binder->BindLogicalType(unbound_type);
return make_uniq<BoundConstantExpression>(Value::TYPE(unbound_type));
}

ScalarFunction MakeTypeFun::GetFunction() {
auto fun = ScalarFunction({LogicalType::VARCHAR}, LogicalType::TYPE(), MakeTypeFunction);
fun.SetNullHandling(FunctionNullHandling::SPECIAL_HANDLING);
fun.SetBindExpressionCallback(BindMakeTypeFunctionExpression);
fun.varargs = LogicalType::ANY;
return fun;
}

} // namespace duckdb
33 changes: 0 additions & 33 deletions src/duckdb/extension/core_functions/scalar/generic/typeof.cpp

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "duckdb/function/lambda_functions.hpp"
#include "duckdb/planner/expression/bound_cast_expression.hpp"
#include "duckdb/planner/expression/bound_lambda_expression.hpp"

namespace duckdb {

Expand Down
29 changes: 17 additions & 12 deletions src/duckdb/extension/core_functions/scalar/list/list_reduce.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#include "core_functions/scalar/list_functions.hpp"

#include "duckdb/function/lambda_functions.hpp"
#include "duckdb/planner/expression/bound_cast_expression.hpp"
#include "duckdb/planner/expression/bound_lambda_expression.hpp"

namespace duckdb {

Expand Down Expand Up @@ -41,11 +43,13 @@ struct ReduceExecuteInfo {
}
left_slice->Slice(left_vector, reduced_row_idx);

input_types.push_back(left_slice->GetType());
input_types.push_back(left_slice->GetType());

if (info.has_index) {
input_types.push_back(LogicalType::BIGINT);
}
input_types.push_back(left_slice->GetType());
input_types.push_back(left_slice->GetType());

// skip the first entry if there is an initial value
for (idx_t i = info.has_initial ? 1 : 0; i < info.column_infos.size(); i++) {
input_types.push_back(info.column_infos[i].vector.get().GetType());
Expand Down Expand Up @@ -133,18 +137,19 @@ bool ExecuteReduce(const idx_t loops, ReduceExecuteInfo &execute_info, LambdaFun
input_chunk.InitializeEmpty(execute_info.input_types);
input_chunk.SetCardinality(reduced_row_idx);

const idx_t slice_offset = info.has_index ? 1 : 0;
if (info.has_index) {
input_chunk.data[0].Reference(index_vector);
}
idx_t vec_offset = 0;

if (loops == 0 && info.has_initial) {
info.column_infos[0].vector.get().Slice(execute_info.active_rows_sel, reduced_row_idx);
input_chunk.data[slice_offset + 1].Reference(info.column_infos[0].vector);
info.column_infos[vec_offset].vector.get().Slice(execute_info.active_rows_sel, reduced_row_idx);
input_chunk.data[vec_offset++].Reference(info.column_infos[0].vector);
} else {
input_chunk.data[slice_offset + 1].Reference(*execute_info.left_slice);
input_chunk.data[vec_offset++].Reference(*execute_info.left_slice);
}
input_chunk.data[vec_offset++].Reference(right_slice);

if (info.has_index) {
input_chunk.data[vec_offset++].Reference(index_vector);
}
input_chunk.data[slice_offset].Reference(right_slice);

// add the other columns
// skip the initial value if there is one
Expand All @@ -153,12 +158,12 @@ bool ExecuteReduce(const idx_t loops, ReduceExecuteInfo &execute_info, LambdaFun
for (idx_t i = 0; i < info.column_infos.size() - initial_offset; i++) {
if (info.column_infos[i].vector.get().GetVectorType() == VectorType::CONSTANT_VECTOR) {
// only reference constant vectors
input_chunk.data[slice_offset + 2 + i].Reference(info.column_infos[initial_offset + i].vector);
input_chunk.data[vec_offset++].Reference(info.column_infos[initial_offset + i].vector);
} else {
// slice the other vectors
slices.emplace_back(info.column_infos[initial_offset + i].vector, execute_info.active_rows_sel,
reduced_row_idx);
input_chunk.data[slice_offset + 2 + i].Reference(slices.back());
input_chunk.data[vec_offset++].Reference(slices.back());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "duckdb/function/lambda_functions.hpp"
#include "duckdb/planner/expression/bound_cast_expression.hpp"
#include "duckdb/planner/expression/bound_lambda_expression.hpp"

namespace duckdb {

Expand Down
9 changes: 6 additions & 3 deletions src/duckdb/extension/icu/icu-makedate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@
#include "duckdb/common/operator/cast_operators.hpp"
#include "duckdb/common/operator/subtract.hpp"
#include "duckdb/common/types/date.hpp"
#include "duckdb/common/types/time.hpp"
#include "duckdb/common/types/timestamp.hpp"
#include "duckdb/common/vector_operations/senary_executor.hpp"
#include "duckdb/common/vector_operations/septenary_executor.hpp"
#include "duckdb/function/cast/cast_function_set.hpp"
#include "duckdb/main/extension/extension_loader.hpp"
#include "duckdb/parser/parsed_data/create_scalar_function_info.hpp"
#include "duckdb/main/settings.hpp"
#include "include/icu-casts.hpp"
#include "include/icu-datefunc.hpp"
#include "include/icu-datetrunc.hpp"
Expand Down Expand Up @@ -57,6 +56,10 @@ BoundCastInfo ICUMakeDate::BindCastToDate(BindCastInput &input, const LogicalTyp
if (!input.context) {
throw InternalException("Missing context for TIMESTAMPTZ to DATE cast.");
}
if (Settings::Get<DisableTimestamptzCastsSetting>(*input.context)) {
throw BinderException("Casting from TIMESTAMP WITH TIME ZONE to DATE without an explicit time zone "
"has been disabled - use \"AT TIME ZONE ...\"");
}

auto cast_data = make_uniq<CastData>(make_uniq<BindData>(*input.context));

Expand All @@ -80,7 +83,7 @@ struct ICUMakeTimestampTZFunc : public ICUDateFunc {
ss -= secs;
ss *= Interval::MSECS_PER_SEC;
const auto millis = int32_t(ss);
int64_t micros = std::round((ss - millis) * Interval::MICROS_PER_MSEC);
int64_t micros = LossyNumericCast<int64_t, double>(std::round((ss - millis) * Interval::MICROS_PER_MSEC));

calendar->set(UCAL_YEAR, year);
calendar->set(UCAL_MONTH, month);
Expand Down
4 changes: 2 additions & 2 deletions src/duckdb/extension/icu/icu-timezone.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ struct ICUFromNaiveTimestamp : public ICUDateFunc {
if (!input.context) {
throw InternalException("Missing context for TIMESTAMP to TIMESTAMPTZ cast.");
}
if (DBConfig::GetSetting<DisableTimestamptzCastsSetting>(*input.context)) {
if (Settings::Get<DisableTimestamptzCastsSetting>(*input.context)) {
throw BinderException("Casting from TIMESTAMP to TIMESTAMP WITH TIME ZONE without an explicit time zone "
"has been disabled - use \"AT TIME ZONE ...\"");
}
Expand Down Expand Up @@ -251,7 +251,7 @@ struct ICUToNaiveTimestamp : public ICUDateFunc {
if (!input.context) {
throw InternalException("Missing context for TIMESTAMPTZ to TIMESTAMP cast.");
}
if (DBConfig::GetSetting<DisableTimestamptzCastsSetting>(*input.context)) {
if (Settings::Get<DisableTimestamptzCastsSetting>(*input.context)) {
throw BinderException("Casting from TIMESTAMP WITH TIME ZONE to TIMESTAMP without an explicit time zone "
"has been disabled - use \"AT TIME ZONE ...\"");
}
Expand Down
Loading
Loading