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(Debug)]
38pub struct PostgreSqlDialect {}
39
40const PERIOD_PREC: u8 = 200;
41const DOUBLE_COLON_PREC: u8 = 140;
42const BRACKET_PREC: u8 = 130;
43const COLLATE_PREC: u8 = 120;
44const AT_TZ_PREC: u8 = 110;
45const CARET_PREC: u8 = 100;
46const MUL_DIV_MOD_OP_PREC: u8 = 90;
47const PLUS_MINUS_PREC: u8 = 80;
48const XOR_PREC: u8 = 75;
50const PG_OTHER_PREC: u8 = 70;
51const BETWEEN_LIKE_PREC: u8 = 60;
52const EQ_PREC: u8 = 50;
53const IS_PREC: u8 = 40;
54const NOT_PREC: u8 = 30;
55const AND_PREC: u8 = 20;
56const OR_PREC: u8 = 10;
57
58impl Dialect for PostgreSqlDialect {
59 fn identifier_quote_style(&self, _identifier: &str) -> Option<char> {
60 Some('"')
61 }
62
63 fn is_delimited_identifier_start(&self, ch: char) -> bool {
64 ch == '"' }
66
67 fn is_identifier_start(&self, ch: char) -> bool {
68 ch.is_alphabetic() || ch == '_' ||
69 !ch.is_ascii()
71 }
72
73 fn is_identifier_part(&self, ch: char) -> bool {
74 ch.is_alphabetic() || ch.is_ascii_digit() || ch == '$' || ch == '_' ||
75 !ch.is_ascii()
77 }
78
79 fn supports_unicode_string_literal(&self) -> bool {
80 true
81 }
82
83 fn is_custom_operator_part(&self, ch: char) -> bool {
85 matches!(
86 ch,
87 '+' | '-'
88 | '*'
89 | '/'
90 | '<'
91 | '>'
92 | '='
93 | '~'
94 | '!'
95 | '@'
96 | '#'
97 | '%'
98 | '^'
99 | '&'
100 | '|'
101 | '`'
102 | '?'
103 )
104 }
105
106 fn get_next_precedence(&self, parser: &Parser) -> Option<Result<u8, ParserError>> {
107 let token = parser.peek_token();
108 debug!("get_next_precedence() {token:?}");
109
110 match token.token {
113 Token::Word(w)
114 if w.keyword == Keyword::COLLATE && !parser.in_column_definition_state() =>
115 {
116 Some(Ok(COLLATE_PREC))
117 }
118 Token::LBracket => Some(Ok(BRACKET_PREC)),
119 Token::Arrow
120 | Token::LongArrow
121 | Token::HashArrow
122 | Token::HashLongArrow
123 | Token::AtArrow
124 | Token::ArrowAt
125 | Token::HashMinus
126 | Token::AtQuestion
127 | Token::AtAt
128 | Token::Question
129 | Token::QuestionAnd
130 | Token::QuestionPipe
131 | Token::ExclamationMark
132 | Token::Overlap
133 | Token::CaretAt
134 | Token::StringConcat
135 | Token::Sharp
136 | Token::ShiftRight
137 | Token::ShiftLeft
138 | Token::CustomBinaryOperator(_) => Some(Ok(PG_OTHER_PREC)),
139 _ => None,
140 }
141 }
142
143 fn supports_filter_during_aggregation(&self) -> bool {
144 true
145 }
146
147 fn supports_group_by_expr(&self) -> bool {
148 true
149 }
150
151 fn prec_value(&self, prec: Precedence) -> u8 {
152 match prec {
153 Precedence::Period => PERIOD_PREC,
154 Precedence::DoubleColon => DOUBLE_COLON_PREC,
155 Precedence::AtTz => AT_TZ_PREC,
156 Precedence::MulDivModOp => MUL_DIV_MOD_OP_PREC,
157 Precedence::PlusMinus => PLUS_MINUS_PREC,
158 Precedence::Xor => XOR_PREC,
159 Precedence::Ampersand => PG_OTHER_PREC,
160 Precedence::Caret => CARET_PREC,
161 Precedence::Pipe => PG_OTHER_PREC,
162 Precedence::Between => BETWEEN_LIKE_PREC,
163 Precedence::Eq => EQ_PREC,
164 Precedence::Like => BETWEEN_LIKE_PREC,
165 Precedence::Is => IS_PREC,
166 Precedence::PgOther => PG_OTHER_PREC,
167 Precedence::UnaryNot => NOT_PREC,
168 Precedence::And => AND_PREC,
169 Precedence::Or => OR_PREC,
170 }
171 }
172
173 fn allow_extract_custom(&self) -> bool {
174 true
175 }
176
177 fn allow_extract_single_quotes(&self) -> bool {
178 true
179 }
180
181 fn supports_create_index_with_clause(&self) -> bool {
182 true
183 }
184
185 fn supports_explain_with_utility_options(&self) -> bool {
187 true
188 }
189
190 fn supports_listen_notify(&self) -> bool {
194 true
195 }
196
197 fn supports_factorial_operator(&self) -> bool {
199 true
200 }
201
202 fn supports_comment_on(&self) -> bool {
204 true
205 }
206
207 fn supports_load_extension(&self) -> bool {
209 true
210 }
211
212 fn supports_named_fn_args_with_colon_operator(&self) -> bool {
219 true
220 }
221
222 fn supports_named_fn_args_with_expr_name(&self) -> bool {
229 true
230 }
231
232 fn supports_empty_projections(&self) -> bool {
239 true
240 }
241
242 fn supports_nested_comments(&self) -> bool {
243 true
244 }
245
246 fn supports_string_escape_constant(&self) -> bool {
247 true
248 }
249
250 fn supports_numeric_literal_underscores(&self) -> bool {
251 true
252 }
253
254 fn supports_array_typedef_with_brackets(&self) -> bool {
256 true
257 }
258
259 fn supports_geometric_types(&self) -> bool {
260 true
261 }
262
263 fn supports_set_names(&self) -> bool {
264 true
265 }
266
267 fn supports_alter_column_type_using(&self) -> bool {
268 true
269 }
270
271 fn supports_notnull_operator(&self) -> bool {
274 true
275 }
276
277 fn supports_interval_options(&self) -> bool {
281 true
282 }
283}