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