Skip to content

Commit

Permalink
Make typeof a constant function (removing its argument) so that the o…
Browse files Browse the repository at this point in the history
…ptimizer can optimize branches away
  • Loading branch information
Mytherin committed Jun 17, 2024
1 parent 0bf7991 commit 4455c46
Showing 1 changed file with 45 additions and 3 deletions.
48 changes: 45 additions & 3 deletions src/core_functions/scalar/generic/typeof.cpp
Original file line number Diff line number Diff line change
@@ -1,15 +1,57 @@
#include "duckdb/core_functions/scalar/generic_functions.hpp"
#include "duckdb/common/serializer/serializer.hpp"
#include "duckdb/common/serializer/deserializer.hpp"
#include "duckdb/planner/expression/bound_function_expression.hpp"

namespace duckdb {

struct ConstantReturnBindData : public FunctionData {
Value val;

explicit ConstantReturnBindData(Value val_p) : val(std::move(val_p)) {
}

unique_ptr<FunctionData> Copy() const override {
return make_uniq<ConstantReturnBindData>(val);
}
bool Equals(const FunctionData &other_p) const override {
auto &other = other_p.Cast<ConstantReturnBindData>();
return val == other.val;
}
static void Serialize(Serializer &serializer, const optional_ptr<FunctionData> bind_data,
const ScalarFunction &function) {
auto &info = bind_data->Cast<ConstantReturnBindData>();
serializer.WriteProperty(100, "constant_value", info.val);
}

static unique_ptr<FunctionData> Deserialize(Deserializer &deserializer, ScalarFunction &bound_function) {
auto value = deserializer.ReadProperty<Value>(100, "constant_value");
return make_uniq<ConstantReturnBindData>(std::move(value));
}
};

static void TypeOfFunction(DataChunk &args, ExpressionState &state, Vector &result) {
Value v(args.data[0].GetType().ToString());
result.Reference(v);
if (args.ColumnCount() == 1) {
Value v(args.data[0].GetType().ToString());
result.Reference(v);
} else {
auto &bind_data = state.expr.Cast<BoundFunctionExpression>().bind_info->Cast<ConstantReturnBindData>();
result.Reference(bind_data.val);
}
}

unique_ptr<FunctionData> BindTypeOfFunction(ClientContext &context, ScalarFunction &bound_function,
vector<unique_ptr<Expression>> &arguments) {
Value return_value(arguments[0]->return_type.ToString());
arguments.clear();
return make_uniq<ConstantReturnBindData>(return_value);
}

ScalarFunction TypeOfFun::GetFunction() {
auto fun = ScalarFunction({LogicalType::ANY}, LogicalType::VARCHAR, TypeOfFunction);
auto fun = ScalarFunction({LogicalType::ANY}, LogicalType::VARCHAR, TypeOfFunction, BindTypeOfFunction);
fun.null_handling = FunctionNullHandling::SPECIAL_HANDLING;
fun.serialize = ConstantReturnBindData::Serialize;
fun.deserialize = ConstantReturnBindData::Deserialize;
return fun;
}

Expand Down

0 comments on commit 4455c46

Please sign in to comment.