sqlparser/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 yachtsql_sqlparser_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 /// `#` Number of points in path or polygon (PostgreSQL/Redshift geometric operator)
57 /// see <https://www.postgresql.org/docs/9.5/functions-geometry.html>
58 Hash,
59 /// `@-@` Length or circumference (PostgreSQL/Redshift geometric operator)
60 /// see <https://www.postgresql.org/docs/9.5/functions-geometry.html>
61 AtDashAt,
62 /// `@@` Center (PostgreSQL/Redshift geometric operator)
63 /// see <https://www.postgresql.org/docs/9.5/functions-geometry.html>
64 DoubleAt,
65 /// `?-` Is horizontal? (PostgreSQL/Redshift geometric operator)
66 /// see <https://www.postgresql.org/docs/9.5/functions-geometry.html>
67 QuestionDash,
68 /// `?|` Is vertical? (PostgreSQL/Redshift geometric operator)
69 /// see <https://www.postgresql.org/docs/9.5/functions-geometry.html>
70 QuestionPipe,
71}
72
73impl fmt::Display for UnaryOperator {
74 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
75 f.write_str(match self {
76 UnaryOperator::Plus => "+",
77 UnaryOperator::Minus => "-",
78 UnaryOperator::Not => "NOT",
79 UnaryOperator::PGBitwiseNot => "~",
80 UnaryOperator::PGSquareRoot => "|/",
81 UnaryOperator::PGCubeRoot => "||/",
82 UnaryOperator::PGPostfixFactorial => "!",
83 UnaryOperator::PGPrefixFactorial => "!!",
84 UnaryOperator::PGAbs => "@",
85 UnaryOperator::BangNot => "!",
86 UnaryOperator::Hash => "#",
87 UnaryOperator::AtDashAt => "@-@",
88 UnaryOperator::DoubleAt => "@@",
89 UnaryOperator::QuestionDash => "?-",
90 UnaryOperator::QuestionPipe => "?|",
91 })
92 }
93}
94
95/// Binary operators
96#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
97#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
98#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
99pub enum BinaryOperator {
100 /// Plus, e.g. `a + b`
101 Plus,
102 /// Minus, e.g. `a - b`
103 Minus,
104 /// Multiply, e.g. `a * b`
105 Multiply,
106 /// Divide, e.g. `a / b`
107 Divide,
108 /// Modulo, e.g. `a % b`
109 Modulo,
110 /// String/Array Concat operator, e.g. `a || b`
111 StringConcat,
112 /// Greater than, e.g. `a > b`
113 Gt,
114 /// Less than, e.g. `a < b`
115 Lt,
116 /// Greater equal, e.g. `a >= b`
117 GtEq,
118 /// Less equal, e.g. `a <= b`
119 LtEq,
120 /// Spaceship, e.g. `a <=> b`
121 Spaceship,
122 /// Equal, e.g. `a = b`
123 Eq,
124 /// Not equal, e.g. `a <> b`
125 NotEq,
126 /// And, e.g. `a AND b`
127 And,
128 /// Or, e.g. `a OR b`
129 Or,
130 /// XOR, e.g. `a XOR b`
131 Xor,
132 /// Bitwise or, e.g. `a | b`
133 BitwiseOr,
134 /// Bitwise and, e.g. `a & b`
135 BitwiseAnd,
136 /// Bitwise XOR, e.g. `a ^ b`
137 BitwiseXor,
138 /// Integer division operator `//` in DuckDB
139 DuckIntegerDivide,
140 /// MySQL [`DIV`](https://dev.mysql.com/doc/refman/8.0/en/arithmetic-functions.html) integer division
141 MyIntegerDivide,
142 /// MATCH operator, e.g. `a MATCH b` (SQLite-specific)
143 /// See <https://www.sqlite.org/lang_expr.html#the_like_glob_regexp_match_and_extract_operators>
144 Match,
145 /// REGEXP operator, e.g. `a REGEXP b` (SQLite-specific)
146 Regexp,
147 /// Support for custom operators (such as Postgres custom operators)
148 Custom(String),
149 /// Bitwise XOR, e.g. `a # b` (PostgreSQL-specific)
150 PGBitwiseXor,
151 /// Bitwise shift left, e.g. `a << b` (PostgreSQL-specific)
152 PGBitwiseShiftLeft,
153 /// Bitwise shift right, e.g. `a >> b` (PostgreSQL-specific)
154 PGBitwiseShiftRight,
155 /// Exponent, e.g. `a ^ b` (PostgreSQL-specific)
156 PGExp,
157 /// Overlap operator, e.g. `a && b` (PostgreSQL-specific)
158 PGOverlap,
159 /// String matches regular expression (case sensitively), e.g. `a ~ b` (PostgreSQL-specific)
160 PGRegexMatch,
161 /// String matches regular expression (case insensitively), e.g. `a ~* b` (PostgreSQL-specific)
162 PGRegexIMatch,
163 /// String does not match regular expression (case sensitively), e.g. `a !~ b` (PostgreSQL-specific)
164 PGRegexNotMatch,
165 /// String does not match regular expression (case insensitively), e.g. `a !~* b` (PostgreSQL-specific)
166 PGRegexNotIMatch,
167 /// String matches pattern (case sensitively), e.g. `a ~~ b` (PostgreSQL-specific)
168 PGLikeMatch,
169 /// String matches pattern (case insensitively), e.g. `a ~~* b` (PostgreSQL-specific)
170 PGILikeMatch,
171 /// String does not match pattern (case sensitively), e.g. `a !~~ b` (PostgreSQL-specific)
172 PGNotLikeMatch,
173 /// String does not match pattern (case insensitively), e.g. `a !~~* b` (PostgreSQL-specific)
174 PGNotILikeMatch,
175 /// String "starts with", eg: `a ^@ b` (PostgreSQL-specific)
176 PGStartsWith,
177 /// The `->` operator.
178 ///
179 /// On PostgreSQL, this operator extracts a JSON object field or array
180 /// element, for example `'{"a":"b"}'::json -> 'a'` or `[1, 2, 3]'::json
181 /// -> 2`.
182 ///
183 /// See <https://www.postgresql.org/docs/current/functions-json.html>.
184 Arrow,
185 /// The `->>` operator.
186 ///
187 /// On PostgreSQL, this operator extracts a JSON object field or JSON
188 /// array element and converts it to text, for example `'{"a":"b"}'::json
189 /// ->> 'a'` or `[1, 2, 3]'::json ->> 2`.
190 ///
191 /// See <https://www.postgresql.org/docs/current/functions-json.html>.
192 LongArrow,
193 /// The `#>` operator.
194 ///
195 /// On PostgreSQL, this operator extracts a JSON sub-object at the specified
196 /// path, for example:
197 ///
198 /// ```notrust
199 ///'{"a": {"b": ["foo","bar"]}}'::json #> '{a,b,1}'
200 /// ```
201 ///
202 /// See <https://www.postgresql.org/docs/current/functions-json.html>.
203 HashArrow,
204 /// The `#>>` operator.
205 ///
206 /// A PostgreSQL-specific operator that extracts JSON sub-object at the
207 /// specified path, for example
208 ///
209 /// ```notrust
210 ///'{"a": {"b": ["foo","bar"]}}'::json #>> '{a,b,1}'
211 /// ```
212 ///
213 /// See <https://www.postgresql.org/docs/current/functions-json.html>.
214 HashLongArrow,
215 /// The `@@` operator.
216 ///
217 /// On PostgreSQL, this is used for JSON and text searches.
218 ///
219 /// See <https://www.postgresql.org/docs/current/functions-json.html>.
220 /// See <https://www.postgresql.org/docs/current/functions-textsearch.html>.
221 AtAt,
222 /// The `@>` operator.
223 ///
224 /// On PostgreSQL, this is used for JSON and text searches.
225 ///
226 /// See <https://www.postgresql.org/docs/current/functions-json.html>.
227 /// See <https://www.postgresql.org/docs/current/functions-textsearch.html>.
228 AtArrow,
229 /// The `<@` operator.
230 ///
231 /// On PostgreSQL, this is used for JSON and text searches.
232 ///
233 /// See <https://www.postgresql.org/docs/current/functions-json.html>.
234 /// See <https://www.postgresql.org/docs/current/functions-textsearch.html>.
235 ArrowAt,
236 /// The `#-` operator.
237 ///
238 /// On PostgreSQL, this operator is used to delete a field or array element
239 /// at a specified path.
240 ///
241 /// See <https://www.postgresql.org/docs/current/functions-json.html>.
242 HashMinus,
243 /// The `@?` operator.
244 ///
245 /// On PostgreSQL, this operator is used to check the given JSON path
246 /// returns an item for the JSON value.
247 ///
248 /// See <https://www.postgresql.org/docs/current/functions-json.html>.
249 AtQuestion,
250 /// The `?` operator.
251 ///
252 /// On PostgreSQL, this operator is used to check whether a string exists as a top-level key
253 /// within the JSON value
254 ///
255 /// See <https://www.postgresql.org/docs/current/functions-json.html>.
256 Question,
257 /// The `?&` operator.
258 ///
259 /// On PostgreSQL, this operator is used to check whether all of the the indicated array
260 /// members exist as top-level keys.
261 ///
262 /// See <https://www.postgresql.org/docs/current/functions-json.html>.
263 QuestionAnd,
264 /// The `?|` operator.
265 ///
266 /// On PostgreSQL, this operator is used to check whether any of the the indicated array
267 /// members exist as top-level keys.
268 ///
269 /// See <https://www.postgresql.org/docs/current/functions-json.html>.
270 QuestionPipe,
271 /// PostgreSQL-specific custom operator.
272 ///
273 /// See [CREATE OPERATOR](https://www.postgresql.org/docs/current/sql-createoperator.html)
274 /// for more information.
275 PGCustomBinaryOperator(Vec<String>),
276 /// The `OVERLAPS` operator
277 ///
278 /// Specifies a test for an overlap between two datetime periods:
279 /// <https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#overlaps-predicate>
280 Overlaps,
281 /// `##` Point of closest proximity (PostgreSQL/Redshift geometric operator)
282 /// See <https://www.postgresql.org/docs/9.5/functions-geometry.html>
283 DoubleHash,
284 /// `<->` Distance between (PostgreSQL/Redshift geometric operator)
285 /// See <https://www.postgresql.org/docs/9.5/functions-geometry.html>
286 LtDashGt,
287 /// `&<` Overlaps to left? (PostgreSQL/Redshift geometric operator)
288 /// See <https://www.postgresql.org/docs/9.5/functions-geometry.html>
289 AndLt,
290 /// `&>` Overlaps to right? (PostgreSQL/Redshift geometric operator)
291 /// See <https://www.postgresql.org/docs/9.5/functions-geometry.html>
292 AndGt,
293 /// `<<|` Is strictly below? (PostgreSQL/Redshift geometric operator)
294 /// See <https://www.postgresql.org/docs/9.5/functions-geometry.html>
295 LtLtPipe,
296 /// `|>>` Is strictly above? (PostgreSQL/Redshift geometric operator)
297 /// See <https://www.postgresql.org/docs/9.5/functions-geometry.html>
298 PipeGtGt,
299 /// `&<|` Does not extend above? (PostgreSQL/Redshift geometric operator)
300 /// See <https://www.postgresql.org/docs/9.5/functions-geometry.html>
301 AndLtPipe,
302 /// `|&>` Does not extend below? (PostgreSQL/Redshift geometric operator)
303 /// See <https://www.postgresql.org/docs/9.5/functions-geometry.html>
304 PipeAndGt,
305 /// `<^` Is below? (PostgreSQL/Redshift geometric operator)
306 /// See <https://www.postgresql.org/docs/9.5/functions-geometry.html>
307 LtCaret,
308 /// `>^` Is above? (PostgreSQL/Redshift geometric operator)
309 /// See <https://www.postgresql.org/docs/9.5/functions-geometry.html>
310 GtCaret,
311 /// `?#` Intersects? (PostgreSQL/Redshift geometric operator)
312 /// See <https://www.postgresql.org/docs/9.5/functions-geometry.html>
313 QuestionHash,
314 /// `?-` Is horizontal? (PostgreSQL/Redshift geometric operator)
315 /// See <https://www.postgresql.org/docs/9.5/functions-geometry.html>
316 QuestionDash,
317 /// `?-|` Is perpendicular? (PostgreSQL/Redshift geometric operator)
318 /// See <https://www.postgresql.org/docs/9.5/functions-geometry.html>
319 QuestionDashPipe,
320 /// `?||` Are Parallel? (PostgreSQL/Redshift geometric operator)
321 /// See <https://www.postgresql.org/docs/9.5/functions-geometry.html>
322 QuestionDoublePipe,
323 /// `@` Contained or on? (PostgreSQL/Redshift geometric operator)
324 /// See <https://www.postgresql.org/docs/9.5/functions-geometry.html>
325 At,
326 /// `~=` Same as? (PostgreSQL/Redshift geometric operator)
327 /// See <https://www.postgresql.org/docs/9.5/functions-geometry.html>
328 TildeEq,
329 /// ':=' Assignment Operator
330 /// See <https://dev.mysql.com/doc/refman/8.4/en/assignment-operators.html#operator_assign-value>
331 Assignment,
332}
333
334impl fmt::Display for BinaryOperator {
335 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
336 match self {
337 BinaryOperator::Plus => f.write_str("+"),
338 BinaryOperator::Minus => f.write_str("-"),
339 BinaryOperator::Multiply => f.write_str("*"),
340 BinaryOperator::Divide => f.write_str("/"),
341 BinaryOperator::Modulo => f.write_str("%"),
342 BinaryOperator::StringConcat => f.write_str("||"),
343 BinaryOperator::Gt => f.write_str(">"),
344 BinaryOperator::Lt => f.write_str("<"),
345 BinaryOperator::GtEq => f.write_str(">="),
346 BinaryOperator::LtEq => f.write_str("<="),
347 BinaryOperator::Spaceship => f.write_str("<=>"),
348 BinaryOperator::Eq => f.write_str("="),
349 BinaryOperator::NotEq => f.write_str("<>"),
350 BinaryOperator::And => f.write_str("AND"),
351 BinaryOperator::Or => f.write_str("OR"),
352 BinaryOperator::Xor => f.write_str("XOR"),
353 BinaryOperator::BitwiseOr => f.write_str("|"),
354 BinaryOperator::BitwiseAnd => f.write_str("&"),
355 BinaryOperator::BitwiseXor => f.write_str("^"),
356 BinaryOperator::DuckIntegerDivide => f.write_str("//"),
357 BinaryOperator::MyIntegerDivide => f.write_str("DIV"),
358 BinaryOperator::Match => f.write_str("MATCH"),
359 BinaryOperator::Regexp => f.write_str("REGEXP"),
360 BinaryOperator::Custom(s) => f.write_str(s),
361 BinaryOperator::PGBitwiseXor => f.write_str("#"),
362 BinaryOperator::PGBitwiseShiftLeft => f.write_str("<<"),
363 BinaryOperator::PGBitwiseShiftRight => f.write_str(">>"),
364 BinaryOperator::PGExp => f.write_str("^"),
365 BinaryOperator::PGOverlap => f.write_str("&&"),
366 BinaryOperator::PGRegexMatch => f.write_str("~"),
367 BinaryOperator::PGRegexIMatch => f.write_str("~*"),
368 BinaryOperator::PGRegexNotMatch => f.write_str("!~"),
369 BinaryOperator::PGRegexNotIMatch => f.write_str("!~*"),
370 BinaryOperator::PGLikeMatch => f.write_str("~~"),
371 BinaryOperator::PGILikeMatch => f.write_str("~~*"),
372 BinaryOperator::PGNotLikeMatch => f.write_str("!~~"),
373 BinaryOperator::PGNotILikeMatch => f.write_str("!~~*"),
374 BinaryOperator::PGStartsWith => f.write_str("^@"),
375 BinaryOperator::Arrow => f.write_str("->"),
376 BinaryOperator::LongArrow => f.write_str("->>"),
377 BinaryOperator::HashArrow => f.write_str("#>"),
378 BinaryOperator::HashLongArrow => f.write_str("#>>"),
379 BinaryOperator::AtAt => f.write_str("@@"),
380 BinaryOperator::AtArrow => f.write_str("@>"),
381 BinaryOperator::ArrowAt => f.write_str("<@"),
382 BinaryOperator::HashMinus => f.write_str("#-"),
383 BinaryOperator::AtQuestion => f.write_str("@?"),
384 BinaryOperator::Question => f.write_str("?"),
385 BinaryOperator::QuestionAnd => f.write_str("?&"),
386 BinaryOperator::QuestionPipe => f.write_str("?|"),
387 BinaryOperator::PGCustomBinaryOperator(idents) => {
388 write!(f, "OPERATOR({})", display_separated(idents, "."))
389 }
390 BinaryOperator::Overlaps => f.write_str("OVERLAPS"),
391 BinaryOperator::DoubleHash => f.write_str("##"),
392 BinaryOperator::LtDashGt => f.write_str("<->"),
393 BinaryOperator::AndLt => f.write_str("&<"),
394 BinaryOperator::AndGt => f.write_str("&>"),
395 BinaryOperator::LtLtPipe => f.write_str("<<|"),
396 BinaryOperator::PipeGtGt => f.write_str("|>>"),
397 BinaryOperator::AndLtPipe => f.write_str("&<|"),
398 BinaryOperator::PipeAndGt => f.write_str("|&>"),
399 BinaryOperator::LtCaret => f.write_str("<^"),
400 BinaryOperator::GtCaret => f.write_str(">^"),
401 BinaryOperator::QuestionHash => f.write_str("?#"),
402 BinaryOperator::QuestionDash => f.write_str("?-"),
403 BinaryOperator::QuestionDashPipe => f.write_str("?-|"),
404 BinaryOperator::QuestionDoublePipe => f.write_str("?||"),
405 BinaryOperator::At => f.write_str("@"),
406 BinaryOperator::TildeEq => f.write_str("~="),
407 BinaryOperator::Assignment => f.write_str(":="),
408 }
409 }
410}