-
Notifications
You must be signed in to change notification settings - Fork 683
[postgres] Add support for custom binary operators #548
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
89e5883
ca6cf22
351e295
7225721
af1e4a9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,6 +12,8 @@ | |
|
|
||
| use core::fmt; | ||
|
|
||
| #[cfg(not(feature = "std"))] | ||
| use alloc::string::String; | ||
| #[cfg(feature = "serde")] | ||
| use serde::{Deserialize, Serialize}; | ||
|
|
||
|
|
@@ -86,41 +88,59 @@ pub enum BinaryOperator { | |
| PGRegexIMatch, | ||
| PGRegexNotMatch, | ||
| PGRegexNotIMatch, | ||
| PGCustomBinaryOperator(PGCustomOperator), | ||
| } | ||
|
|
||
| /// PostgreSQL-specific custom operator. | ||
| /// | ||
| /// See [CREATE OPERATOR](https://www.postgresql.org/docs/current/sql-createoperator.html) for more information. | ||
| #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
| #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] | ||
| pub struct PGCustomOperator { | ||
| pub schema: Option<String>, | ||
| pub name: String, | ||
|
||
| } | ||
|
|
||
| impl fmt::Display for BinaryOperator { | ||
| fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
| f.write_str(match self { | ||
| BinaryOperator::Plus => "+", | ||
| BinaryOperator::Minus => "-", | ||
| BinaryOperator::Multiply => "*", | ||
| BinaryOperator::Divide => "/", | ||
| BinaryOperator::Modulo => "%", | ||
| BinaryOperator::StringConcat => "||", | ||
| BinaryOperator::Gt => ">", | ||
| BinaryOperator::Lt => "<", | ||
| BinaryOperator::GtEq => ">=", | ||
| BinaryOperator::LtEq => "<=", | ||
| BinaryOperator::Spaceship => "<=>", | ||
| BinaryOperator::Eq => "=", | ||
| BinaryOperator::NotEq => "<>", | ||
| BinaryOperator::And => "AND", | ||
| BinaryOperator::Or => "OR", | ||
| BinaryOperator::Xor => "XOR", | ||
| BinaryOperator::Like => "LIKE", | ||
| BinaryOperator::NotLike => "NOT LIKE", | ||
| BinaryOperator::ILike => "ILIKE", | ||
| BinaryOperator::NotILike => "NOT ILIKE", | ||
| BinaryOperator::BitwiseOr => "|", | ||
| BinaryOperator::BitwiseAnd => "&", | ||
| BinaryOperator::BitwiseXor => "^", | ||
| BinaryOperator::PGBitwiseXor => "#", | ||
| BinaryOperator::PGBitwiseShiftLeft => "<<", | ||
| BinaryOperator::PGBitwiseShiftRight => ">>", | ||
| BinaryOperator::PGRegexMatch => "~", | ||
| BinaryOperator::PGRegexIMatch => "~*", | ||
| BinaryOperator::PGRegexNotMatch => "!~", | ||
| BinaryOperator::PGRegexNotIMatch => "!~*", | ||
| }) | ||
| match self { | ||
| BinaryOperator::Plus => f.write_str("+"), | ||
| BinaryOperator::Minus => f.write_str("-"), | ||
| BinaryOperator::Multiply => f.write_str("*"), | ||
| BinaryOperator::Divide => f.write_str("/"), | ||
| BinaryOperator::Modulo => f.write_str("%"), | ||
| BinaryOperator::StringConcat => f.write_str("||"), | ||
| BinaryOperator::Gt => f.write_str(">"), | ||
| BinaryOperator::Lt => f.write_str("<"), | ||
| BinaryOperator::GtEq => f.write_str(">="), | ||
| BinaryOperator::LtEq => f.write_str("<="), | ||
| BinaryOperator::Spaceship => f.write_str("<=>"), | ||
| BinaryOperator::Eq => f.write_str("="), | ||
| BinaryOperator::NotEq => f.write_str("<>"), | ||
| BinaryOperator::And => f.write_str("AND"), | ||
| BinaryOperator::Or => f.write_str("OR"), | ||
| BinaryOperator::Xor => f.write_str("XOR"), | ||
| BinaryOperator::Like => f.write_str("LIKE"), | ||
| BinaryOperator::NotLike => f.write_str("NOT LIKE"), | ||
| BinaryOperator::ILike => f.write_str("ILIKE"), | ||
| BinaryOperator::NotILike => f.write_str("NOT ILIKE"), | ||
| BinaryOperator::BitwiseOr => f.write_str("|"), | ||
| BinaryOperator::BitwiseAnd => f.write_str("&"), | ||
| BinaryOperator::BitwiseXor => f.write_str("^"), | ||
| BinaryOperator::PGBitwiseXor => f.write_str("#"), | ||
| BinaryOperator::PGBitwiseShiftLeft => f.write_str("<<"), | ||
| BinaryOperator::PGBitwiseShiftRight => f.write_str(">>"), | ||
| BinaryOperator::PGRegexMatch => f.write_str("~"), | ||
| BinaryOperator::PGRegexIMatch => f.write_str("~*"), | ||
| BinaryOperator::PGRegexNotMatch => f.write_str("!~"), | ||
| BinaryOperator::PGRegexNotIMatch => f.write_str("!~*"), | ||
| BinaryOperator::PGCustomBinaryOperator(ref custom_operator) => { | ||
| write!(f, "OPERATOR(")?; | ||
| if let Some(ref schema) = custom_operator.schema { | ||
| write!(f, "{}.", schema)?; | ||
| } | ||
| write!(f, "{})", custom_operator.name) | ||
| } | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -358,6 +358,7 @@ define_keywords!( | |
| ON, | ||
| ONLY, | ||
| OPEN, | ||
| OPERATOR, | ||
| OPTION, | ||
| OR, | ||
| ORC, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What would you think about using the pre-existing
Identifierhere (that supports various qualified names)like:
Thank you could use
parse_object_nameinstead of custom parsing logic.https://github.com/sqlparser-rs/sqlparser-rs/blob/076b587bb26f725a9a172c2ca4da373e83937158/src/parser.rs#L3114-L3125
This would likely require less code as well as handle parsing more cases (like
OPERATOR("~")-- aka quoted strings)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried doing this, but looks like
Identifierdoesn't allow forTokens that are un-quoted operators, for e.g:~is not a valid identifier. I am not sure if extending theparse_identifierto allow for un-quoted operators is the right call here.IMO we could start with the existing mechanism of schema qualifier operator name (though I would've liked to use the
parse_object_namelogic) and can extend it as needed later. Let me know.