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 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    /// Support for custom operators (such as Postgres custom operators)
143    Custom(String),
144    /// Bitwise XOR, e.g. `a # b` (PostgreSQL-specific)
145    PGBitwiseXor,
146    /// Bitwise shift left, e.g. `a << b` (PostgreSQL-specific)
147    PGBitwiseShiftLeft,
148    /// Bitwise shift right, e.g. `a >> b` (PostgreSQL-specific)
149    PGBitwiseShiftRight,
150    /// Exponent, e.g. `a ^ b` (PostgreSQL-specific)
151    PGExp,
152    /// Overlap operator, e.g. `a && b` (PostgreSQL-specific)
153    PGOverlap,
154    /// String matches regular expression (case sensitively), e.g. `a ~ b` (PostgreSQL-specific)
155    PGRegexMatch,
156    /// String matches regular expression (case insensitively), e.g. `a ~* b` (PostgreSQL-specific)
157    PGRegexIMatch,
158    /// String does not match regular expression (case sensitively), e.g. `a !~ b` (PostgreSQL-specific)
159    PGRegexNotMatch,
160    /// String does not match regular expression (case insensitively), e.g. `a !~* b` (PostgreSQL-specific)
161    PGRegexNotIMatch,
162    /// String matches pattern (case sensitively), e.g. `a ~~ b` (PostgreSQL-specific)
163    PGLikeMatch,
164    /// String matches pattern (case insensitively), e.g. `a ~~* b` (PostgreSQL-specific)
165    PGILikeMatch,
166    /// String does not match pattern (case sensitively), e.g. `a !~~ b` (PostgreSQL-specific)
167    PGNotLikeMatch,
168    /// String does not match pattern (case insensitively), e.g. `a !~~* b` (PostgreSQL-specific)
169    PGNotILikeMatch,
170    /// String "starts with", eg: `a ^@ b` (PostgreSQL-specific)
171    PGStartsWith,
172    /// The `->` operator.
173    ///
174    /// On PostgreSQL, this operator extracts a JSON object field or array
175    /// element, for example `'{"a":"b"}'::json -> 'a'` or `[1, 2, 3]'::json
176    /// -> 2`.
177    ///
178    /// See <https://www.postgresql.org/docs/current/functions-json.html>.
179    Arrow,
180    /// The `->>` operator.
181    ///
182    /// On PostgreSQL, this operator extracts a JSON object field or JSON
183    /// array element and converts it to text, for example `'{"a":"b"}'::json
184    /// ->> 'a'` or `[1, 2, 3]'::json ->> 2`.
185    ///
186    /// See <https://www.postgresql.org/docs/current/functions-json.html>.
187    LongArrow,
188    /// The `#>` operator.
189    ///
190    /// On PostgreSQL, this operator extracts a JSON sub-object at the specified
191    /// path, for example:
192    ///
193    /// ```notrust
194    ///'{"a": {"b": ["foo","bar"]}}'::json #> '{a,b,1}'
195    /// ```
196    ///
197    /// See <https://www.postgresql.org/docs/current/functions-json.html>.
198    HashArrow,
199    /// The `#>>` operator.
200    ///
201    /// A PostgreSQL-specific operator that extracts JSON sub-object at the
202    /// specified path, for example
203    ///
204    /// ```notrust
205    ///'{"a": {"b": ["foo","bar"]}}'::json #>> '{a,b,1}'
206    /// ```
207    ///
208    /// See <https://www.postgresql.org/docs/current/functions-json.html>.
209    HashLongArrow,
210    /// The `@@` operator.
211    ///
212    /// On PostgreSQL, this is used for JSON and text searches.
213    ///
214    /// See <https://www.postgresql.org/docs/current/functions-json.html>.
215    /// See <https://www.postgresql.org/docs/current/functions-textsearch.html>.
216    AtAt,
217    /// The `@>` operator.
218    ///
219    /// On PostgreSQL, this is used for JSON and text searches.
220    ///
221    /// See <https://www.postgresql.org/docs/current/functions-json.html>.
222    /// See <https://www.postgresql.org/docs/current/functions-textsearch.html>.
223    AtArrow,
224    /// The `<@` operator.
225    ///
226    /// On PostgreSQL, this is used for JSON and text searches.
227    ///
228    /// See <https://www.postgresql.org/docs/current/functions-json.html>.
229    /// See <https://www.postgresql.org/docs/current/functions-textsearch.html>.
230    ArrowAt,
231    /// The `#-` operator.
232    ///
233    /// On PostgreSQL, this operator is used to delete a field or array element
234    /// at a specified path.
235    ///
236    /// See <https://www.postgresql.org/docs/current/functions-json.html>.
237    HashMinus,
238    /// The `@?` operator.
239    ///
240    /// On PostgreSQL, this operator is used to check the given JSON path
241    /// returns an item for the JSON value.
242    ///
243    /// See <https://www.postgresql.org/docs/current/functions-json.html>.
244    AtQuestion,
245    /// The `?` operator.
246    ///
247    /// On PostgreSQL, this operator is used to check whether a string exists as a top-level key
248    /// within the JSON value
249    ///
250    /// See <https://www.postgresql.org/docs/current/functions-json.html>.
251    Question,
252    /// The `?&` operator.
253    ///
254    /// On PostgreSQL, this operator is used to check whether all of the the indicated array
255    /// members exist as top-level keys.
256    ///
257    /// See <https://www.postgresql.org/docs/current/functions-json.html>.
258    QuestionAnd,
259    /// The `?|` operator.
260    ///
261    /// On PostgreSQL, this operator is used to check whether any of the the indicated array
262    /// members exist as top-level keys.
263    ///
264    /// See <https://www.postgresql.org/docs/current/functions-json.html>.
265    QuestionPipe,
266    /// PostgreSQL-specific custom operator.
267    ///
268    /// See [CREATE OPERATOR](https://www.postgresql.org/docs/current/sql-createoperator.html)
269    /// for more information.
270    PGCustomBinaryOperator(Vec<String>),
271    /// The `OVERLAPS` operator
272    ///
273    /// Specifies a test for an overlap between two datetime periods:
274    /// <https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#overlaps-predicate>
275    Overlaps,
276    /// `##` Point of closest proximity (PostgreSQL/Redshift geometric operator)
277    /// See <https://www.postgresql.org/docs/9.5/functions-geometry.html>
278    DoubleHash,
279    /// `<->` Distance between (PostgreSQL/Redshift geometric operator)
280    /// See <https://www.postgresql.org/docs/9.5/functions-geometry.html>
281    LtDashGt,
282    /// `&<` Overlaps to left? (PostgreSQL/Redshift geometric operator)
283    /// See <https://www.postgresql.org/docs/9.5/functions-geometry.html>
284    AndLt,
285    /// `&>` Overlaps to right? (PostgreSQL/Redshift geometric operator)
286    /// See <https://www.postgresql.org/docs/9.5/functions-geometry.html>
287    AndGt,
288    /// `<<|` Is strictly below? (PostgreSQL/Redshift geometric operator)
289    /// See <https://www.postgresql.org/docs/9.5/functions-geometry.html>
290    LtLtPipe,
291    /// `|>>` Is strictly above? (PostgreSQL/Redshift geometric operator)
292    /// See <https://www.postgresql.org/docs/9.5/functions-geometry.html>
293    PipeGtGt,
294    /// `&<|` Does not extend above? (PostgreSQL/Redshift geometric operator)
295    /// See <https://www.postgresql.org/docs/9.5/functions-geometry.html>
296    AndLtPipe,
297    /// `|&>` Does not extend below? (PostgreSQL/Redshift geometric operator)
298    /// See <https://www.postgresql.org/docs/9.5/functions-geometry.html>
299    PipeAndGt,
300    /// `<^` Is below? (PostgreSQL/Redshift geometric operator)
301    /// See <https://www.postgresql.org/docs/9.5/functions-geometry.html>
302    LtCaret,
303    /// `>^` Is above? (PostgreSQL/Redshift geometric operator)
304    /// See <https://www.postgresql.org/docs/9.5/functions-geometry.html>
305    GtCaret,
306    /// `?#` Intersects? (PostgreSQL/Redshift geometric operator)
307    /// See <https://www.postgresql.org/docs/9.5/functions-geometry.html>
308    QuestionHash,
309    /// `?-` Is horizontal? (PostgreSQL/Redshift geometric operator)
310    /// See <https://www.postgresql.org/docs/9.5/functions-geometry.html>
311    QuestionDash,
312    /// `?-|` Is perpendicular? (PostgreSQL/Redshift geometric operator)
313    /// See <https://www.postgresql.org/docs/9.5/functions-geometry.html>
314    QuestionDashPipe,
315    /// `?||` Are Parallel? (PostgreSQL/Redshift geometric operator)
316    /// See <https://www.postgresql.org/docs/9.5/functions-geometry.html>
317    QuestionDoublePipe,
318    /// `@` Contained or on? (PostgreSQL/Redshift geometric operator)
319    /// See <https://www.postgresql.org/docs/9.5/functions-geometry.html>
320    At,
321    /// `~=` Same as? (PostgreSQL/Redshift geometric operator)
322    /// See <https://www.postgresql.org/docs/9.5/functions-geometry.html>
323    TildeEq,
324    /// ':=' Assignment Operator
325    /// See <https://dev.mysql.com/doc/refman/8.4/en/assignment-operators.html#operator_assign-value>
326    Assignment,
327}
328
329impl fmt::Display for BinaryOperator {
330    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
331        match self {
332            BinaryOperator::Plus => f.write_str("+"),
333            BinaryOperator::Minus => f.write_str("-"),
334            BinaryOperator::Multiply => f.write_str("*"),
335            BinaryOperator::Divide => f.write_str("/"),
336            BinaryOperator::Modulo => f.write_str("%"),
337            BinaryOperator::StringConcat => f.write_str("||"),
338            BinaryOperator::Gt => f.write_str(">"),
339            BinaryOperator::Lt => f.write_str("<"),
340            BinaryOperator::GtEq => f.write_str(">="),
341            BinaryOperator::LtEq => f.write_str("<="),
342            BinaryOperator::Spaceship => f.write_str("<=>"),
343            BinaryOperator::Eq => f.write_str("="),
344            BinaryOperator::NotEq => f.write_str("<>"),
345            BinaryOperator::And => f.write_str("AND"),
346            BinaryOperator::Or => f.write_str("OR"),
347            BinaryOperator::Xor => f.write_str("XOR"),
348            BinaryOperator::BitwiseOr => f.write_str("|"),
349            BinaryOperator::BitwiseAnd => f.write_str("&"),
350            BinaryOperator::BitwiseXor => f.write_str("^"),
351            BinaryOperator::DuckIntegerDivide => f.write_str("//"),
352            BinaryOperator::MyIntegerDivide => f.write_str("DIV"),
353            BinaryOperator::Custom(s) => f.write_str(s),
354            BinaryOperator::PGBitwiseXor => f.write_str("#"),
355            BinaryOperator::PGBitwiseShiftLeft => f.write_str("<<"),
356            BinaryOperator::PGBitwiseShiftRight => f.write_str(">>"),
357            BinaryOperator::PGExp => f.write_str("^"),
358            BinaryOperator::PGOverlap => f.write_str("&&"),
359            BinaryOperator::PGRegexMatch => f.write_str("~"),
360            BinaryOperator::PGRegexIMatch => f.write_str("~*"),
361            BinaryOperator::PGRegexNotMatch => f.write_str("!~"),
362            BinaryOperator::PGRegexNotIMatch => f.write_str("!~*"),
363            BinaryOperator::PGLikeMatch => f.write_str("~~"),
364            BinaryOperator::PGILikeMatch => f.write_str("~~*"),
365            BinaryOperator::PGNotLikeMatch => f.write_str("!~~"),
366            BinaryOperator::PGNotILikeMatch => f.write_str("!~~*"),
367            BinaryOperator::PGStartsWith => f.write_str("^@"),
368            BinaryOperator::Arrow => f.write_str("->"),
369            BinaryOperator::LongArrow => f.write_str("->>"),
370            BinaryOperator::HashArrow => f.write_str("#>"),
371            BinaryOperator::HashLongArrow => f.write_str("#>>"),
372            BinaryOperator::AtAt => f.write_str("@@"),
373            BinaryOperator::AtArrow => f.write_str("@>"),
374            BinaryOperator::ArrowAt => f.write_str("<@"),
375            BinaryOperator::HashMinus => f.write_str("#-"),
376            BinaryOperator::AtQuestion => f.write_str("@?"),
377            BinaryOperator::Question => f.write_str("?"),
378            BinaryOperator::QuestionAnd => f.write_str("?&"),
379            BinaryOperator::QuestionPipe => f.write_str("?|"),
380            BinaryOperator::PGCustomBinaryOperator(idents) => {
381                write!(f, "OPERATOR({})", display_separated(idents, "."))
382            }
383            BinaryOperator::Overlaps => f.write_str("OVERLAPS"),
384            BinaryOperator::DoubleHash => f.write_str("##"),
385            BinaryOperator::LtDashGt => f.write_str("<->"),
386            BinaryOperator::AndLt => f.write_str("&<"),
387            BinaryOperator::AndGt => f.write_str("&>"),
388            BinaryOperator::LtLtPipe => f.write_str("<<|"),
389            BinaryOperator::PipeGtGt => f.write_str("|>>"),
390            BinaryOperator::AndLtPipe => f.write_str("&<|"),
391            BinaryOperator::PipeAndGt => f.write_str("|&>"),
392            BinaryOperator::LtCaret => f.write_str("<^"),
393            BinaryOperator::GtCaret => f.write_str(">^"),
394            BinaryOperator::QuestionHash => f.write_str("?#"),
395            BinaryOperator::QuestionDash => f.write_str("?-"),
396            BinaryOperator::QuestionDashPipe => f.write_str("?-|"),
397            BinaryOperator::QuestionDoublePipe => f.write_str("?||"),
398            BinaryOperator::At => f.write_str("@"),
399            BinaryOperator::TildeEq => f.write_str("~="),
400            BinaryOperator::Assignment => f.write_str(":="),
401        }
402    }
403}