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}