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}
55
56impl fmt::Display for UnaryOperator {
57    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
58        f.write_str(match self {
59            UnaryOperator::Plus => "+",
60            UnaryOperator::Minus => "-",
61            UnaryOperator::Not => "NOT",
62            UnaryOperator::PGBitwiseNot => "~",
63            UnaryOperator::PGSquareRoot => "|/",
64            UnaryOperator::PGCubeRoot => "||/",
65            UnaryOperator::PGPostfixFactorial => "!",
66            UnaryOperator::PGPrefixFactorial => "!!",
67            UnaryOperator::PGAbs => "@",
68        })
69    }
70}
71
72/// Binary operators
73#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
74#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
75#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
76pub enum BinaryOperator {
77    /// Plus, e.g. `a + b`
78    Plus,
79    /// Minus, e.g. `a - b`
80    Minus,
81    /// Multiply, e.g. `a * b`
82    Multiply,
83    /// Divide, e.g. `a / b`
84    Divide,
85    /// Modulo, e.g. `a % b`
86    Modulo,
87    /// String/Array Concat operator, e.g. `a || b`
88    StringConcat,
89    /// Greater than, e.g. `a > b`
90    Gt,
91    /// Less than, e.g. `a < b`
92    Lt,
93    /// Greater equal, e.g. `a >= b`
94    GtEq,
95    /// Less equal, e.g. `a <= b`
96    LtEq,
97    /// Spaceship, e.g. `a <=> b`
98    Spaceship,
99    /// Equal, e.g. `a = b`
100    Eq,
101    /// Not equal, e.g. `a <> b`
102    NotEq,
103    /// And, e.g. `a AND b`
104    And,
105    /// Or, e.g. `a OR b`
106    Or,
107    /// XOR, e.g. `a XOR b`
108    Xor,
109    /// Bitwise or, e.g. `a | b`
110    BitwiseOr,
111    /// Bitwise and, e.g. `a & b`
112    BitwiseAnd,
113    /// Bitwise XOR, e.g. `a ^ b`
114    BitwiseXor,
115    /// Integer division operator `//` in DuckDB
116    DuckIntegerDivide,
117    /// MySQL [`DIV`](https://dev.mysql.com/doc/refman/8.0/en/arithmetic-functions.html) integer division
118    MyIntegerDivide,
119    /// Support for custom operators (such as Postgres custom operators)
120    Custom(String),
121    /// Bitwise XOR, e.g. `a # b` (PostgreSQL-specific)
122    PGBitwiseXor,
123    /// Bitwise shift left, e.g. `a << b` (PostgreSQL-specific)
124    PGBitwiseShiftLeft,
125    /// Bitwise shift right, e.g. `a >> b` (PostgreSQL-specific)
126    PGBitwiseShiftRight,
127    /// Exponent, e.g. `a ^ b` (PostgreSQL-specific)
128    PGExp,
129    /// Overlap operator, e.g. `a && b` (PostgreSQL-specific)
130    PGOverlap,
131    /// String matches regular expression (case sensitively), e.g. `a ~ b` (PostgreSQL-specific)
132    PGRegexMatch,
133    /// String matches regular expression (case insensitively), e.g. `a ~* b` (PostgreSQL-specific)
134    PGRegexIMatch,
135    /// String does not match regular expression (case sensitively), e.g. `a !~ b` (PostgreSQL-specific)
136    PGRegexNotMatch,
137    /// String does not match regular expression (case insensitively), e.g. `a !~* b` (PostgreSQL-specific)
138    PGRegexNotIMatch,
139    /// String matches pattern (case sensitively), e.g. `a ~~ b` (PostgreSQL-specific)
140    PGLikeMatch,
141    /// String matches pattern (case insensitively), e.g. `a ~~* b` (PostgreSQL-specific)
142    PGILikeMatch,
143    /// String does not match pattern (case sensitively), e.g. `a !~~ b` (PostgreSQL-specific)
144    PGNotLikeMatch,
145    /// String does not match pattern (case insensitively), e.g. `a !~~* b` (PostgreSQL-specific)
146    PGNotILikeMatch,
147    /// String "starts with", eg: `a ^@ b` (PostgreSQL-specific)
148    PGStartsWith,
149    /// The `->` operator.
150    ///
151    /// On PostgreSQL, this operator extracts a JSON object field or array
152    /// element, for example `'{"a":"b"}'::json -> 'a'` or `[1, 2, 3]'::json
153    /// -> 2`.
154    ///
155    /// See <https://www.postgresql.org/docs/current/functions-json.html>.
156    Arrow,
157    /// The `->>` operator.
158    ///
159    /// On PostgreSQL, this operator extracts a JSON object field or JSON
160    /// array element and converts it to text, for example `'{"a":"b"}'::json
161    /// ->> 'a'` or `[1, 2, 3]'::json ->> 2`.
162    ///
163    /// See <https://www.postgresql.org/docs/current/functions-json.html>.
164    LongArrow,
165    /// The `#>` operator.
166    ///
167    /// On PostgreSQL, this operator extracts a JSON sub-object at the specified
168    /// path, for example:
169    ///
170    /// ```notrust
171    ///'{"a": {"b": ["foo","bar"]}}'::json #> '{a,b,1}'
172    /// ```
173    ///
174    /// See <https://www.postgresql.org/docs/current/functions-json.html>.
175    HashArrow,
176    /// The `#>>` operator.
177    ///
178    /// A PostgreSQL-specific operator that extracts JSON sub-object at the
179    /// specified path, for example
180    ///
181    /// ```notrust
182    ///'{"a": {"b": ["foo","bar"]}}'::json #>> '{a,b,1}'
183    /// ```
184    ///
185    /// See <https://www.postgresql.org/docs/current/functions-json.html>.
186    HashLongArrow,
187    /// The `@@` operator.
188    ///
189    /// On PostgreSQL, this is used for JSON and text searches.
190    ///
191    /// See <https://www.postgresql.org/docs/current/functions-json.html>.
192    /// See <https://www.postgresql.org/docs/current/functions-textsearch.html>.
193    AtAt,
194    /// The `@>` operator.
195    ///
196    /// On PostgreSQL, this is used for JSON and text searches.
197    ///
198    /// See <https://www.postgresql.org/docs/current/functions-json.html>.
199    /// See <https://www.postgresql.org/docs/current/functions-textsearch.html>.
200    AtArrow,
201    /// The `<@` operator.
202    ///
203    /// On PostgreSQL, this is used for JSON and text searches.
204    ///
205    /// See <https://www.postgresql.org/docs/current/functions-json.html>.
206    /// See <https://www.postgresql.org/docs/current/functions-textsearch.html>.
207    ArrowAt,
208    /// The `#-` operator.
209    ///
210    /// On PostgreSQL, this operator is used to delete a field or array element
211    /// at a specified path.
212    ///
213    /// See <https://www.postgresql.org/docs/current/functions-json.html>.
214    HashMinus,
215    /// The `@?` operator.
216    ///
217    /// On PostgreSQL, this operator is used to check the given JSON path
218    /// returns an item for the JSON value.
219    ///
220    /// See <https://www.postgresql.org/docs/current/functions-json.html>.
221    AtQuestion,
222    /// The `?` operator.
223    ///
224    /// On PostgreSQL, this operator is used to check whether a string exists as a top-level key
225    /// within the JSON value
226    ///
227    /// See <https://www.postgresql.org/docs/current/functions-json.html>.
228    Question,
229    /// The `?&` operator.
230    ///
231    /// On PostgreSQL, this operator is used to check whether all of the the indicated array
232    /// members exist as top-level keys.
233    ///
234    /// See <https://www.postgresql.org/docs/current/functions-json.html>.
235    QuestionAnd,
236    /// The `?|` operator.
237    ///
238    /// On PostgreSQL, this operator is used to check whether any of the the indicated array
239    /// members exist as top-level keys.
240    ///
241    /// See <https://www.postgresql.org/docs/current/functions-json.html>.
242    QuestionPipe,
243    /// PostgreSQL-specific custom operator.
244    ///
245    /// See [CREATE OPERATOR](https://www.postgresql.org/docs/current/sql-createoperator.html)
246    /// for more information.
247    PGCustomBinaryOperator(Vec<String>),
248}
249
250impl fmt::Display for BinaryOperator {
251    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
252        match self {
253            BinaryOperator::Plus => f.write_str("+"),
254            BinaryOperator::Minus => f.write_str("-"),
255            BinaryOperator::Multiply => f.write_str("*"),
256            BinaryOperator::Divide => f.write_str("/"),
257            BinaryOperator::Modulo => f.write_str("%"),
258            BinaryOperator::StringConcat => f.write_str("||"),
259            BinaryOperator::Gt => f.write_str(">"),
260            BinaryOperator::Lt => f.write_str("<"),
261            BinaryOperator::GtEq => f.write_str(">="),
262            BinaryOperator::LtEq => f.write_str("<="),
263            BinaryOperator::Spaceship => f.write_str("<=>"),
264            BinaryOperator::Eq => f.write_str("="),
265            BinaryOperator::NotEq => f.write_str("<>"),
266            BinaryOperator::And => f.write_str("AND"),
267            BinaryOperator::Or => f.write_str("OR"),
268            BinaryOperator::Xor => f.write_str("XOR"),
269            BinaryOperator::BitwiseOr => f.write_str("|"),
270            BinaryOperator::BitwiseAnd => f.write_str("&"),
271            BinaryOperator::BitwiseXor => f.write_str("^"),
272            BinaryOperator::DuckIntegerDivide => f.write_str("//"),
273            BinaryOperator::MyIntegerDivide => f.write_str("DIV"),
274            BinaryOperator::Custom(s) => f.write_str(s),
275            BinaryOperator::PGBitwiseXor => f.write_str("#"),
276            BinaryOperator::PGBitwiseShiftLeft => f.write_str("<<"),
277            BinaryOperator::PGBitwiseShiftRight => f.write_str(">>"),
278            BinaryOperator::PGExp => f.write_str("^"),
279            BinaryOperator::PGOverlap => f.write_str("&&"),
280            BinaryOperator::PGRegexMatch => f.write_str("~"),
281            BinaryOperator::PGRegexIMatch => f.write_str("~*"),
282            BinaryOperator::PGRegexNotMatch => f.write_str("!~"),
283            BinaryOperator::PGRegexNotIMatch => f.write_str("!~*"),
284            BinaryOperator::PGLikeMatch => f.write_str("~~"),
285            BinaryOperator::PGILikeMatch => f.write_str("~~*"),
286            BinaryOperator::PGNotLikeMatch => f.write_str("!~~"),
287            BinaryOperator::PGNotILikeMatch => f.write_str("!~~*"),
288            BinaryOperator::PGStartsWith => f.write_str("^@"),
289            BinaryOperator::Arrow => f.write_str("->"),
290            BinaryOperator::LongArrow => f.write_str("->>"),
291            BinaryOperator::HashArrow => f.write_str("#>"),
292            BinaryOperator::HashLongArrow => f.write_str("#>>"),
293            BinaryOperator::AtAt => f.write_str("@@"),
294            BinaryOperator::AtArrow => f.write_str("@>"),
295            BinaryOperator::ArrowAt => f.write_str("<@"),
296            BinaryOperator::HashMinus => f.write_str("#-"),
297            BinaryOperator::AtQuestion => f.write_str("@?"),
298            BinaryOperator::Question => f.write_str("?"),
299            BinaryOperator::QuestionAnd => f.write_str("?&"),
300            BinaryOperator::QuestionPipe => f.write_str("?|"),
301            BinaryOperator::PGCustomBinaryOperator(idents) => {
302                write!(f, "OPERATOR({})", display_separated(idents, "."))
303            }
304        }
305    }
306}