1#include "duckdb/parser/expression/function_expression.hpp"
2#include "duckdb/common/string_util.hpp"
3#include "duckdb/common/exception.hpp"
4#include "duckdb/common/serializer.hpp"
5#include "duckdb/common/types/hash.hpp"
6
7using namespace duckdb;
8using namespace std;
9
10FunctionExpression::FunctionExpression(string schema, string function_name,
11 vector<unique_ptr<ParsedExpression>> &children, bool distinct, bool is_operator)
12 : ParsedExpression(ExpressionType::FUNCTION, ExpressionClass::FUNCTION), schema(schema),
13 function_name(StringUtil::Lower(function_name)), is_operator(is_operator), distinct(distinct) {
14 for (auto &child : children) {
15 this->children.push_back(move(child));
16 }
17}
18
19FunctionExpression::FunctionExpression(string function_name, vector<unique_ptr<ParsedExpression>> &children,
20 bool distinct, bool is_operator)
21 : FunctionExpression(DEFAULT_SCHEMA, function_name, children, distinct, is_operator) {
22}
23
24string FunctionExpression::ToString() const {
25 if (is_operator) {
26 // built-in operator
27 if (children.size() == 1) {
28 return function_name + children[0]->ToString();
29 } else if (children.size() == 2) {
30 return children[0]->ToString() + " " + function_name + " " + children[1]->ToString();
31 }
32 }
33 // standard function call
34 string result = function_name + "(";
35 result += StringUtil::Join(children, children.size(), ", ",
36 [](const unique_ptr<ParsedExpression> &child) { return child->ToString(); });
37 return result + ")";
38}
39
40bool FunctionExpression::Equals(const FunctionExpression *a, const FunctionExpression *b) {
41 if (a->schema != b->schema || a->function_name != b->function_name || b->distinct != a->distinct) {
42 return false;
43 }
44 if (b->children.size() != a->children.size()) {
45 return false;
46 }
47 for (idx_t i = 0; i < a->children.size(); i++) {
48 if (!a->children[i]->Equals(b->children[i].get())) {
49 return false;
50 }
51 }
52 return true;
53}
54
55hash_t FunctionExpression::Hash() const {
56 hash_t result = ParsedExpression::Hash();
57 result = CombineHash(result, duckdb::Hash<const char *>(schema.c_str()));
58 result = CombineHash(result, duckdb::Hash<const char *>(function_name.c_str()));
59 result = CombineHash(result, duckdb::Hash<bool>(distinct));
60 return result;
61}
62
63unique_ptr<ParsedExpression> FunctionExpression::Copy() const {
64 vector<unique_ptr<ParsedExpression>> copy_children;
65 for (auto &child : children) {
66 copy_children.push_back(child->Copy());
67 }
68 auto copy = make_unique<FunctionExpression>(function_name, copy_children, distinct, is_operator);
69 copy->schema = schema;
70 copy->CopyProperties(*this);
71 return move(copy);
72}
73
74void FunctionExpression::Serialize(Serializer &serializer) {
75 ParsedExpression::Serialize(serializer);
76 serializer.WriteString(function_name);
77 serializer.WriteString(schema);
78 serializer.WriteList(children);
79 serializer.Write<bool>(distinct);
80 serializer.Write<bool>(is_operator);
81}
82
83unique_ptr<ParsedExpression> FunctionExpression::Deserialize(ExpressionType type, Deserializer &source) {
84 vector<unique_ptr<ParsedExpression>> children;
85 auto function_name = source.Read<string>();
86 auto schema = source.Read<string>();
87 source.ReadList<ParsedExpression>(children);
88 auto distinct = source.Read<bool>();
89 auto is_operator = source.Read<bool>();
90
91 auto function = make_unique<FunctionExpression>(function_name, children, distinct, is_operator);
92 function->schema = schema;
93 return move(function);
94}
95