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}