LCOV - code coverage report
Current view: top level - dashql-core/src/analyzer - types.rs Coverage Total Hit
Test: DashQL 915828b Lines: 97.3 % 73 71
Test Date: 2026-11-06 19:30:32

            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              : }
        

Generated by: LCOV version 2.0-1