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