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}