Skip to main content

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