sqlparser/dialect/
postgresql.rs1use log::debug;
30
31use crate::dialect::{Dialect, Precedence};
32use crate::keywords::Keyword;
33use crate::parser::{Parser, ParserError};
34use crate::tokenizer::Token;
35
36#[derive(#[automatically_derived]
impl ::core::fmt::Debug for PostgreSqlDialect {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f, "PostgreSqlDialect")
}
}Debug, #[automatically_derived]
impl ::core::default::Default for PostgreSqlDialect {
#[inline]
fn default() -> PostgreSqlDialect { PostgreSqlDialect {} }
}Default, #[automatically_derived]
impl ::core::clone::Clone for PostgreSqlDialect {
#[inline]
fn clone(&self) -> PostgreSqlDialect { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for PostgreSqlDialect { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for PostgreSqlDialect {
#[inline]
fn eq(&self, other: &PostgreSqlDialect) -> bool { true }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for PostgreSqlDialect {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {}
}Eq, #[automatically_derived]
impl ::core::hash::Hash for PostgreSqlDialect {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {}
}Hash, #[automatically_derived]
impl ::core::cmp::PartialOrd for PostgreSqlDialect {
#[inline]
fn partial_cmp(&self, other: &PostgreSqlDialect)
-> ::core::option::Option<::core::cmp::Ordering> {
::core::option::Option::Some(::core::cmp::Ordering::Equal)
}
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Ord for PostgreSqlDialect {
#[inline]
fn cmp(&self, other: &PostgreSqlDialect) -> ::core::cmp::Ordering {
::core::cmp::Ordering::Equal
}
}Ord)]
38#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
39pub struct PostgreSqlDialect {}
40
41const PERIOD_PREC: u8 = 200;
42const DOUBLE_COLON_PREC: u8 = 140;
43const BRACKET_PREC: u8 = 130;
44const COLLATE_PREC: u8 = 120;
45const AT_TZ_PREC: u8 = 110;
46const CARET_PREC: u8 = 100;
47const MUL_DIV_MOD_OP_PREC: u8 = 90;
48const PLUS_MINUS_PREC: u8 = 80;
49const XOR_PREC: u8 = 75;
51const PG_OTHER_PREC: u8 = 70;
52const BETWEEN_LIKE_PREC: u8 = 60;
53const EQ_PREC: u8 = 50;
54const IS_PREC: u8 = 40;
55const NOT_PREC: u8 = 30;
56const AND_PREC: u8 = 20;
57const OR_PREC: u8 = 10;
58
59impl Dialect for PostgreSqlDialect {
60 fn identifier_quote_style(&self, _identifier: &str) -> Option<char> {
61 Some('"')
62 }
63
64 fn is_delimited_identifier_start(&self, ch: char) -> bool {
65 ch == '"' }
67
68 fn is_identifier_start(&self, ch: char) -> bool {
69 ch.is_alphabetic() || ch == '_' ||
70 !ch.is_ascii()
72 }
73
74 fn is_identifier_part(&self, ch: char) -> bool {
75 ch.is_alphabetic() || ch.is_ascii_digit() || ch == '$' || ch == '_' ||
76 !ch.is_ascii()
78 }
79
80 fn supports_unicode_string_literal(&self) -> bool {
81 true
82 }
83
84 fn is_custom_operator_part(&self, ch: char) -> bool {
86 #[allow(non_exhaustive_omitted_patterns)] match ch {
'+' | '-' | '*' | '/' | '<' | '>' | '=' | '~' | '!' | '@' | '#' | '%' |
'^' | '&' | '|' | '`' | '?' => true,
_ => false,
}matches!(
87 ch,
88 '+' | '-'
89 | '*'
90 | '/'
91 | '<'
92 | '>'
93 | '='
94 | '~'
95 | '!'
96 | '@'
97 | '#'
98 | '%'
99 | '^'
100 | '&'
101 | '|'
102 | '`'
103 | '?'
104 )
105 }
106
107 fn get_next_precedence(&self, parser: &Parser) -> Option<Result<u8, ParserError>> {
108 let token = parser.peek_token();
109 {
{
let lvl = ::log::Level::Debug;
if lvl <= ::log::STATIC_MAX_LEVEL && lvl <= ::log::max_level() {
::log::__private_api::log({ ::log::__private_api::GlobalLogger },
format_args!("get_next_precedence() {0:?}", token), lvl,
&("sqlparser::dialect::postgresql",
"sqlparser::dialect::postgresql",
::log::__private_api::loc()), ());
}
}
};debug!("get_next_precedence() {token:?}");
110
111 match token.token {
114 Token::Word(w)
115 if w.keyword == Keyword::COLLATE && !parser.in_column_definition_state() =>
116 {
117 Some(Ok(COLLATE_PREC))
118 }
119 Token::LBracket => Some(Ok(BRACKET_PREC)),
120 Token::Arrow
121 | Token::LongArrow
122 | Token::HashArrow
123 | Token::HashLongArrow
124 | Token::AtArrow
125 | Token::ArrowAt
126 | Token::HashMinus
127 | Token::AtQuestion
128 | Token::AtAt
129 | Token::Question
130 | Token::QuestionAnd
131 | Token::QuestionPipe
132 | Token::ExclamationMark
133 | Token::Overlap
134 | Token::CaretAt
135 | Token::StringConcat
136 | Token::Sharp
137 | Token::ShiftRight
138 | Token::ShiftLeft
139 | Token::CustomBinaryOperator(_) => Some(Ok(PG_OTHER_PREC)),
140 Token::Colon => Some(Ok(self.prec_unknown())),
142 _ => None,
143 }
144 }
145
146 fn supports_filter_during_aggregation(&self) -> bool {
147 true
148 }
149
150 fn supports_group_by_expr(&self) -> bool {
151 true
152 }
153
154 fn prec_value(&self, prec: Precedence) -> u8 {
155 match prec {
156 Precedence::Period => PERIOD_PREC,
157 Precedence::DoubleColon => DOUBLE_COLON_PREC,
158 Precedence::AtTz => AT_TZ_PREC,
159 Precedence::MulDivModOp => MUL_DIV_MOD_OP_PREC,
160 Precedence::PlusMinus => PLUS_MINUS_PREC,
161 Precedence::Xor => XOR_PREC,
162 Precedence::Ampersand => PG_OTHER_PREC,
163 Precedence::Caret => CARET_PREC,
164 Precedence::Pipe => PG_OTHER_PREC,
165 Precedence::Colon => PG_OTHER_PREC,
166 Precedence::Between => BETWEEN_LIKE_PREC,
167 Precedence::Eq => EQ_PREC,
168 Precedence::Like => BETWEEN_LIKE_PREC,
169 Precedence::Is => IS_PREC,
170 Precedence::PgOther => PG_OTHER_PREC,
171 Precedence::UnaryNot => NOT_PREC,
172 Precedence::And => AND_PREC,
173 Precedence::Or => OR_PREC,
174 }
175 }
176
177 fn allow_extract_custom(&self) -> bool {
178 true
179 }
180
181 fn allow_extract_single_quotes(&self) -> bool {
182 true
183 }
184
185 fn supports_create_index_with_clause(&self) -> bool {
186 true
187 }
188
189 fn supports_explain_with_utility_options(&self) -> bool {
191 true
192 }
193
194 fn supports_listen_notify(&self) -> bool {
198 true
199 }
200
201 fn supports_factorial_operator(&self) -> bool {
203 true
204 }
205
206 fn supports_bitwise_shift_operators(&self) -> bool {
207 true
208 }
209
210 fn supports_comment_on(&self) -> bool {
212 true
213 }
214
215 fn supports_load_extension(&self) -> bool {
217 true
218 }
219
220 fn supports_named_fn_args_with_colon_operator(&self) -> bool {
227 true
228 }
229
230 fn supports_named_fn_args_with_expr_name(&self) -> bool {
237 true
238 }
239
240 fn supports_empty_projections(&self) -> bool {
247 true
248 }
249
250 fn supports_nested_comments(&self) -> bool {
251 true
252 }
253
254 fn supports_string_escape_constant(&self) -> bool {
255 true
256 }
257
258 fn supports_numeric_literal_underscores(&self) -> bool {
259 true
260 }
261
262 fn supports_array_typedef_with_brackets(&self) -> bool {
264 true
265 }
266
267 fn supports_geometric_types(&self) -> bool {
268 true
269 }
270
271 fn supports_set_names(&self) -> bool {
272 true
273 }
274
275 fn supports_alter_column_type_using(&self) -> bool {
276 true
277 }
278
279 fn supports_notnull_operator(&self) -> bool {
282 true
283 }
284
285 fn supports_interval_options(&self) -> bool {
289 true
290 }
291}