Line data Source code
1 : //! The analyzer types.
2 : //!
3 : //! Every object lives in an arena of the analyzed script and is referenced by its index.
4 :
5 : use crate::catalog::*;
6 : use dashql_buffers::algebra::{BinaryExpressionFunction, ComparisonFunction, LiteralType};
7 : use dashql_buffers::analyzer::{AnalyzerErrorSeverity, AnalyzerErrorType};
8 : use dashql_buffers::parser::{IntervalType as IntervalTypeEnum, KnownFunction, SymbolSpan};
9 : use dashql_parser::span::TextSpan;
10 : use crate::hash::HashMap;
11 : use std::sync::Arc;
12 :
13 : /// An expression id (index into the expressions)
14 : pub type ExprId = u32;
15 : /// A name scope id (index into the name scopes)
16 : pub type ScopeId = u32;
17 : /// A table reference id (index into the table references)
18 : pub type TableRefId = u32;
19 :
20 : /// A map that iterates in insertion order and never overwrites
21 : #[derive(Clone, Debug)]
22 : pub struct OrderedMap<V> {
23 : /// The keys and values in insertion order
24 : entries: Vec<(Arc<str>, V)>,
25 : /// The index of every key in the entries
26 : index: HashMap<Arc<str>, usize>,
27 : }
28 :
29 : impl<V> Default for OrderedMap<V> {
30 5595 : fn default() -> Self {
31 5595 : Self {
32 5595 : entries: Vec::new(),
33 5595 : index: HashMap::default(),
34 5595 : }
35 5595 : }
36 : }
37 :
38 : impl<V> OrderedMap<V> {
39 2808 : pub fn get_index(&self, key: &str) -> Option<usize> {
40 2808 : self.index.get(key).copied()
41 2808 : }
42 352 : pub fn at(&self, i: usize) -> &V {
43 352 : &self.entries[i].1
44 352 : }
45 : /// Insert a value unless the key exists. Returns the index of the key.
46 134 : pub fn insert(&mut self, key: Arc<str>, value: V) -> usize {
47 134 : if let Some(&i) = self.index.get(&key) {
48 0 : return i;
49 134 : }
50 134 : self.entries.push((key.clone(), value));
51 134 : self.index.insert(key, self.entries.len() - 1);
52 134 : self.entries.len() - 1
53 134 : }
54 388 : pub fn iter(&self) -> impl Iterator<Item = (&Arc<str>, &V)> {
55 388 : self.entries.iter().map(|(k, v)| (k, v))
56 388 : }
57 : }
58 :
59 : /// An analyzer error
60 : #[derive(Clone, Debug, PartialEq)]
61 : pub struct AnalyzerError {
62 : /// The error type
63 : pub error_type: AnalyzerErrorType,
64 : /// The error severity
65 : pub severity: AnalyzerErrorSeverity,
66 : /// The AST node id of the error location, None if there is none
67 : pub ast_node_id: Option<u32>,
68 : /// The symbol span of the AST node
69 : pub symbol_span: Option<SymbolSpan>,
70 : /// The location in the script text
71 : pub text_span: Option<TextSpan>,
72 : /// The error message
73 : pub message: String,
74 : }
75 :
76 : /// Whether a table reference reads or writes
77 : #[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
78 : pub enum TableRole {
79 : #[default]
80 : Read,
81 : Write,
82 : }
83 :
84 : /// A resolved table
85 : #[derive(Clone, Debug)]
86 : pub struct ResolvedTableEntry {
87 : /// The table name, may refer to a different catalog entry
88 : pub table_name: QualifiedTableName,
89 : /// The catalog id of the schema
90 : pub catalog_schema_id: QualifiedCatalogObjectId,
91 : /// The catalog id of the table
92 : pub catalog_table_id: QualifiedCatalogObjectId,
93 : /// The catalog version of the resolved table
94 : pub referenced_catalog_version: CatalogVersion,
95 : }
96 :
97 : /// A relation expression
98 : #[derive(Clone, Debug)]
99 : pub struct RelationExpression {
100 : /// The table name as written in the script
101 : pub table_name: QualifiedTableName,
102 : /// The resolved table, None if the name was not found
103 : pub resolved_table: Option<ResolvedTableEntry>,
104 : /// The ambiguous matches
105 : pub resolved_alternatives: Vec<ResolvedTableEntry>,
106 : }
107 :
108 : /// A table reference
109 : #[derive(Clone, Debug)]
110 : pub struct TableReference {
111 : /// The table reference id
112 : pub table_reference_id: ExternalObjectId,
113 : /// The AST node id of the table ref
114 : pub ast_node_id: u32,
115 : /// The location in the script
116 : pub location: Option<SymbolSpan>,
117 : /// The AST statement id
118 : pub ast_statement_id: Option<u32>,
119 : /// The AST node id of the root of the enclosing name scope
120 : pub ast_scope_root: Option<u32>,
121 : /// The alias name and its location
122 : pub alias: Option<(Name, SymbolSpan)>,
123 : /// The column names of the alias, they rename the leading columns of the table
124 : pub column_aliases: Vec<Name>,
125 : /// The referenced relation, None if the table ref has no table name
126 : pub inner: Option<RelationExpression>,
127 : /// Whether the reference reads or writes the table
128 : pub role: TableRole,
129 : }
130 :
131 : impl TableReference {
132 : /// Does the table reference read the result of a script, a table parameter `:foo`? The planner reads it through
133 : /// the script references, not as a relation.
134 3899 : pub fn reads_table_parameter(&self) -> bool {
135 3899 : self.inner
136 3899 : .as_ref()
137 3899 : .and_then(|r| r.resolved_table.as_ref())
138 3899 : .is_some_and(|t| t.catalog_table_id.unpack_table_id().origin == crate::table_parameters::TABLE_PARAMETERS_ENTRY_ID)
139 3899 : }
140 : }
141 :
142 : /// An explicit INSERT target column
143 : #[derive(Clone, Debug)]
144 : pub struct InsertTargetColumn {
145 : /// The AST node id of the column name
146 : pub ast_node_id: u32,
147 : /// The column name
148 : pub column_name: Name,
149 : /// The resolved column of the target table
150 : pub resolved: Option<ColumnLoc>,
151 : }
152 :
153 : /// An INSERT statement
154 : #[derive(Clone, Debug)]
155 : pub struct InsertStatement {
156 : /// The AST node id of the INSERT
157 : pub ast_node_id: u32,
158 : /// The AST statement id
159 : pub ast_statement_id: Option<u32>,
160 : /// The table reference of the target table
161 : pub target: TableRefId,
162 : /// The AST node id of the source query
163 : pub source_ast_node_id: Option<u32>,
164 : /// Whether the statement inserts DEFAULT VALUES
165 : pub default_values: bool,
166 : /// Whether the statement has a RETURNING clause
167 : pub returning: bool,
168 : /// The explicit target columns
169 : pub target_columns: Vec<InsertTargetColumn>,
170 : }
171 :
172 : /// The confidence of a schema inference
173 : #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
174 : pub enum InferenceConfidence {
175 : #[default]
176 : None = 0,
177 : Candidate = 1,
178 : Confident = 2,
179 : }
180 :
181 : /// The inferred owner of an unresolved column
182 : #[derive(Clone, Debug)]
183 : pub struct InferredOwner {
184 : /// The unresolved table reference that owns the column
185 : pub table_ref: TableRefId,
186 : /// The (un-normalized) table name of the owner
187 : pub table_name: QualifiedTableName,
188 : /// The confidence of the assignment
189 : pub confidence: InferenceConfidence,
190 : }
191 :
192 : /// What a column reference resolved to
193 : #[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
194 : pub enum ColumnResolution {
195 : #[default]
196 : Unresolved,
197 : /// A catalog table column
198 : TableColumn(ColumnLoc),
199 : /// An output column of a scope
200 : ScopeColumn { scope: ScopeId, column: u32 },
201 : }
202 :
203 : impl ColumnResolution {
204 17990 : pub fn is_resolved(&self) -> bool {
205 17990 : !matches!(self, ColumnResolution::Unresolved)
206 17990 : }
207 : }
208 :
209 : /// The catalog ids of a resolved column
210 : #[derive(Clone, Copy, Debug, PartialEq, Eq)]
211 : pub struct ResolvedColumnIds {
212 : /// The catalog id of the schema
213 : pub catalog_schema_id: QualifiedCatalogObjectId,
214 : /// The catalog id of the table column
215 : pub catalog_table_column_id: QualifiedCatalogObjectId,
216 : /// The catalog version of the table
217 : pub referenced_catalog_version: CatalogVersion,
218 : }
219 :
220 : /// A column reference
221 : #[derive(Clone, Debug)]
222 : pub struct ColumnRef {
223 : /// The qualified column name as written in the script
224 : pub column_name: QualifiedColumnName,
225 : /// The AST node id of the root of the enclosing name scope
226 : pub ast_scope_root: Option<u32>,
227 : /// What the column ref resolved to
228 : pub resolved: ColumnResolution,
229 : /// The catalog ids behind the resolution, computed once the analysis is done
230 : /// (scope columns are followed through their source expressions)
231 : pub resolved_ids: Option<ResolvedColumnIds>,
232 : /// The inferred owner of a column that stays unresolved, set by the schema inference
233 : pub inferred: Option<InferredOwner>,
234 : }
235 :
236 : /// A literal
237 : #[derive(Clone, Debug)]
238 : pub struct Literal {
239 : /// The literal type
240 : pub literal_type: LiteralType,
241 : /// The raw value in the script text
242 : pub raw_value: TextSpan,
243 : }
244 :
245 : /// A comparison
246 : #[derive(Clone, Copy, Debug)]
247 : pub struct Comparison {
248 : /// The comparison function
249 : pub func: ComparisonFunction,
250 : /// The expression id of the left child
251 : pub left_expression_id: u32,
252 : /// The expression id of the right child
253 : pub right_expression_id: u32,
254 : }
255 :
256 : /// A binary expression
257 : #[derive(Clone, Copy, Debug)]
258 : pub struct BinaryExpression {
259 : /// The binary expression function
260 : pub func: BinaryExpressionFunction,
261 : /// The expression id of the left child
262 : pub left_expression_id: u32,
263 : /// The expression id of the right child
264 : pub right_expression_id: u32,
265 : }
266 :
267 : /// A function argument
268 : #[derive(Clone, Debug)]
269 : pub struct FunctionArgument {
270 : /// The AST node id of the argument
271 : pub ast_node_id: u32,
272 : /// The AST node id of the argument value
273 : pub value_ast_node_id: u32,
274 : /// The argument name, if the argument is named
275 : pub name: Option<Name>,
276 : /// The expression id, `Some(0)` by default
277 : pub expression_id: Option<u32>,
278 : }
279 :
280 : impl Default for FunctionArgument {
281 166 : fn default() -> Self {
282 166 : Self {
283 166 : ast_node_id: 0,
284 166 : value_ast_node_id: 0,
285 166 : name: None,
286 166 : expression_id: Some(0),
287 166 : }
288 166 : }
289 : }
290 :
291 : /// The name of a called function
292 : #[derive(Clone, Debug)]
293 : pub enum FunctionName {
294 : Known(KnownFunction),
295 : Qualified(QualifiedFunctionName),
296 : }
297 :
298 : /// The arguments of a function call
299 : #[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
300 : pub enum FunctionArguments {
301 : #[default]
302 : None,
303 : /// A slice of the function arguments of the script
304 : Generic { begin: u32, count: u32 },
305 : }
306 :
307 : /// A function call
308 : #[derive(Clone, Debug)]
309 : pub struct FunctionCall {
310 : /// The function name
311 : pub function_name: FunctionName,
312 : /// The `FunctionCallModifier` bits (star, ALL, DISTINCT, VARIADIC, OVER, WITHIN GROUP)
313 : pub function_call_modifiers: u8,
314 : /// The arguments
315 : pub arguments: FunctionArguments,
316 : }
317 :
318 : /// An interval type
319 : #[derive(Clone, Copy, Debug)]
320 : pub struct IntervalType {
321 : /// The interval type
322 : pub interval_type: IntervalTypeEnum,
323 : /// The expression id of the interval precision, if any
324 : pub precision_expression: Option<i32>,
325 : }
326 :
327 : /// A constant interval cast
328 : #[derive(Clone, Copy, Debug)]
329 : pub struct ConstIntervalCast {
330 : /// The expression id of the value
331 : pub value_expression_id: u32,
332 : /// The interval type, if not in the value text
333 : pub interval: Option<IntervalType>,
334 : }
335 :
336 : /// The kind of an expression
337 : #[derive(Clone, Debug, Default)]
338 : pub enum ExpressionInner {
339 : #[default]
340 : None,
341 : ColumnRef(ColumnRef),
342 : Literal(Literal),
343 : Comparison(Comparison),
344 : BinaryExpression(BinaryExpression),
345 : FunctionCall(FunctionCall),
346 : ConstIntervalCast(ConstIntervalCast),
347 : }
348 :
349 : /// An expression
350 : #[derive(Clone, Debug)]
351 : pub struct Expression {
352 : /// The expression id (index into the expressions)
353 : pub expression_id: u32,
354 : /// The AST node id
355 : pub ast_node_id: u32,
356 : /// The location in the script
357 : pub location: Option<SymbolSpan>,
358 : /// The AST statement id
359 : pub ast_statement_id: Option<u32>,
360 : /// The kind of the expression
361 : pub inner: ExpressionInner,
362 : /// Whether the expression is constant
363 : pub is_constant_expression: bool,
364 : }
365 :
366 : impl Expression {
367 24941 : pub fn column_ref(&self) -> Option<&ColumnRef> {
368 24941 : match &self.inner {
369 21606 : ExpressionInner::ColumnRef(c) => Some(c),
370 3335 : _ => None,
371 : }
372 24941 : }
373 7693 : pub fn column_ref_mut(&mut self) -> Option<&mut ColumnRef> {
374 7693 : match &mut self.inner {
375 7693 : ExpressionInner::ColumnRef(c) => Some(c),
376 0 : _ => None,
377 : }
378 7693 : }
379 : }
380 :
381 : /// A result target
382 : #[derive(Clone, Debug, Default)]
383 : pub struct ResultTarget {
384 : /// The AST node id
385 : pub ast_node_id: u32,
386 : /// The output column name, the alias or the name of a column ref
387 : pub column_name: Option<Name>,
388 : /// The expression id, if not a star
389 : pub expression_id: Option<u32>,
390 : /// Whether the target is a star
391 : pub is_star: bool,
392 : /// The source name of a qualified star (`t.*`)
393 : pub star_qualifier: Option<Name>,
394 : }
395 :
396 : /// The source of a scope output column
397 : #[derive(Clone, Copy, Debug, PartialEq, Eq)]
398 : pub enum ScopeColumnSource {
399 : Expression(ExprId),
400 : TableColumn(ColumnLoc),
401 : /// A computed column that has no expression of the analyzer
402 : Computed,
403 : }
404 :
405 : /// An output column of a scope
406 : #[derive(Clone, Debug)]
407 : pub struct ScopeColumn {
408 : /// The column name
409 : pub column_name: Name,
410 : /// The source of the column values
411 : pub source: ScopeColumnSource,
412 : }
413 :
414 : /// A CTE definition in the AST
415 : #[derive(Clone, Debug)]
416 : pub struct CteDefinition {
417 : /// The CTE name
418 : pub cte_name: Name,
419 : /// The AST node id of the CTE statement
420 : pub select_node_id: u32,
421 : /// The AST node id of the column alias array, if there is one
422 : pub columns_node_id: Option<u32>,
423 : /// The number of column aliases
424 : pub columns_count: u16,
425 : /// The AST node id of the CTE definition
426 : pub ast_node_id: u32,
427 : }
428 :
429 : /// A CTE attached to a scope
430 : #[derive(Clone, Debug)]
431 : pub struct ResolvedCte {
432 : /// The CTE name
433 : pub cte_name: Name,
434 : /// The scope of the CTE statement
435 : pub child_scope: Option<ScopeId>,
436 : /// The AST node id of the CTE definition
437 : pub definition_node_id: u32,
438 : /// The column aliases, they rename the leading output columns of the statement
439 : pub column_aliases: Vec<Name>,
440 : }
441 :
442 : /// A CTE location: the scope that defines it and its index in the CTEs of that scope
443 : #[derive(Clone, Copy, Debug, PartialEq, Eq)]
444 : pub struct CteLoc {
445 : /// The scope that defines the CTE
446 : pub scope: ScopeId,
447 : /// The index in the CTEs of that scope
448 : pub index: u32,
449 : }
450 :
451 : /// An unresolved table in scope
452 : #[derive(Clone, Debug)]
453 : pub struct UnresolvedRelation {
454 : /// The table reference that introduced the relation
455 : pub table_ref: TableRefId,
456 : /// The (un-normalized) table name, the identity for schema inference
457 : pub table_name: QualifiedTableName,
458 : }
459 :
460 : /// A table-like source in scope
461 : #[derive(Clone, Debug)]
462 : pub enum ReferencedTable {
463 : Table(TableLoc),
464 : Cte(CteLoc),
465 : /// A derived table, the output columns of a child scope
466 : Subquery(ScopeId),
467 : Unresolved(UnresolvedRelation),
468 : }
469 :
470 : impl ReferencedTable {
471 7 : pub fn is_unresolved_relation(&self) -> bool {
472 7 : matches!(self, ReferencedTable::Unresolved(_))
473 7 : }
474 : }
475 :
476 : /// A FROM item of a scope
477 : #[derive(Clone, Debug)]
478 : pub struct ScopeSource {
479 : /// The table ref node
480 : pub ast_node_id: u32,
481 : /// The alias or the table name, an unaliased derived table has no name
482 : pub name: Option<Arc<str>>,
483 : /// The column names of the alias, they rename the leading columns of the source
484 : pub column_aliases: Vec<Name>,
485 : /// The table-like source
486 : pub table: ReferencedTable,
487 : }
488 :
489 : /// The FROM items of a scope that column refs can see
490 : #[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
491 : pub enum SourceVisibility {
492 : #[default]
493 : All,
494 : /// The FROM items before a table ref node, a lateral derived table sees those of its parent
495 : Before(u32),
496 : /// Derived tables and CTEs see no FROM items of their parent, but those of the scopes above it
497 : None,
498 : }
499 :
500 : impl SourceVisibility {
501 4208 : pub fn sees(self, source: &ScopeSource) -> bool {
502 4208 : self.sees_node(source.ast_node_id)
503 4208 : }
504 :
505 : /// Whether the FROM item with an AST node id is visible
506 4484 : pub fn sees_node(self, ast_node_id: u32) -> bool {
507 4484 : match self {
508 4383 : SourceVisibility::All => true,
509 18 : SourceVisibility::Before(node_id) => ast_node_id < node_id,
510 83 : SourceVisibility::None => false,
511 : }
512 4484 : }
513 : }
514 :
515 : /// A naming scope
516 : #[derive(Clone, Debug, Default)]
517 : pub struct NameScope {
518 : /// The scope id (index into the name scopes)
519 : pub name_scope_id: u32,
520 : /// The AST node id of the scope root
521 : pub ast_node_id: u32,
522 : /// The AST statement id, None outside of statements
523 : pub ast_statement_id: Option<u32>,
524 : /// The parent scope, None for a root scope
525 : pub parent_scope: Option<ScopeId>,
526 : /// The child scopes
527 : pub child_scopes: Vec<ScopeId>,
528 : /// The column references of the scope
529 : pub expressions: Vec<ExprId>,
530 : /// The table references of the scope
531 : pub table_references: Vec<TableRefId>,
532 : /// The result targets of the scope
533 : pub result_targets: Vec<ResultTarget>,
534 : /// The output columns in order, for positional column aliases
535 : pub output_columns: Vec<ScopeColumn>,
536 : /// The output columns by name (index into the output columns)
537 : pub output_columns_by_name: HashMap<Arc<str>, usize>,
538 : /// The CTEs attached to the scope by name, in declaration order
539 : pub cte_definitions: OrderedMap<ResolvedCte>,
540 : /// The AST node ids of the CTE definitions by name
541 : pub cte_definition_nodes: HashMap<Arc<str>, u32>,
542 : /// Whether the WITH clause of the scope is recursive
543 : pub ctes_recursive: bool,
544 : /// Column refs cannot correlate with any parent scope
545 : pub column_correlation_barrier: bool,
546 : /// The FROM items of the parent scope that the column refs of this scope can see
547 : pub parent_visibility: SourceVisibility,
548 : /// The FROM items in FROM order
549 : pub sources: Vec<ScopeSource>,
550 : }
551 :
552 : impl NameScope {
553 : /// The FROM item with a name
554 2683 : pub fn source(&self, name: &str) -> Option<&ScopeSource> {
555 2686 : self.sources.iter().find(|s| s.name.as_deref() == Some(name))
556 2683 : }
557 : }
558 :
559 : /// A candidate owner of an inference constraint
560 : #[derive(Clone, Debug)]
561 : pub struct InferenceCandidate {
562 : /// The (un-normalized) table name, the identity in the solver
563 : pub table_name: QualifiedTableName,
564 : /// The unresolved table reference
565 : pub table_ref: TableRefId,
566 : }
567 :
568 : /// The kind of an inference constraint
569 : #[derive(Clone, Copy, Debug, PartialEq, Eq)]
570 : pub enum InferenceConstraintKind {
571 : Forced,
572 : Disjunctive,
573 : }
574 :
575 : /// A schema-inference constraint
576 : #[derive(Clone, Debug)]
577 : pub struct InferenceConstraint {
578 : /// The kind of the constraint
579 : pub kind: InferenceConstraintKind,
580 : /// The column ref expression the constraint was derived from
581 : pub expression_id: u32,
582 : /// The column name that must be owned
583 : pub column_name: Name,
584 : /// The candidate owner tables, one for a forced constraint
585 : pub candidates: Vec<InferenceCandidate>,
586 : }
587 :
588 : /// An inferred column of an unresolved table
589 : #[derive(Clone, Debug)]
590 : pub struct InferredColumn {
591 : /// The column name
592 : pub column_name: Name,
593 : /// The confidence of the inference
594 : pub confidence: InferenceConfidence,
595 : /// The other feasible owner tables of a candidate column, empty if confident
596 : pub candidate_table_names: Vec<QualifiedTableName>,
597 : }
598 :
599 : /// An inferred schema of a table that is not in the catalog
600 : #[derive(Clone, Debug)]
601 : pub struct InferredTableSchema {
602 : /// The (un-normalized) table name, the identity across statements
603 : pub table_name: QualifiedTableName,
604 : /// The confidence of the schema, the maximum over its columns
605 : pub confidence: InferenceConfidence,
606 : /// The inferred columns in order of first appearance
607 : pub columns: Vec<InferredColumn>,
608 : /// The columns by name (index into the columns)
609 : pub columns_by_name: HashMap<Arc<str>, usize>,
610 : }
611 :
612 : /// What a parameter stands for
613 : #[derive(Clone, Copy, Debug, PartialEq, Eq)]
614 : pub enum ParameterKind {
615 : /// A scalar value, e.g. `where x > :min`
616 : Scalar,
617 : /// A table, e.g. `from :source`
618 : Table,
619 : }
620 :
621 : /// A parameter of the script: a named `:name` (also `:"name"`, `:'name'`), a positional `$1` or an unnamed `?`
622 : #[derive(Clone, Debug)]
623 : pub struct Parameter {
624 : /// The parameter ref node
625 : pub ast_node_id: u32,
626 : /// The statement of the parameter
627 : pub ast_statement_id: Option<u32>,
628 : /// The location, with the prefix
629 : pub location: SymbolSpan,
630 : /// What the parameter stands for
631 : pub kind: ParameterKind,
632 : /// The name without the prefix, `1` for `$1`, None for an unnamed `?`
633 : pub name: Option<Arc<str>>,
634 : /// The type of the cast whose value is a scalar parameter, `:min::int`
635 : pub cast_type: Option<super::sql_types::SqlType>,
636 : }
637 :
638 : /// A constant expression root
639 : #[derive(Clone, Copy, Debug)]
640 : pub struct ConstantExpression {
641 : /// The root expression of the constant tree
642 : pub root: ExprId,
643 : }
644 :
645 : /// Dashboard placement
646 : #[derive(Clone, Debug)]
647 : pub struct DashboardSpec {
648 : /// The grid row, None for automatic placement
649 : pub row: Option<i32>,
650 : /// The grid column (0-11), None for automatic placement
651 : pub column: Option<i32>,
652 : /// The width in grid columns (1-12)
653 : pub width: i32,
654 : /// The height in grid rows (at least 1), a row is as high as a collapsed card
655 : pub height: i32,
656 : }
657 :
658 : impl Default for DashboardSpec {
659 155 : fn default() -> Self {
660 155 : Self {
661 155 : row: None,
662 155 : column: None,
663 155 : width: 6,
664 155 : height: 6,
665 155 : }
666 155 : }
667 : }
668 :
669 : /// The dashboard placement of a script, the `@board` tag of its last statement. A statement without a renderer is a
670 : /// collapsed card.
671 : #[derive(Clone, Debug)]
672 : pub struct BoardSpec {
673 : /// The statement whose annotation holds the tag, the last statement
674 : pub statement_id: u32,
675 : /// The placement
676 : pub dashboard: DashboardSpec,
677 : }
678 :
679 : /// The placement of a script on the dataflow canvas, its `@flow` tag: a position, a size, or both
680 : #[derive(Clone, Copy, Debug, PartialEq, Eq)]
681 : pub struct FlowSpec {
682 : /// The statement whose annotation holds the tag
683 : pub statement_id: u32,
684 : /// The x and y coordinates of the top left corner of the box, None places the box automatically
685 : pub position: Option<(i32, i32)>,
686 : /// The width of the box, None for the default width
687 : pub width: Option<i32>,
688 : /// The height of the chart of the box, None for the default height
689 : pub height: Option<i32>,
690 : }
691 :
692 : /// The value of an input of the script, its `@param :name = <literal>` tag
693 : #[derive(Clone, Debug, PartialEq, Eq)]
694 : pub struct ParamTag {
695 : /// The statement whose annotation holds the tag
696 : pub statement_id: u32,
697 : /// The name of the input, the scalar parameter `:name`
698 : pub name: Arc<str>,
699 : /// The value, a literal in the Hyper dialect, None if the input is unset or the value is no literal
700 : pub literal: Option<crate::sql_literal::SqlLiteral>,
701 : }
702 :
703 : /// A Markdown spec
704 : #[derive(Clone, Debug, Default)]
705 : pub struct MarkdownSpec {
706 : /// The row template of the `@vis markdown` tag
707 : pub row_template: String,
708 : }
709 :
710 : /// A visualization specification, built from the `@vis` tags of a query
711 : #[derive(Clone, Debug, Default)]
712 : pub struct VisualizationSpec {
713 : /// The AST node id of the visualized query
714 : pub ast_node_id: u32,
715 : /// The AST statement id
716 : pub ast_statement_id: Option<u32>,
717 : /// The renderer named by the `@vis` tag (`vegalite`, `markdown` or `table`)
718 : pub renderer: Option<String>,
719 : /// The dashboard grid placement
720 : pub dashboard: DashboardSpec,
721 : /// The Markdown spec, present if the renderer is `markdown`
722 : pub markdown: Option<MarkdownSpec>,
723 : /// The Vega-Lite spec of a `@vis vegalite` tag, a JSON object without `data`
724 : pub vegalite: Option<serde_json::Map<String, serde_json::Value>>,
725 : }
|