Skip to main content

uqa_sql/schema/
open_columns.rs

1//
2// Unified Query Algebra
3//
4// Copyright (c) 2023-2026 Cognica, Inc.
5//
6
7//! Deferred row descriptors for document and native-function sources.
8
9use super::{RowSchema, SchemaBuildMetadata};
10
11impl RowSchema {
12    /// Mark a source whose remaining column names are supplied at execution. This is analysis metadata: it allocates no physical columns and never changes runtime lookup or wildcard expansion.
13    pub fn with_open_columns(input: &Self, qualifier: Option<&str>) -> Self {
14        let mut open_qualifiers = input.index.cold.open_qualifiers.clone();
15        open_qualifiers.insert(qualifier.map(Box::<str>::from));
16        Self::from_typed_parts_with_aliases_and_exact_precedence(
17            input.columns().to_vec(),
18            input.identities().to_vec(),
19            input.column_types().to_vec(),
20            input.index.slots.to_vec(),
21            input.physical_width(),
22            SchemaBuildMetadata {
23                record_fields: input.index.cold.record_fields.clone(),
24                aliases: input.index.aliases.clone(),
25                alias_types: input.index.cold.aliases.clone(),
26                internal: input.index.executor_attributes.clone(),
27                internal_types: input.index.cold.executor_attribute_types.clone(),
28                score_sources: input.index.cold.score_sources.clone(),
29                wildcard_hidden: input.index.cold.wildcard_hidden.clone(),
30                binding_only: input.index.cold.binding_only.clone(),
31                open_qualifiers,
32                extra_ambiguous_unqualified: input.index.ambiguous_unqualified.clone(),
33                extra_ambiguous_qualified: input.index.ambiguous_qualified.clone(),
34                ..SchemaBuildMetadata::default()
35            },
36        )
37    }
38
39    /// Whether unresolved names in this namespace require the source's runtime descriptor. An unqualified lookup can depend on any open source.
40    #[must_use]
41    pub fn columns_are_open(&self, qualifier: Option<&str>) -> bool {
42        qualifier.map_or_else(
43            || !self.index.cold.open_qualifiers.is_empty(),
44            |qualifier| {
45                self.index
46                    .cold
47                    .open_qualifiers
48                    .iter()
49                    .any(|candidate| candidate.as_deref() == Some(qualifier))
50            },
51        )
52    }
53}