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 | |
7 | using namespace duckdb; |
8 | using namespace std; |
9 | |
10 | FunctionExpression::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 | |
19 | FunctionExpression::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 | |
24 | string 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 | |
40 | bool 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 | |
55 | hash_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 | |
63 | unique_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 | |
74 | void 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 | |
83 | unique_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 | |