sqltk_parser/ast/operator.rs
1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements. See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership. The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License. You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied. See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18use core::fmt;
19
20#[cfg(not(feature = "std"))]
21use alloc::{string::String, vec::Vec};
22
23#[cfg(feature = "serde")]
24use serde::{Deserialize, Serialize};
25
26#[cfg(feature = "visitor")]
27use sqltk_parser_derive::{Visit, VisitMut};
28
29use super::display_separated;
30
31/// Unary operators
32#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
33#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
34#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
35pub enum UnaryOperator {
36 /// Plus, e.g. `+9`
37 Plus,
38 /// Minus, e.g. `-9`
39 Minus,
40 /// Not, e.g. `NOT(true)`
41 Not,
42 /// Bitwise Not, e.g. `~9` (PostgreSQL-specific)
43 PGBitwiseNot,
44 /// Square root, e.g. `|/9` (PostgreSQL-specific)
45 PGSquareRoot,
46 /// Cube root, e.g. `||/27` (PostgreSQL-specific)
47 PGCubeRoot,
48 /// Factorial, e.g. `9!` (PostgreSQL-specific)
49 PGPostfixFactorial,
50 /// Factorial, e.g. `!!9` (PostgreSQL-specific)
51 PGPrefixFactorial,
52 /// Absolute value, e.g. `@ -9` (PostgreSQL-specific)
53 PGAbs,
54 /// Unary logical not operator: e.g. `! false` (Hive-specific)
55 BangNot,
56}
57
58impl fmt::Display for UnaryOperator {
59 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
60 f.write_str(match self {
61 UnaryOperator::Plus => "+",
62 UnaryOperator::Minus => "-",
63 UnaryOperator::Not => "NOT",
64 UnaryOperator::PGBitwiseNot => "~",
65 UnaryOperator::PGSquareRoot => "|/",
66 UnaryOperator::PGCubeRoot => "||/",
67 UnaryOperator::PGPostfixFactorial => "!",
68 UnaryOperator::PGPrefixFactorial => "!!",
69 UnaryOperator::PGAbs => "@",
70 UnaryOperator::BangNot => "!",
71 })
72 }
73}
74
75/// Binary operators
76#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
77#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
78#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
79pub enum BinaryOperator {
80 /// Plus, e.g. `a + b`
81 Plus,
82 /// Minus, e.g. `a - b`
83 Minus,
84 /// Multiply, e.g. `a * b`
85 Multiply,
86 /// Divide, e.g. `a / b`
87 Divide,
88 /// Modulo, e.g. `a % b`
89 Modulo,
90 /// String/Array Concat operator, e.g. `a || b`
91 StringConcat,
92 /// Greater than, e.g. `a > b`
93 Gt,
94 /// Less than, e.g. `a < b`
95 Lt,
96 /// Greater equal, e.g. `a >= b`
97 GtEq,
98 /// Less equal, e.g. `a <= b`
99 LtEq,
100 /// Spaceship, e.g. `a <=> b`
101 Spaceship,
102 /// Equal, e.g. `a = b`
103 Eq,
104 /// Not equal, e.g. `a <> b`
105 NotEq,
106 /// And, e.g. `a AND b`
107 And,
108 /// Or, e.g. `a OR b`
109 Or,
110 /// XOR, e.g. `a XOR b`
111 Xor,
112 /// Bitwise or, e.g. `a | b`
113 BitwiseOr,
114 /// Bitwise and, e.g. `a & b`
115 BitwiseAnd,
116 /// Bitwise XOR, e.g. `a ^ b`
117 BitwiseXor,
118 /// Integer division operator `//` in DuckDB
119 DuckIntegerDivide,
120 /// MySQL [`DIV`](https://dev.mysql.com/doc/refman/8.0/en/arithmetic-functions.html) integer division
121 MyIntegerDivide,
122 /// Support for custom operators (such as Postgres custom operators)
123 Custom(String),
124 /// Bitwise XOR, e.g. `a # b` (PostgreSQL-specific)
125 PGBitwiseXor,
126 /// Bitwise shift left, e.g. `a << b` (PostgreSQL-specific)
127 PGBitwiseShiftLeft,
128 /// Bitwise shift right, e.g. `a >> b` (PostgreSQL-specific)
129 PGBitwiseShiftRight,
130 /// Exponent, e.g. `a ^ b` (PostgreSQL-specific)
131 PGExp,
132 /// Overlap operator, e.g. `a && b` (PostgreSQL-specific)
133 PGOverlap,
134 /// String matches regular expression (case sensitively), e.g. `a ~ b` (PostgreSQL-specific)
135 PGRegexMatch,
136 /// String matches regular expression (case insensitively), e.g. `a ~* b` (PostgreSQL-specific)
137 PGRegexIMatch,
138 /// String does not match regular expression (case sensitively), e.g. `a !~ b` (PostgreSQL-specific)
139 PGRegexNotMatch,
140 /// String does not match regular expression (case insensitively), e.g. `a !~* b` (PostgreSQL-specific)
141 PGRegexNotIMatch,
142 /// String matches pattern (case sensitively), e.g. `a ~~ b` (PostgreSQL-specific)
143 PGLikeMatch,
144 /// String matches pattern (case insensitively), e.g. `a ~~* b` (PostgreSQL-specific)
145 PGILikeMatch,
146 /// String does not match pattern (case sensitively), e.g. `a !~~ b` (PostgreSQL-specific)
147 PGNotLikeMatch,
148 /// String does not match pattern (case insensitively), e.g. `a !~~* b` (PostgreSQL-specific)
149 PGNotILikeMatch,
150 /// String "starts with", eg: `a ^@ b` (PostgreSQL-specific)
151 PGStartsWith,
152 /// The `->` operator.
153 ///
154 /// On PostgreSQL, this operator extracts a JSON object field or array
155 /// element, for example `'{"a":"b"}'::json -> 'a'` or `[1, 2, 3]'::json
156 /// -> 2`.
157 ///
158 /// See <https://www.postgresql.org/docs/current/functions-json.html>.
159 Arrow,
160 /// The `->>` operator.
161 ///
162 /// On PostgreSQL, this operator extracts a JSON object field or JSON
163 /// array element and converts it to text, for example `'{"a":"b"}'::json
164 /// ->> 'a'` or `[1, 2, 3]'::json ->> 2`.
165 ///
166 /// See <https://www.postgresql.org/docs/current/functions-json.html>.
167 LongArrow,
168 /// The `#>` operator.
169 ///
170 /// On PostgreSQL, this operator extracts a JSON sub-object at the specified
171 /// path, for example:
172 ///
173 /// ```notrust
174 ///'{"a": {"b": ["foo","bar"]}}'::json #> '{a,b,1}'
175 /// ```
176 ///
177 /// See <https://www.postgresql.org/docs/current/functions-json.html>.
178 HashArrow,
179 /// The `#>>` operator.
180 ///
181 /// A PostgreSQL-specific operator that extracts JSON sub-object at the
182 /// specified path, for example
183 ///
184 /// ```notrust
185 ///'{"a": {"b": ["foo","bar"]}}'::json #>> '{a,b,1}'
186 /// ```
187 ///
188 /// See <https://www.postgresql.org/docs/current/functions-json.html>.
189 HashLongArrow,
190 /// The `@@` operator.
191 ///
192 /// On PostgreSQL, this is used for JSON and text searches.
193 ///
194 /// See <https://www.postgresql.org/docs/current/functions-json.html>.
195 /// See <https://www.postgresql.org/docs/current/functions-textsearch.html>.
196 AtAt,
197 /// The `@>` operator.
198 ///
199 /// On PostgreSQL, this is used for JSON and text searches.
200 ///
201 /// See <https://www.postgresql.org/docs/current/functions-json.html>.
202 /// See <https://www.postgresql.org/docs/current/functions-textsearch.html>.
203 AtArrow,
204 /// The `<@` operator.
205 ///
206 /// On PostgreSQL, this is used for JSON and text searches.
207 ///
208 /// See <https://www.postgresql.org/docs/current/functions-json.html>.
209 /// See <https://www.postgresql.org/docs/current/functions-textsearch.html>.
210 ArrowAt,
211 /// The `#-` operator.
212 ///
213 /// On PostgreSQL, this operator is used to delete a field or array element
214 /// at a specified path.
215 ///
216 /// See <https://www.postgresql.org/docs/current/functions-json.html>.
217 HashMinus,
218 /// The `@?` operator.
219 ///
220 /// On PostgreSQL, this operator is used to check the given JSON path
221 /// returns an item for the JSON value.
222 ///
223 /// See <https://www.postgresql.org/docs/current/functions-json.html>.
224 AtQuestion,
225 /// The `?` operator.
226 ///
227 /// On PostgreSQL, this operator is used to check whether a string exists as a top-level key
228 /// within the JSON value
229 ///
230 /// See <https://www.postgresql.org/docs/current/functions-json.html>.
231 Question,
232 /// The `?&` operator.
233 ///
234 /// On PostgreSQL, this operator is used to check whether all of the the indicated array
235 /// members exist as top-level keys.
236 ///
237 /// See <https://www.postgresql.org/docs/current/functions-json.html>.
238 QuestionAnd,
239 /// The `?|` operator.
240 ///
241 /// On PostgreSQL, this operator is used to check whether any of the the indicated array
242 /// members exist as top-level keys.
243 ///
244 /// See <https://www.postgresql.org/docs/current/functions-json.html>.
245 QuestionPipe,
246 /// PostgreSQL-specific custom operator.
247 ///
248 /// See [CREATE OPERATOR](https://www.postgresql.org/docs/current/sql-createoperator.html)
249 /// for more information.
250 PGCustomBinaryOperator(Vec<String>),
251}
252
253impl fmt::Display for BinaryOperator {
254 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
255 match self {
256 BinaryOperator::Plus => f.write_str("+"),
257 BinaryOperator::Minus => f.write_str("-"),
258 BinaryOperator::Multiply => f.write_str("*"),
259 BinaryOperator::Divide => f.write_str("/"),
260 BinaryOperator::Modulo => f.write_str("%"),
261 BinaryOperator::StringConcat => f.write_str("||"),
262 BinaryOperator::Gt => f.write_str(">"),
263 BinaryOperator::Lt => f.write_str("<"),
264 BinaryOperator::GtEq => f.write_str(">="),
265 BinaryOperator::LtEq => f.write_str("<="),
266 BinaryOperator::Spaceship => f.write_str("<=>"),
267 BinaryOperator::Eq => f.write_str("="),
268 BinaryOperator::NotEq => f.write_str("<>"),
269 BinaryOperator::And => f.write_str("AND"),
270 BinaryOperator::Or => f.write_str("OR"),
271 BinaryOperator::Xor => f.write_str("XOR"),
272 BinaryOperator::BitwiseOr => f.write_str("|"),
273 BinaryOperator::BitwiseAnd => f.write_str("&"),
274 BinaryOperator::BitwiseXor => f.write_str("^"),
275 BinaryOperator::DuckIntegerDivide => f.write_str("//"),
276 BinaryOperator::MyIntegerDivide => f.write_str("DIV"),
277 BinaryOperator::Custom(s) => f.write_str(s),
278 BinaryOperator::PGBitwiseXor => f.write_str("#"),
279 BinaryOperator::PGBitwiseShiftLeft => f.write_str("<<"),
280 BinaryOperator::PGBitwiseShiftRight => f.write_str(">>"),
281 BinaryOperator::PGExp => f.write_str("^"),
282 BinaryOperator::PGOverlap => f.write_str("&&"),
283 BinaryOperator::PGRegexMatch => f.write_str("~"),
284 BinaryOperator::PGRegexIMatch => f.write_str("~*"),
285 BinaryOperator::PGRegexNotMatch => f.write_str("!~"),
286 BinaryOperator::PGRegexNotIMatch => f.write_str("!~*"),
287 BinaryOperator::PGLikeMatch => f.write_str("~~"),
288 BinaryOperator::PGILikeMatch => f.write_str("~~*"),
289 BinaryOperator::PGNotLikeMatch => f.write_str("!~~"),
290 BinaryOperator::PGNotILikeMatch => f.write_str("!~~*"),
291 BinaryOperator::PGStartsWith => f.write_str("^@"),
292 BinaryOperator::Arrow => f.write_str("->"),
293 BinaryOperator::LongArrow => f.write_str("->>"),
294 BinaryOperator::HashArrow => f.write_str("#>"),
295 BinaryOperator::HashLongArrow => f.write_str("#>>"),
296 BinaryOperator::AtAt => f.write_str("@@"),
297 BinaryOperator::AtArrow => f.write_str("@>"),
298 BinaryOperator::ArrowAt => f.write_str("<@"),
299 BinaryOperator::HashMinus => f.write_str("#-"),
300 BinaryOperator::AtQuestion => f.write_str("@?"),
301 BinaryOperator::Question => f.write_str("?"),
302 BinaryOperator::QuestionAnd => f.write_str("?&"),
303 BinaryOperator::QuestionPipe => f.write_str("?|"),
304 BinaryOperator::PGCustomBinaryOperator(idents) => {
305 write!(f, "OPERATOR({})", display_separated(idents, "."))
306 }
307 }
308 }
309}