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}