1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
//
// Unified Query Algebra
//
// Copyright (c) 2023-2026 Cognica, Inc.
//
//! Composite type declarations and their bound type references.
use serde::{Deserialize, Serialize};
use uqa_core::{
memory::{Produced, ProductionControl},
ValueRetentionError,
};
use super::ColumnType;
/// `CREATE TYPE name AS (attribute type [COLLATE collation], ...)` with attributes in declaration order.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CreateCompositeType {
/// Rendered qualified type name, resolved against the creation namespace during execution.
pub name: String,
pub attributes: Vec<CompositeAttributeDefinition>,
}
/// One declared attribute. The type is a declaration until execution binds it through the catalog.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CompositeAttributeDefinition {
pub name: String,
pub ty: ColumnType,
/// The rendered qualified collation name of an explicit `COLLATE` clause.
pub collation: Option<String>,
/// `SETOF type`, which the grammar accepts and `BuildDescForRelation` rejects.
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub setof: bool,
}
/// One ADD ATTRIBUTE declaration. Unlike CREATE TYPE, ALTER applies column declaration lowering, including SERIAL.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CompositeAttributeAddition {
pub attribute: CompositeAttributeDefinition,
pub declaration: super::ColumnDeclaration,
}
/// Creation-time positional binding of a stored ROW constructor. Type references use the same canonical-name lifecycle as stored casts; attribute numbers survive additions and dropped slots.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct CompositeRowBinding {
pub ty: String,
pub attributes: Vec<i16>,
}
/// A composite type bound by catalog identity: a standalone composite type or the row type of a relation. The schema and name are the catalog's current names; equality compares the type identity only.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CompositeTypeReference {
pub schema: String,
pub name: String,
/// The row type's `pg_type` OID.
pub oid: u32,
pub array_oid: u32,
/// The `pg_class` OID of the relation that describes the attributes (`pg_type.typrelid`).
pub relation_oid: u32,
}
impl PartialEq for CompositeTypeReference {
fn eq(&self, other: &Self) -> bool {
self.oid == other.oid
}
}
impl Eq for CompositeTypeReference {}
impl CompositeTypeReference {
/// Copy the owned catalog names under the production reservation; the identities are inline.
pub fn clone_with_control(
&self,
control: &ProductionControl<'_>,
) -> Result<Produced<Self>, ValueRetentionError> {
let schema = control.copy_text(&self.schema)?;
let name = control.copy_text(&self.name)?;
let (schema, schema_memory) = schema.into_parts();
let (name, name_memory) = name.into_parts();
control.finish(
Self {
schema,
name,
oid: self.oid,
array_oid: self.array_oid,
relation_oid: self.relation_oid,
},
control.combine(schema_memory, name_memory),
)
}
}