Line data Source code
1 : //! The SQL formatter.
2 : //!
3 : //! The formatter visits the AST in post-order and builds a document for every node in a
4 : //! [`FormattingProgram`], so the documents of the children always exist when a parent is visited.
5 : //! Nodes that cannot be formatted are rendered as `'<NODE_TYPE>'` placeholders and recorded as
6 : //! unformattable. The statements are then rendered with the comments of the script in between.
7 : //!
8 : //! The output keeps the quirks listed in docs/design/core_quirks.md. The statement formatters live in
9 : //! the submodules, one per statement kind.
10 :
11 : mod comments;
12 : mod create;
13 : mod delete;
14 : mod explain;
15 : mod insert;
16 : mod pgq;
17 : pub mod program;
18 : mod select;
19 :
20 : pub use program::*;
21 :
22 : use dashql_parser::attrs;
23 : use dashql_buffers::formatting::{FormattingConfigT, FormattingDialect, FormattingMode};
24 : use dashql_buffers::parser::{
25 : AttributeKey, CharacterType, ColumnConstraint, ConstraintAttribute, ExpressionOperator, ExtractTarget,
26 : GroupByItemType, IntervalType, JoinType, KeyActionCommand, KeyActionTrigger, KeyMatch, KnownFunction, Node,
27 : NodeType, NumericType, OrderDirection, OrderNullRule, RowLockingBlockBehavior, RowLockingStrength, SampleCountUnit,
28 : SubqueryQuantifier, SymbolSpan, TableConstraint, TempType, TrimDirection, WindowBoundDirection, WindowBoundMode,
29 : WindowRangeMode,
30 : };
31 : use dashql_parser::parser::context::resolve_text_span;
32 : use dashql_parser::parser::ParsedScript;
33 : use dashql_parser::scanner::ScannedScript;
34 : use dashql_parser::span::TextSpan;
35 : use std::cell::{Cell, RefCell};
36 :
37 : type K = AttributeKey;
38 :
39 : #[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
40 : pub enum FormattingAssociativity {
41 : Left,
42 : Right,
43 : #[default]
44 : NonAssoc,
45 : }
46 :
47 : use FormattingAssociativity as Associativity;
48 :
49 : /// The formatting state of an AST node
50 : #[derive(Clone, Copy, Debug, Default)]
51 : pub struct FormattingNodeState {
52 : /// The operator precedence of an n-ary expression or its argument array, 0 if none
53 : pub precedence: usize,
54 : /// The operator associativity of an n-ary expression or its argument array
55 : pub associativity: FormattingAssociativity,
56 : /// Must the n-ary expression be parenthesized within its parent expression?
57 : pub needs_parentheses: bool,
58 : /// Is the node the root of a statement, or the statement of an EXPLAIN?
59 : pub is_statement_root: bool,
60 : /// The formatted document of the node
61 : pub reg: FmtReg,
62 : }
63 :
64 27005 : fn get_operator_precedence(op: ExpressionOperator) -> (usize, Associativity) {
65 : use ExpressionOperator as O;
66 27005 : match op {
67 805 : O::OR => (3, Associativity::Left),
68 3332 : O::AND => (4, Associativity::Left),
69 93 : O::NOT => (5, Associativity::Right),
70 : O::IS_NULL
71 : | O::NOT_NULL
72 : | O::IS_TRUE
73 : | O::IS_FALSE
74 : | O::IS_UNKNOWN
75 : | O::IS_DISTINCT_FROM
76 : | O::IS_OF
77 : | O::IS_NOT_TRUE
78 : | O::IS_NOT_FALSE
79 : | O::IS_NOT_UNKNOWN
80 : | O::IS_NOT_DISTINCT_FROM
81 : | O::IS_NOT_OF
82 : | O::EQUAL
83 : | O::NOT_EQUAL
84 : | O::GREATER_EQUAL
85 : | O::GREATER_THAN
86 : | O::LESS_EQUAL
87 14612 : | O::LESS_THAN => (6, Associativity::NonAssoc),
88 : O::BETWEEN_SYMMETRIC
89 : | O::BETWEEN_ASYMMETRIC
90 : | O::NOT_BETWEEN_SYMMETRIC
91 : | O::NOT_BETWEEN_ASYMMETRIC
92 : | O::IN
93 : | O::NOT_IN
94 : | O::GLOB
95 : | O::NOT_GLOB
96 : | O::LIKE
97 : | O::NOT_LIKE
98 : | O::ILIKE
99 : | O::NOT_ILIKE
100 : | O::SIMILAR_TO
101 : | O::NOT_SIMILAR_TO
102 2847 : | O::OVERLAPS => (7, Associativity::NonAssoc),
103 2729 : O::PLUS | O::MINUS => (12, Associativity::Left),
104 2261 : O::MULTIPLY | O::DIVIDE | O::MODULUS => (13, Associativity::Left),
105 24 : O::XOR => (14, Associativity::Left),
106 12 : O::AT_TIMEZONE => (15, Associativity::Left),
107 9 : O::COLLATE => (16, Associativity::Left),
108 274 : O::NEGATE => (17, Associativity::Right),
109 0 : O::TYPECAST => (20, Associativity::Left),
110 : // Unknown operators get precedence 0, non-associative (see docs/design/core_quirks.md)
111 7 : _ => (0, Associativity::NonAssoc),
112 : }
113 27005 : }
114 :
115 : /// Break before AND and OR, after every other operator
116 23826 : fn breaks_before_operator(op: ExpressionOperator) -> bool {
117 23826 : matches!(op, ExpressionOperator::OR | ExpressionOperator::AND)
118 23826 : }
119 :
120 27122 : fn get_operator_text(op: ExpressionOperator) -> &'static str {
121 : use ExpressionOperator as O;
122 27122 : match op {
123 274 : O::NEGATE => "-",
124 93 : O::NOT => "not",
125 1895 : O::PLUS => "+",
126 852 : O::MINUS => "-",
127 1376 : O::MULTIPLY => "*",
128 873 : O::DIVIDE => "/",
129 12 : O::MODULUS => "%",
130 3332 : O::AND => "and",
131 805 : O::OR => "or",
132 : // The `^` of the grammar, the exponentiation of Hyper and PostgreSQL (`#` would be their bitwise xor)
133 24 : O::XOR => "^",
134 12080 : O::EQUAL => "=",
135 159 : O::NOT_EQUAL => "<>",
136 315 : O::LESS_THAN => "<",
137 1119 : O::GREATER_THAN => ">",
138 489 : O::LESS_EQUAL => "<=",
139 222 : O::GREATER_EQUAL => ">=",
140 117 : O::LIKE => "like",
141 30 : O::NOT_LIKE => "not like",
142 9 : O::ILIKE => "ilike",
143 9 : O::NOT_ILIKE => "not ilike",
144 9 : O::SIMILAR_TO => "similar to",
145 6 : O::NOT_SIMILAR_TO => "not similar to",
146 12 : O::OVERLAPS => "overlaps",
147 12 : O::GLOB => "glob",
148 18 : O::NOT_GLOB => "not glob",
149 105 : O::IS_NULL => "is null",
150 102 : O::NOT_NULL => "is not null",
151 9 : O::IS_TRUE => "is true",
152 9 : O::IS_FALSE => "is false",
153 9 : O::IS_UNKNOWN => "is unknown",
154 9 : O::IS_NOT_TRUE => "is not true",
155 9 : O::IS_NOT_FALSE => "is not false",
156 9 : O::IS_NOT_UNKNOWN => "is not unknown",
157 15 : O::IS_DISTINCT_FROM => "is distinct from",
158 15 : O::IS_NOT_DISTINCT_FROM => "is not distinct from",
159 1086 : O::IN => "in",
160 18 : O::NOT_IN => "not in",
161 1482 : O::BETWEEN_ASYMMETRIC => "between",
162 21 : O::BETWEEN_SYMMETRIC => "between symmetric",
163 33 : O::NOT_BETWEEN_ASYMMETRIC => "not between",
164 21 : O::NOT_BETWEEN_SYMMETRIC => "not between symmetric",
165 9 : O::COLLATE => "collate",
166 12 : O::AT_TIMEZONE => "at time zone",
167 7 : O::DEFAULT => "default",
168 0 : _ => "",
169 : }
170 27122 : }
171 :
172 2175 : fn get_known_function_text(function: KnownFunction) -> &'static str {
173 : use KnownFunction as F;
174 2175 : match function {
175 3 : F::COLLATION_FOR => "collation for",
176 9 : F::CURRENT_DATE => "current_date",
177 24 : F::CURRENT_TIME => "current_time",
178 36 : F::CURRENT_TIMESTAMP => "current_timestamp",
179 18 : F::LOCALTIME => "localtime",
180 18 : F::LOCALTIMESTAMP => "localtimestamp",
181 9 : F::CURRENT_ROLE => "current_role",
182 9 : F::CURRENT_USER => "current_user",
183 9 : F::SESSION_USER => "session_user",
184 9 : F::USER => "user",
185 9 : F::CURRENT_CATALOG => "current_catalog",
186 9 : F::CURRENT_SCHEMA => "current_schema",
187 1122 : F::CAST => "cast",
188 81 : F::EXTRACT => "extract",
189 18 : F::OVERLAY => "overlay",
190 15 : F::POSITION => "position",
191 255 : F::SUBSTRING => "substring",
192 15 : F::TREAT => "treat",
193 81 : F::TRIM => "trim",
194 15 : F::NULLIF => "nullif",
195 402 : F::COALESCE => "coalesce",
196 9 : F::TRY_CAST => "try_cast",
197 0 : _ => "",
198 : }
199 2175 : }
200 :
201 : /// The value of an enum node
202 97256 : fn value_u8(node: &Node) -> u8 {
203 97256 : node.children_begin_or_value() as u8
204 97256 : }
205 :
206 : /// Is the node a true BOOL?
207 30635 : fn is_true(node: Option<&Node>) -> bool {
208 30635 : node.is_some_and(|n| n.node_type() == NodeType::BOOL && n.children_begin_or_value() != 0)
209 30635 : }
210 :
211 : /// A part of the formatted script
212 : #[derive(Clone, Copy, Debug)]
213 : enum OutputPart {
214 : /// A parsed statement without errors, the index in the statements of the parsed script
215 : Statement(usize),
216 : /// A statement with syntax errors, the text span that is copied as written
217 : Damaged(TextSpan),
218 : }
219 :
220 : /// The SQL formatter
221 : pub struct Formatter<'a> {
222 : /// The scanned script
223 : scanned: &'a ScannedScript,
224 : /// Emit executable literals instead of obfuscated literal markers?
225 : replace_obfuscated_literals: bool,
226 : /// The parsed script
227 : parsed: &'a ParsedScript,
228 : /// The AST nodes of the parsed script
229 : ast: &'a [Node],
230 : /// The formatting config of the current run
231 : config: FormattingConfigT,
232 : /// The document arena that holds the formatted nodes
233 : fmt: FormattingProgram<'a>,
234 : /// The formatting states, indexed by AST node id
235 : node_states: Vec<FormattingNodeState>,
236 : /// The ids of the nodes that were rendered as placeholders
237 : unformattable_nodes: RefCell<Vec<u32>>,
238 : /// Was a part of the script with syntax errors copied as written?
239 : copied_damaged_text: Cell<bool>,
240 : }
241 :
242 : impl<'a> Formatter<'a> {
243 4398 : pub fn new(parsed: &'a ParsedScript) -> Self {
244 4398 : let mut formatter = Self {
245 4398 : scanned: &parsed.scanned,
246 4398 : replace_obfuscated_literals: false,
247 4398 : parsed,
248 4398 : ast: &parsed.nodes,
249 4398 : config: FormattingConfigT::default(),
250 4398 : fmt: FormattingProgram::new(),
251 4398 : node_states: vec![FormattingNodeState::default(); parsed.nodes.len()],
252 4398 : unformattable_nodes: RefCell::new(Vec::new()),
253 4398 : copied_damaged_text: Cell::new(false),
254 4398 : };
255 4398 : formatter.mark_statement_roots();
256 4398 : formatter
257 4398 : }
258 :
259 : /// Emit executable literals instead of the obfuscated literal markers of Hyper
260 6 : pub fn replace_obfuscated_literals(&mut self) {
261 6 : self.replace_obfuscated_literals = true;
262 6 : }
263 :
264 5606 : pub fn estimate_formatted_size(&self) -> usize {
265 5606 : self.scanned.text.len() + 64
266 5606 : }
267 :
268 : /// The nodes that could not be formatted by the last call of `format` or `format_node_at`
269 634 : pub fn unformattable_nodes(&self) -> Vec<u32> {
270 634 : self.unformattable_nodes.borrow().clone()
271 634 : }
272 :
273 : /// Was everything formatted? Parts with syntax errors are copied as written and nodes that cannot be
274 : /// formatted are rendered as placeholders.
275 2064 : pub fn is_fully_formatted(&self) -> bool {
276 2064 : self.unformattable_nodes.borrow().is_empty() && !self.copied_damaged_text.get()
277 2064 : }
278 :
279 : /// Format the script
280 5598 : pub fn format(&mut self, config: &FormattingConfigT) -> String {
281 5598 : bytes_to_string(self.format_bytes(config))
282 5598 : }
283 :
284 : /// Format the script, the output may contain partial UTF-8 sequences where comments were wrapped
285 5606 : pub fn format_bytes(&mut self, config: &FormattingConfigT) -> Vec<u8> {
286 5606 : self.prepare(config);
287 5606 : self.mark_statement_roots();
288 5606 : self.prepare_precedence();
289 460776 : for i in 0..self.ast.len() {
290 460776 : self.identify_parentheses(self.ast.len() - 1 - i);
291 460776 : }
292 5606 : self.build_docs();
293 5606 : self.write_output()
294 5606 : }
295 :
296 : /// Format a single node (without the statement roots that only `format` marks)
297 375 : pub fn format_node_at(&mut self, node_id: usize, config: &FormattingConfigT) -> String {
298 375 : if node_id >= self.ast.len() {
299 1 : return String::new();
300 374 : }
301 374 : self.prepare(config);
302 374 : self.prepare_precedence();
303 1880 : for i in 0..self.ast.len() {
304 1880 : self.identify_parentheses(self.ast.len() - 1 - i);
305 1880 : }
306 374 : self.build_docs();
307 374 : self.render(self.node_states[node_id].reg)
308 375 : }
309 :
310 5980 : fn prepare(&mut self, config: &FormattingConfigT) {
311 5980 : self.config = config.clone();
312 5980 : self.fmt.reset();
313 5980 : self.fmt.set_config(config);
314 5980 : self.node_states.clear();
315 5980 : self.node_states.resize(self.ast.len(), FormattingNodeState::default());
316 5980 : self.unformattable_nodes.borrow_mut().clear();
317 5980 : self.copied_damaged_text.set(false);
318 5980 : }
319 :
320 10004 : fn mark_statement_roots(&mut self) {
321 10379 : for statement in &self.parsed.statements {
322 10379 : if (statement.root as usize) < self.node_states.len() {
323 10379 : self.node_states[statement.root as usize].is_statement_root = true;
324 10379 : self.mark_explain_inner_statement_root(statement.root as usize);
325 10379 : }
326 : }
327 10004 : }
328 :
329 10379 : fn mark_explain_inner_statement_root(&mut self, root_id: usize) {
330 10379 : let root_node = &self.ast[root_id];
331 10379 : if root_node.node_type() != NodeType::OBJECT_EXT_EXPLAIN {
332 10139 : return;
333 240 : }
334 240 : if let Some(child) = self.children(root_node).iter().find(|c| c.attribute_key() == K::EXT_EXPLAIN_STATEMENT) {
335 240 : let inner_id = self.node_id(child);
336 240 : if inner_id < self.node_states.len() {
337 240 : self.node_states[inner_id].is_statement_root = true;
338 240 : }
339 0 : }
340 10379 : }
341 :
342 : // -----------------------------------------------------------------------------------------
343 : // AST access
344 : // -----------------------------------------------------------------------------------------
345 :
346 : /// The id of a node of the AST
347 237160 : fn node_id(&self, node: &Node) -> usize {
348 237160 : (node as *const Node as usize - self.ast.as_ptr() as usize) / std::mem::size_of::<Node>()
349 237160 : }
350 :
351 209749 : fn state(&self, node: &Node) -> &FormattingNodeState {
352 209749 : &self.node_states[self.node_id(node)]
353 209749 : }
354 :
355 : /// The document of a node
356 209749 : fn reg(&self, node: &Node) -> FmtReg {
357 209749 : self.state(node).reg
358 209749 : }
359 :
360 : /// The children of a node (`ast.subspan(children_begin_or_value, children_count)`)
361 271426 : fn children(&self, node: &Node) -> &'a [Node] {
362 271426 : let count = node.children_count() as usize;
363 271426 : if count == 0 {
364 135 : return &[];
365 271291 : }
366 271291 : let begin = node.children_begin_or_value() as usize;
367 271291 : &self.ast[begin..begin + count]
368 271426 : }
369 :
370 : /// The documents of the elements of an array
371 158917 : fn array_regs(&self, node: &Node) -> Vec<FmtReg> {
372 158917 : let count = node.children_count() as usize;
373 158917 : if count == 0 {
374 162 : return Vec::new();
375 158755 : }
376 158755 : let begin = node.children_begin_or_value() as usize;
377 158755 : self.node_states[begin..begin + count].iter().map(|s| s.reg).collect()
378 158917 : }
379 :
380 : /// Look up attributes of an object.
381 : ///
382 : /// A single key finds the first child with that key, several keys find the last child with each
383 : /// key (see docs/design/core_quirks.md).
384 1244 : fn attrs<const N: usize>(&self, node: &Node, keys: [AttributeKey; N]) -> [Option<&'a Node>; N] {
385 1244 : let mut out = [None; N];
386 2488 : for child in self.children(node) {
387 4978 : for (slot, key) in out.iter_mut().zip(keys.iter()) {
388 4978 : if child.attribute_key() == *key {
389 2488 : *slot = Some(child);
390 2488 : if N == 1 {
391 1 : return out;
392 2487 : }
393 2490 : }
394 : }
395 : }
396 1243 : out
397 1244 : }
398 :
399 : /// The text of a symbol span
400 129185 : fn text_at(&self, span: &SymbolSpan) -> &'a str {
401 129185 : let text: &'a str = &self.scanned.text;
402 129185 : let ts = resolve_text_span(text, &self.scanned.symbols, *span);
403 129185 : let begin = (ts.offset as usize).min(text.len());
404 129185 : let end = (begin + ts.length as usize).min(text.len());
405 129185 : &text[begin..end]
406 129185 : }
407 :
408 12477 : fn is_pretty(&self) -> bool {
409 12477 : self.config.mode == FormattingMode::PRETTY
410 12477 : }
411 :
412 : /// ForceBreak in pretty mode, `otherwise` in the other modes
413 10242 : fn pretty_policy(&self, otherwise: FormattingJoinPolicy) -> FormattingJoinPolicy {
414 10242 : if self.is_pretty() {
415 3290 : FormattingJoinPolicy::ForceBreak
416 : } else {
417 6952 : otherwise
418 : }
419 10242 : }
420 :
421 : // -----------------------------------------------------------------------------------------
422 : // Precedence
423 : // -----------------------------------------------------------------------------------------
424 :
425 5980 : fn prepare_precedence(&mut self) {
426 462656 : for i in 0..self.ast.len() {
427 462656 : let node = &self.ast[i];
428 462656 : if node.node_type() != NodeType::OBJECT_SQL_NARY_EXPRESSION {
429 435501 : continue;
430 27155 : }
431 27155 : let [op_node, args_node] = attrs!(self.children(node), [K::SQL_EXPRESSION_OPERATOR, K::SQL_EXPRESSION_ARGS]);
432 27155 : let Some(op_node) = op_node else { continue };
433 :
434 27155 : let (precedence, associativity) = if op_node.node_type() == NodeType::ENUM_SQL_EXPRESSION_OPERATOR {
435 27005 : get_operator_precedence(ExpressionOperator(value_u8(op_node)))
436 150 : } else if matches!(op_node.node_type(), NodeType::OPERATOR | NodeType::ARRAY) {
437 150 : (11, Associativity::Left)
438 : } else {
439 0 : continue;
440 : };
441 27155 : let state = &mut self.node_states[i];
442 27155 : state.precedence = precedence;
443 27155 : state.associativity = associativity;
444 27155 : if let Some(args_node) = args_node {
445 27148 : let args_id = self.node_id(args_node);
446 27148 : let args_state = &mut self.node_states[args_id];
447 27148 : args_state.precedence = precedence;
448 27148 : args_state.associativity = associativity;
449 27149 : }
450 : }
451 5980 : }
452 :
453 462656 : fn identify_parentheses(&mut self, node_id: usize) {
454 462656 : let node = &self.ast[node_id];
455 462656 : if node.node_type() != NodeType::OBJECT_SQL_NARY_EXPRESSION {
456 435501 : return;
457 27155 : }
458 27155 : let parent_id = node.parent() as usize;
459 27155 : if parent_id >= self.ast.len() {
460 0 : return;
461 27155 : }
462 27155 : let parent = &self.ast[parent_id];
463 27155 : if parent.node_type() != NodeType::ARRAY {
464 8122 : return;
465 19033 : }
466 19033 : let args_begin = parent.children_begin_or_value() as usize;
467 19033 : let args_count = parent.children_count() as usize;
468 19033 : if node_id < args_begin || node_id >= args_begin + args_count {
469 0 : return;
470 19033 : }
471 :
472 19033 : let arg_index = node_id - args_begin;
473 19033 : let parent_state = self.node_states[parent_id];
474 19033 : let state = &mut self.node_states[node_id];
475 19033 : let need_parens = if args_count == 1 {
476 15 : true
477 : } else {
478 19018 : let left_or_none = matches!(parent_state.associativity, Associativity::Left | Associativity::NonAssoc);
479 19018 : let right_or_none = matches!(parent_state.associativity, Associativity::Right | Associativity::NonAssoc);
480 19018 : state.precedence < parent_state.precedence
481 18065 : || (state.precedence == parent_state.precedence
482 567 : && ((arg_index == 0 && right_or_none)
483 561 : || (arg_index == args_count - 1 && left_or_none)
484 525 : || (arg_index > 0 && arg_index + 1 < args_count)))
485 : };
486 19033 : state.needs_parentheses = need_parens;
487 462656 : }
488 :
489 : // -----------------------------------------------------------------------------------------
490 : // Leaves and lists
491 : // -----------------------------------------------------------------------------------------
492 :
493 128374 : fn format_leaf(&self, node: &'a Node) -> FmtReg {
494 128374 : let text = self.text_at(node.symbol_span());
495 128374 : if self.replace_obfuscated_literals {
496 12 : let text_offset = resolve_text_span(&self.scanned.text, &self.scanned.symbols, *node.symbol_span()).offset;
497 12 : if let Some(literal) = self.find_obfuscated_literal(text_offset) {
498 0 : return self.fmt.verbatim(&literal.replacement);
499 12 : }
500 128362 : }
501 128374 : if matches!(node.node_type(), NodeType::BOOL | NodeType::LITERAL_NULL | NodeType::OPERATOR) {
502 4208 : return self.fmt.text(text);
503 124166 : }
504 124166 : self.fmt.verbatim(text)
505 128374 : }
506 :
507 : /// The obfuscated literal whose marker starts at a text offset
508 12 : fn find_obfuscated_literal(&self, offset: u32) -> Option<&'a dashql_parser::scanner::ObfuscatedLiteral> {
509 12 : let literals: &'a [dashql_parser::scanner::ObfuscatedLiteral] = &self.scanned.obfuscated_literals;
510 12 : let i = literals.partition_point(|l| l.location.offset < offset);
511 12 : literals.get(i).filter(|l| l.location.offset == offset)
512 12 : }
513 :
514 20 : fn format_unimplemented(&self, node: &Node) -> FmtReg {
515 20 : self.unformattable_nodes.borrow_mut().push(self.node_id(node) as u32);
516 20 : let type_name = node.node_type().variant_name().unwrap_or("");
517 20 : let f = &self.fmt;
518 20 : f.concat(&[f.text("'<"), f.verbatim(type_name), f.text(">'")])
519 20 : }
520 :
521 : /// Format a node or record the child as unformattable (`reg_or_placeholder`)
522 6208 : fn reg_or_placeholder(&self, child: &Node) -> FmtReg {
523 6208 : let reg = self.reg(child);
524 6208 : if reg == 0 {
525 0 : return self.format_unimplemented(child);
526 6208 : }
527 6208 : reg
528 6208 : }
529 :
530 66310 : fn comma_separators(&self) -> (FmtReg, FmtReg) {
531 66310 : let f = &self.fmt;
532 66310 : let inline_separator = f.text(", ");
533 66310 : let break_separator = f.concat(&[f.text(","), f.break_()]);
534 66310 : (inline_separator, break_separator)
535 66310 : }
536 :
537 58963 : fn format_comma_list(&self, node: &Node, indent_after_breaks: bool) -> FmtReg {
538 58963 : let parts = self.array_regs(node);
539 58963 : let (inline_separator, break_separator) = self.comma_separators();
540 58963 : self.fmt.join(&parts, inline_separator, break_separator, None, indent_after_breaks)
541 58963 : }
542 :
543 : /// A comma-separated join that breaks on overflow
544 6406 : fn comma_join_on_overflow(&self, items: &[FmtReg], indent_after_breaks: bool) -> FmtReg {
545 6406 : let (inline_separator, break_separator) = self.comma_separators();
546 6406 : self.fmt.join(
547 6406 : items,
548 6406 : inline_separator,
549 6406 : break_separator,
550 6406 : Some(FormattingJoinPolicy::BreakOnOverflow),
551 6406 : indent_after_breaks,
552 : )
553 6406 : }
554 :
555 : /// A space-separated join
556 18797 : fn space_join(&self, items: &[FmtReg], policy: FormattingJoinPolicy, indent_after_breaks: bool) -> FmtReg {
557 18797 : let f = &self.fmt;
558 18797 : f.join(items, f.text(" "), f.break_(), Some(policy), indent_after_breaks)
559 18797 : }
560 :
561 69686 : fn format_qualified_name(&self, node: &Node) -> FmtReg {
562 69686 : let f = &self.fmt;
563 : // An index like `a[1]` follows its name without a dot
564 69686 : let mut parts: Vec<FmtReg> = Vec::new();
565 79146 : for (child, reg) in self.children(node).iter().zip(self.array_regs(node)) {
566 79146 : match parts.pop() {
567 9460 : Some(previous) if child.node_type() == NodeType::OBJECT_SQL_INDIRECTION_INDEX => {
568 81 : parts.push(f.concat(&[previous, reg]))
569 : }
570 9379 : Some(previous) => {
571 9379 : parts.push(previous);
572 9379 : parts.push(reg);
573 9379 : }
574 69686 : None => parts.push(reg),
575 : }
576 : }
577 69686 : if parts.is_empty() {
578 0 : return self.fmt.empty();
579 69686 : }
580 69686 : let inline_separator = f.text(".");
581 69686 : let break_separator = f.concat(&[f.break_(), f.text(".")]);
582 69686 : f.join(&parts, inline_separator, break_separator, None, true)
583 69686 : }
584 :
585 : /// The fields of an object in parentheses, with one field per line if they don't fit on one
586 99 : fn format_vararg_object(&self, node: &Node) -> FmtReg {
587 99 : if node.children_count() == 0 {
588 9 : return self.fmt.text("()");
589 90 : }
590 90 : self.fmt.parenthesized_list(self.format_comma_list(node, false))
591 99 : }
592 :
593 129507 : fn format_array(&self, node: &'a Node) -> FmtReg {
594 129507 : let f = &self.fmt;
595 129507 : if node.attribute_key() == K::NONE {
596 1083 : let parent_id = node.parent() as usize;
597 1083 : let parent = self.ast.get(parent_id);
598 1083 : let parent_key = parent.map(|p| p.attribute_key());
599 1083 : if parent_key == Some(K::SQL_SELECT_VALUES) {
600 126 : return f.parenthesized(self.format_comma_list(node, true));
601 957 : }
602 957 : if parent_key == Some(K::SQL_EXPRESSION_ARGS) {
603 798 : return self.format_comma_list(node, true);
604 159 : }
605 : // An object in an array of varargs
606 159 : if parent_key == Some(K::EXT_VARARG_ARRAY_VALUES) {
607 27 : return self.format_vararg_object(node);
608 132 : }
609 132 : if parent_key == Some(K::SQL_ROW_LOCKING_OF) {
610 24 : return self.format_qualified_name(node);
611 108 : }
612 108 : if parent_key == Some(K::SQL_GRAPH_MATCH_PATTERNS) {
613 108 : let parts = self.array_regs(node);
614 108 : return f.join(&parts, f.empty(), f.break_(), Some(FormattingJoinPolicy::BreakOnOverflow), true);
615 0 : }
616 0 : if parent.is_some_and(|p| p.node_type() == NodeType::OBJECT_SQL_NARY_EXPRESSION) {
617 0 : return self.format_comma_list(node, true);
618 0 : }
619 128424 : }
620 :
621 128424 : match node.attribute_key() {
622 : K::SQL_SELECT_TARGETS
623 : | K::SQL_SELECT_FROM
624 : | K::SQL_SELECT_GROUPS
625 : | K::SQL_SELECT_ORDER
626 : | K::SQL_WINDOW_FRAME_PARTITION
627 : | K::SQL_WINDOW_FRAME_ORDER
628 : | K::SQL_FUNCTION_WITHIN_GROUP
629 : | K::SQL_FUNCTION_ARGUMENTS
630 : | K::SQL_FUNCTION_ORDER
631 : | K::SQL_EXPRESSION_ARGS
632 : | K::SQL_DESCRIPTOR_COLUMNS
633 : | K::SQL_ROW_TYPE_FIELDS
634 : | K::SQL_CASE_CLAUSES
635 : | K::SQL_CREATE_TABLE_ELEMENTS
636 : | K::SQL_CREATE_AS_COLUMNS
637 : | K::SQL_VIEW_COLUMNS
638 : | K::SQL_CREATE_FUNCTION_PARAMS
639 : | K::SQL_SELECT_WINDOWS
640 : | K::SQL_SELECT_ROW_LOCKING
641 : | K::SQL_ROW_LOCKING_OF
642 : | K::SQL_GROUP_BY_ITEM_ARG
643 : | K::SQL_NUMERIC_TYPE_MODIFIERS
644 : | K::SQL_GENERIC_TYPE_MODIFIERS
645 : | K::SQL_TYPENAME_ARRAY
646 : | K::SQL_ATTACH_DATABASE_OPTIONS
647 : | K::SQL_INSERT_COLUMNS
648 : | K::SQL_INSERT_RETURNING
649 : | K::SQL_DELETE_USING
650 : | K::SQL_DELETE_RETURNING
651 : | K::SQL_CTE_COLUMNS
652 : | K::SQL_GRAPH_ELEMENT_TABLE_LABELS
653 : | K::SQL_GRAPH_MATCH_PATTERNS
654 : | K::SQL_RESULT_TARGET_EXCLUDE
655 : | K::SQL_TYPETEST_TYPES
656 : | K::SQL_FUNCTION_TABLE_ROWS_FROM
657 : | K::SQL_COLUMN_DEF_OPTIONS
658 : | K::SQL_CTE_OPTIONS
659 : | K::SQL_CONST_CAST_FUNC_ARGS_LIST
660 : | K::SQL_ROWSFROM_ITEM_COLUMNS
661 : | K::SQL_TABLE_CONSTRAINT_DEFINITION
662 54027 : | K::SQL_COLUMN_CONSTRAINT_DEFINITION => self.format_comma_list(node, true),
663 : K::SQL_PROPERTY_GRAPH_VERTEX_TABLES
664 : | K::SQL_PROPERTY_GRAPH_EDGE_TABLES
665 : | K::SQL_GRAPH_ELEMENT_TABLE_KEY
666 : | K::SQL_GRAPH_VERTEX_REFERENCE_KEY
667 : | K::SQL_GRAPH_VERTEX_REFERENCE_COLUMNS
668 : | K::SQL_GRAPH_PROPERTIES_COLUMNS
669 : | K::SQL_GRAPH_PROPERTIES_EXCLUDE
670 465 : | K::SQL_GRAPH_TABLE_COLUMNS => self.format_comma_list(node, false),
671 : K::SQL_SUBQUERY_OPERATOR | K::SQL_DEFINITION_ARG_VALUE | K::SQL_EXPRESSION_OPERATOR => {
672 21 : self.format_operator_path(node)
673 : }
674 864 : K::SQL_TABLE_CONSTRAINT_ATTRIBUTES | K::SQL_COLUMN_DEF_CONSTRAINTS => self.format_space_list(node),
675 175 : K::EXT_EXPLAIN_OPTIONS | K::SQL_CALL_ARGS => self.format_comma_list(node, false),
676 : K::EXT_EXPLAIN_EXPRESSIONS => {
677 9 : let parts = self.array_regs(node);
678 9 : let (inline_separator, break_separator) = self.comma_separators();
679 9 : f.join(&parts, inline_separator, break_separator, Some(FormattingJoinPolicy::ForceBreak), false)
680 : }
681 72 : K::EXT_VARARG_FIELD_VALUE | K::SQL_FUNCTION_ARG_VALUE => self.format_vararg_object(node),
682 15 : K::SQL_GENERIC_OPTION_VALUE => f.parenthesized(self.format_comma_list(node, true)),
683 117 : K::SQL_INDIRECTION_PATH | K::SQL_SELECT_EXPRESSION_INDIRECTION => self.format_indirection_path(node),
684 : K::SQL_ROW_EXPRESSION_VALUES | K::SQL_ARRAY_EXPRESSION_VALUES => {
685 363 : let values = self.array_regs(node);
686 759 : if values.iter().any(|&v| v == 0) {
687 0 : return self.format_unimplemented(node);
688 363 : }
689 363 : self.comma_join_on_overflow(&values, true)
690 : }
691 : K::SQL_WINDOW_FRAME_BOUNDS => {
692 126 : let bounds = self.array_regs(node);
693 126 : if bounds.len() == 1 && bounds[0] != 0 {
694 30 : return bounds[0];
695 96 : }
696 96 : if bounds.len() == 2 && bounds[0] != 0 && bounds[1] != 0 {
697 96 : return f.concat(&[f.text("between "), bounds[0], f.text(" and "), bounds[1]]);
698 0 : }
699 0 : self.format_unimplemented(node)
700 : }
701 : K::SQL_SELECT_VALUES => {
702 81 : let rows = self.array_regs(node);
703 126 : if rows.iter().any(|&r| r == 0) {
704 0 : return self.format_unimplemented(node);
705 81 : }
706 81 : let policy = self.pretty_policy(FormattingJoinPolicy::BreakOnOverflow);
707 81 : let indent_after_breaks = !self.is_pretty();
708 81 : let (inline_separator, break_separator) = self.comma_separators();
709 81 : f.join(&rows, inline_separator, break_separator, Some(policy), indent_after_breaks)
710 : }
711 : K::SQL_TEMP_NAME
712 : | K::SQL_CREATE_TABLE_NAME
713 : | K::SQL_FUNCTION_NAME
714 : | K::SQL_CONST_CAST_FUNC_NAME
715 : | K::SQL_COLUMN_CONSTRAINT_COLLATE
716 : | K::SQL_TABLEREF_NAME
717 : | K::SQL_PARAMETER_NAME
718 : | K::SQL_TABLE_CONSTRAINT_REFERENCES_NAME
719 : | K::SQL_COLUMN_REF_PATH
720 : | K::SQL_COLUMN_DEF_COLLATE
721 : | K::SQL_CREATE_AS_NAME
722 : | K::SQL_VIEW_NAME
723 : | K::SQL_CREATE_FUNCTION_NAME
724 : | K::SQL_DROP_NAME
725 : | K::SQL_ALTER_TABLE_NAME
726 : | K::SQL_ALTER_ACTION_NEW_TABLE
727 : | K::SQL_SCHEMA_NAME
728 : | K::SQL_CALL_NAME
729 : | K::EXT_VARARG_FIELD_KEY
730 69662 : | K::SQL_GRAPH_TABLE_GRAPH => self.format_qualified_name(node),
731 : K::SQL_SELECT_DISTINCT
732 : | K::SQL_SELECT_WITH_CTES
733 : | K::SQL_COMBINE_INPUT
734 : | K::SQL_JOIN_INPUT
735 : | K::SQL_TABLE_CONSTRAINT_COLUMNS
736 : | K::SQL_TABLE_CONSTRAINT_REFERENCES_COLUMNS
737 : | K::SQL_JOIN_USING
738 : | K::SQL_FUNCTION_TRIM_INPUT
739 : | K::SQL_ALIAS_COLUMN_NAMES
740 : | K::SQL_ALIAS_COLUMN_DEFS
741 : | K::EXT_VARARG_ARRAY_VALUES
742 2412 : | K::SQL_ALTER_TABLE_ACTIONS => self.format_comma_list(node, true),
743 15 : _ => self.format_unimplemented(node),
744 : }
745 129507 : }
746 :
747 : // -----------------------------------------------------------------------------------------
748 : // Table references
749 : // -----------------------------------------------------------------------------------------
750 :
751 13180 : fn format_table_ref(&self, node: &'a Node) -> FmtReg {
752 13180 : let f = &self.fmt;
753 13180 : let [name, alias, table, lateral, sample, only] = attrs!(self.children(node), [
754 : K::SQL_TABLEREF_NAME,
755 : K::SQL_TABLEREF_ALIAS,
756 : K::SQL_TABLEREF_TABLE,
757 : K::SQL_TABLEREF_LATERAL,
758 : K::SQL_TABLEREF_SAMPLE,
759 : K::SQL_TABLEREF_ONLY,
760 : ],
761 : );
762 :
763 13180 : let mut base_reg = 0;
764 13180 : if let Some(table) = table {
765 1947 : base_reg = self.reg(table);
766 1947 : if table.node_type() == NodeType::OBJECT_SQL_SELECT {
767 918 : base_reg = f.parenthesized(base_reg);
768 1029 : }
769 11233 : } else if let Some(name) = name {
770 11233 : base_reg = self.reg(name);
771 11233 : }
772 13180 : if base_reg == 0 {
773 0 : return self.format_unimplemented(node);
774 13180 : }
775 13180 : if is_true(only) {
776 9 : base_reg = f.concat(&[f.text("only "), base_reg]);
777 13171 : }
778 13180 : if is_true(lateral) {
779 48 : base_reg = f.concat(&[f.text("lateral "), base_reg]);
780 13132 : }
781 13180 : if let Some(alias) = alias {
782 2490 : let alias_reg = self.reg(alias);
783 2490 : if alias_reg == 0 {
784 0 : return self.format_unimplemented(node);
785 2490 : }
786 2490 : base_reg = f.concat(&[base_reg, f.text(" "), alias_reg]);
787 10690 : }
788 13180 : if let Some(sample) = sample {
789 57 : let sample_reg = self.reg(sample);
790 57 : if sample_reg == 0 {
791 0 : return self.format_unimplemented(node);
792 57 : }
793 57 : base_reg = f.concat(&[base_reg, f.text(" "), sample_reg]);
794 13123 : }
795 13180 : base_reg
796 13180 : }
797 :
798 51 : fn format_into(&self, node: &'a Node) -> FmtReg {
799 51 : let f = &self.fmt;
800 51 : let [temp, name] = attrs!(self.children(node), [K::SQL_TEMP_TYPE, K::SQL_TEMP_NAME]);
801 51 : let Some(name) = name else { return self.format_unimplemented(node) };
802 51 : let mut parts = vec![f.text("into ")];
803 51 : if let Some(temp) = temp {
804 51 : if TempType(value_u8(temp)) != TempType::NONE {
805 3 : parts.push(self.reg(temp));
806 3 : parts.push(f.text(" "));
807 48 : }
808 0 : }
809 51 : parts.push(self.reg(name));
810 51 : f.concat(&parts)
811 51 : }
812 :
813 78 : fn format_window_def(&self, node: &'a Node) -> FmtReg {
814 78 : let f = &self.fmt;
815 78 : let [name, frame] = attrs!(self.children(node), [K::SQL_WINDOW_DEF_NAME, K::SQL_WINDOW_DEF_FRAME]);
816 78 : let (Some(name), Some(frame)) = (name, frame) else { return self.format_unimplemented(node) };
817 : // An empty window specification is still a pair of parentheses
818 78 : let frame_reg = self.reg(frame);
819 78 : let frame_reg = if frame_reg == 0 { f.text("()") } else { f.parenthesized(frame_reg) };
820 78 : f.concat(&[self.reg(name), f.text(" as "), frame_reg])
821 78 : }
822 :
823 81 : fn format_row_locking_strength(&self, node: &'a Node) -> FmtReg {
824 81 : let text = match RowLockingStrength(value_u8(node)) {
825 33 : RowLockingStrength::UPDATE => "for update",
826 12 : RowLockingStrength::NO_KEY_UPDATE => "for no key update",
827 12 : RowLockingStrength::SHARE => "for share",
828 12 : RowLockingStrength::KEY_SHARE => "for key share",
829 12 : RowLockingStrength::READ_ONLY => "for read only",
830 0 : _ => return self.format_unimplemented(node),
831 : };
832 81 : self.fmt.text(text)
833 81 : }
834 :
835 30 : fn format_row_locking_block_behavior(&self, node: &'a Node) -> FmtReg {
836 30 : let text = match RowLockingBlockBehavior(value_u8(node)) {
837 15 : RowLockingBlockBehavior::NOWAIT => "nowait",
838 15 : RowLockingBlockBehavior::SKIP_LOCKED => "skip locked",
839 0 : _ => return self.format_unimplemented(node),
840 : };
841 30 : self.fmt.text(text)
842 30 : }
843 :
844 81 : fn format_row_locking(&self, node: &'a Node) -> FmtReg {
845 81 : let f = &self.fmt;
846 81 : let [strength, of, behavior] =
847 81 : attrs!(self.children(node), [K::SQL_ROW_LOCKING_STRENGTH, K::SQL_ROW_LOCKING_OF, K::SQL_ROW_LOCKING_BLOCK_BEHAVIOR]);
848 81 : let Some(strength) = strength else { return self.format_unimplemented(node) };
849 81 : let mut parts = vec![self.reg(strength)];
850 81 : if let Some(of) = of.filter(|of| of.children_count() > 0) {
851 18 : parts.push(f.text(" of "));
852 18 : parts.push(self.reg(of));
853 63 : }
854 81 : if let Some(behavior) = behavior {
855 30 : parts.push(f.text(" "));
856 30 : parts.push(self.reg(behavior));
857 54 : }
858 81 : f.concat(&parts)
859 81 : }
860 :
861 105 : fn format_sample_unit(&self, node: &'a Node) -> FmtReg {
862 105 : let text = match SampleCountUnit(value_u8(node)) {
863 72 : SampleCountUnit::PERCENT => "%",
864 33 : SampleCountUnit::ROWS => " rows",
865 0 : _ => return self.format_unimplemented(node),
866 : };
867 105 : self.fmt.text(text)
868 105 : }
869 :
870 105 : fn format_sample(&self, node: &'a Node, table_sample: bool) -> FmtReg {
871 105 : let f = &self.fmt;
872 105 : let [value, unit, function, repeat, seed] = attrs!(self.children(node), [
873 : K::SQL_SAMPLE_COUNT_VALUE,
874 : K::SQL_SAMPLE_COUNT_UNIT,
875 : K::SQL_SAMPLE_FUNCTION,
876 : K::SQL_SAMPLE_REPEAT,
877 : K::SQL_SAMPLE_SEED,
878 : ],
879 : );
880 105 : let (Some(value), Some(unit)) = (value, unit) else { return self.format_unimplemented(node) };
881 :
882 : // Hyper only knows the word PERCENT for a table sample, DuckDB's `using sample` also takes `%`
883 105 : let is_percent = unit.node_type() == NodeType::ENUM_SQL_SAMPLE_UNIT_TYPE
884 105 : && SampleCountUnit(value_u8(unit)) == SampleCountUnit::PERCENT;
885 105 : let unit_reg = if table_sample && is_percent { f.text(" percent") } else { self.reg(unit) };
886 105 : let count = f.concat(&[self.reg(value), unit_reg]);
887 105 : let mut body = count;
888 105 : match (function, seed) {
889 9 : (Some(function), Some(seed)) => {
890 9 : let args = f.concat(&[self.reg(function), f.text(", "), self.reg(seed)]);
891 9 : body = f.concat(&[count, f.text(" "), f.parenthesized(args)]);
892 9 : }
893 78 : (Some(function), None) => body = f.concat(&[self.reg(function), f.parenthesized(count)]),
894 18 : _ => {}
895 : }
896 105 : if let Some(repeat) = repeat {
897 24 : body = f.concat(&[body, f.text(" repeatable "), f.parenthesized(self.reg(repeat))]);
898 81 : }
899 105 : f.concat(&[f.text(if table_sample { "tablesample " } else { "using sample " }), body])
900 105 : }
901 :
902 690 : fn format_joined_table(&self, node: &'a Node) -> FmtReg {
903 690 : let f = &self.fmt;
904 690 : let [inputs, join_type, join_on, join_using] =
905 690 : attrs!(self.children(node), [K::SQL_JOIN_INPUT, K::SQL_JOIN_TYPE, K::SQL_JOIN_ON, K::SQL_JOIN_USING]);
906 690 : let (Some(inputs), Some(join_type)) = (inputs, join_type) else { return self.format_unimplemented(node) };
907 690 : if inputs.node_type() != NodeType::ARRAY || inputs.children_count() != 2 {
908 0 : return self.format_unimplemented(node);
909 690 : }
910 :
911 690 : let left_reg = self.reg(&self.ast[inputs.children_begin_or_value() as usize]);
912 690 : let right_reg = self.reg(&self.ast[inputs.children_begin_or_value() as usize + 1]);
913 690 : if left_reg == 0 || right_reg == 0 {
914 0 : return self.format_unimplemented(node);
915 690 : }
916 :
917 690 : let join_text = match JoinType(value_u8(join_type)) {
918 63 : JoinType::NONE => "cross join",
919 213 : JoinType::INNER => "join",
920 216 : JoinType::LEFT | JoinType::OUTER_LEFT => "left join",
921 12 : JoinType::RIGHT | JoinType::OUTER_RIGHT => "right join",
922 30 : JoinType::FULL | JoinType::OUTER_FULL => "full join",
923 39 : JoinType::SEMI => "semi join",
924 39 : JoinType::ANTI => "anti join",
925 30 : JoinType::NATURAL_INNER => "natural join",
926 24 : JoinType::NATURAL_LEFT | JoinType::NATURAL_OUTER_LEFT => "natural left join",
927 12 : JoinType::NATURAL_RIGHT | JoinType::NATURAL_OUTER_RIGHT => "natural right join",
928 12 : JoinType::NATURAL_FULL | JoinType::NATURAL_OUTER_FULL => "natural full join",
929 0 : _ => return self.format_unimplemented(node),
930 : };
931 :
932 690 : let mut join_clause_parts = vec![f.concat(&[f.text(join_text), f.text(" "), right_reg])];
933 690 : if let Some(join_on) = join_on {
934 531 : let on_reg = self.reg(join_on);
935 531 : if on_reg == 0 {
936 0 : return self.format_unimplemented(node);
937 531 : }
938 531 : join_clause_parts.push(f.concat(&[f.text("on "), on_reg]));
939 159 : } else if let Some(join_using) = join_using {
940 18 : let using_reg = self.reg(join_using);
941 18 : if using_reg == 0 {
942 0 : return self.format_unimplemented(node);
943 18 : }
944 18 : join_clause_parts.push(f.concat(&[f.text("using "), f.parenthesized(using_reg)]));
945 141 : }
946 690 : let join_clause = self.space_join(&join_clause_parts, FormattingJoinPolicy::BreakOnOverflow, true);
947 :
948 690 : let clause_policy = self.pretty_policy(FormattingJoinPolicy::BreakAllOrNone);
949 690 : let mut is_left_nested_join = false;
950 690 : let table_ref_id = node.parent() as usize;
951 690 : if table_ref_id < self.ast.len() {
952 690 : let parent_id = self.ast[table_ref_id].parent() as usize;
953 690 : is_left_nested_join = parent_id < self.ast.len()
954 690 : && self.ast[parent_id].node_type() == NodeType::ARRAY
955 690 : && self.ast[parent_id].attribute_key() == K::SQL_JOIN_INPUT
956 231 : && table_ref_id == self.ast[parent_id].children_begin_or_value() as usize;
957 0 : }
958 690 : self.space_join(&[left_reg, join_clause], clause_policy, !is_left_nested_join)
959 690 : }
960 :
961 3879 : fn format_group_by_item(&self, node: &'a Node) -> FmtReg {
962 3879 : let f = &self.fmt;
963 3879 : let [item_type, arg] = attrs!(self.children(node), [K::SQL_GROUP_BY_ITEM_TYPE, K::SQL_GROUP_BY_ITEM_ARG]);
964 3879 : let Some(item_type) = item_type.filter(|t| t.node_type() == NodeType::ENUM_SQL_GROUP_BY_ITEM_TYPE) else {
965 0 : return f.empty();
966 : };
967 3879 : let arg_reg = match arg {
968 3873 : Some(arg) if arg.node_type() != NodeType::NONE => self.reg(arg),
969 6 : _ => 0,
970 : };
971 3879 : let wrap = |keyword: &'static str| {
972 90 : if arg_reg == 0 {
973 0 : return f.empty();
974 90 : }
975 90 : f.concat(&[f.text(keyword), f.parenthesized(arg_reg)])
976 90 : };
977 3879 : match GroupByItemType(value_u8(item_type)) {
978 3786 : GroupByItemType::EXPRESSION => arg_reg,
979 3 : GroupByItemType::EMPTY => f.text("()"),
980 3 : GroupByItemType::CUBE => wrap("cube"),
981 84 : GroupByItemType::ROLLUP => wrap("rollup"),
982 3 : GroupByItemType::GROUPING_SETS => wrap("grouping sets"),
983 0 : _ => f.empty(),
984 : }
985 3879 : }
986 :
987 : // -----------------------------------------------------------------------------------------
988 : // Types
989 : // -----------------------------------------------------------------------------------------
990 :
991 3030 : fn format_type_name(&self, node: &'a Node) -> FmtReg {
992 3030 : let f = &self.fmt;
993 3030 : let [type_node, array, setof] =
994 3030 : attrs!(self.children(node), [K::SQL_TYPENAME_TYPE, K::SQL_TYPENAME_ARRAY, K::SQL_TYPENAME_SETOF]);
995 3030 : let Some(type_node) = type_node else { return self.format_unimplemented(node) };
996 :
997 3030 : let mut type_reg = self.reg(type_node);
998 3030 : if let Some(array) = array.filter(|a| a.node_type() == NodeType::ARRAY) {
999 : // Hyper does not accept row(...)[], only array(row(...))
1000 57 : let row_element = type_node.node_type() == NodeType::OBJECT_SQL_ROW_TYPE;
1001 : // The keyword form `text array` has no children, a type without array has no text
1002 57 : let keyword_form = array.children_count() == 0 && array.symbol_span().length() > 0;
1003 57 : let bounds: Vec<Option<&Node>> =
1004 57 : if keyword_form { vec![None] } else { self.children(array).iter().map(Some).collect() };
1005 60 : for bound in bounds {
1006 60 : let unbounded = bound.map_or(true, |b| b.node_type() == NodeType::BOOL);
1007 60 : if self.config.dialect == FormattingDialect::TRINO {
1008 6 : if !unbounded {
1009 0 : return self.format_unimplemented(node);
1010 6 : }
1011 6 : type_reg = f.concat(&[f.text("array("), type_reg, f.text(")")]);
1012 54 : } else if row_element && unbounded {
1013 6 : type_reg = f.concat(&[f.text("array("), type_reg, f.text(")")]);
1014 6 : } else {
1015 48 : let bound_reg = bound.filter(|b| b.node_type() != NodeType::BOOL).map_or(f.empty(), |b| self.reg(b));
1016 48 : type_reg = f.concat(&[type_reg, f.text("["), bound_reg, f.text("]")]);
1017 : }
1018 : }
1019 2973 : }
1020 :
1021 3030 : let mut parts = Vec::with_capacity(2);
1022 3030 : if is_true(setof) {
1023 3 : parts.push(f.text("setof "));
1024 3027 : }
1025 3030 : parts.push(type_reg);
1026 3030 : f.concat(&parts)
1027 3030 : }
1028 :
1029 191 : fn format_interval_type_enum(&self, node: &'a Node) -> FmtReg {
1030 191 : if node.node_type() != NodeType::ENUM_SQL_INTERVAL_TYPE {
1031 0 : return self.format_unimplemented(node);
1032 191 : }
1033 191 : match crate::analyzer::sql_types::interval_keyword(IntervalType(value_u8(node))) {
1034 191 : Some(text) => self.fmt.text(text),
1035 0 : None => self.format_unimplemented(node),
1036 : }
1037 191 : }
1038 :
1039 : /// The type of `interval '1' day` is the interval qualifier alone, a type name needs the keyword
1040 215 : fn format_interval_type(&self, node: &'a Node) -> FmtReg {
1041 215 : let f = &self.fmt;
1042 215 : let [interval_type, precision] = attrs!(self.children(node), [K::SQL_INTERVAL_TYPE, K::SQL_INTERVAL_PRECISION]);
1043 215 : let is_qualifier = node.attribute_key() == K::SQL_CONST_CAST_INTERVAL;
1044 215 : let mut parts = Vec::with_capacity(4);
1045 215 : if !is_qualifier {
1046 57 : parts.push(f.text("interval"));
1047 158 : }
1048 215 : if let Some(interval_type) = interval_type {
1049 191 : if !is_qualifier {
1050 33 : parts.push(f.text(" "));
1051 158 : }
1052 191 : parts.push(self.reg(interval_type));
1053 24 : } else if is_qualifier {
1054 0 : return self.format_unimplemented(node);
1055 24 : }
1056 215 : if let Some(precision) = precision {
1057 12 : parts.push(f.parenthesized(self.reg(precision)));
1058 203 : }
1059 215 : f.concat(&parts)
1060 215 : }
1061 :
1062 25 : fn format_const_type_cast(&self, node: &'a Node) -> FmtReg {
1063 25 : let f = &self.fmt;
1064 25 : let [type_node, value] = attrs!(self.children(node), [K::SQL_CONST_CAST_TYPE, K::SQL_CONST_CAST_VALUE]);
1065 25 : let (Some(type_node), Some(value)) = (type_node, value) else { return self.format_unimplemented(node) };
1066 : // Trino reads the time zone of a timestamp or time literal from its text, its literals have no zone in the type
1067 25 : if self.config.dialect == FormattingDialect::TRINO {
1068 1 : if let Some(keyword) = self.zoned_time_type(type_node) {
1069 1 : let value_reg = self.reg(value);
1070 1 : if value_reg == 0 {
1071 0 : return self.format_unimplemented(node);
1072 1 : }
1073 1 : return f.concat(&[f.text(keyword), f.text(" "), value_reg]);
1074 0 : }
1075 24 : }
1076 24 : let type_reg = self.reg(type_node);
1077 24 : let value_reg = self.reg(value);
1078 24 : if type_reg == 0 || value_reg == 0 {
1079 0 : return self.format_unimplemented(node);
1080 24 : }
1081 24 : f.concat(&[type_reg, f.text(" "), value_reg])
1082 25 : }
1083 :
1084 : /// The keyword of a timestamp or time type with a time zone, `timestamp with time zone` is `timestamp`
1085 1 : fn zoned_time_type(&self, type_node: &'a Node) -> Option<&'static str> {
1086 1 : let [element] = attrs!(self.children(type_node), [K::SQL_TYPENAME_TYPE]);
1087 1 : let element = element?;
1088 1 : let [tz] = attrs!(self.children(element), [K::SQL_TIME_TYPE_WITH_TIMEZONE]);
1089 1 : let zoned = tz.is_some_and(|t| t.node_type() == NodeType::BOOL && t.children_begin_or_value() != 0);
1090 1 : match element.node_type() {
1091 1 : NodeType::OBJECT_SQL_TIMESTAMP_TYPE if zoned => Some("timestamp"),
1092 0 : NodeType::OBJECT_SQL_TIME_TYPE if zoned => Some("time"),
1093 0 : _ => None,
1094 : }
1095 1 : }
1096 :
1097 173 : fn format_const_interval_cast(&self, node: &'a Node) -> FmtReg {
1098 173 : let f = &self.fmt;
1099 173 : let [value, interval] = attrs!(self.children(node), [K::SQL_CONST_CAST_VALUE, K::SQL_CONST_CAST_INTERVAL]);
1100 173 : let Some(value) = value else { return self.format_unimplemented(node) };
1101 173 : let mut parts = vec![f.text("interval "), self.reg(value)];
1102 173 : if let Some(interval) = interval {
1103 158 : parts.push(f.text(" "));
1104 158 : parts.push(self.reg(interval));
1105 158 : }
1106 173 : f.concat(&parts)
1107 173 : }
1108 :
1109 : /// The arguments of a function call, None if an argument cannot be formatted
1110 6623 : fn format_call_arguments(&self, args: Option<&'a Node>) -> Option<Vec<FmtReg>> {
1111 6623 : let mut arg_items = Vec::new();
1112 6623 : if let Some(args) = args {
1113 5998 : if args.node_type() != NodeType::ARRAY {
1114 0 : return None;
1115 5998 : }
1116 7138 : for arg in self.children(args) {
1117 7138 : let reg = self.reg(arg);
1118 7138 : if reg == 0 {
1119 0 : return None;
1120 7138 : }
1121 7138 : arg_items.push(reg);
1122 : }
1123 625 : }
1124 6623 : Some(arg_items)
1125 6623 : }
1126 :
1127 343 : fn format_const_function_cast(&self, node: &'a Node) -> FmtReg {
1128 343 : let f = &self.fmt;
1129 343 : let [name, args, order, value] = attrs!(self.children(node), [
1130 : K::SQL_CONST_CAST_FUNC_NAME,
1131 : K::SQL_CONST_CAST_FUNC_ARGS_LIST,
1132 : K::SQL_CONST_CAST_FUNC_ARGS_ORDER,
1133 : K::SQL_CONST_CAST_VALUE,
1134 : ],
1135 : );
1136 343 : let (Some(name), Some(value)) = (name, value) else { return self.format_unimplemented(node) };
1137 343 : let mut name_reg = self.reg(name);
1138 : // Trino reads the time zone of a timestamp or time literal from its text, `timestamptz '...'` is `timestamp '...'`
1139 343 : if self.config.dialect == FormattingDialect::TRINO && args.is_none() {
1140 16 : match self.text_at(name.symbol_span()).to_ascii_lowercase().as_str() {
1141 16 : "timestamptz" => name_reg = f.text("timestamp"),
1142 15 : "timetz" => name_reg = f.text("time"),
1143 15 : _ => {}
1144 : }
1145 327 : }
1146 343 : let value_reg = self.reg(value);
1147 343 : if name_reg == 0 || value_reg == 0 {
1148 0 : return self.format_unimplemented(node);
1149 343 : }
1150 :
1151 343 : let Some(arg_items) = self.format_call_arguments(args) else { return self.format_unimplemented(node) };
1152 343 : let mut call_parts = Vec::with_capacity(3);
1153 343 : if !arg_items.is_empty() {
1154 9 : call_parts.push(self.comma_join_on_overflow(&arg_items, true));
1155 334 : }
1156 343 : if let Some(order) = order {
1157 0 : let order_reg = self.reg(order);
1158 0 : if order_reg == 0 {
1159 0 : return self.format_unimplemented(node);
1160 0 : }
1161 0 : call_parts.push(f.text(if call_parts.is_empty() { "order by " } else { " order by " }));
1162 0 : call_parts.push(order_reg);
1163 343 : }
1164 :
1165 343 : let mut call_reg = name_reg;
1166 343 : if !call_parts.is_empty() {
1167 9 : let call_body = f.concat(&call_parts);
1168 9 : if call_body == 0 {
1169 0 : return self.format_unimplemented(node);
1170 9 : }
1171 9 : call_reg = f.concat(&[name_reg, f.parenthesized(call_body)]);
1172 334 : }
1173 343 : f.concat(&[call_reg, f.text(" "), value_reg])
1174 343 : }
1175 :
1176 1494 : fn format_numeric_type_base(&self, node: &'a Node) -> FmtReg {
1177 1494 : if node.node_type() != NodeType::ENUM_SQL_NUMERIC_TYPE {
1178 0 : return self.format_unimplemented(node);
1179 1494 : }
1180 1494 : let text = match NumericType(value_u8(node)) {
1181 0 : NumericType::INT1 => "tinyint",
1182 9 : NumericType::INT2 => "smallint",
1183 875 : NumericType::INT4 => "integer",
1184 57 : NumericType::INT8 => "bigint",
1185 21 : NumericType::FLOAT4 => "real",
1186 15 : NumericType::FLOAT8 => "double precision",
1187 502 : NumericType::NUMERIC => "numeric",
1188 15 : NumericType::BOOL => "boolean",
1189 0 : _ => return self.format_unimplemented(node),
1190 : };
1191 1494 : self.fmt.text(text)
1192 1494 : }
1193 :
1194 : /// `(m1, m2, ...)` of a type with modifiers
1195 493 : fn format_type_modifiers(&self, modifiers: &'a Node) -> FmtReg {
1196 980 : let values: Vec<FmtReg> = self.children(modifiers).iter().map(|m| self.reg(m)).collect();
1197 493 : let (inline_separator, break_separator) = self.comma_separators();
1198 493 : let joined = self.fmt.join(&values, inline_separator, break_separator, None, true);
1199 493 : self.fmt.parenthesized(joined)
1200 493 : }
1201 :
1202 502 : fn format_numeric_type(&self, node: &'a Node) -> FmtReg {
1203 502 : let [base, modifiers] = attrs!(self.children(node), [K::SQL_NUMERIC_TYPE_BASE, K::SQL_NUMERIC_TYPE_MODIFIERS]);
1204 502 : let Some(base) = base else { return self.format_unimplemented(node) };
1205 502 : let mut parts = vec![self.reg(base)];
1206 502 : if let Some(modifiers) = modifiers.filter(|m| m.node_type() == NodeType::ARRAY && m.children_count() > 0) {
1207 490 : parts.push(self.format_type_modifiers(modifiers));
1208 490 : }
1209 502 : self.fmt.concat(&parts)
1210 502 : }
1211 :
1212 447 : fn format_character_type_base(&self, node: &'a Node) -> FmtReg {
1213 447 : if node.node_type() != NodeType::ENUM_SQL_CHARACTER_TYPE {
1214 0 : return self.format_unimplemented(node);
1215 447 : }
1216 447 : let text = match CharacterType(value_u8(node)) {
1217 246 : CharacterType::VARCHAR => "varchar",
1218 201 : CharacterType::BLANK_PADDED_CHAR => "char",
1219 0 : _ => return self.format_unimplemented(node),
1220 : };
1221 447 : self.fmt.text(text)
1222 447 : }
1223 :
1224 447 : fn format_character_type(&self, node: &'a Node) -> FmtReg {
1225 447 : let f = &self.fmt;
1226 447 : let [character_type, length] = attrs!(self.children(node), [K::SQL_CHARACTER_TYPE, K::SQL_CHARACTER_TYPE_LENGTH]);
1227 447 : let Some(character_type) = character_type else { return self.format_unimplemented(node) };
1228 447 : let mut parts = vec![self.reg(character_type)];
1229 447 : if let Some(length) = length {
1230 372 : parts.push(f.parenthesized(self.reg(length)));
1231 375 : }
1232 447 : f.concat(&parts)
1233 447 : }
1234 :
1235 795 : fn format_generic_type(&self, node: &'a Node) -> FmtReg {
1236 795 : let f = &self.fmt;
1237 795 : let [name, modifiers] = attrs!(self.children(node), [K::SQL_GENERIC_TYPE_NAME, K::SQL_GENERIC_TYPE_MODIFIERS]);
1238 795 : let Some(name) = name else { return self.format_unimplemented(node) };
1239 :
1240 795 : let name_text = self.text_at(name.symbol_span());
1241 795 : if name_text.eq_ignore_ascii_case("array") {
1242 57 : if let Some(modifiers) = modifiers.filter(|m| m.node_type() == NodeType::ARRAY && m.children_count() == 1) {
1243 57 : let element_node = &self.ast[modifiers.children_begin_or_value() as usize];
1244 57 : let element = self.reg(element_node);
1245 : // Hyper does not accept row(...)[], only array(row(...))
1246 57 : let [element_type] = attrs!(self.children(element_node), [K::SQL_TYPENAME_TYPE]);
1247 57 : let row_element = element_type.is_some_and(|t| t.node_type() == NodeType::OBJECT_SQL_ROW_TYPE);
1248 57 : if self.config.dialect == FormattingDialect::HYPER && !row_element {
1249 13 : return f.concat(&[element, f.text("[]")]);
1250 44 : }
1251 44 : return f.concat(&[f.text("array("), element, f.text(")")]);
1252 0 : }
1253 738 : }
1254 :
1255 738 : let mut parts = vec![self.reg(name)];
1256 738 : if let Some(modifiers) = modifiers.filter(|m| m.node_type() == NodeType::ARRAY && m.children_count() > 0) {
1257 3 : parts.push(self.format_type_modifiers(modifiers));
1258 735 : }
1259 738 : f.concat(&parts)
1260 795 : }
1261 :
1262 72 : fn format_timestamp_type(&self, node: &'a Node) -> FmtReg {
1263 72 : let f = &self.fmt;
1264 72 : let [precision, with_tz] = attrs!(self.children(node), [K::SQL_TIME_TYPE_PRECISION, K::SQL_TIME_TYPE_WITH_TIMEZONE]);
1265 72 : let is_time = node.node_type() == NodeType::OBJECT_SQL_TIME_TYPE;
1266 72 : let mut parts = vec![f.text(if is_time { "time" } else { "timestamp" })];
1267 72 : if let Some(precision) = precision {
1268 24 : parts.push(f.parenthesized(self.reg(precision)));
1269 48 : }
1270 72 : if is_true(with_tz) {
1271 33 : parts.push(f.text(" with time zone"));
1272 51 : }
1273 72 : f.concat(&parts)
1274 72 : }
1275 :
1276 : // -----------------------------------------------------------------------------------------
1277 : // Ordering and enums
1278 : // -----------------------------------------------------------------------------------------
1279 :
1280 3942 : fn format_order(&self, node: &'a Node) -> FmtReg {
1281 3942 : let [value, direction, nullrule] =
1282 3942 : attrs!(self.children(node), [K::SQL_ORDER_VALUE, K::SQL_ORDER_DIRECTION, K::SQL_ORDER_NULLRULE]);
1283 3942 : let Some(value) = value else { return self.format_unimplemented(node) };
1284 3942 : let mut parts = vec![self.reg(value)];
1285 3942 : if let Some(direction) = direction {
1286 498 : parts.push(self.reg(direction));
1287 3444 : }
1288 3942 : if let Some(nullrule) = nullrule {
1289 1473 : parts.push(self.reg(nullrule));
1290 2469 : }
1291 3942 : self.space_join(&parts, FormattingJoinPolicy::BreakAllOrNone, true)
1292 3942 : }
1293 :
1294 498 : fn format_order_direction(&self, node: &'a Node) -> FmtReg {
1295 498 : if node.node_type() != NodeType::ENUM_SQL_ORDER_DIRECTION {
1296 0 : return self.format_unimplemented(node);
1297 498 : }
1298 498 : let text = match OrderDirection(value_u8(node)) {
1299 87 : OrderDirection::ASCENDING => "asc",
1300 411 : OrderDirection::DESCENDING => "desc",
1301 0 : _ => return self.format_unimplemented(node),
1302 : };
1303 498 : self.fmt.text(text)
1304 498 : }
1305 :
1306 1473 : fn format_order_null_rule(&self, node: &'a Node) -> FmtReg {
1307 1473 : if node.node_type() != NodeType::ENUM_SQL_ORDER_NULL_RULE {
1308 0 : return self.format_unimplemented(node);
1309 1473 : }
1310 1473 : let text = match OrderNullRule(value_u8(node)) {
1311 1449 : OrderNullRule::NULLS_FIRST => "nulls first",
1312 24 : OrderNullRule::NULLS_LAST => "nulls last",
1313 0 : _ => return self.format_unimplemented(node),
1314 : };
1315 1473 : self.fmt.text(text)
1316 1473 : }
1317 :
1318 81 : fn format_extract_target(&self, node: &'a Node) -> FmtReg {
1319 81 : if node.node_type() != NodeType::ENUM_SQL_EXTRACT_TARGET {
1320 0 : return self.format_unimplemented(node);
1321 81 : }
1322 81 : let text = match ExtractTarget(value_u8(node)) {
1323 42 : ExtractTarget::YEAR => "year",
1324 6 : ExtractTarget::MONTH => "month",
1325 15 : ExtractTarget::DAY => "day",
1326 6 : ExtractTarget::HOUR => "hour",
1327 6 : ExtractTarget::MINUTE => "minute",
1328 6 : ExtractTarget::SECOND => "second",
1329 0 : _ => return self.format_unimplemented(node),
1330 : };
1331 81 : self.fmt.text(text)
1332 81 : }
1333 :
1334 66 : fn format_trim_direction(&self, node: &'a Node) -> FmtReg {
1335 66 : if node.node_type() != NodeType::ENUM_SQL_TRIM_TARGET {
1336 0 : return self.format_unimplemented(node);
1337 66 : }
1338 66 : let text = match TrimDirection(value_u8(node)) {
1339 39 : TrimDirection::BOTH => "both",
1340 15 : TrimDirection::LEADING => "leading",
1341 12 : TrimDirection::TRAILING => "trailing",
1342 0 : _ => return self.format_unimplemented(node),
1343 : };
1344 66 : self.fmt.text(text)
1345 66 : }
1346 :
1347 : // -----------------------------------------------------------------------------------------
1348 : // References and rows
1349 : // -----------------------------------------------------------------------------------------
1350 :
1351 50753 : fn format_column_ref(&self, node: &'a Node) -> FmtReg {
1352 50753 : let [path] = attrs!(self.children(node), [K::SQL_COLUMN_REF_PATH]);
1353 50753 : match path {
1354 50753 : Some(path) => self.reg(path),
1355 0 : None => self.format_unimplemented(node),
1356 : }
1357 50753 : }
1358 :
1359 300 : fn format_parameter_ref(&self, node: &'a Node) -> FmtReg {
1360 300 : let [prefix, name] = attrs!(self.children(node), [K::SQL_PARAMETER_PREFIX, K::SQL_PARAMETER_NAME]);
1361 300 : let Some(prefix) = prefix else { return self.format_unimplemented(node) };
1362 300 : let prefix_reg = self.reg(prefix);
1363 300 : if prefix_reg == 0 {
1364 0 : return self.format_unimplemented(node);
1365 300 : }
1366 : // Positional parameters (?) have no name
1367 300 : let Some(name) = name else { return prefix_reg };
1368 240 : let name_reg = self.reg(name);
1369 240 : if name_reg == 0 {
1370 0 : return self.format_unimplemented(node);
1371 240 : }
1372 240 : self.fmt.concat(&[prefix_reg, name_reg])
1373 300 : }
1374 :
1375 : /// `<keyword>(<attribute>)`, unformattable without the attribute
1376 417 : fn format_keyword_call(&self, node: &'a Node, key: AttributeKey, keyword: &'static str) -> FmtReg {
1377 417 : let [child] = attrs!(self.children(node), [key]);
1378 417 : let Some(child) = child else { return self.format_unimplemented(node) };
1379 417 : let child_reg = self.reg(child);
1380 417 : if child_reg == 0 {
1381 0 : return self.format_unimplemented(node);
1382 417 : }
1383 417 : let f = &self.fmt;
1384 417 : f.concat(&[f.text(keyword), f.parenthesized(child_reg)])
1385 417 : }
1386 :
1387 36 : fn format_relation_expression(&self, node: &'a Node) -> FmtReg {
1388 36 : self.format_keyword_call(node, K::SQL_TABLEREF_NAME, "table")
1389 36 : }
1390 :
1391 42 : fn format_descriptor(&self, node: &'a Node) -> FmtReg {
1392 42 : self.format_keyword_call(node, K::SQL_DESCRIPTOR_COLUMNS, "descriptor")
1393 42 : }
1394 :
1395 108 : fn format_indirection(&self, node: &'a Node) -> FmtReg {
1396 108 : let [value, path] = attrs!(self.children(node), [K::SQL_INDIRECTION_VALUE, K::SQL_INDIRECTION_PATH]);
1397 108 : let (Some(value), Some(path)) = (value, path) else { return self.format_unimplemented(node) };
1398 108 : let value_reg = self.reg(value);
1399 108 : let path_reg = self.reg(path);
1400 108 : if value_reg == 0 || path_reg == 0 {
1401 0 : return self.format_unimplemented(node);
1402 108 : }
1403 108 : self.fmt.concat(&[self.fmt.parenthesized(value_reg), path_reg])
1404 108 : }
1405 :
1406 135 : fn format_row_type(&self, node: &'a Node) -> FmtReg {
1407 135 : self.format_keyword_call(node, K::SQL_ROW_TYPE_FIELDS, "row")
1408 135 : }
1409 :
1410 258 : fn format_row_expression(&self, node: &'a Node) -> FmtReg {
1411 258 : let f = &self.fmt;
1412 258 : let [is_explicit, values] = attrs!(self.children(node), [K::SQL_ROW_EXPRESSION_EXPLICIT, K::SQL_ROW_EXPRESSION_VALUES]);
1413 258 : let Some(values) = values.filter(|v| v.node_type() == NodeType::ARRAY) else {
1414 0 : return self.format_unimplemented(node);
1415 : };
1416 258 : if values.children_count() == 0 {
1417 12 : return f.text("row()");
1418 246 : }
1419 246 : let values_reg = self.reg(values);
1420 246 : if values_reg == 0 {
1421 0 : return self.format_unimplemented(node);
1422 246 : }
1423 : // (x) is just x, so a single value always needs the row keyword
1424 246 : if is_explicit.is_some() || values.children_count() == 1 {
1425 102 : return f.concat(&[f.text("row"), f.parenthesized(values_reg)]);
1426 144 : }
1427 144 : f.parenthesized(values_reg)
1428 258 : }
1429 :
1430 : /// `array[...]` or `array(select ...)`
1431 126 : fn format_array_expression(&self, node: &'a Node) -> FmtReg {
1432 126 : let f = &self.fmt;
1433 126 : let [values, statement] =
1434 126 : attrs!(self.children(node), [K::SQL_ARRAY_EXPRESSION_VALUES, K::SQL_ARRAY_EXPRESSION_STATEMENT]);
1435 126 : if statement.is_some() {
1436 24 : return self.format_keyword_call(node, K::SQL_ARRAY_EXPRESSION_STATEMENT, "array");
1437 102 : }
1438 102 : let Some(values) = values.filter(|v| v.node_type() == NodeType::ARRAY) else {
1439 0 : return self.format_unimplemented(node);
1440 : };
1441 102 : if values.children_count() == 0 {
1442 12 : return f.text("array[]");
1443 90 : }
1444 90 : let values_reg = self.reg(values);
1445 90 : if values_reg == 0 {
1446 0 : return self.format_unimplemented(node);
1447 90 : }
1448 90 : f.concat(&[f.text("array"), f.bracketed(values_reg)])
1449 126 : }
1450 :
1451 : // -----------------------------------------------------------------------------------------
1452 : // Column definitions and constraints
1453 : // -----------------------------------------------------------------------------------------
1454 :
1455 1502 : fn format_column_def(&self, node: &'a Node) -> FmtReg {
1456 1502 : let f = &self.fmt;
1457 : #[rustfmt::skip]
1458 1502 : let [name, type_node, options, constraints, collate] = attrs!(self.children(node), [
1459 : K::SQL_COLUMN_DEF_NAME,
1460 : K::SQL_COLUMN_DEF_TYPE,
1461 : K::SQL_COLUMN_DEF_OPTIONS,
1462 : K::SQL_COLUMN_DEF_CONSTRAINTS,
1463 : K::SQL_COLUMN_DEF_COLLATE,
1464 : ]);
1465 1502 : let (Some(name), Some(type_node)) = (name, type_node) else { return self.format_unimplemented(node) };
1466 :
1467 1502 : let mut parts = Vec::with_capacity(6);
1468 1502 : parts.push(self.reg_or_placeholder(name));
1469 1502 : parts.push(f.text(" "));
1470 1502 : parts.push(self.reg_or_placeholder(type_node));
1471 1502 : if let Some(collate) = collate {
1472 21 : parts.push(f.text(" collate "));
1473 21 : parts.push(self.reg_or_placeholder(collate));
1474 1481 : }
1475 :
1476 1502 : if let Some(options) = options {
1477 12 : if options.node_type() != NodeType::ARRAY {
1478 0 : parts.push(f.text(" "));
1479 0 : parts.push(self.format_unimplemented(options));
1480 12 : } else if options.children_count() > 0 {
1481 12 : let option_parts: Vec<FmtReg> =
1482 15 : self.children(options).iter().map(|o| self.reg_or_placeholder(o)).collect();
1483 12 : let option_list = self.comma_join_on_overflow(&option_parts, true);
1484 12 : parts.push(f.text(" options "));
1485 12 : parts.push(f.parenthesized(option_list));
1486 0 : }
1487 1490 : }
1488 :
1489 1502 : if let Some(constraints) = constraints {
1490 804 : if constraints.node_type() != NodeType::ARRAY {
1491 0 : parts.push(f.text(" "));
1492 0 : parts.push(self.format_unimplemented(constraints));
1493 804 : } else if constraints.children_count() > 0 {
1494 804 : let constraint_parts: Vec<FmtReg> =
1495 822 : self.children(constraints).iter().map(|c| self.reg_or_placeholder(c)).collect();
1496 804 : let constraint_list = self.space_join(&constraint_parts, FormattingJoinPolicy::BreakOnOverflow, true);
1497 804 : parts.push(f.text(" "));
1498 804 : parts.push(constraint_list);
1499 0 : }
1500 698 : }
1501 1502 : f.concat(&parts)
1502 1502 : }
1503 :
1504 219 : fn format_table_constraint_type(&self, node: &'a Node) -> FmtReg {
1505 219 : if node.node_type() != NodeType::ENUM_SQL_TABLE_CONSTRAINT {
1506 0 : return self.format_unimplemented(node);
1507 219 : }
1508 219 : let text = match TableConstraint(value_u8(node)) {
1509 36 : TableConstraint::CHECK => "check",
1510 45 : TableConstraint::UNIQUE => "unique",
1511 123 : TableConstraint::PRIMARY_KEY => "primary key",
1512 15 : TableConstraint::FOREIGN_KEY => "foreign key",
1513 0 : _ => return self.format_unimplemented(node),
1514 : };
1515 219 : self.fmt.text(text)
1516 219 : }
1517 :
1518 12 : fn format_key_match(&self, node: &'a Node) -> FmtReg {
1519 12 : if node.node_type() != NodeType::ENUM_SQL_KEY_MATCH {
1520 0 : return self.format_unimplemented(node);
1521 12 : }
1522 12 : let text = match KeyMatch(value_u8(node)) {
1523 6 : KeyMatch::FULL => "match full",
1524 3 : KeyMatch::PARTIAL => "match partial",
1525 3 : KeyMatch::SIMPLE => "match simple",
1526 0 : _ => return self.format_unimplemented(node),
1527 : };
1528 12 : self.fmt.text(text)
1529 12 : }
1530 :
1531 21 : fn format_key_action_command(&self, node: &'a Node) -> FmtReg {
1532 21 : if node.node_type() != NodeType::ENUM_SQL_KEY_ACTION_COMMAND {
1533 0 : return self.format_unimplemented(node);
1534 21 : }
1535 21 : let text = match KeyActionCommand(value_u8(node)) {
1536 3 : KeyActionCommand::NO_ACTION => "no action",
1537 3 : KeyActionCommand::RESTRICT => "restrict",
1538 6 : KeyActionCommand::CASCADE => "cascade",
1539 6 : KeyActionCommand::SET_NULL => "set null",
1540 3 : KeyActionCommand::SET_DEFAULT => "set default",
1541 0 : _ => return self.format_unimplemented(node),
1542 : };
1543 21 : self.fmt.text(text)
1544 21 : }
1545 :
1546 21 : fn format_key_action_trigger(&self, node: &'a Node) -> FmtReg {
1547 21 : if node.node_type() != NodeType::ENUM_SQL_KEY_ACTION_TRIGGER {
1548 0 : return self.format_unimplemented(node);
1549 21 : }
1550 21 : let text = match KeyActionTrigger(value_u8(node)) {
1551 9 : KeyActionTrigger::UPDATE => "on update",
1552 12 : KeyActionTrigger::DELETE => "on delete",
1553 0 : _ => return self.format_unimplemented(node),
1554 : };
1555 21 : self.fmt.text(text)
1556 21 : }
1557 :
1558 21 : fn format_key_action(&self, node: &'a Node) -> FmtReg {
1559 21 : let [trigger, command] = attrs!(self.children(node), [K::SQL_KEY_ACTION_TRIGGER, K::SQL_KEY_ACTION_COMMAND]);
1560 21 : let (Some(trigger), Some(command)) = (trigger, command) else { return self.format_unimplemented(node) };
1561 21 : self.space_join(&[self.reg(trigger), self.reg(command)], FormattingJoinPolicy::BreakAllOrNone, true)
1562 21 : }
1563 :
1564 : /// A space-separated list of constraint parts
1565 939 : fn format_space_list(&self, list: &'a Node) -> FmtReg {
1566 939 : if list.node_type() != NodeType::ARRAY {
1567 0 : return self.format_unimplemented(list);
1568 939 : }
1569 939 : if list.children_count() == 0 {
1570 0 : return self.fmt.empty();
1571 939 : }
1572 981 : let parts: Vec<FmtReg> = self.children(list).iter().map(|c| self.reg_or_placeholder(c)).collect();
1573 939 : self.space_join(&parts, FormattingJoinPolicy::BreakOnOverflow, true)
1574 939 : }
1575 :
1576 219 : fn format_table_constraint(&self, node: &'a Node) -> FmtReg {
1577 219 : let f = &self.fmt;
1578 : #[rustfmt::skip]
1579 : let [
1580 219 : constraint_type, constraint_name, constraint_argument, constraint_index, constraint_columns,
1581 219 : constraint_references_name, constraint_references_columns, constraint_attributes, constraint_definition,
1582 219 : constraint_key_actions, constraint_key_match,
1583 219 : ] = attrs!(self.children(node), [
1584 : K::SQL_TABLE_CONSTRAINT_TYPE,
1585 : K::SQL_TABLE_CONSTRAINT_NAME,
1586 : K::SQL_TABLE_CONSTRAINT_ARGUMENT,
1587 : K::SQL_TABLE_CONSTRAINT_INDEX,
1588 : K::SQL_TABLE_CONSTRAINT_COLUMNS,
1589 : K::SQL_TABLE_CONSTRAINT_REFERENCES_NAME,
1590 : K::SQL_TABLE_CONSTRAINT_REFERENCES_COLUMNS,
1591 : K::SQL_TABLE_CONSTRAINT_ATTRIBUTES,
1592 : K::SQL_TABLE_CONSTRAINT_DEFINITION,
1593 : K::SQL_TABLE_CONSTRAINT_KEY_ACTIONS,
1594 : K::SQL_TABLE_CONSTRAINT_KEY_MATCH,
1595 : ],
1596 : );
1597 219 : let Some(constraint_type) = constraint_type.filter(|t| t.node_type() == NodeType::ENUM_SQL_TABLE_CONSTRAINT)
1598 : else {
1599 0 : return self.format_unimplemented(node);
1600 : };
1601 228 : let or_placeholder = |child: Option<&'a Node>| match child {
1602 216 : Some(child) => self.reg_or_placeholder(child),
1603 0 : None => self.format_unimplemented(node),
1604 216 : };
1605 :
1606 219 : let mut parts = Vec::with_capacity(16);
1607 219 : if let Some(constraint_name) = constraint_name {
1608 15 : parts.push(f.text("constraint "));
1609 15 : parts.push(self.reg_or_placeholder(constraint_name));
1610 15 : parts.push(f.text(" "));
1611 204 : }
1612 :
1613 219 : let ctype = TableConstraint(value_u8(constraint_type));
1614 219 : parts.push(self.reg_or_placeholder(constraint_type));
1615 219 : match ctype {
1616 36 : TableConstraint::CHECK => {
1617 36 : parts.push(f.text(" "));
1618 36 : parts.push(f.parenthesized(or_placeholder(constraint_argument)));
1619 36 : }
1620 : TableConstraint::UNIQUE | TableConstraint::PRIMARY_KEY => {
1621 168 : if let Some(constraint_index) = constraint_index {
1622 18 : parts.push(f.text(" using index "));
1623 18 : parts.push(self.reg_or_placeholder(constraint_index));
1624 150 : } else {
1625 150 : parts.push(f.text(" "));
1626 150 : parts.push(f.parenthesized(or_placeholder(constraint_columns)));
1627 150 : }
1628 : }
1629 : TableConstraint::FOREIGN_KEY => {
1630 15 : parts.push(f.text(" "));
1631 15 : parts.push(f.parenthesized(or_placeholder(constraint_columns)));
1632 15 : parts.push(f.text(" references "));
1633 15 : parts.push(or_placeholder(constraint_references_name));
1634 9 : if let Some(columns) =
1635 15 : constraint_references_columns.filter(|c| c.node_type() == NodeType::ARRAY && c.children_count() > 0)
1636 9 : {
1637 9 : parts.push(f.text(" "));
1638 9 : parts.push(f.parenthesized(self.reg_or_placeholder(columns)));
1639 9 : }
1640 : }
1641 0 : _ => {}
1642 : }
1643 :
1644 219 : if let Some(constraint_key_match) = constraint_key_match {
1645 12 : parts.push(f.text(" "));
1646 12 : parts.push(self.reg_or_placeholder(constraint_key_match));
1647 207 : }
1648 219 : if let Some(constraint_key_actions) = constraint_key_actions {
1649 15 : let actions = self.format_space_list(constraint_key_actions);
1650 15 : if actions != 0 {
1651 15 : parts.push(f.text(" "));
1652 15 : parts.push(actions);
1653 15 : }
1654 204 : }
1655 219 : if let Some(constraint_attributes) = constraint_attributes {
1656 60 : let attributes = self.format_space_list(constraint_attributes);
1657 60 : if attributes != 0 {
1658 60 : parts.push(f.text(" "));
1659 60 : parts.push(attributes);
1660 60 : }
1661 159 : }
1662 219 : if let Some(constraint_definition) = constraint_definition {
1663 12 : let definition = self.reg_or_placeholder(constraint_definition);
1664 12 : if definition != 0 {
1665 12 : parts.push(f.text(" with "));
1666 12 : parts.push(f.parenthesized(definition));
1667 12 : }
1668 207 : }
1669 219 : f.concat(&parts)
1670 219 : }
1671 :
1672 816 : fn format_column_constraint_type(&self, node: &'a Node) -> FmtReg {
1673 816 : if node.node_type() != NodeType::ENUM_SQL_COLUMN_CONSTRAINT {
1674 0 : return self.format_unimplemented(node);
1675 816 : }
1676 816 : let text = match ColumnConstraint(value_u8(node)) {
1677 762 : ColumnConstraint::NOT_NULL => "not null",
1678 3 : ColumnConstraint::NULL_ => "null",
1679 6 : ColumnConstraint::UNIQUE => "unique",
1680 9 : ColumnConstraint::PRIMARY_KEY => "primary key",
1681 12 : ColumnConstraint::CHECK => "check",
1682 15 : ColumnConstraint::DEFAULT => "default",
1683 9 : ColumnConstraint::COLLATE => "collate",
1684 0 : _ => return self.format_unimplemented(node),
1685 : };
1686 816 : self.fmt.text(text)
1687 816 : }
1688 :
1689 816 : fn format_column_constraint(&self, node: &'a Node) -> FmtReg {
1690 816 : let f = &self.fmt;
1691 : #[rustfmt::skip]
1692 : let [
1693 816 : constraint_type, constraint_name, constraint_value, constraint_no_inherit, constraint_definition,
1694 816 : constraint_collate,
1695 816 : ] = attrs!(self.children(node), [
1696 : K::SQL_COLUMN_CONSTRAINT_TYPE,
1697 : K::SQL_COLUMN_CONSTRAINT_NAME,
1698 : K::SQL_COLUMN_CONSTRAINT_VALUE,
1699 : K::SQL_COLUMN_CONSTRAINT_NO_INHERIT,
1700 : K::SQL_COLUMN_CONSTRAINT_DEFINITION,
1701 : K::SQL_COLUMN_CONSTRAINT_COLLATE,
1702 : ],
1703 : );
1704 816 : let Some(constraint_type) = constraint_type.filter(|t| t.node_type() == NodeType::ENUM_SQL_COLUMN_CONSTRAINT)
1705 : else {
1706 0 : return self.format_unimplemented(node);
1707 : };
1708 816 : let or_placeholder = |child: Option<&'a Node>| match child {
1709 36 : Some(child) => self.reg_or_placeholder(child),
1710 0 : None => self.format_unimplemented(node),
1711 36 : };
1712 :
1713 816 : let mut parts = Vec::with_capacity(8);
1714 816 : if let Some(constraint_name) = constraint_name {
1715 12 : parts.push(f.text("constraint "));
1716 12 : parts.push(self.reg_or_placeholder(constraint_name));
1717 12 : parts.push(f.text(" "));
1718 804 : }
1719 :
1720 816 : let ctype = ColumnConstraint(value_u8(constraint_type));
1721 816 : parts.push(self.reg_or_placeholder(constraint_type));
1722 816 : match ctype {
1723 : ColumnConstraint::CHECK => {
1724 12 : parts.push(f.text(" "));
1725 12 : parts.push(f.parenthesized(or_placeholder(constraint_value)));
1726 12 : if is_true(constraint_no_inherit) {
1727 3 : parts.push(f.text(" no inherit"));
1728 9 : }
1729 : }
1730 15 : ColumnConstraint::DEFAULT => {
1731 15 : parts.push(f.text(" "));
1732 15 : parts.push(or_placeholder(constraint_value));
1733 15 : }
1734 9 : ColumnConstraint::COLLATE => {
1735 9 : parts.push(f.text(" "));
1736 9 : parts.push(or_placeholder(constraint_collate));
1737 9 : }
1738 780 : _ => {}
1739 : }
1740 :
1741 816 : if let Some(constraint_definition) = constraint_definition {
1742 0 : let def_reg = self.reg_or_placeholder(constraint_definition);
1743 0 : if def_reg != 0 {
1744 0 : parts.push(f.text(" with "));
1745 0 : parts.push(f.parenthesized(def_reg));
1746 0 : }
1747 816 : }
1748 816 : f.concat(&parts)
1749 816 : }
1750 :
1751 75 : fn format_constraint_attribute(&self, node: &'a Node) -> FmtReg {
1752 75 : if node.node_type() != NodeType::ENUM_SQL_CONSTRAINT_ATTRIBUTE {
1753 0 : return self.format_unimplemented(node);
1754 75 : }
1755 75 : let text = match ConstraintAttribute(value_u8(node)) {
1756 18 : ConstraintAttribute::DEFERRABLE => "deferrable",
1757 9 : ConstraintAttribute::NOT_DEFERRABLE => "not deferrable",
1758 9 : ConstraintAttribute::INITIALLY_DEFERRED => "initially deferred",
1759 9 : ConstraintAttribute::INITIALLY_IMMEDIATE => "initially immediate",
1760 15 : ConstraintAttribute::NOT_VALID => "not valid",
1761 15 : ConstraintAttribute::NO_INHERIT => "no inherit",
1762 0 : _ => return self.format_unimplemented(node),
1763 : };
1764 75 : self.fmt.text(text)
1765 75 : }
1766 :
1767 312 : fn format_generic_option(&self, node: &'a Node) -> FmtReg {
1768 312 : let f = &self.fmt;
1769 312 : let [key, value] = attrs!(self.children(node), [K::SQL_GENERIC_OPTION_KEY, K::SQL_GENERIC_OPTION_VALUE]);
1770 312 : let Some(key) = key else { return self.format_unimplemented(node) };
1771 312 : let key_reg = self.reg(key);
1772 282 : match value {
1773 282 : Some(value) if value.node_type() != NodeType::NONE => f.concat(&[key_reg, f.text(" "), self.reg(value)]),
1774 30 : _ => key_reg,
1775 : }
1776 312 : }
1777 :
1778 : // -----------------------------------------------------------------------------------------
1779 : // Functions
1780 : // -----------------------------------------------------------------------------------------
1781 :
1782 6059 : fn format_function_arg(&self, node: &'a Node) -> FmtReg {
1783 6059 : let f = &self.fmt;
1784 6059 : let [arg_name, arg_value] = attrs!(self.children(node), [K::SQL_FUNCTION_ARG_NAME, K::SQL_FUNCTION_ARG_VALUE]);
1785 6059 : let Some(arg_value) = arg_value else { return self.format_unimplemented(node) };
1786 6059 : let value_reg = self.reg(arg_value);
1787 6059 : if value_reg == 0 {
1788 0 : return self.format_unimplemented(node);
1789 6059 : }
1790 6059 : let Some(arg_name) = arg_name else { return value_reg };
1791 295 : let name_reg = self.reg(arg_name);
1792 295 : if name_reg == 0 {
1793 0 : return self.format_unimplemented(node);
1794 295 : }
1795 295 : f.concat(&[name_reg, f.text(" => "), value_reg])
1796 6059 : }
1797 :
1798 : /// `name(<a> <keyword> <b>)` of the special function syntaxes, None if a part is missing
1799 1242 : fn format_special_call(
1800 1242 : &self,
1801 1242 : name_reg: FmtReg,
1802 1242 : args: &'a Node,
1803 1242 : keys: [AttributeKey; 2],
1804 1242 : keyword: &'static str,
1805 1242 : ) -> Option<FmtReg> {
1806 1242 : let f = &self.fmt;
1807 1242 : let [a, b] = self.attrs(args, keys);
1808 1242 : let a_reg = self.reg(a?);
1809 1242 : let b_reg = self.reg(b?);
1810 1242 : if a_reg == 0 || b_reg == 0 {
1811 0 : return None;
1812 1242 : }
1813 1242 : Some(f.concat(&[name_reg, f.parenthesized(f.concat(&[a_reg, f.text(keyword), b_reg]))]))
1814 1242 : }
1815 :
1816 8206 : fn format_function_expression(&self, node: &'a Node) -> FmtReg {
1817 8206 : let f = &self.fmt;
1818 : #[rustfmt::skip]
1819 : let [
1820 8206 : star, all, distinct, variadic, over, within_group, filter, name, args, order, cast_args, extract_args,
1821 8206 : overlay_args, position_args, substring_args, treat_args, trim_args,
1822 8206 : ] = attrs!(self.children(node), [
1823 : K::SQL_FUNCTION_ARGUMENTS_STAR,
1824 : K::SQL_FUNCTION_ALL,
1825 : K::SQL_FUNCTION_DISTINCT,
1826 : K::SQL_FUNCTION_VARIADIC,
1827 : K::SQL_FUNCTION_OVER,
1828 : K::SQL_FUNCTION_WITHIN_GROUP,
1829 : K::SQL_FUNCTION_FILTER,
1830 : K::SQL_FUNCTION_NAME,
1831 : K::SQL_FUNCTION_ARGUMENTS,
1832 : K::SQL_FUNCTION_ORDER,
1833 : K::SQL_FUNCTION_CAST_ARGS,
1834 : K::SQL_FUNCTION_EXTRACT_ARGS,
1835 : K::SQL_FUNCTION_OVERLAY_ARGS,
1836 : K::SQL_FUNCTION_POSITION_ARGS,
1837 : K::SQL_FUNCTION_SUBSTRING_ARGS,
1838 : K::SQL_FUNCTION_TREAT_ARGS,
1839 : K::SQL_FUNCTION_TRIM_ARGS,
1840 : ],
1841 : );
1842 8206 : let Some(name) = name else { return self.format_unimplemented(node) };
1843 8206 : if all.is_some() && distinct.is_some() {
1844 0 : return self.format_unimplemented(node);
1845 8206 : }
1846 :
1847 8206 : let known_function_text = || {
1848 2175 : if name.node_type() != NodeType::ENUM_SQL_KNOWN_FUNCTION {
1849 0 : return None;
1850 2175 : }
1851 2175 : Some(get_known_function_text(KnownFunction(value_u8(name)))).filter(|t| !t.is_empty())
1852 2175 : };
1853 :
1854 8206 : if cast_args.is_some()
1855 7075 : || extract_args.is_some()
1856 6994 : || overlay_args.is_some()
1857 6976 : || position_args.is_some()
1858 6961 : || substring_args.is_some()
1859 6862 : || treat_args.is_some()
1860 6847 : || trim_args.is_some()
1861 : {
1862 1440 : let Some(name_text) = known_function_text() else { return self.format_unimplemented(node) };
1863 1440 : let name_reg = f.text(name_text);
1864 :
1865 1440 : let special = if let Some(cast_args) = cast_args {
1866 1131 : self.format_special_call(
1867 1131 : name_reg,
1868 1131 : cast_args,
1869 1131 : [K::SQL_FUNCTION_CAST_VALUE, K::SQL_FUNCTION_CAST_TYPE],
1870 : " as ",
1871 : )
1872 309 : } else if let Some(extract_args) = extract_args {
1873 81 : self.format_special_call(
1874 81 : name_reg,
1875 81 : extract_args,
1876 81 : [K::SQL_FUNCTION_EXTRACT_TARGET, K::SQL_FUNCTION_EXTRACT_INPUT],
1877 : " from ",
1878 : )
1879 228 : } else if let Some(position_args) = position_args {
1880 15 : self.format_special_call(
1881 15 : name_reg,
1882 15 : position_args,
1883 15 : [K::SQL_FUNCTION_POSITION_SEARCH, K::SQL_FUNCTION_POSITION_INPUT],
1884 : " in ",
1885 : )
1886 213 : } else if let Some(treat_args) = treat_args {
1887 15 : self.format_special_call(
1888 15 : name_reg,
1889 15 : treat_args,
1890 15 : [K::SQL_FUNCTION_TREAT_VALUE, K::SQL_FUNCTION_TREAT_TYPE],
1891 : " as ",
1892 : )
1893 198 : } else if let Some(substring_args) = substring_args {
1894 99 : self.format_substring_args(name_reg, substring_args)
1895 99 : } else if let Some(trim_args) = trim_args {
1896 81 : self.format_trim_args(name_reg, trim_args)
1897 18 : } else if let Some(overlay_args) = overlay_args {
1898 18 : self.format_overlay_args(name_reg, overlay_args)
1899 : } else {
1900 0 : None
1901 : };
1902 1440 : return special.unwrap_or_else(|| self.format_unimplemented(node));
1903 6766 : }
1904 :
1905 6766 : let name_reg = if name.node_type() == NodeType::ARRAY {
1906 6031 : self.reg(name)
1907 735 : } else if let Some(name_text) = known_function_text() {
1908 735 : f.text(name_text)
1909 : } else {
1910 0 : return self.format_unimplemented(node);
1911 : };
1912 6766 : if name_reg == 0 {
1913 0 : return self.format_unimplemented(node);
1914 6766 : }
1915 :
1916 6766 : let mut call_parts = Vec::with_capacity(4);
1917 6766 : if star.is_some() {
1918 486 : if args.is_some() || variadic.is_some() || all.is_some() || distinct.is_some() || order.is_some() {
1919 0 : return self.format_unimplemented(node);
1920 486 : }
1921 486 : call_parts.push(f.text("*"));
1922 : } else {
1923 6280 : let Some(mut arg_items) = self.format_call_arguments(args) else { return self.format_unimplemented(node) };
1924 6280 : if let Some(variadic) = variadic {
1925 6 : let variadic_reg = self.reg(variadic);
1926 6 : if variadic_reg == 0 {
1927 0 : return self.format_unimplemented(node);
1928 6 : }
1929 6 : arg_items.push(f.concat(&[f.text("variadic "), variadic_reg]));
1930 6274 : }
1931 6280 : if all.is_some() || distinct.is_some() {
1932 123 : if arg_items.is_empty() {
1933 0 : return self.format_unimplemented(node);
1934 123 : }
1935 123 : call_parts.push(f.text(if all.is_some() { "all " } else { "distinct " }));
1936 6157 : }
1937 6280 : if !arg_items.is_empty() {
1938 5992 : call_parts.push(self.comma_join_on_overflow(&arg_items, true));
1939 5992 : }
1940 : }
1941 :
1942 6766 : if let Some(order) = order {
1943 18 : let order_reg = self.reg(order);
1944 18 : if order_reg == 0 {
1945 0 : return self.format_unimplemented(node);
1946 18 : }
1947 18 : call_parts.push(f.text(if call_parts.is_empty() { "order by " } else { " order by " }));
1948 18 : call_parts.push(order_reg);
1949 6748 : }
1950 :
1951 6766 : let call_body = f.concat(&call_parts);
1952 6766 : let mut result = if call_body == 0 {
1953 288 : if name.node_type() == NodeType::ENUM_SQL_KNOWN_FUNCTION {
1954 117 : name_reg
1955 : } else {
1956 171 : f.concat(&[name_reg, f.text("()")])
1957 : }
1958 : } else {
1959 6478 : f.concat(&[name_reg, f.parenthesized(call_body)])
1960 : };
1961 :
1962 6766 : if let Some(filter) = filter {
1963 21 : let filter_reg = self.reg(filter);
1964 21 : if filter_reg == 0 {
1965 0 : return self.format_unimplemented(node);
1966 21 : }
1967 21 : let body = f.concat(&[f.text("where "), filter_reg]);
1968 21 : result = f.concat(&[result, f.text(" filter "), f.parenthesized(body)]);
1969 6745 : }
1970 6766 : if let Some(within_group) = within_group {
1971 21 : let wg_reg = self.reg(within_group);
1972 21 : if wg_reg == 0 {
1973 0 : return self.format_unimplemented(node);
1974 21 : }
1975 21 : let body = f.concat(&[f.text("order by "), wg_reg]);
1976 21 : result = f.concat(&[result, f.text(" within group "), f.parenthesized(body)]);
1977 6745 : }
1978 6766 : if let Some(over) = over {
1979 393 : let over_reg = self.reg(over);
1980 393 : result = if over_reg == 0 {
1981 9 : f.concat(&[result, f.text(" over ()")])
1982 384 : } else if over.node_type() == NodeType::NAME {
1983 : // A reference to a named window, `over w`
1984 33 : f.concat(&[result, f.text(" over "), over_reg])
1985 : } else {
1986 351 : f.concat(&[result, f.text(" over "), f.parenthesized(over_reg)])
1987 : };
1988 6373 : }
1989 6766 : result
1990 8206 : }
1991 :
1992 99 : fn format_substring_args(&self, name_reg: FmtReg, args: &'a Node) -> Option<FmtReg> {
1993 99 : let f = &self.fmt;
1994 99 : let [sub_input, sub_from, sub_for] = attrs!(self.children(args), [K::SQL_FUNCTION_SUBSTRING_INPUT, K::SQL_FUNCTION_SUBSTRING_FROM, K::SQL_FUNCTION_SUBSTRING_FOR],
1995 : );
1996 99 : let input_reg = self.reg(sub_input?);
1997 99 : if input_reg == 0 {
1998 0 : return None;
1999 99 : }
2000 : // `substring(x from 2)`, `substring(x for 3)` or both
2001 99 : let mut parts = vec![input_reg];
2002 99 : if let Some(sub_from) = sub_from {
2003 87 : let from_reg = self.reg(sub_from);
2004 87 : if from_reg == 0 {
2005 0 : return None;
2006 87 : }
2007 87 : parts.push(f.text(" from "));
2008 87 : parts.push(from_reg);
2009 12 : }
2010 99 : if let Some(sub_for) = sub_for {
2011 78 : let for_reg = self.reg(sub_for);
2012 78 : if for_reg == 0 {
2013 0 : return None;
2014 78 : }
2015 78 : parts.push(f.text(" for "));
2016 78 : parts.push(for_reg);
2017 21 : } else if sub_from.is_none() {
2018 0 : return None;
2019 21 : }
2020 99 : Some(f.concat(&[name_reg, f.parenthesized(f.concat(&parts))]))
2021 99 : }
2022 :
2023 81 : fn format_trim_args(&self, name_reg: FmtReg, args: &'a Node) -> Option<FmtReg> {
2024 81 : let f = &self.fmt;
2025 81 : let [trim_input, trim_dir, trim_chars] = attrs!(self.children(args), [K::SQL_FUNCTION_TRIM_INPUT, K::SQL_FUNCTION_TRIM_DIRECTION, K::SQL_FUNCTION_TRIM_CHARACTERS]);
2026 81 : let input_reg = self.reg(trim_input?);
2027 81 : if input_reg == 0 {
2028 0 : return None;
2029 81 : }
2030 81 : let mut parts = Vec::with_capacity(6);
2031 81 : if let Some(trim_dir) = trim_dir {
2032 66 : let dir_reg = self.reg(trim_dir);
2033 66 : if dir_reg == 0 {
2034 0 : return None;
2035 66 : }
2036 66 : parts.push(dir_reg);
2037 66 : parts.push(f.text(" "));
2038 15 : }
2039 81 : if let Some(trim_chars) = trim_chars {
2040 33 : let chars_reg = self.reg(trim_chars);
2041 33 : if chars_reg == 0 {
2042 0 : return None;
2043 33 : }
2044 33 : parts.push(chars_reg);
2045 33 : parts.push(f.text(" "));
2046 48 : }
2047 81 : if trim_dir.is_some() || trim_chars.is_some() {
2048 66 : parts.push(f.text("from "));
2049 66 : }
2050 81 : parts.push(input_reg);
2051 81 : Some(f.concat(&[name_reg, f.parenthesized(f.concat(&parts))]))
2052 81 : }
2053 :
2054 18 : fn format_overlay_args(&self, name_reg: FmtReg, args: &'a Node) -> Option<FmtReg> {
2055 18 : let f = &self.fmt;
2056 18 : let [ov_input, ov_placing, ov_from, ov_for] = attrs!(self.children(args), [
2057 : K::SQL_FUNCTION_OVERLAY_INPUT,
2058 : K::SQL_FUNCTION_OVERLAY_PLACING,
2059 : K::SQL_FUNCTION_OVERLAY_FROM,
2060 : K::SQL_FUNCTION_OVERLAY_FOR,
2061 : ],
2062 : );
2063 18 : let (ov_input, ov_placing, ov_from) = (ov_input?, ov_placing?, ov_from?);
2064 18 : let input_reg = self.reg(ov_input);
2065 18 : let placing_reg = self.reg(ov_placing);
2066 18 : let from_reg = self.reg(ov_from);
2067 18 : if input_reg == 0 || placing_reg == 0 || from_reg == 0 {
2068 0 : return None;
2069 18 : }
2070 18 : let mut parts = vec![input_reg, f.text(" placing "), placing_reg, f.text(" from "), from_reg];
2071 18 : if let Some(ov_for) = ov_for {
2072 6 : let for_reg = self.reg(ov_for);
2073 6 : if for_reg == 0 {
2074 0 : return None;
2075 6 : }
2076 6 : parts.push(f.text(" for "));
2077 6 : parts.push(for_reg);
2078 12 : }
2079 18 : Some(f.concat(&[name_reg, f.parenthesized(f.concat(&parts))]))
2080 18 : }
2081 :
2082 150 : fn format_function_table(&self, node: &'a Node) -> FmtReg {
2083 150 : let f = &self.fmt;
2084 150 : let [function, rows_from, with_ordinality] = attrs!(self.children(node), [K::SQL_FUNCTION_TABLE_FUNCTION, K::SQL_FUNCTION_TABLE_ROWS_FROM, K::SQL_FUNCTION_TABLE_WITH_ORDINALITY],
2085 : );
2086 150 : let mut base_reg = 0;
2087 150 : if let Some(function) = function {
2088 120 : base_reg = self.reg(function);
2089 120 : } else if let Some(rows_from) = rows_from {
2090 30 : let items = self.array_regs(rows_from);
2091 60 : if items.iter().any(|&i| i == 0) {
2092 0 : return self.format_unimplemented(node);
2093 30 : }
2094 30 : let list = self.comma_join_on_overflow(&items, true);
2095 30 : base_reg = f.concat(&[f.text("rows from "), f.parenthesized(list)]);
2096 0 : }
2097 150 : if base_reg == 0 {
2098 0 : return self.format_unimplemented(node);
2099 150 : }
2100 150 : if is_true(with_ordinality) {
2101 12 : base_reg = f.concat(&[base_reg, f.text(" with ordinality")]);
2102 138 : }
2103 150 : base_reg
2104 150 : }
2105 :
2106 : // -----------------------------------------------------------------------------------------
2107 : // Windows
2108 : // -----------------------------------------------------------------------------------------
2109 :
2110 438 : fn format_window_frame(&self, node: &'a Node) -> FmtReg {
2111 438 : let f = &self.fmt;
2112 438 : let [partition, order, mode, bounds, exclude, name] = attrs!(self.children(node), [
2113 : K::SQL_WINDOW_FRAME_PARTITION,
2114 : K::SQL_WINDOW_FRAME_ORDER,
2115 : K::SQL_WINDOW_FRAME_MODE,
2116 : K::SQL_WINDOW_FRAME_BOUNDS,
2117 : K::SQL_WINDOW_FRAME_EXCLUDE,
2118 : K::SQL_WINDOW_FRAME_NAME,
2119 : ],
2120 : );
2121 438 : if exclude.is_some() || mode.is_none() != bounds.is_none() {
2122 0 : return self.format_unimplemented(node);
2123 438 : }
2124 :
2125 438 : let mut clauses = Vec::with_capacity(4);
2126 438 : if let Some(name) = name {
2127 9 : let name_reg = self.reg(name);
2128 9 : if name_reg == 0 {
2129 0 : return self.format_unimplemented(node);
2130 9 : }
2131 9 : clauses.push(name_reg);
2132 429 : }
2133 438 : if let Some(partition) = partition {
2134 258 : let part_reg = self.reg(partition);
2135 258 : if part_reg == 0 {
2136 0 : return self.format_unimplemented(node);
2137 258 : }
2138 258 : clauses.push(f.concat(&[f.text("partition by "), part_reg]));
2139 180 : }
2140 438 : if let Some(order) = order {
2141 279 : let order_reg = self.reg(order);
2142 279 : if order_reg == 0 {
2143 0 : return self.format_unimplemented(node);
2144 279 : }
2145 279 : clauses.push(f.concat(&[f.text("order by "), order_reg]));
2146 159 : }
2147 438 : if let (Some(mode), Some(bounds)) = (mode, bounds) {
2148 126 : let mode_reg = self.reg(mode);
2149 126 : let bounds_reg = self.reg(bounds);
2150 126 : if mode_reg == 0 || bounds_reg == 0 {
2151 0 : return self.format_unimplemented(node);
2152 126 : }
2153 126 : clauses.push(f.concat(&[mode_reg, f.text(" "), bounds_reg]));
2154 312 : }
2155 438 : if clauses.is_empty() {
2156 21 : return f.empty();
2157 417 : }
2158 417 : self.space_join(&clauses, FormattingJoinPolicy::BreakOnOverflow, true)
2159 438 : }
2160 :
2161 222 : fn format_window_bound(&self, node: &'a Node) -> FmtReg {
2162 222 : let f = &self.fmt;
2163 222 : let [mode, direction, value] =
2164 222 : attrs!(self.children(node), [K::SQL_WINDOW_BOUND_MODE, K::SQL_WINDOW_BOUND_DIRECTION, K::SQL_WINDOW_BOUND_VALUE]);
2165 222 : let Some(mode) = mode else { return self.format_unimplemented(node) };
2166 222 : match (WindowBoundMode(value_u8(mode)), direction, value) {
2167 75 : (WindowBoundMode::UNBOUNDED, Some(direction), None) => {
2168 75 : f.concat(&[self.reg(mode), f.text(" "), self.reg(direction)])
2169 : }
2170 84 : (WindowBoundMode::CURRENT_ROW, None, None) => self.reg(mode),
2171 63 : (WindowBoundMode::VALUE, Some(direction), Some(value)) => {
2172 63 : f.concat(&[self.reg(value), f.text(" "), self.reg(direction)])
2173 : }
2174 0 : _ => self.format_unimplemented(node),
2175 : }
2176 222 : }
2177 :
2178 222 : fn format_window_bound_mode(&self, node: &'a Node) -> FmtReg {
2179 222 : match WindowBoundMode(value_u8(node)) {
2180 75 : WindowBoundMode::UNBOUNDED => self.fmt.text("unbounded"),
2181 84 : WindowBoundMode::CURRENT_ROW => self.fmt.text("current row"),
2182 63 : WindowBoundMode::VALUE => self.fmt.empty(),
2183 0 : _ => self.format_unimplemented(node),
2184 : }
2185 222 : }
2186 :
2187 138 : fn format_window_bound_direction(&self, node: &'a Node) -> FmtReg {
2188 138 : match WindowBoundDirection(value_u8(node)) {
2189 114 : WindowBoundDirection::PRECEDING => self.fmt.text("preceding"),
2190 24 : WindowBoundDirection::FOLLOWING => self.fmt.text("following"),
2191 0 : _ => self.format_unimplemented(node),
2192 : }
2193 138 : }
2194 :
2195 126 : fn format_window_range_mode(&self, node: &'a Node) -> FmtReg {
2196 126 : match WindowRangeMode(value_u8(node)) {
2197 18 : WindowRangeMode::RANGE => self.fmt.text("range"),
2198 90 : WindowRangeMode::ROWS => self.fmt.text("rows"),
2199 18 : WindowRangeMode::GROUPS => self.fmt.text("groups"),
2200 0 : _ => self.format_unimplemented(node),
2201 : }
2202 126 : }
2203 :
2204 : // -----------------------------------------------------------------------------------------
2205 : // Expressions
2206 : // -----------------------------------------------------------------------------------------
2207 :
2208 108 : fn format_alias(&self, node: &'a Node) -> FmtReg {
2209 108 : let f = &self.fmt;
2210 108 : let [name, col_names, col_defs] =
2211 108 : attrs!(self.children(node), [K::SQL_ALIAS_NAME, K::SQL_ALIAS_COLUMN_NAMES, K::SQL_ALIAS_COLUMN_DEFS]);
2212 108 : let Some(name) = name else { return self.format_unimplemented(node) };
2213 108 : let name_reg = self.reg(name);
2214 108 : if name_reg == 0 {
2215 0 : return self.format_unimplemented(node);
2216 108 : }
2217 108 : for columns in [col_names, col_defs].into_iter().flatten() {
2218 66 : if columns.node_type() == NodeType::ARRAY && columns.children_count() > 0 {
2219 66 : let cols = self.format_comma_list(columns, true);
2220 66 : return f.concat(&[name_reg, f.parenthesized(cols)]);
2221 0 : }
2222 : }
2223 42 : name_reg
2224 108 : }
2225 :
2226 150 : fn format_typecast_expression(&self, node: &'a Node) -> FmtReg {
2227 150 : let f = &self.fmt;
2228 150 : let [value, type_node] = attrs!(self.children(node), [K::SQL_TYPECAST_VALUE, K::SQL_TYPECAST_TYPE]);
2229 150 : let (Some(value), Some(type_node)) = (value, type_node) else { return self.format_unimplemented(node) };
2230 150 : let mut value_reg = self.reg(value);
2231 150 : let type_reg = self.reg(type_node);
2232 150 : if value_reg == 0 || type_reg == 0 {
2233 0 : return self.format_unimplemented(node);
2234 150 : }
2235 150 : if value.node_type() == NodeType::OBJECT_SQL_NARY_EXPRESSION {
2236 18 : value_reg = f.parenthesized(value_reg);
2237 132 : }
2238 150 : f.concat(&[value_reg, f.text("::"), type_reg])
2239 150 : }
2240 :
2241 1248 : fn format_case(&self, node: &'a Node) -> FmtReg {
2242 1248 : let f = &self.fmt;
2243 1248 : let [argument, clauses, default_value] =
2244 1248 : attrs!(self.children(node), [K::SQL_CASE_ARGUMENT, K::SQL_CASE_CLAUSES, K::SQL_CASE_DEFAULT]);
2245 1248 : let Some(clauses) = clauses else { return self.format_unimplemented(node) };
2246 :
2247 1248 : let mut parts = Vec::new();
2248 1248 : if let Some(argument) = argument {
2249 45 : let arg_reg = self.reg(argument);
2250 45 : if arg_reg == 0 {
2251 0 : return self.format_unimplemented(node);
2252 45 : }
2253 45 : parts.push(f.concat(&[f.text("case "), arg_reg]));
2254 1203 : } else {
2255 1203 : parts.push(f.text("case"));
2256 1203 : }
2257 1278 : for clause in self.array_regs(clauses) {
2258 1278 : if clause == 0 {
2259 0 : return self.format_unimplemented(node);
2260 1278 : }
2261 1278 : parts.push(clause);
2262 : }
2263 1248 : if let Some(default_value) = default_value {
2264 1179 : let default_reg = self.reg(default_value);
2265 1179 : if default_reg == 0 {
2266 0 : return self.format_unimplemented(node);
2267 1179 : }
2268 1179 : parts.push(f.concat(&[f.text("else "), default_reg]));
2269 69 : }
2270 1248 : parts.push(f.text("end"));
2271 :
2272 1248 : if self.is_pretty() {
2273 416 : let body = self.space_join(&parts[..parts.len() - 1], FormattingJoinPolicy::ForceBreak, true);
2274 416 : return self.space_join(&[body, parts[parts.len() - 1]], FormattingJoinPolicy::ForceBreak, false);
2275 832 : }
2276 832 : self.space_join(&parts, FormattingJoinPolicy::BreakOnOverflow, true)
2277 1248 : }
2278 :
2279 1278 : fn format_case_clause(&self, node: &'a Node) -> FmtReg {
2280 1278 : let f = &self.fmt;
2281 1278 : let [when_value, then_value] = attrs!(self.children(node), [K::SQL_CASE_CLAUSE_WHEN, K::SQL_CASE_CLAUSE_THEN]);
2282 1278 : let (Some(when_value), Some(then_value)) = (when_value, then_value) else {
2283 0 : return self.format_unimplemented(node);
2284 : };
2285 1278 : let when_reg = self.reg(when_value);
2286 1278 : let then_reg = self.reg(then_value);
2287 1278 : if when_reg == 0 || then_reg == 0 {
2288 0 : return self.format_unimplemented(node);
2289 1278 : }
2290 1278 : f.concat(&[f.text("when "), when_reg, f.text(" then "), then_reg])
2291 1278 : }
2292 :
2293 180 : fn format_exists_expression(&self, node: &'a Node) -> FmtReg {
2294 180 : self.format_keyword_call(node, K::SQL_EXISTS_EXPRESSION_STATEMENT, "exists ")
2295 180 : }
2296 :
2297 : /// `OPERATOR(schema.op)`, the elements are the qualifying names and the operator
2298 21 : fn format_operator_path(&self, node: &'a Node) -> FmtReg {
2299 21 : let f = &self.fmt;
2300 21 : let parts = self.array_regs(node);
2301 42 : if parts.is_empty() || parts.iter().any(|&p| p == 0) {
2302 0 : return self.format_unimplemented(node);
2303 21 : }
2304 21 : let joined = f.join(&parts, f.text("."), f.text("."), None, false);
2305 21 : f.concat(&[f.text("operator"), f.parenthesized(joined)])
2306 21 : }
2307 :
2308 : /// `a = any (select ...)`
2309 99 : fn format_subquery_expression(&self, node: &'a Node) -> FmtReg {
2310 99 : let f = &self.fmt;
2311 : #[rustfmt::skip]
2312 99 : let [arg0, arg1, operator, quantifier] = attrs!(self.children(node), [
2313 : K::SQL_SUBQUERY_ARG0, K::SQL_SUBQUERY_ARG1, K::SQL_SUBQUERY_OPERATOR, K::SQL_SUBQUERY_QUANTIFIER,
2314 : ]);
2315 99 : let (Some(arg0), Some(arg1), Some(operator), Some(quantifier)) = (arg0, arg1, operator, quantifier) else {
2316 3 : return self.format_unimplemented(node);
2317 : };
2318 96 : let (arg0_reg, arg1_reg, op_reg) = (self.reg(arg0), self.reg(arg1), self.reg(operator));
2319 96 : if arg0_reg == 0 || arg1_reg == 0 || op_reg == 0 {
2320 0 : return self.format_unimplemented(node);
2321 96 : }
2322 : // The right hand side is either a subquery, which parenthesizes itself, or an expression
2323 96 : let arg1_reg =
2324 96 : if arg1.node_type() == NodeType::OBJECT_SQL_SELECT_EXPRESSION { arg1_reg } else { f.parenthesized(arg1_reg) };
2325 96 : f.concat(&[arg0_reg, f.text(" "), op_reg, f.text(" "), self.reg(quantifier), f.text(" "), arg1_reg])
2326 99 : }
2327 :
2328 99 : fn format_subquery_quantifier(&self, node: &'a Node) -> FmtReg {
2329 99 : let text = match SubqueryQuantifier(value_u8(node)) {
2330 63 : SubqueryQuantifier::ANY => "any",
2331 18 : SubqueryQuantifier::SOME => "some",
2332 18 : SubqueryQuantifier::ALL => "all",
2333 0 : _ => return self.format_unimplemented(node),
2334 : };
2335 99 : self.fmt.text(text)
2336 99 : }
2337 :
2338 : /// `[value]` or `[lower:upper]`, a missing bound of a slice stays empty
2339 93 : fn format_indirection_index(&self, node: &'a Node) -> FmtReg {
2340 93 : let f = &self.fmt;
2341 93 : let [value, lower, upper] = attrs!(self.children(node), [
2342 : K::SQL_INDIRECTION_INDEX_VALUE,
2343 : K::SQL_INDIRECTION_INDEX_LOWER_BOUND,
2344 : K::SQL_INDIRECTION_INDEX_UPPER_BOUND,
2345 : ]);
2346 159 : let reg_of = |bound: Option<&'a Node>| bound.map_or(f.empty(), |b| self.reg(b));
2347 93 : if let Some(value) = value {
2348 15 : return f.concat(&[f.text("["), self.reg(value), f.text("]")]);
2349 78 : }
2350 78 : f.concat(&[f.text("["), reg_of(lower), f.text(":"), reg_of(upper), f.text("]")])
2351 93 : }
2352 :
2353 : /// The elements of a path after a value: `.field` and `[index]`
2354 117 : fn format_indirection_path(&self, node: &'a Node) -> FmtReg {
2355 117 : let f = &self.fmt;
2356 117 : let mut parts = Vec::with_capacity(node.children_count() as usize * 2);
2357 117 : for element in self.children(node) {
2358 117 : let reg = self.reg(element);
2359 117 : match element.node_type() {
2360 105 : NodeType::NAME if reg != 0 => {
2361 105 : parts.push(f.text("."));
2362 105 : parts.push(reg);
2363 105 : }
2364 12 : NodeType::OBJECT_SQL_INDIRECTION_INDEX if reg != 0 => parts.push(reg),
2365 0 : _ => return self.format_unimplemented(node),
2366 : }
2367 : }
2368 117 : f.concat(&parts)
2369 117 : }
2370 :
2371 : /// `a is [not] of (type, ...)`
2372 18 : fn format_typetest_expression(&self, node: &'a Node) -> FmtReg {
2373 18 : let f = &self.fmt;
2374 18 : let [negate, value, types] =
2375 18 : attrs!(self.children(node), [K::SQL_TYPETEST_NEGATE, K::SQL_TYPETEST_VALUE, K::SQL_TYPETEST_TYPES]);
2376 18 : let (Some(value), Some(types)) = (value, types) else { return self.format_unimplemented(node) };
2377 18 : let (value_reg, types_reg) = (self.reg(value), self.reg(types));
2378 18 : if value_reg == 0 || types_reg == 0 {
2379 0 : return self.format_unimplemented(node);
2380 18 : }
2381 18 : let keyword = if is_true(negate) { " is not of " } else { " is of " };
2382 18 : f.concat(&[value_reg, f.text(keyword), f.parenthesized(types_reg)])
2383 18 : }
2384 :
2385 : /// `f(...) [as (column definitions)]` of `rows from (...)`
2386 60 : fn format_rows_from_item(&self, node: &'a Node) -> FmtReg {
2387 60 : let f = &self.fmt;
2388 60 : let [function, columns] = attrs!(self.children(node), [K::SQL_ROWSFROM_ITEM_FUNCTION, K::SQL_ROWSFROM_ITEM_COLUMNS]);
2389 60 : let Some(function) = function else { return self.format_unimplemented(node) };
2390 60 : let function_reg = self.reg(function);
2391 60 : if function_reg == 0 {
2392 0 : return self.format_unimplemented(node);
2393 60 : }
2394 60 : match columns.filter(|c| c.node_type() == NodeType::ARRAY) {
2395 27 : Some(columns) => f.concat(&[function_reg, f.text(" as "), f.parenthesized(self.reg(columns))]),
2396 33 : None => function_reg,
2397 : }
2398 60 : }
2399 :
2400 : /// `bit [varying] [(length)]`
2401 30 : fn format_bit_type(&self, node: &'a Node) -> FmtReg {
2402 30 : let f = &self.fmt;
2403 30 : let [varying, length] = attrs!(self.children(node), [K::SQL_BIT_TYPE_VARYING, K::SQL_BIT_TYPE_LENGTH]);
2404 30 : let mut parts = vec![f.text(if is_true(varying) { "bit varying" } else { "bit" })];
2405 30 : if let Some(length) = length {
2406 18 : parts.push(f.parenthesized(self.reg(length)));
2407 18 : }
2408 30 : f.concat(&parts)
2409 30 : }
2410 :
2411 : /// `key = value` of a definition list
2412 12 : fn format_definition_arg(&self, node: &'a Node) -> FmtReg {
2413 12 : let f = &self.fmt;
2414 12 : let [key, value] = attrs!(self.children(node), [K::SQL_DEFINITION_ARG_KEY, K::SQL_DEFINITION_ARG_VALUE]);
2415 12 : let Some(key) = key else { return self.format_unimplemented(node) };
2416 12 : let value_reg = match value {
2417 12 : Some(value) => self.reg(value),
2418 0 : None => f.text("none"),
2419 : };
2420 12 : if value_reg == 0 {
2421 0 : return self.format_unimplemented(node);
2422 12 : }
2423 12 : f.concat(&[self.reg(key), f.text(" = "), value_reg])
2424 12 : }
2425 :
2426 846 : fn format_cte(&self, node: &'a Node) -> FmtReg {
2427 846 : let f = &self.fmt;
2428 846 : let [name, columns, statement, graph, secure, options] = attrs!(self.children(node), [
2429 : K::SQL_CTE_NAME,
2430 : K::SQL_CTE_COLUMNS,
2431 : K::SQL_CTE_STATEMENT,
2432 : K::SQL_CTE_PROPERTY_GRAPH,
2433 : K::SQL_CTE_SECURE,
2434 : K::SQL_CTE_OPTIONS,
2435 : ],
2436 : );
2437 846 : let Some(name) = name else { return self.format_unimplemented(node) };
2438 846 : let Some(body_node) = statement.or(graph) else { return self.format_unimplemented(node) };
2439 846 : let name_reg = self.reg(name);
2440 846 : let body_reg = self.reg(body_node);
2441 846 : if name_reg == 0 || body_reg == 0 {
2442 0 : return self.format_unimplemented(node);
2443 846 : }
2444 :
2445 846 : let body = if graph.is_some_and(|g| g.children_count() == 0) {
2446 45 : f.text("()")
2447 801 : } else if self.is_pretty() {
2448 267 : f.concat(&[f.text("("), f.indented(f.concat(&[f.break_(), body_reg])), f.break_(), f.text(")")])
2449 : } else {
2450 534 : f.parenthesized(body_reg)
2451 : };
2452 :
2453 846 : let as_reg = if graph.is_some() {
2454 90 : f.text(" as property graph ")
2455 756 : } else if secure.is_some() {
2456 12 : f.text(" as secure ")
2457 : } else {
2458 744 : f.text(" as ")
2459 : };
2460 846 : let mut result = match columns.filter(|c| c.node_type() == NodeType::ARRAY && c.children_count() > 0) {
2461 21 : Some(columns) => {
2462 21 : let cols_reg = self.reg(columns);
2463 21 : if cols_reg == 0 {
2464 0 : return self.format_unimplemented(columns);
2465 21 : }
2466 21 : f.concat(&[name_reg, f.text(" "), f.parenthesized(cols_reg), as_reg, body])
2467 : }
2468 825 : None => f.concat(&[name_reg, as_reg, body]),
2469 : };
2470 846 : if let Some(options) = options {
2471 36 : let options_reg = self.reg(options);
2472 36 : if options_reg == 0 {
2473 0 : return self.format_unimplemented(options);
2474 36 : }
2475 36 : result = f.concat(&[result, f.text(" options "), f.parenthesized(options_reg)]);
2476 810 : }
2477 846 : result
2478 846 : }
2479 :
2480 27122 : fn format_expression_operator_type(&self, node: &'a Node) -> FmtReg {
2481 27122 : if node.node_type() != NodeType::ENUM_SQL_EXPRESSION_OPERATOR {
2482 0 : return self.format_unimplemented(node);
2483 27122 : }
2484 27122 : let text = get_operator_text(ExpressionOperator(value_u8(node)));
2485 27122 : if text.is_empty() {
2486 0 : return self.format_unimplemented(node);
2487 27122 : }
2488 27122 : self.fmt.text(text)
2489 27122 : }
2490 :
2491 20560 : fn format_result_target(&self, node: &'a Node) -> FmtReg {
2492 20560 : let f = &self.fmt;
2493 20560 : let [value, name, star, exclude] = attrs!(self.children(node), [
2494 : K::SQL_RESULT_TARGET_VALUE,
2495 : K::SQL_RESULT_TARGET_NAME,
2496 : K::SQL_RESULT_TARGET_STAR,
2497 : K::SQL_RESULT_TARGET_EXCLUDE,
2498 : ],
2499 : );
2500 20560 : if let Some(star) = star {
2501 1377 : if name.is_some() {
2502 0 : return self.format_unimplemented(node);
2503 1377 : }
2504 1377 : if star.node_type() != NodeType::BOOL || star.children_begin_or_value() == 0 {
2505 0 : return self.format_unimplemented(star);
2506 1377 : }
2507 1377 : let mut result = match value {
2508 21 : Some(value) => f.concat(&[self.reg(value), f.text(".*")]),
2509 1356 : None => f.text("*"),
2510 : };
2511 1377 : if let Some(exclude) = exclude {
2512 12 : let exclude_reg = self.reg(exclude);
2513 12 : if exclude_reg == 0 {
2514 0 : return self.format_unimplemented(exclude);
2515 12 : }
2516 12 : result = if exclude.children_count() == 1 {
2517 3 : f.concat(&[result, f.text(" exclude "), exclude_reg])
2518 : } else {
2519 9 : f.concat(&[result, f.text(" exclude "), f.parenthesized(exclude_reg)])
2520 : };
2521 1365 : }
2522 1377 : return result;
2523 19183 : }
2524 19183 : let Some(value) = value else { return self.format_unimplemented(node) };
2525 19183 : let value_reg = self.reg(value);
2526 19183 : if value_reg == 0 {
2527 0 : return self.format_unimplemented(value);
2528 19183 : }
2529 19183 : let Some(name) = name else { return value_reg };
2530 8182 : let name_reg = self.reg(name);
2531 8182 : if name_reg == 0 {
2532 0 : return self.format_unimplemented(name);
2533 8182 : }
2534 8182 : f.concat(&[value_reg, f.text(" as "), name_reg])
2535 20560 : }
2536 :
2537 816 : fn format_select_expression(&self, node: &'a Node) -> FmtReg {
2538 816 : let [statement, indirection] =
2539 816 : attrs!(self.children(node), [K::SQL_SELECT_EXPRESSION_STATEMENT, K::SQL_SELECT_EXPRESSION_INDIRECTION]);
2540 816 : let Some(statement) = statement else { return self.format_unimplemented(node) };
2541 816 : let subquery = self.fmt.parenthesized(self.reg(statement));
2542 816 : match indirection.filter(|i| i.node_type() == NodeType::ARRAY && i.children_count() > 0) {
2543 9 : Some(indirection) => self.fmt.concat(&[subquery, self.reg(indirection)]),
2544 807 : None => subquery,
2545 : }
2546 816 : }
2547 :
2548 : /// Is a DEFAULT expression a value of an INSERT ... VALUES?
2549 7 : fn is_in_insert_values(&self, node: &Node) -> bool {
2550 7 : let mut parent_id = node.parent() as usize;
2551 7 : let mut depth = 0;
2552 24 : while parent_id < self.ast.len() && depth < self.ast.len() {
2553 24 : let parent = &self.ast[parent_id];
2554 24 : if parent.attribute_key() == K::SQL_INSERT_SOURCE {
2555 6 : let [values] = attrs!(self.children(parent), [K::SQL_SELECT_VALUES]);
2556 6 : return parent.node_type() == NodeType::OBJECT_SQL_SELECT && values.is_some();
2557 18 : }
2558 18 : if parent.node_type() == NodeType::OBJECT_SQL_INSERT {
2559 0 : break;
2560 18 : }
2561 18 : let next_parent = parent.parent() as usize;
2562 18 : if next_parent == parent_id {
2563 1 : break;
2564 17 : }
2565 17 : parent_id = next_parent;
2566 17 : depth += 1;
2567 : }
2568 1 : false
2569 7 : }
2570 :
2571 27155 : fn format_expression(&self, node_id: usize) -> FmtReg {
2572 27155 : let f = &self.fmt;
2573 27155 : let node = &self.ast[node_id];
2574 27155 : let state = self.node_states[node_id];
2575 :
2576 27155 : let [op_node, args_node] = attrs!(self.children(node), [K::SQL_EXPRESSION_OPERATOR, K::SQL_EXPRESSION_ARGS]);
2577 27155 : if let (Some(op_node), None) = (op_node, args_node) {
2578 7 : if op_node.node_type() == NodeType::ENUM_SQL_EXPRESSION_OPERATOR
2579 7 : && ExpressionOperator(value_u8(op_node)) == ExpressionOperator::DEFAULT
2580 : {
2581 7 : if !self.is_in_insert_values(node) {
2582 1 : return self.format_unimplemented(node);
2583 6 : }
2584 6 : return self.reg(op_node);
2585 0 : }
2586 27148 : }
2587 27148 : let (Some(op_node), Some(args_node)) = (op_node, args_node) else { return self.format_unimplemented(node) };
2588 0 : if !matches!(
2589 27148 : op_node.node_type(),
2590 : NodeType::ENUM_SQL_EXPRESSION_OPERATOR | NodeType::OPERATOR | NodeType::ARRAY
2591 27148 : ) || args_node.node_type() != NodeType::ARRAY
2592 27148 : || args_node.children_count() == 0
2593 : {
2594 0 : return self.format_unimplemented(node);
2595 27148 : }
2596 :
2597 27148 : let known_operator = op_node.node_type() == NodeType::ENUM_SQL_EXPRESSION_OPERATOR;
2598 27148 : let op = if known_operator { ExpressionOperator(value_u8(op_node)) } else { ExpressionOperator::DEFAULT };
2599 27148 : let op_reg = self.reg(op_node);
2600 27148 : if op_reg == 0 {
2601 0 : return self.format_unimplemented(node);
2602 27148 : }
2603 :
2604 27148 : let args = self.array_regs(args_node);
2605 27148 : if !known_operator && args.len() != 2 {
2606 0 : return self.format_unimplemented(node);
2607 27148 : }
2608 :
2609 : use ExpressionOperator as O;
2610 27148 : let mut reg = if args.len() == 1 && known_operator {
2611 631 : match op {
2612 274 : O::NEGATE => f.concat(&[op_reg, args[0]]),
2613 93 : O::NOT => f.concat(&[op_reg, f.text(" "), args[0]]),
2614 : O::IS_NULL
2615 : | O::NOT_NULL
2616 : | O::IS_TRUE
2617 : | O::IS_FALSE
2618 : | O::IS_UNKNOWN
2619 : | O::IS_NOT_TRUE
2620 : | O::IS_NOT_FALSE
2621 261 : | O::IS_NOT_UNKNOWN => f.concat(&[args[0], f.text(" "), op_reg]),
2622 3 : _ => f.concat(&[op_reg, f.text(" "), args[0]]),
2623 : }
2624 26517 : } else if args.len() == 3
2625 2436 : && known_operator
2626 879 : && matches!(
2627 2436 : op,
2628 : O::BETWEEN_ASYMMETRIC | O::NOT_BETWEEN_ASYMMETRIC | O::BETWEEN_SYMMETRIC | O::NOT_BETWEEN_SYMMETRIC
2629 : )
2630 : {
2631 1557 : f.concat(&[args[0], f.text(" "), op_reg, f.text(" "), args[1], f.text(" and "), args[2]])
2632 24960 : } else if args.len() == 2 && known_operator && matches!(op, O::IN | O::NOT_IN) {
2633 1104 : let mut rhs = args[1];
2634 1104 : let rhs_node = &self.ast[args_node.children_begin_or_value() as usize + 1];
2635 1104 : if rhs_node.node_type() == NodeType::ARRAY {
2636 789 : let list = self.format_comma_list(rhs_node, true);
2637 789 : rhs = f.parenthesized(list);
2638 789 : }
2639 1104 : f.concat(&[args[0], f.text(" "), op_reg, f.text(" "), rhs])
2640 23856 : } else if args.len() == 2 && known_operator && matches!(op, O::IS_DISTINCT_FROM | O::IS_NOT_DISTINCT_FROM) {
2641 30 : f.concat(&[args[0], f.text(" "), op_reg, f.text(" "), args[1]])
2642 : } else {
2643 23826 : let is_boolean_chain = known_operator && matches!(op, O::AND | O::OR);
2644 23826 : let inline_separator = f.concat(&[f.text(" "), op_reg, f.text(" ")]);
2645 23826 : let break_separator = if breaks_before_operator(op) {
2646 4137 : f.concat(&[f.break_(), op_reg, f.text(" ")])
2647 : } else {
2648 19689 : f.concat(&[f.text(" "), op_reg, f.break_()])
2649 : };
2650 23826 : let policy = if is_boolean_chain { None } else { Some(FormattingJoinPolicy::BreakOnOverflow) };
2651 23826 : f.join(&args, inline_separator, break_separator, policy, true)
2652 : };
2653 :
2654 27148 : if state.needs_parentheses {
2655 1004 : reg = f.parenthesized(reg);
2656 26144 : }
2657 27148 : reg
2658 27155 : }
2659 :
2660 : // -----------------------------------------------------------------------------------------
2661 : // Dispatch
2662 : // -----------------------------------------------------------------------------------------
2663 :
2664 462656 : fn format_node(&self, node_id: usize) -> FmtReg {
2665 462656 : let node: &'a Node = &self.ast[node_id];
2666 462656 : let f = &self.fmt;
2667 462656 : match node.node_type() {
2668 129507 : NodeType::ARRAY => self.format_array(node),
2669 9066 : NodeType::OBJECT_SQL_SELECT => self.format_select(node_id),
2670 90 : NodeType::OBJECT_SQL_INSERT => self.format_insert(node),
2671 84 : NodeType::OBJECT_SQL_DELETE => self.format_delete(node),
2672 335 : NodeType::OBJECT_SQL_CREATE => self.format_create(node_id),
2673 39 : NodeType::OBJECT_SQL_CREATE_AS => self.format_create_as(node),
2674 24 : NodeType::OBJECT_SQL_VIEW => self.format_view(node),
2675 45 : NodeType::OBJECT_SQL_CREATE_FUNCTION => self.format_create_function(node),
2676 21 : NodeType::OBJECT_SQL_DROP_TABLE => self.format_drop(node, true),
2677 21 : NodeType::OBJECT_SQL_DROP_VIEW => self.format_drop(node, false),
2678 150 : NodeType::OBJECT_SQL_ALTER_TABLE => self.format_alter_table(node, "alter table "),
2679 18 : NodeType::OBJECT_SQL_ALTER_VIEW => self.format_alter_table(node, "alter view "),
2680 39 : NodeType::OBJECT_SQL_CREATE_SCHEMA | NodeType::OBJECT_SQL_DROP_SCHEMA | NodeType::OBJECT_SQL_ALTER_SCHEMA => self.format_schema_statement(node),
2681 : NodeType::OBJECT_SQL_ALTER_ADD_COLUMN
2682 : | NodeType::OBJECT_SQL_ALTER_DROP_COLUMN
2683 : | NodeType::OBJECT_SQL_ALTER_RENAME_COLUMN
2684 : | NodeType::OBJECT_SQL_ALTER_RENAME_TABLE
2685 : | NodeType::OBJECT_SQL_ALTER_SET_SCHEMA
2686 186 : | NodeType::OBJECT_SQL_ALTER_COLUMN_TYPE => self.format_alter_table_action(node),
2687 18 : NodeType::OBJECT_SQL_ATTACH_DATABASE => self.format_attach_database(node),
2688 18 : NodeType::OBJECT_SQL_ATTACH_DATABASE_OPTION => self.format_attach_database_option(node),
2689 57 : NodeType::OBJECT_SQL_FUNCTION_PARAM => self.format_function_param(node),
2690 24 : NodeType::OBJECT_EXT_SET => self.format_set(node),
2691 201 : NodeType::OBJECT_EXT_VARARG_FIELD => self.format_vararg_field(node),
2692 135 : NodeType::OBJECT_EXT_EXPLAIN => self.format_explain(node_id),
2693 9 : NodeType::OBJECT_EXT_EXPLAIN_EXPRESSIONS => self.format_explain_expressions(node),
2694 106 : NodeType::OBJECT_SQL_CALL => self.format_call(node),
2695 13180 : NodeType::OBJECT_SQL_TABLEREF => self.format_table_ref(node),
2696 690 : NodeType::OBJECT_SQL_JOINED_TABLE => self.format_joined_table(node),
2697 690 : NodeType::ENUM_SQL_JOIN_TYPE => f.empty(),
2698 51 : NodeType::OBJECT_SQL_INTO => self.format_into(node),
2699 78 : NodeType::OBJECT_SQL_WINDOW_DEF => self.format_window_def(node),
2700 81 : NodeType::OBJECT_SQL_ROW_LOCKING => self.format_row_locking(node),
2701 81 : NodeType::ENUM_SQL_ROW_LOCKING_STRENGTH => self.format_row_locking_strength(node),
2702 30 : NodeType::ENUM_SQL_ROW_LOCKING_BLOCK_BEHAVIOR => self.format_row_locking_block_behavior(node),
2703 48 : NodeType::OBJECT_SQL_SELECT_SAMPLE => self.format_sample(node, false),
2704 57 : NodeType::OBJECT_SQL_TABLEREF_SAMPLE => self.format_sample(node, true),
2705 105 : NodeType::ENUM_SQL_SAMPLE_UNIT_TYPE => self.format_sample_unit(node),
2706 3879 : NodeType::OBJECT_SQL_GROUP_BY_ITEM => self.format_group_by_item(node),
2707 : NodeType::ENUM_SQL_GROUP_BY_ITEM_TYPE
2708 : | NodeType::ENUM_SQL_COMBINE_MODIFIER
2709 4767 : | NodeType::ENUM_SQL_COMBINE_OPERATION => f.empty(),
2710 3942 : NodeType::OBJECT_SQL_ORDER => self.format_order(node),
2711 498 : NodeType::ENUM_SQL_ORDER_DIRECTION => self.format_order_direction(node),
2712 1473 : NodeType::ENUM_SQL_ORDER_NULL_RULE => self.format_order_null_rule(node),
2713 105 : NodeType::ENUM_SQL_TEMP_TYPE => self.format_temp_type(node),
2714 33 : NodeType::ENUM_SQL_ON_COMMIT_OPTION => self.format_on_commit_option(node),
2715 3030 : NodeType::OBJECT_SQL_TYPENAME => self.format_type_name(node),
2716 215 : NodeType::OBJECT_SQL_INTERVAL_TYPE => self.format_interval_type(node),
2717 191 : NodeType::ENUM_SQL_INTERVAL_TYPE => self.format_interval_type_enum(node),
2718 502 : NodeType::OBJECT_SQL_NUMERIC_TYPE => self.format_numeric_type(node),
2719 1494 : NodeType::ENUM_SQL_NUMERIC_TYPE => self.format_numeric_type_base(node),
2720 447 : NodeType::OBJECT_SQL_CHARACTER_TYPE => self.format_character_type(node),
2721 447 : NodeType::ENUM_SQL_CHARACTER_TYPE => self.format_character_type_base(node),
2722 795 : NodeType::OBJECT_SQL_GENERIC_TYPE => self.format_generic_type(node),
2723 72 : NodeType::OBJECT_SQL_TIMESTAMP_TYPE | NodeType::OBJECT_SQL_TIME_TYPE => self.format_timestamp_type(node),
2724 50753 : NodeType::OBJECT_SQL_COLUMN_REF => self.format_column_ref(node),
2725 300 : NodeType::OBJECT_SQL_PARAMETER_REF => self.format_parameter_ref(node),
2726 36 : NodeType::OBJECT_SQL_RELATION_EXPR => self.format_relation_expression(node),
2727 42 : NodeType::OBJECT_SQL_DESCRIPTOR => self.format_descriptor(node),
2728 108 : NodeType::OBJECT_SQL_INDIRECTION => self.format_indirection(node),
2729 135 : NodeType::OBJECT_SQL_ROW_TYPE => self.format_row_type(node),
2730 258 : NodeType::OBJECT_SQL_ROW_EXPRESSION => self.format_row_expression(node),
2731 126 : NodeType::OBJECT_SQL_ARRAY_EXPRESSION => self.format_array_expression(node),
2732 816 : NodeType::OBJECT_SQL_SELECT_EXPRESSION => self.format_select_expression(node),
2733 20560 : NodeType::OBJECT_SQL_RESULT_TARGET => self.format_result_target(node),
2734 1502 : NodeType::OBJECT_SQL_COLUMN_DEF => self.format_column_def(node),
2735 219 : NodeType::ENUM_SQL_TABLE_CONSTRAINT => self.format_table_constraint_type(node),
2736 219 : NodeType::OBJECT_SQL_TABLE_CONSTRAINT => self.format_table_constraint(node),
2737 12 : NodeType::ENUM_SQL_KEY_MATCH => self.format_key_match(node),
2738 21 : NodeType::ENUM_SQL_KEY_ACTION_COMMAND => self.format_key_action_command(node),
2739 21 : NodeType::ENUM_SQL_KEY_ACTION_TRIGGER => self.format_key_action_trigger(node),
2740 21 : NodeType::OBJECT_SQL_KEY_ACTION => self.format_key_action(node),
2741 816 : NodeType::ENUM_SQL_COLUMN_CONSTRAINT => self.format_column_constraint_type(node),
2742 816 : NodeType::OBJECT_SQL_COLUMN_CONSTRAINT => self.format_column_constraint(node),
2743 75 : NodeType::ENUM_SQL_CONSTRAINT_ATTRIBUTE => self.format_constraint_attribute(node),
2744 81 : NodeType::ENUM_SQL_EXTRACT_TARGET => self.format_extract_target(node),
2745 66 : NodeType::ENUM_SQL_TRIM_TARGET => self.format_trim_direction(node),
2746 312 : NodeType::OBJECT_SQL_GENERIC_OPTION => self.format_generic_option(node),
2747 108 : NodeType::OBJECT_SQL_ALIAS => self.format_alias(node),
2748 150 : NodeType::OBJECT_SQL_TYPECAST_EXPRESSION => self.format_typecast_expression(node),
2749 1248 : NodeType::OBJECT_SQL_CASE => self.format_case(node),
2750 1278 : NodeType::OBJECT_SQL_CASE_CLAUSE => self.format_case_clause(node),
2751 180 : NodeType::OBJECT_SQL_EXISTS_EXPRESSION => self.format_exists_expression(node),
2752 99 : NodeType::OBJECT_SQL_SUBQUERY_EXPRESSION => self.format_subquery_expression(node),
2753 99 : NodeType::ENUM_SQL_SUBQUERY_QUANTIFIER => self.format_subquery_quantifier(node),
2754 93 : NodeType::OBJECT_SQL_INDIRECTION_INDEX => self.format_indirection_index(node),
2755 18 : NodeType::OBJECT_SQL_TYPETEST_EXPRESSION => self.format_typetest_expression(node),
2756 60 : NodeType::OBJECT_SQL_ROWSFROM_ITEM => self.format_rows_from_item(node),
2757 30 : NodeType::OBJECT_SQL_BIT_TYPE => self.format_bit_type(node),
2758 12 : NodeType::OBJECT_SQL_DEF_ARG => self.format_definition_arg(node),
2759 846 : NodeType::OBJECT_SQL_CTE => self.format_cte(node),
2760 90 : NodeType::OBJECT_SQL_PROPERTY_GRAPH => self.format_property_graph(node),
2761 135 : NodeType::OBJECT_SQL_GRAPH_ELEMENT_TABLE => self.format_graph_element_table(node),
2762 96 : NodeType::OBJECT_SQL_GRAPH_VERTEX_REFERENCE => self.format_graph_vertex_reference(node),
2763 138 : NodeType::OBJECT_SQL_GRAPH_LABEL => self.format_graph_label(node),
2764 138 : NodeType::OBJECT_SQL_GRAPH_PROPERTIES => self.format_graph_properties(node),
2765 78 : NodeType::OBJECT_SQL_GRAPH_PROPERTY => self.format_graph_property(node),
2766 105 : NodeType::OBJECT_SQL_GRAPH_TABLE => self.format_graph_table(node),
2767 105 : NodeType::OBJECT_SQL_GRAPH_MATCH => self.format_graph_match(node),
2768 318 : NodeType::OBJECT_SQL_GRAPH_PATH_ELEMENT => self.format_graph_path_element(node),
2769 21 : NodeType::OBJECT_SQL_GRAPH_QUANTIFIER => self.format_graph_quantifier(node),
2770 288 : NodeType::OBJECT_SQL_GRAPH_LABEL_EXPRESSION => self.format_graph_label_expression(node),
2771 18 : NodeType::OBJECT_SQL_GRAPH_ROWS => self.format_graph_rows(node),
2772 8206 : NodeType::OBJECT_SQL_FUNCTION_EXPRESSION => self.format_function_expression(node),
2773 : NodeType::OBJECT_SQL_FUNCTION_CAST_ARGS
2774 : | NodeType::OBJECT_SQL_FUNCTION_EXTRACT_ARGS
2775 : | NodeType::OBJECT_SQL_FUNCTION_OVERLAY_ARGS
2776 : | NodeType::OBJECT_SQL_FUNCTION_POSITION_ARGS
2777 : | NodeType::OBJECT_SQL_FUNCTION_SUBSTRING_ARGS
2778 : | NodeType::OBJECT_SQL_FUNCTION_TREAT_ARGS
2779 1440 : | NodeType::OBJECT_SQL_FUNCTION_TRIM_ARGS => f.empty(),
2780 2175 : NodeType::ENUM_SQL_KNOWN_FUNCTION => f.empty(),
2781 150 : NodeType::OBJECT_SQL_FUNCTION_TABLE => self.format_function_table(node),
2782 438 : NodeType::OBJECT_SQL_WINDOW_FRAME => self.format_window_frame(node),
2783 222 : NodeType::OBJECT_SQL_WINDOW_BOUND => self.format_window_bound(node),
2784 222 : NodeType::ENUM_SQL_WINDOW_BOUND_MODE => self.format_window_bound_mode(node),
2785 138 : NodeType::ENUM_SQL_WINDOW_BOUND_DIRECTION => self.format_window_bound_direction(node),
2786 126 : NodeType::ENUM_SQL_WINDOW_RANGE_MODE => self.format_window_range_mode(node),
2787 6059 : NodeType::OBJECT_SQL_FUNCTION_ARG => self.format_function_arg(node),
2788 25 : NodeType::OBJECT_SQL_CONST_TYPE_CAST => self.format_const_type_cast(node),
2789 173 : NodeType::OBJECT_SQL_CONST_INTERVAL_CAST => self.format_const_interval_cast(node),
2790 343 : NodeType::OBJECT_SQL_CONST_FUNCTION_CAST => self.format_const_function_cast(node),
2791 27122 : NodeType::ENUM_SQL_EXPRESSION_OPERATOR => self.format_expression_operator_type(node),
2792 27155 : NodeType::OBJECT_SQL_NARY_EXPRESSION => self.format_expression(node_id),
2793 48 : NodeType::OBJECT_EXT_VARARG_ARRAY => self.format_vararg_array(node),
2794 : NodeType::LITERAL_NULL
2795 : | NodeType::LITERAL_INTEGER
2796 : | NodeType::LITERAL_FLOAT
2797 : | NodeType::LITERAL_STRING
2798 : | NodeType::LITERAL_INTERVAL
2799 : | NodeType::BOOL
2800 : | NodeType::OPERATOR
2801 128374 : | NodeType::NAME => self.format_leaf(node),
2802 0 : _ => self.format_unimplemented(node),
2803 : }
2804 462656 : }
2805 :
2806 5980 : fn build_docs(&mut self) {
2807 462656 : for node_id in 0..self.ast.len() {
2808 462656 : let reg = self.format_node(node_id);
2809 462656 : self.node_states[node_id].reg = reg;
2810 462656 : }
2811 5980 : }
2812 :
2813 : // -----------------------------------------------------------------------------------------
2814 : // Output
2815 : // -----------------------------------------------------------------------------------------
2816 :
2817 5980 : fn render_options(&self) -> FormattingRenderOptions {
2818 5980 : FormattingRenderOptions {
2819 5980 : max_width: self.config.max_width as usize,
2820 5980 : indentation_width: self.config.indentation_width as usize,
2821 5980 : debug_mode: self.config.debug_mode,
2822 5980 : mode: self.config.mode,
2823 5980 : keyword_case: self.config.keyword_case,
2824 5980 : }
2825 5980 : }
2826 :
2827 374 : fn render(&self, reg: FmtReg) -> String {
2828 374 : self.fmt.render(reg, &self.render_options())
2829 374 : }
2830 :
2831 : /// The parts of the script in text order.
2832 : ///
2833 : /// The parser recovers from syntax errors by dropping the broken statement or by keeping a partial one.
2834 : /// Formatting these would silently remove or truncate what the user wrote, so every statement (the text up
2835 : /// to the next semicolon) with a scanner or parser error is copied as written.
2836 5606 : fn output_parts(&self) -> Vec<OutputPart> {
2837 : use dashql_parser::symbol_kind::{S_SEMICOLON, S_YYEOF};
2838 5606 : let symbols = &self.scanned.symbols;
2839 5606 : let statements = &self.parsed.statements;
2840 5606 : let mut parts = Vec::with_capacity(statements.len());
2841 :
2842 : // The symbol index ranges of the statements, each ends with a semicolon
2843 5606 : let mut chunks: Vec<(usize, usize)> = Vec::new();
2844 5606 : let mut begin = 0;
2845 315485 : for (i, symbol) in symbols.iter().enumerate() {
2846 315485 : if symbol.kind == S_SEMICOLON || symbol.kind == S_YYEOF {
2847 8429 : if i > begin || symbol.kind == S_SEMICOLON {
2848 5851 : chunks.push((begin, if symbol.kind == S_SEMICOLON { i + 1 } else { i }));
2849 2578 : }
2850 8429 : begin = i + 1;
2851 307056 : }
2852 : }
2853 5606 : let chunk_of_symbol = |symbol: usize| chunks.iter().position(|&(b, e)| symbol >= b && symbol < e);
2854 5606 : let mut damaged = vec![false; chunks.len()];
2855 5606 : for error in &self.parsed.errors {
2856 30 : let symbol = (error.location.offset() as usize).min(symbols.len().saturating_sub(1));
2857 30 : if let Some(chunk) = chunk_of_symbol(symbol).or(chunks.len().checked_sub(1)) {
2858 30 : damaged[chunk] = true;
2859 30 : }
2860 : }
2861 5606 : for error in &self.scanned.errors {
2862 3 : let offset = error.location.offset;
2863 12 : let symbol = symbols.partition_point(|s| s.location.end() <= offset);
2864 3 : if let Some(chunk) = chunk_of_symbol(symbol).or(chunks.len().checked_sub(1)) {
2865 3 : damaged[chunk] = true;
2866 3 : }
2867 : }
2868 :
2869 5606 : let mut next_statement = 0;
2870 5851 : for (chunk, &(begin, end)) in chunks.iter().enumerate() {
2871 5851 : let chunk_symbols = &symbols[begin..end];
2872 5851 : let begin_offset = chunk_symbols.first().map_or(0, |s| s.location.offset);
2873 : // The last statement may end in text that the scanner dropped, like an unterminated string
2874 5851 : let end_offset = match chunk_symbols.last() {
2875 5851 : Some(last) if last.kind == S_SEMICOLON => last.location.end(),
2876 3028 : _ => self.scanned.text.trim_end().len() as u32,
2877 : };
2878 5851 : let mut in_chunk = Vec::new();
2879 11672 : while next_statement < statements.len() {
2880 6060 : let root = self.ast[statements[next_statement].root as usize];
2881 6060 : let root_offset = resolve_text_span(&self.scanned.text, symbols, *root.symbol_span()).offset;
2882 6060 : if root_offset >= end_offset {
2883 239 : break;
2884 5821 : }
2885 5821 : in_chunk.push(next_statement);
2886 5821 : next_statement += 1;
2887 : }
2888 5851 : let only_separator = chunk_symbols.len() == 1 && chunk_symbols[0].kind == S_SEMICOLON;
2889 5851 : if !damaged[chunk] && (!in_chunk.is_empty() || only_separator) {
2890 5815 : parts.extend(in_chunk.into_iter().map(OutputPart::Statement));
2891 5815 : } else if !only_separator {
2892 36 : parts.push(OutputPart::Damaged(TextSpan::new(begin_offset, end_offset - begin_offset)));
2893 36 : }
2894 : }
2895 5606 : parts
2896 5606 : }
2897 :
2898 5606 : fn write_output(&self) -> Vec<u8> {
2899 5606 : let options = self.render_options();
2900 5606 : let statements = &self.parsed.statements;
2901 5606 : let parts = self.output_parts();
2902 5606 : let mut output: Vec<u8> = Vec::with_capacity(self.estimate_formatted_size());
2903 :
2904 5606 : if self.config.debug_mode {
2905 0 : output.extend_from_slice(
2906 0 : format!("/* indentation={}, max_width={} */\n", self.config.indentation_width, self.config.max_width)
2907 0 : .as_bytes(),
2908 0 : );
2909 5606 : }
2910 :
2911 5606 : let input = self.scanned.text.as_bytes();
2912 5606 : let damaged_text = |span: &TextSpan| &input[span.offset as usize..span.end() as usize];
2913 5822 : if parts.iter().any(|p| matches!(p, OutputPart::Damaged(_))) {
2914 30 : self.copied_damaged_text.set(true);
2915 5576 : }
2916 :
2917 5606 : if self.config.mode == FormattingMode::INLINE {
2918 1958 : for (i, part) in parts.iter().enumerate() {
2919 1958 : match part {
2920 1944 : OutputPart::Statement(statement) => {
2921 1944 : let root = statements[*statement].root as usize;
2922 1944 : output.extend_from_slice(self.fmt.render(self.node_states[root].reg, &options).as_bytes());
2923 1944 : output.push(b';');
2924 1944 : }
2925 14 : OutputPart::Damaged(span) => output.extend_from_slice(damaged_text(span)),
2926 : }
2927 1958 : if i + 1 < parts.len() {
2928 85 : output.extend_from_slice(b"\n\n");
2929 1873 : }
2930 : }
2931 1873 : return output;
2932 3733 : }
2933 :
2934 3733 : let comments = &self.scanned.comments[..];
2935 3733 : let max_width = self.config.max_width as usize;
2936 3733 : let descriptions = self.parsed.associate_descriptions();
2937 4041 : let ensure_line_break = |output: &mut Vec<u8>| {
2938 4041 : if !output.is_empty() && output.last() != Some(&b'\n') {
2939 319 : output.push(b'\n');
2940 3723 : }
2941 4041 : };
2942 3733 : let mut comment_begin = 0;
2943 3887 : for (i, part) in parts.iter().enumerate() {
2944 3887 : if i > 0 {
2945 154 : ensure_line_break(&mut output);
2946 154 : output.push(b'\n');
2947 3733 : }
2948 3887 : let statement = match part {
2949 3865 : OutputPart::Statement(statement) => *statement,
2950 22 : OutputPart::Damaged(span) => {
2951 : // Comments inside the damaged text are part of it
2952 22 : let mut before_end = comment_begin;
2953 25 : while before_end < comments.len() && comments[before_end].offset < span.offset {
2954 3 : before_end += 1;
2955 3 : }
2956 22 : comments::append_comments(
2957 22 : &mut output,
2958 22 : input,
2959 22 : &comments[comment_begin..before_end],
2960 22 : max_width,
2961 22 : Some(span.offset as usize),
2962 : );
2963 22 : ensure_line_break(&mut output);
2964 22 : output.extend_from_slice(damaged_text(span));
2965 22 : comment_begin = before_end;
2966 25 : while comment_begin < comments.len() && comments[comment_begin].offset < span.end() {
2967 3 : comment_begin += 1;
2968 3 : }
2969 22 : continue;
2970 : }
2971 : };
2972 3865 : let root = statements[statement].root as usize;
2973 3865 : let description = &descriptions[statement];
2974 3865 : let root_span = resolve_text_span(&self.scanned.text, &self.scanned.symbols, *self.ast[root].symbol_span());
2975 3865 : let mut before_end = comment_begin;
2976 4323 : while before_end < comments.len() && comments[before_end].offset < root_span.offset {
2977 458 : before_end += 1;
2978 458 : }
2979 3865 : let description_begin = description.description_begin as usize;
2980 3865 : if description.description_count > 0 && description_begin >= comment_begin {
2981 169 : let leading_end = description_begin + description.description_count as usize;
2982 169 : comments::append_comments(
2983 169 : &mut output,
2984 169 : input,
2985 169 : &comments[comment_begin..description_begin],
2986 169 : max_width,
2987 169 : Some(comments[description_begin].offset as usize),
2988 169 : );
2989 169 : comments::append_description(
2990 169 : &mut output,
2991 169 : input,
2992 169 : &comments[description_begin..leading_end],
2993 169 : max_width,
2994 169 : Some(root_span.offset as usize),
2995 169 : );
2996 3696 : } else {
2997 3696 : comments::append_comments(
2998 3696 : &mut output,
2999 3696 : input,
3000 3696 : &comments[comment_begin..before_end],
3001 3696 : max_width,
3002 3696 : Some(root_span.offset as usize),
3003 3696 : );
3004 3696 : }
3005 :
3006 3865 : ensure_line_break(&mut output);
3007 3865 : output.extend_from_slice(self.fmt.render(self.node_states[root].reg, &options).as_bytes());
3008 3865 : output.push(b';');
3009 :
3010 3865 : let statement_end = description.source_span.end() as usize;
3011 3865 : let mut within_end = before_end;
3012 3906 : while within_end < comments.len() && (comments[within_end].offset as usize) < statement_end {
3013 41 : within_end += 1;
3014 41 : }
3015 3865 : comments::append_comments(&mut output, input, &comments[before_end..within_end], max_width, None);
3016 3865 : comment_begin = within_end;
3017 : }
3018 3733 : comments::append_comments(&mut output, input, &comments[comment_begin..], max_width, None);
3019 3733 : output
3020 5606 : }
3021 : }
3022 :
3023 : /// The formatted output as a string. Wrapped comments may split UTF-8 sequences, they are replaced
3024 : /// with U+FFFD.
3025 5598 : fn bytes_to_string(bytes: Vec<u8>) -> String {
3026 5598 : match String::from_utf8(bytes) {
3027 5598 : Ok(text) => text,
3028 0 : Err(e) => String::from_utf8_lossy(e.as_bytes()).into_owned(),
3029 : }
3030 5598 : }
3031 :
3032 : #[cfg(test)]
3033 : mod tests {
3034 : use super::*;
3035 : use dashql_parser::parser::parse;
3036 : use dashql_parser::scanner::scan;
3037 : use std::sync::Arc;
3038 :
3039 7 : fn format(text: &str, mode: FormattingMode, max_width: u32) -> (String, Vec<u32>) {
3040 7 : let parsed = parse(Arc::new(scan(text, 0, 2)));
3041 7 : let mut formatter = Formatter::new(&parsed);
3042 7 : let mut config = FormattingConfigT::default();
3043 7 : config.mode = mode;
3044 7 : config.max_width = max_width;
3045 7 : config.indentation_width = 2;
3046 7 : let out = formatter.format(&config);
3047 7 : (out, formatter.unformattable_nodes())
3048 7 : }
3049 :
3050 : #[test]
3051 1 : fn formats_select() {
3052 1 : let (out, unformattable) = format("SELECT a,b FROM t WHERE a=1 AND b", FormattingMode::COMPACT, 120);
3053 1 : assert_eq!(out, "select a, b from t where a = 1 and b;");
3054 1 : assert!(unformattable.is_empty());
3055 1 : let (out, _) = format("select a, b from t where a = 1", FormattingMode::PRETTY, 120);
3056 1 : assert_eq!(out, "select a, b\nfrom t\nwhere a = 1;");
3057 1 : }
3058 :
3059 : #[test]
3060 1 : fn adds_parentheses_by_precedence() {
3061 1 : let (out, _) = format("select (1 + 2) * 3, 1 + 2 * 3, (a or b) and c", FormattingMode::INLINE, 120);
3062 1 : assert_eq!(out, "select (1 + 2) * 3, 1 + 2 * 3, (a or b) and c;");
3063 1 : }
3064 :
3065 : #[test]
3066 1 : fn copies_statements_with_syntax_errors() {
3067 1 : let (out, unformattable) = format("select 1; selec 1; select 2", FormattingMode::INLINE, 120);
3068 1 : assert_eq!(out, "select 1;\n\nselec 1;\n\nselect 2;");
3069 1 : assert!(unformattable.is_empty());
3070 : // Comments inside the copied text stay, the comments around it are formatted
3071 1 : let (out, _) = format("-- a\nselect from /* b */ from;\n-- c\nselect 2", FormattingMode::COMPACT, 120);
3072 1 : assert_eq!(out, "-- a\nselect from /* b */ from;\n\n-- c\nselect 2;");
3073 : // A script that is nothing but an error is copied
3074 1 : assert_eq!(format("select from where", FormattingMode::PRETTY, 120).0, "select from where");
3075 1 : }
3076 :
3077 : #[test]
3078 1 : fn keeps_comments() {
3079 1 : let (out, _) = format("-- head\nselect 1; -- tail\nselect 2", FormattingMode::COMPACT, 120);
3080 1 : assert_eq!(out, "-- head\nselect 1;\n-- tail\n\nselect 2;");
3081 1 : }
3082 :
3083 : #[test]
3084 1 : fn records_unformattable_nodes() {
3085 : // CREATE TABLE is only formatted as statement root, format_node_at does not mark the roots
3086 1 : let parsed = parse(Arc::new(scan("create table t (a int)", 0, 2)));
3087 1 : let root = parsed.statements[0].root as usize;
3088 1 : let mut formatter = Formatter::new(&parsed);
3089 1 : let mut config = FormattingConfigT::default();
3090 1 : config.mode = FormattingMode::INLINE;
3091 1 : assert_eq!(formatter.format(&config), "create table t (a integer);");
3092 1 : assert!(formatter.is_fully_formatted());
3093 1 : assert_eq!(formatter.format_node_at(root, &config), "'<OBJECT_SQL_CREATE>'");
3094 1 : assert_eq!(formatter.unformattable_nodes(), vec![root as u32]);
3095 1 : assert_eq!(formatter.format_node_at(parsed.nodes.len(), &config), "");
3096 1 : }
3097 :
3098 : #[test]
3099 1 : fn looks_up_attributes_like_cxx() {
3100 3 : let node = |key: AttributeKey| Node::new(&SymbolSpan::default(), NodeType::NAME, key, 3, 0, 0);
3101 1 : let nodes = vec![
3102 1 : node(K::SQL_ALIAS_NAME),
3103 1 : node(K::SQL_ALIAS_NAME),
3104 1 : node(K::SQL_ALIAS_COLUMN_NAMES),
3105 1 : Node::new(&SymbolSpan::default(), NodeType::OBJECT_SQL_ALIAS, K::NONE, u32::MAX, 0, 3),
3106 : ];
3107 1 : let mut parsed = parse(Arc::new(scan("", 0, 2)));
3108 1 : parsed.nodes = nodes;
3109 1 : parsed.statements.clear();
3110 1 : let formatter = Formatter::new(&parsed);
3111 1 : let object = &parsed.nodes[3];
3112 : // One key: the first match, several keys: the last match
3113 1 : let [first] = formatter.attrs(object, [K::SQL_ALIAS_NAME]);
3114 1 : assert_eq!(formatter.node_id(first.unwrap()), 0);
3115 1 : let [last, columns, missing] =
3116 1 : formatter.attrs(object, [K::SQL_ALIAS_NAME, K::SQL_ALIAS_COLUMN_NAMES, K::SQL_ALIAS_COLUMN_DEFS]);
3117 1 : assert_eq!(formatter.node_id(last.unwrap()), 1);
3118 1 : assert_eq!(formatter.node_id(columns.unwrap()), 2);
3119 1 : assert!(missing.is_none());
3120 1 : }
3121 : }
|