| 1 | #include "duckdb/parser/parsed_expression.hpp" |
| 2 | |
| 3 | #include "duckdb/common/serializer.hpp" |
| 4 | #include "duckdb/common/types/hash.hpp" |
| 5 | #include "duckdb/parser/expression/list.hpp" |
| 6 | #include "duckdb/parser/parsed_expression_iterator.hpp" |
| 7 | |
| 8 | using namespace duckdb; |
| 9 | using namespace std; |
| 10 | |
| 11 | bool ParsedExpression::IsAggregate() const { |
| 12 | bool is_aggregate = false; |
| 13 | ParsedExpressionIterator::EnumerateChildren( |
| 14 | *this, [&](const ParsedExpression &child) { is_aggregate |= child.IsAggregate(); }); |
| 15 | return is_aggregate; |
| 16 | } |
| 17 | |
| 18 | bool ParsedExpression::IsWindow() const { |
| 19 | bool is_window = false; |
| 20 | ParsedExpressionIterator::EnumerateChildren(*this, |
| 21 | [&](const ParsedExpression &child) { is_window |= child.IsWindow(); }); |
| 22 | return is_window; |
| 23 | } |
| 24 | |
| 25 | bool ParsedExpression::IsScalar() const { |
| 26 | bool is_scalar = true; |
| 27 | ParsedExpressionIterator::EnumerateChildren(*this, [&](const ParsedExpression &child) { |
| 28 | if (!child.IsScalar()) { |
| 29 | is_scalar = false; |
| 30 | } |
| 31 | }); |
| 32 | return is_scalar; |
| 33 | } |
| 34 | |
| 35 | bool ParsedExpression::HasParameter() const { |
| 36 | bool has_parameter = false; |
| 37 | ParsedExpressionIterator::EnumerateChildren( |
| 38 | *this, [&](const ParsedExpression &child) { has_parameter |= child.HasParameter(); }); |
| 39 | return has_parameter; |
| 40 | } |
| 41 | |
| 42 | bool ParsedExpression::HasSubquery() const { |
| 43 | bool has_subquery = false; |
| 44 | ParsedExpressionIterator::EnumerateChildren( |
| 45 | *this, [&](const ParsedExpression &child) { has_subquery |= child.HasSubquery(); }); |
| 46 | return has_subquery; |
| 47 | } |
| 48 | |
| 49 | bool ParsedExpression::Equals(const BaseExpression *other) const { |
| 50 | if (other->expression_class == ExpressionClass::BOUND_EXPRESSION) { |
| 51 | auto bound_expr = (BoundExpression *)other; |
| 52 | other = bound_expr->parsed_expr.get(); |
| 53 | } |
| 54 | if (!BaseExpression::Equals(other)) { |
| 55 | return false; |
| 56 | } |
| 57 | switch (expression_class) { |
| 58 | case ExpressionClass::CASE: |
| 59 | return CaseExpression::Equals((CaseExpression *)this, (CaseExpression *)other); |
| 60 | case ExpressionClass::CAST: |
| 61 | return CastExpression::Equals((CastExpression *)this, (CastExpression *)other); |
| 62 | case ExpressionClass::COLLATE: |
| 63 | return CollateExpression::Equals((CollateExpression *)this, (CollateExpression *)other); |
| 64 | case ExpressionClass::COLUMN_REF: |
| 65 | return ColumnRefExpression::Equals((ColumnRefExpression *)this, (ColumnRefExpression *)other); |
| 66 | case ExpressionClass::COMPARISON: |
| 67 | return ComparisonExpression::Equals((ComparisonExpression *)this, (ComparisonExpression *)other); |
| 68 | case ExpressionClass::CONJUNCTION: |
| 69 | return ConjunctionExpression::Equals((ConjunctionExpression *)this, (ConjunctionExpression *)other); |
| 70 | case ExpressionClass::CONSTANT: |
| 71 | return ConstantExpression::Equals((ConstantExpression *)this, (ConstantExpression *)other); |
| 72 | case ExpressionClass::DEFAULT: |
| 73 | return true; |
| 74 | case ExpressionClass::FUNCTION: |
| 75 | return FunctionExpression::Equals((FunctionExpression *)this, (FunctionExpression *)other); |
| 76 | case ExpressionClass::OPERATOR: |
| 77 | return OperatorExpression::Equals((OperatorExpression *)this, (OperatorExpression *)other); |
| 78 | case ExpressionClass::PARAMETER: |
| 79 | return true; |
| 80 | case ExpressionClass::STAR: |
| 81 | return true; |
| 82 | case ExpressionClass::TABLE_STAR: |
| 83 | return TableStarExpression::Equals((TableStarExpression *)this, (TableStarExpression *)other); |
| 84 | case ExpressionClass::SUBQUERY: |
| 85 | return SubqueryExpression::Equals((SubqueryExpression *)this, (SubqueryExpression *)other); |
| 86 | case ExpressionClass::WINDOW: |
| 87 | return WindowExpression::Equals((WindowExpression *)this, (WindowExpression *)other); |
| 88 | default: |
| 89 | throw SerializationException("Unsupported type for expression deserialization!" ); |
| 90 | } |
| 91 | } |
| 92 | |
| 93 | hash_t ParsedExpression::Hash() const { |
| 94 | hash_t hash = duckdb::Hash<uint32_t>((uint32_t)type); |
| 95 | ParsedExpressionIterator::EnumerateChildren( |
| 96 | *this, [&](const ParsedExpression &child) { hash = CombineHash(child.Hash(), hash); }); |
| 97 | return hash; |
| 98 | } |
| 99 | |
| 100 | void ParsedExpression::Serialize(Serializer &serializer) { |
| 101 | serializer.Write<ExpressionClass>(GetExpressionClass()); |
| 102 | serializer.Write<ExpressionType>(type); |
| 103 | serializer.WriteString(alias); |
| 104 | } |
| 105 | |
| 106 | unique_ptr<ParsedExpression> ParsedExpression::Deserialize(Deserializer &source) { |
| 107 | auto expression_class = source.Read<ExpressionClass>(); |
| 108 | auto type = source.Read<ExpressionType>(); |
| 109 | auto alias = source.Read<string>(); |
| 110 | unique_ptr<ParsedExpression> result; |
| 111 | switch (expression_class) { |
| 112 | case ExpressionClass::CASE: |
| 113 | result = CaseExpression::Deserialize(type, source); |
| 114 | break; |
| 115 | case ExpressionClass::CAST: |
| 116 | result = CastExpression::Deserialize(type, source); |
| 117 | break; |
| 118 | case ExpressionClass::COLLATE: |
| 119 | result = CollateExpression::Deserialize(type, source); |
| 120 | break; |
| 121 | case ExpressionClass::COLUMN_REF: |
| 122 | result = ColumnRefExpression::Deserialize(type, source); |
| 123 | break; |
| 124 | case ExpressionClass::COMPARISON: |
| 125 | result = ComparisonExpression::Deserialize(type, source); |
| 126 | break; |
| 127 | case ExpressionClass::CONJUNCTION: |
| 128 | result = ConjunctionExpression::Deserialize(type, source); |
| 129 | break; |
| 130 | case ExpressionClass::CONSTANT: |
| 131 | result = ConstantExpression::Deserialize(type, source); |
| 132 | break; |
| 133 | case ExpressionClass::DEFAULT: |
| 134 | result = DefaultExpression::Deserialize(type, source); |
| 135 | break; |
| 136 | case ExpressionClass::FUNCTION: |
| 137 | result = FunctionExpression::Deserialize(type, source); |
| 138 | break; |
| 139 | case ExpressionClass::OPERATOR: |
| 140 | result = OperatorExpression::Deserialize(type, source); |
| 141 | break; |
| 142 | case ExpressionClass::PARAMETER: |
| 143 | result = ParameterExpression::Deserialize(type, source); |
| 144 | break; |
| 145 | case ExpressionClass::STAR: |
| 146 | result = StarExpression::Deserialize(type, source); |
| 147 | break; |
| 148 | case ExpressionClass::TABLE_STAR: |
| 149 | result = TableStarExpression::Deserialize(type, source); |
| 150 | break; |
| 151 | case ExpressionClass::SUBQUERY: |
| 152 | result = SubqueryExpression::Deserialize(type, source); |
| 153 | break; |
| 154 | case ExpressionClass::WINDOW: |
| 155 | result = WindowExpression::Deserialize(type, source); |
| 156 | break; |
| 157 | default: |
| 158 | throw SerializationException("Unsupported type for expression deserialization!" ); |
| 159 | } |
| 160 | result->alias = alias; |
| 161 | return result; |
| 162 | } |
| 163 | |