1#![forbid(unsafe_code)]
10
11pub mod database;
12pub mod names;
13pub mod size;
14pub mod tablespace;
15pub mod toast;
16
17mod aggregate;
18mod alter_type;
19mod default_acl;
20mod drop;
21mod enum_label;
22mod opclass;
23mod operator;
24mod owner;
25mod sequence;
26mod set_schema;
27mod stats;
28mod tsearch;
29
30pub use aggregate::{Aggregate, PG_AGGREGATE};
31pub use default_acl::{DefaultAcl, PG_DEFAULT_ACL};
32pub use drop::{Refusal, Target, flag};
33pub use opclass::{
34 AmOp, AmProc, MemberLink, OpClass, OpFamily, PG_AM, PG_AMOP, PG_AMPROC, PG_OPFAMILY,
35};
36pub use operator::{Operator, PG_OPERATOR};
37pub use owner::acl_new_owner;
38pub use sequence::SequenceData;
39pub use stats::{PG_STATISTIC_EXT, StatExt};
40pub use tsearch::{
41 PG_TS_CONFIG, PG_TS_DICT, PG_TS_PARSER, PG_TS_TEMPLATE, TsConfig, TsDictionary, TsMapping,
42 TsParser, TsTemplate,
43};
44
45use std::collections::{BTreeMap, BTreeSet};
46use std::sync::Arc;
47
48use rupg_common::{Error, Object, Result, SqlState};
49
50pub use database::Database;
51use names::{index_column_names, make_object_name, name_addition};
52pub use tablespace::Tablespace;
53
54pub const FIRST_NORMAL_OID: u32 = 16384;
56pub const FIRST_UNPINNED_OID: u32 = 12000;
58pub const MAX_COLUMNS: usize = 1600;
60pub const PG_CLASS: u32 = 1259;
62pub const PG_TYPE: u32 = 1247;
64pub const PG_REWRITE: u32 = 2618;
66pub const PG_PROC: u32 = 1255;
68pub const PG_NAMESPACE: u32 = 2615;
70pub const PG_DATABASE: u32 = 1262;
72pub const PG_TABLESPACE: u32 = 1213;
74pub const PG_LARGEOBJECT: u32 = 2613;
76pub const PG_TOAST_NAMESPACE: u32 = 99;
78pub const PG_CAST: u32 = 2605;
80pub const PG_OPCLASS: u32 = 2616;
82const TEXT: u32 = 25;
84const INTERNAL_LANGUAGE: u32 = 12;
86pub const BOOTSTRAP_SUPERUSER: u32 = 10;
88const OID: u32 = 26;
90const INT4: u32 = 23;
92const BYTEA: u32 = 17;
94const OID_OPS: u32 = 1981;
96const INT4_OPS: u32 = 1978;
98pub const PUBLIC: u32 = 2200;
100pub const PG_CONSTRAINT: u32 = 2606;
102pub const PG_ATTRDEF: u32 = 2604;
104pub const PG_COLLATION: u32 = 3456;
106pub const PG_LANGUAGE: u32 = 2612;
108pub const PG_EXTENSION: u32 = 3079;
110pub const BTREE: u32 = 403;
112pub const PG_TRIGGER: u32 = 2620;
114const RI_FKEY_CHECK_INS: u32 = 1644;
116const UNIQUE_KEY_RECHECK: u32 = 1250;
118pub const TRIGGER_ROW: i16 = 1;
120pub const TRIGGER_BEFORE: i16 = 2;
122pub const TRIGGER_INSERT: i16 = 4;
124pub const TRIGGER_DELETE: i16 = 8;
126pub const TRIGGER_UPDATE: i16 = 16;
128pub const TRIGGER_TRUNCATE: i16 = 32;
130pub const TRIGGER_INSTEAD: i16 = 64;
132
133#[derive(Clone, Debug, PartialEq, Eq)]
135pub struct Schema {
136 pub oid: u32,
138 pub name: String,
140 pub owner: u32,
142 pub acl: Option<Vec<String>>,
144}
145
146#[derive(Clone, Copy, Debug, PartialEq, Eq)]
148pub enum RelKind {
149 Table,
151 Index,
153 Sequence,
155 Toast,
157 View,
159 Composite,
161 Partitioned,
163 PartitionedIndex,
165 MatView,
167}
168
169impl RelKind {
170 pub fn code(self) -> char {
172 match self {
173 RelKind::Table => 'r',
174 RelKind::Index => 'i',
175 RelKind::Sequence => 'S',
176 RelKind::Toast => 't',
177 RelKind::View => 'v',
178 RelKind::Composite => 'c',
179 RelKind::Partitioned => 'p',
180 RelKind::PartitionedIndex => 'I',
181 RelKind::MatView => 'm',
182 }
183 }
184}
185
186#[derive(Clone, Debug, PartialEq, Eq)]
188pub struct Column {
189 pub name: String,
191 pub ty: u32,
193 pub typmod: i32,
195 pub ndims: i16,
197 pub collation: u32,
199 pub not_null: bool,
201 pub not_null_invalid: bool,
203 pub has_default: bool,
205 pub identity: u8,
207 pub generated: u8,
209 pub dropped: bool,
211 pub stat_target: Option<i16>,
213 pub storage: u8,
215 pub compression: u8,
217 pub options: Vec<String>,
219 pub local: bool,
221 pub inhcount: i16,
223}
224
225impl Column {
226 pub fn new(name: impl Into<String>, ty: u32, typmod: i32, collation: u32) -> Column {
228 Column {
229 name: name.into(),
230 ty,
231 typmod,
232 ndims: 0,
233 collation,
234 not_null: false,
235 not_null_invalid: false,
236 has_default: false,
237 identity: 0,
238 generated: 0,
239 dropped: false,
240 stat_target: None,
241 storage: 0,
242 compression: 0,
243 options: Vec::new(),
244 local: true,
245 inhcount: 0,
246 }
247 }
248}
249
250#[derive(Clone, Debug, PartialEq, Eq)]
252pub struct IndexInfo {
253 pub table: u32,
255 pub keys: Vec<i16>,
257 pub key_count: i16,
259 pub unique: bool,
261 pub nulls_not_distinct: bool,
263 pub primary: bool,
265 pub immediate: bool,
267 pub method: u32,
269 pub collations: Vec<u32>,
271 pub classes: Vec<u32>,
273 pub options: Vec<i16>,
275 pub exprs: Option<String>,
277 pub predicate: Option<String>,
279 pub pages: i32,
281 pub clustered: bool,
283 pub replica_identity: bool,
285 pub valid: bool,
287 pub ready: bool,
289 pub parent: u32,
291}
292
293#[derive(Clone, Debug, PartialEq, Eq)]
295pub struct SequenceInfo {
296 pub ty: u32,
298 pub start: i64,
300 pub increment: i64,
302 pub max: i64,
304 pub min: i64,
306 pub cache: i64,
308 pub cycle: bool,
310 pub file: u32,
312 pub data: SequenceData,
314}
315
316#[derive(Clone, Debug, PartialEq, Eq)]
318pub struct Relation {
319 pub oid: u32,
321 pub file: u32,
323 pub name: String,
325 pub namespace: u32,
327 pub kind: RelKind,
329 pub owner: u32,
331 pub row_type: u32,
333 pub columns: Vec<Column>,
335 pub has_index: bool,
337 pub has_triggers: bool,
339 pub toast: u32,
341 pub index: Option<IndexInfo>,
343 pub sequence: Option<SequenceInfo>,
345 pub view: Option<ViewInfo>,
347 pub options: Vec<String>,
349 pub acl: Option<Vec<String>>,
351 pub replica_identity: u8,
353 pub unlogged: bool,
355 pub partition_key: Option<PartitionKey>,
357 pub partition_of: Option<PartitionOf>,
359 pub inherits: Vec<u32>,
361 pub of_type: u32,
363}
364
365#[derive(Clone, Copy, Debug, PartialEq, Eq)]
367pub enum PartStrategy {
368 Hash,
370 List,
372 Range,
374}
375
376impl PartStrategy {
377 pub fn code(self) -> char {
379 match self {
380 PartStrategy::Hash => 'h',
381 PartStrategy::List => 'l',
382 PartStrategy::Range => 'r',
383 }
384 }
385}
386
387#[derive(Clone, Debug, PartialEq, Eq)]
389pub struct PartitionKey {
390 pub strategy: PartStrategy,
392 pub attrs: Vec<i16>,
394 pub classes: Vec<u32>,
396 pub collations: Vec<u32>,
398 pub exprs: Option<String>,
400}
401
402#[derive(Clone, Debug, PartialEq, Eq)]
404pub enum RangeDatum {
405 MinValue,
407 MaxValue,
409 Value(String),
411}
412
413#[derive(Clone, Debug, PartialEq, Eq)]
415pub enum PartitionBound {
416 Default,
418 Hash {
420 modulus: i32,
422 remainder: i32,
424 },
425 List(Vec<Option<String>>),
427 Range {
429 lower: Vec<RangeDatum>,
431 upper: Vec<RangeDatum>,
433 },
434}
435
436#[derive(Clone, Debug, PartialEq, Eq)]
438pub struct PartitionOf {
439 pub parent: u32,
441 pub bound: PartitionBound,
443}
444
445#[derive(Clone, Debug, PartialEq, Eq)]
447pub struct ViewInfo {
448 pub rule: u32,
450 pub text: String,
452 pub path: Vec<u32>,
454 pub populated: bool,
456}
457
458impl Relation {
459 pub fn column_number(&self, name: &str) -> Option<i16> {
461 let index = self.columns.iter().position(|c| !c.dropped && c.name == name)?;
462 i16::try_from(index + 1).ok()
463 }
464
465 pub fn column(&self, number: i16) -> Option<&Column> {
467 let index = usize::try_from(number).ok()?.checked_sub(1)?;
468 self.columns.get(index)
469 }
470}
471
472#[derive(Clone, Debug, PartialEq, Eq)]
474pub struct Type {
475 pub oid: u32,
477 pub name: String,
479 pub namespace: u32,
481 pub owner: u32,
483 pub relation: u32,
485 pub element: u32,
487 pub array: u32,
489 pub domain: Option<Domain>,
491 pub labels: Option<Vec<EnumLabel>>,
493 pub range: Option<RangePart>,
495}
496
497#[derive(Clone, Debug, PartialEq, Eq)]
499pub struct RangeInfo {
500 pub subtype: u32,
502 pub collation: u32,
504 pub subopc: u32,
506 pub canonical: u32,
508 pub subdiff: u32,
510 pub multirange: u32,
512 pub align: u8,
514 pub constructors: [u32; 5],
516}
517
518#[derive(Clone, Debug, PartialEq, Eq)]
520pub enum RangePart {
521 Range(RangeInfo),
523 Multirange(u32),
525}
526
527#[derive(Clone, Debug, PartialEq, Eq)]
529pub struct Cast {
530 pub oid: u32,
532 pub source: u32,
534 pub target: u32,
536 pub func: u32,
538 pub context: u8,
540 pub method: u8,
542}
543
544#[derive(Clone, Debug)]
546pub struct EnumLabel {
547 pub oid: u32,
549 pub sort_order: f32,
551 pub label: String,
553}
554
555impl PartialEq for EnumLabel {
556 fn eq(&self, other: &EnumLabel) -> bool {
557 self.oid == other.oid
558 && self.sort_order.to_bits() == other.sort_order.to_bits()
559 && self.label == other.label
560 }
561}
562
563impl Eq for EnumLabel {}
564
565#[derive(Clone, Debug, PartialEq, Eq)]
567pub struct Domain {
568 pub base: u32,
570 pub typmod: i32,
572 pub collation: u32,
574 pub default: Option<String>,
576 pub not_null: bool,
578}
579
580#[derive(Clone, Debug, PartialEq)]
582pub struct Function {
583 pub oid: u32,
585 pub name: String,
587 pub namespace: u32,
589 pub owner: u32,
591 pub lang: u32,
593 pub cost: f32,
595 pub rows: u32,
597 pub support: u32,
599 pub kind: u8,
601 pub strict: bool,
603 pub leakproof: bool,
605 pub volatile: u8,
607 pub parallel: u8,
609 pub rettype: u32,
611 pub retset: bool,
613 pub argtypes: Vec<u32>,
615 pub allargtypes: Vec<u32>,
617 pub argmodes: Vec<u8>,
619 pub argnames: Vec<String>,
621 pub argdefaults: Option<String>,
623 pub nargdefaults: i16,
625 pub src: String,
627 pub bin: String,
629 pub body: Option<FunctionBody>,
631 pub config: Vec<String>,
633 pub secdef: bool,
635}
636
637impl Eq for Function {}
639
640#[derive(Clone, Debug, PartialEq, Eq)]
642pub struct FunctionBody {
643 pub text: String,
645 pub path: Vec<u32>,
647}
648
649#[derive(Clone, Debug, PartialEq, Eq)]
651pub struct AttrDefault {
652 pub oid: u32,
654 pub relation: u32,
656 pub column: i16,
658 pub expr: String,
660}
661
662#[derive(Clone, Copy, Debug, PartialEq, Eq)]
664pub enum ConKind {
665 Check,
667 NotNull,
669 Primary,
671 Unique,
673 Foreign,
675 Trigger,
677}
678
679impl ConKind {
680 pub fn code(self) -> char {
682 match self {
683 ConKind::Check => 'c',
684 ConKind::NotNull => 'n',
685 ConKind::Primary => 'p',
686 ConKind::Unique => 'u',
687 ConKind::Foreign => 'f',
688 ConKind::Trigger => 't',
689 }
690 }
691}
692
693#[derive(Clone, Debug, PartialEq, Eq)]
695pub struct ForeignKey {
696 pub table: u32,
698 pub keys: Vec<i16>,
700 pub update: char,
702 pub delete: char,
704 pub match_type: char,
706 pub pf_eq: Vec<u32>,
708 pub pp_eq: Vec<u32>,
710 pub ff_eq: Vec<u32>,
712}
713
714#[derive(Clone, Debug, PartialEq, Eq)]
716pub struct Constraint {
717 pub oid: u32,
719 pub name: String,
721 pub namespace: u32,
723 pub kind: ConKind,
725 pub relation: u32,
727 pub domain: u32,
729 pub keys: Vec<i16>,
731 pub index: u32,
733 pub deferrable: bool,
735 pub deferred: bool,
737 pub validated: bool,
739 pub enforced: bool,
741 pub no_inherit: bool,
743 pub local: bool,
745 pub inhcount: i16,
747 pub parent: u32,
749 pub expr: Option<String>,
751 pub foreign: Option<ForeignKey>,
753}
754
755#[derive(Clone, Debug, Default, PartialEq, Eq)]
757pub struct Trigger {
758 pub oid: u32,
760 pub relation: u32,
762 pub name: String,
764 pub function: u32,
766 pub kind: i16,
768 pub constraint_relation: u32,
770 pub constraint_index: u32,
772 pub constraint: u32,
774 pub deferrable: bool,
776 pub deferred: bool,
778 pub enabled: u8,
780 pub internal: bool,
782 pub args: Vec<String>,
784 pub columns: Vec<i16>,
786 pub old_table: Option<String>,
788 pub new_table: Option<String>,
790 pub qual: Option<String>,
792 pub parent: u32,
794}
795
796impl Trigger {
797 pub fn fires(&self) -> bool {
799 matches!(self.enabled, b'O' | b'A')
800 }
801}
802
803#[derive(Clone, Debug, Default, PartialEq, Eq)]
805pub struct NewTrigger {
806 pub name: String,
808 pub relation: u32,
810 pub function: u32,
812 pub kind: i16,
814 pub args: Vec<String>,
816 pub columns: Vec<i16>,
818 pub old_table: Option<String>,
820 pub new_table: Option<String>,
822 pub qual: Option<String>,
824 pub constraint: bool,
826 pub constraint_relation: u32,
828 pub deferrable: bool,
830 pub deferred: bool,
832 pub parent: u32,
834 pub enabled: u8,
836}
837
838#[derive(Clone, Debug, PartialEq, Eq)]
840pub struct Rule {
841 pub oid: u32,
843 pub name: String,
845 pub relation: u32,
847 pub event: u8,
849 pub instead: bool,
851 pub enabled: u8,
853 pub qualified: bool,
855 pub text: String,
857 pub path: Vec<u32>,
859}
860
861#[derive(Clone, Debug, PartialEq, Eq)]
863pub struct NewRule {
864 pub name: String,
866 pub relation: u32,
868 pub event: u8,
870 pub instead: bool,
872 pub qualified: bool,
874 pub text: String,
876 pub path: Vec<u32>,
878}
879
880#[derive(Clone, Debug, PartialEq, Eq)]
882pub struct Collation {
883 pub oid: u32,
885 pub name: String,
887 pub namespace: u32,
889 pub owner: u32,
891 pub provider: u8,
893 pub encoding: i32,
895 pub libc_locale: Option<String>,
897 pub locale: Option<String>,
899 pub version: Option<String>,
901}
902
903#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
905pub struct ObjRef {
906 pub class: u32,
908 pub oid: u32,
910 pub sub: i32,
912}
913
914impl ObjRef {
915 pub fn new(class: u32, oid: u32) -> ObjRef {
917 ObjRef { class, oid, sub: 0 }
918 }
919
920 pub fn column(relation: u32, number: i16) -> ObjRef {
922 ObjRef { class: PG_CLASS, oid: relation, sub: i32::from(number) }
923 }
924}
925
926#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
928pub enum DepKind {
929 Normal,
931 Auto,
933 Internal,
935 Extension,
937 PartitionPri,
939 PartitionSec,
941}
942
943impl DepKind {
944 pub fn code(self) -> char {
946 match self {
947 DepKind::Normal => 'n',
948 DepKind::Auto => 'a',
949 DepKind::Internal => 'i',
950 DepKind::Extension => 'e',
951 DepKind::PartitionPri => 'P',
952 DepKind::PartitionSec => 'S',
953 }
954 }
955}
956
957#[derive(Clone, Debug, PartialEq, Eq)]
959pub struct Language {
960 pub oid: u32,
962 pub name: String,
964 pub owner: u32,
966 pub trusted: bool,
968 pub handler: u32,
970 pub inline: u32,
972 pub validator: u32,
974}
975
976#[derive(Clone, Debug, PartialEq, Eq)]
978pub struct Extension {
979 pub oid: u32,
981 pub name: String,
983 pub owner: u32,
985 pub namespace: u32,
987 pub relocatable: bool,
989 pub version: String,
991}
992
993#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
995pub struct Depend {
996 pub object: ObjRef,
998 pub referenced: ObjRef,
1000 pub kind: DepKind,
1002}
1003
1004#[derive(Clone, Debug, PartialEq, Eq)]
1006pub struct NewDomain {
1007 pub namespace: u32,
1009 pub name: String,
1011 pub owner: u32,
1013 pub domain: Domain,
1015}
1016
1017#[derive(Clone, Debug, PartialEq, Eq)]
1019pub struct NewEnum {
1020 pub namespace: u32,
1022 pub name: String,
1024 pub owner: u32,
1026 pub labels: Vec<String>,
1028}
1029
1030#[derive(Clone, Debug, PartialEq, Eq)]
1032pub struct NewRange {
1033 pub namespace: u32,
1035 pub name: String,
1037 pub owner: u32,
1039 pub multirange_namespace: u32,
1041 pub multirange_name: String,
1043 pub info: RangeInfo,
1045}
1046
1047#[derive(Clone, Debug, PartialEq, Eq)]
1049pub struct NewRelation {
1050 pub namespace: u32,
1052 pub name: String,
1054 pub owner: u32,
1056 pub columns: Vec<Column>,
1058}
1059
1060#[derive(Clone, Debug, PartialEq, Eq)]
1062pub struct NewIndexColumn {
1063 pub name: String,
1065 pub key: i16,
1067 pub ty: u32,
1069 pub typmod: i32,
1071 pub collation: u32,
1073 pub class: u32,
1075 pub option: i16,
1077}
1078
1079#[derive(Clone, Debug, PartialEq, Eq)]
1081pub struct NewIndex {
1082 pub table: u32,
1084 pub name: Option<String>,
1086 pub columns: Vec<NewIndexColumn>,
1088 pub key_count: usize,
1090 pub method: u32,
1092 pub unique: bool,
1094 pub nulls_not_distinct: bool,
1096 pub constraint: Option<ConKind>,
1098 pub deferrable: bool,
1100 pub deferred: bool,
1102 pub exprs: Option<String>,
1104 pub predicate: Option<String>,
1106 pub refs: Vec<ObjRef>,
1108 pub pages: i32,
1110}
1111
1112#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1114pub enum FkSide {
1115 Both,
1117 Referenced,
1119 Referencing,
1121}
1122
1123#[derive(Clone, Debug, PartialEq, Eq)]
1125pub struct NewForeignKey {
1126 pub table: u32,
1128 pub name: Option<String>,
1130 pub keys: Vec<i16>,
1132 pub index: u32,
1134 pub deferrable: bool,
1136 pub deferred: bool,
1138 pub foreign: ForeignKey,
1140}
1141
1142#[derive(Clone, Debug, PartialEq, Eq)]
1144pub struct Catalog {
1145 next_oid: u32,
1146 schemas: BTreeMap<u32, Schema>,
1147 relations: BTreeMap<u32, Relation>,
1148 types: BTreeMap<u32, Type>,
1149 defaults: BTreeMap<u32, AttrDefault>,
1150 constraints: BTreeMap<u32, Constraint>,
1151 functions: BTreeMap<u32, Function>,
1152 aggregates: BTreeMap<u32, Aggregate>,
1153 casts: BTreeMap<u32, Cast>,
1154 operators: BTreeMap<u32, Operator>,
1155 opfamilies: BTreeMap<u32, OpFamily>,
1156 opclasses: BTreeMap<u32, OpClass>,
1157 amops: BTreeMap<u32, AmOp>,
1158 amprocs: BTreeMap<u32, AmProc>,
1159 languages: BTreeMap<u32, Language>,
1160 extensions: BTreeMap<u32, Extension>,
1161 triggers: BTreeMap<u32, Trigger>,
1162 rules: BTreeMap<u32, Rule>,
1163 collations: Arc<BTreeMap<u32, Collation>>,
1164 ts_templates: BTreeMap<u32, TsTemplate>,
1165 ts_parsers: BTreeMap<u32, TsParser>,
1166 ts_dictionaries: BTreeMap<u32, TsDictionary>,
1167 ts_configs: BTreeMap<u32, TsConfig>,
1168 ts_mappings: Vec<TsMapping>,
1169 stat_exts: BTreeMap<u32, StatExt>,
1170 depends: Vec<Depend>,
1171 descriptions: Arc<BTreeMap<ObjRef, String>>,
1172 acls: Arc<BTreeMap<ObjRef, Vec<String>>>,
1174 default_acls: Arc<BTreeMap<u32, DefaultAcl>>,
1176 uncommitted_types: Vec<u32>,
1178 uncommitted_labels: Vec<u32>,
1180 dropped_builtins: BTreeSet<ObjRef>,
1182}
1183
1184impl Default for Catalog {
1185 fn default() -> Catalog {
1186 Catalog::new()
1187 }
1188}
1189
1190const UTF8: i32 = 6;
1192
1193pub fn eliminate_duplicates(refs: &[ObjRef]) -> Vec<ObjRef> {
1195 let mut refs = refs.to_vec();
1196 refs.sort_by(|a, b| {
1197 b.oid
1198 .cmp(&a.oid)
1199 .then(a.class.cmp(&b.class))
1200 .then(a.sub.cast_unsigned().cmp(&b.sub.cast_unsigned()))
1201 });
1202 let mut kept: Vec<ObjRef> = Vec::with_capacity(refs.len());
1203 for r in refs {
1204 match kept.last_mut() {
1205 Some(prior) if prior.class == r.class && prior.oid == r.oid => {
1206 if prior.sub == 0 {
1207 prior.sub = r.sub;
1208 } else if prior.sub != r.sub {
1209 kept.push(r);
1210 }
1211 }
1212 _ => kept.push(r),
1213 }
1214 }
1215 kept
1216}
1217
1218pub fn is_pinned(object: ObjRef) -> bool {
1220 if object.oid >= FIRST_UNPINNED_OID
1221 || object.class == PG_LARGEOBJECT
1222 || object.class == PG_DATABASE
1223 {
1224 return false;
1225 }
1226 !(object.class == PG_NAMESPACE && object.oid == PUBLIC)
1227}
1228
1229pub fn foreign_key_function(function: u32) -> Option<u32> {
1231 function.checked_sub(RI_FKEY_CHECK_INS).filter(|&at| at <= 11)
1232}
1233
1234fn duplicate_table(name: &str) -> Error {
1235 Error::new(SqlState::DUPLICATE_TABLE, format!("relation \"{name}\" already exists"))
1236}
1237
1238fn duplicate_constraint(name: &str, relation: &str) -> Error {
1239 Error::new(
1240 SqlState::DUPLICATE_OBJECT,
1241 format!("constraint \"{name}\" for relation \"{relation}\" already exists"),
1242 )
1243}
1244
1245fn no_object(what: &str, oid: u32) -> Error {
1246 Error::internal(format!("cache lookup failed for {what} {oid}"))
1247}
1248
1249pub fn collation_conflict(existing: i32, new: i32) -> bool {
1251 existing == new || existing == -1 || (new == -1 && existing == UTF8)
1252}
1253
1254impl Catalog {
1255 pub fn new() -> Catalog {
1257 Catalog {
1258 next_oid: FIRST_NORMAL_OID,
1259 schemas: BTreeMap::new(),
1260 relations: BTreeMap::new(),
1261 types: BTreeMap::new(),
1262 defaults: BTreeMap::new(),
1263 constraints: BTreeMap::new(),
1264 functions: BTreeMap::new(),
1265 aggregates: BTreeMap::new(),
1266 casts: BTreeMap::new(),
1267 operators: BTreeMap::new(),
1268 opfamilies: BTreeMap::new(),
1269 opclasses: BTreeMap::new(),
1270 amops: BTreeMap::new(),
1271 amprocs: BTreeMap::new(),
1272 languages: BTreeMap::new(),
1273 extensions: BTreeMap::new(),
1274 triggers: BTreeMap::new(),
1275 rules: BTreeMap::new(),
1276 collations: Arc::default(),
1277 ts_templates: BTreeMap::new(),
1278 ts_parsers: BTreeMap::new(),
1279 ts_dictionaries: BTreeMap::new(),
1280 ts_configs: BTreeMap::new(),
1281 ts_mappings: Vec::new(),
1282 stat_exts: BTreeMap::new(),
1283 depends: Vec::new(),
1284 descriptions: Arc::default(),
1285 acls: Arc::default(),
1286 default_acls: Arc::default(),
1287 uncommitted_types: Vec::new(),
1288 uncommitted_labels: Vec::new(),
1289 dropped_builtins: BTreeSet::new(),
1290 }
1291 }
1292
1293 pub fn next_oid(&self) -> u32 {
1295 self.next_oid
1296 }
1297
1298 pub fn advance_oid(&mut self, oid: u32) {
1300 self.next_oid = self.next_oid.max(oid);
1301 }
1302
1303 pub fn set_next_oid(&mut self, oid: u32) {
1305 self.next_oid = oid;
1306 }
1307
1308 pub fn skip_oids(&mut self, count: u32) {
1310 for _ in 0..count {
1311 self.new_oid();
1312 }
1313 }
1314
1315 pub fn take_oid(&mut self) -> u32 {
1317 self.new_oid()
1318 }
1319
1320 fn new_oid(&mut self) -> u32 {
1321 let oid = self.next_oid;
1322 self.next_oid = match oid.checked_add(1) {
1323 Some(next) => next,
1324 None => FIRST_NORMAL_OID,
1325 };
1326 oid
1327 }
1328
1329 fn depend(&mut self, object: ObjRef, referenced: ObjRef, kind: DepKind) {
1330 if is_pinned(referenced) {
1331 return;
1332 }
1333 self.depends.push(Depend { object, referenced, kind });
1334 }
1335
1336 fn depend_on_expr(
1338 &mut self,
1339 object: ObjRef,
1340 refs: &[ObjRef],
1341 relation: u32,
1342 self_kind: DepKind,
1343 ) {
1344 for &referenced in refs {
1345 let kind = if referenced.class == PG_CLASS && referenced.oid == relation {
1346 self_kind
1347 } else {
1348 DepKind::Normal
1349 };
1350 self.depend(object, referenced, kind);
1351 }
1352 }
1353
1354 pub fn schemas(&self) -> impl Iterator<Item = &Schema> {
1356 self.schemas.values()
1357 }
1358
1359 pub fn schema(&self, oid: u32) -> Option<&Schema> {
1361 self.schemas.get(&oid)
1362 }
1363
1364 pub fn builtin_dropped(&self, object: ObjRef) -> bool {
1366 self.dropped_builtins.contains(&object)
1367 }
1368
1369 pub fn schema_dropped(&self, oid: u32) -> bool {
1371 self.builtin_dropped(ObjRef::new(PG_NAMESPACE, oid))
1372 }
1373
1374 pub fn any_builtin_dropped(&self) -> bool {
1376 !self.dropped_builtins.is_empty()
1377 }
1378
1379 pub fn schema_by_name(&self, name: &str) -> Option<&Schema> {
1381 self.schemas.values().find(|s| s.name == name)
1382 }
1383
1384 pub fn is_temp_schema(&self, oid: u32) -> bool {
1386 self.schemas.get(&oid).is_some_and(|s| {
1387 s.name
1388 .strip_prefix("pg_temp_")
1389 .or_else(|| s.name.strip_prefix("pg_toast_temp_"))
1390 .is_some_and(|n| !n.is_empty() && n.bytes().all(|b| b.is_ascii_digit()))
1391 })
1392 }
1393
1394 fn toast_namespace(&self, namespace: u32) -> u32 {
1396 self.schemas
1397 .get(&namespace)
1398 .and_then(|s| s.name.strip_prefix("pg_temp_"))
1399 .and_then(|n| self.schema_by_name(&format!("pg_toast_temp_{n}")))
1400 .map_or(PG_TOAST_NAMESPACE, |s| s.oid)
1401 }
1402
1403 pub fn relations(&self) -> impl Iterator<Item = &Relation> {
1405 self.relations.values()
1406 }
1407
1408 pub fn relation(&self, oid: u32) -> Option<&Relation> {
1410 self.relations.get(&oid)
1411 }
1412
1413 pub fn relation_by_name(&self, namespace: u32, name: &str) -> Option<&Relation> {
1415 self.relations.values().find(|r| r.namespace == namespace && r.name == name)
1416 }
1417
1418 pub fn types(&self) -> impl Iterator<Item = &Type> {
1420 self.types.values()
1421 }
1422
1423 pub fn type_by_oid(&self, oid: u32) -> Option<&Type> {
1425 self.types.get(&oid)
1426 }
1427
1428 pub fn type_by_name(&self, namespace: u32, name: &str) -> Option<&Type> {
1430 self.types.values().find(|t| t.namespace == namespace && t.name == name)
1431 }
1432
1433 pub fn defaults(&self) -> impl Iterator<Item = &AttrDefault> {
1435 self.defaults.values()
1436 }
1437
1438 pub fn default_of(&self, relation: u32, column: i16) -> Option<&AttrDefault> {
1440 self.defaults.values().find(|d| d.relation == relation && d.column == column)
1441 }
1442
1443 pub fn constraints(&self) -> impl Iterator<Item = &Constraint> {
1445 self.constraints.values()
1446 }
1447
1448 pub fn constraint(&self, oid: u32) -> Option<&Constraint> {
1450 self.constraints.get(&oid)
1451 }
1452
1453 pub fn constraints_of(&self, relation: u32) -> impl Iterator<Item = &Constraint> {
1455 self.constraints.values().filter(move |c| c.relation == relation)
1456 }
1457
1458 pub fn triggers(&self) -> impl Iterator<Item = &Trigger> {
1460 self.triggers.values()
1461 }
1462
1463 pub fn trigger(&self, oid: u32) -> Option<&Trigger> {
1465 self.triggers.get(&oid)
1466 }
1467
1468 pub fn triggers_of(&self, relation: u32) -> Vec<&Trigger> {
1470 let mut list: Vec<&Trigger> =
1471 self.triggers.values().filter(|t| t.relation == relation).collect();
1472 list.sort_by(|a, b| a.name.cmp(&b.name));
1473 list
1474 }
1475
1476 pub fn trigger_by_name(&self, relation: u32, name: &str) -> Option<&Trigger> {
1478 self.triggers.values().find(|t| t.relation == relation && t.name == name)
1479 }
1480
1481 pub fn create_trigger(
1489 &mut self,
1490 new: NewTrigger,
1491 replace: bool,
1492 qual: &[ObjRef],
1493 ) -> Result<u32> {
1494 let old = self
1495 .trigger_by_name(new.relation, &new.name)
1496 .map(|t| (t.oid, t.internal || (t.parent != 0 && new.parent == 0)));
1497 let constraint = if new.constraint && old.is_none() {
1498 if self.constraints_of(new.relation).any(|c| c.domain == 0 && c.name == new.name) {
1499 return Err(Error::new(
1500 SqlState::UNIQUE_VIOLATION,
1501 "duplicate key value violates unique constraint \"pg_constraint_conrelid_contypid_conname_index\"",
1502 )
1503 .with_detail(format!(
1504 "Key (conrelid, contypid, conname)=({}, 0, {}) already exists.",
1505 new.relation, new.name
1506 ))
1507 .with_object(Object::Schema, "pg_catalog")
1508 .with_object(Object::Table, "pg_constraint")
1509 .with_object(Object::Constraint, "pg_constraint_conrelid_contypid_conname_index"));
1510 }
1511 let namespace = self.relation(new.relation).map_or(0, |r| r.namespace);
1512 let mut constraint = self.new_constraint(
1513 new.name.clone(),
1514 namespace,
1515 ConKind::Trigger,
1516 new.relation,
1517 Vec::new(),
1518 );
1519 constraint.deferrable = new.deferrable;
1520 constraint.deferred = new.deferred;
1521 constraint.no_inherit = true;
1522 Some(constraint)
1523 } else {
1524 None
1525 };
1526 let relation = self.relation(new.relation).map_or("", |r| r.name.as_str());
1527 let oid = match old {
1528 Some(_) if !replace => {
1529 return Err(Error::new(
1530 SqlState::DUPLICATE_OBJECT,
1531 format!("trigger \"{}\" for relation \"{relation}\" already exists", new.name),
1532 ));
1533 }
1534 Some((_, true)) => {
1535 return Err(Error::new(
1536 SqlState::DUPLICATE_OBJECT,
1537 format!(
1538 "trigger \"{}\" for relation \"{relation}\" is an internal or a child trigger",
1539 new.name
1540 ),
1541 ));
1542 }
1543 Some((oid, false)) => oid,
1544 None => self.new_oid(),
1545 };
1546 let enabled = match self.triggers.get(&oid) {
1547 Some(t) => t.enabled,
1548 None if new.enabled == 0 => b'O',
1549 None => new.enabled,
1550 };
1551 let object = ObjRef::new(PG_TRIGGER, oid);
1552 self.depends.retain(|d| d.object != object);
1553 self.depend(object, ObjRef::new(PG_PROC, new.function), DepKind::Normal);
1554 self.depend(object, ObjRef::new(PG_CLASS, new.relation), DepKind::Auto);
1555 if new.constraint_relation != 0 {
1556 self.depend(object, ObjRef::new(PG_CLASS, new.constraint_relation), DepKind::Auto);
1557 }
1558 if let Some(constraint) = &constraint {
1559 self.depend(ObjRef::new(PG_CONSTRAINT, constraint.oid), object, DepKind::Internal);
1560 }
1561 for &column in &new.columns {
1562 self.depend(object, ObjRef::column(new.relation, column), DepKind::Normal);
1563 }
1564 self.depend_refs(object, qual);
1565 if new.parent != 0 {
1566 self.depend(object, ObjRef::new(PG_TRIGGER, new.parent), DepKind::PartitionPri);
1567 self.depend(object, ObjRef::new(PG_CLASS, new.relation), DepKind::PartitionSec);
1568 }
1569 let NewTrigger {
1570 name,
1571 relation,
1572 function,
1573 kind,
1574 args,
1575 columns,
1576 old_table,
1577 new_table,
1578 qual,
1579 constraint: _,
1580 constraint_relation,
1581 deferrable,
1582 deferred,
1583 parent,
1584 enabled: _,
1585 } = new;
1586 let trigger = Trigger {
1587 oid,
1588 relation,
1589 name,
1590 function,
1591 kind,
1592 enabled,
1593 args,
1594 columns,
1595 old_table,
1596 new_table,
1597 qual,
1598 constraint: constraint.as_ref().map_or(0, |c| c.oid),
1599 constraint_relation,
1600 deferrable,
1601 deferred,
1602 parent,
1603 ..Trigger::default()
1604 };
1605 if let Some(constraint) = constraint {
1606 self.insert_constraint(constraint);
1607 }
1608 self.triggers.insert(oid, trigger);
1609 self.relation_mut(relation)?.has_triggers = true;
1610 Ok(oid)
1611 }
1612
1613 pub fn rename_trigger(&mut self, oid: u32, name: &str) -> Result<()> {
1619 let Some(relation) = self.triggers.get(&oid).map(|t| t.relation) else {
1620 return Err(no_object("trigger", oid));
1621 };
1622 if self.trigger_by_name(relation, name).is_some() {
1623 let rel = self.relation(relation).map_or("", |r| r.name.as_str());
1624 return Err(Error::new(
1625 SqlState::DUPLICATE_OBJECT,
1626 format!("trigger \"{name}\" for relation \"{rel}\" already exists"),
1627 ));
1628 }
1629 if let Some(trigger) = self.triggers.get_mut(&oid) {
1630 trigger.name = name.to_string();
1631 }
1632 Ok(())
1633 }
1634
1635 pub fn clear_trigger_parent(&mut self, oid: u32) {
1637 if let Some(trigger) = self.triggers.get_mut(&oid) {
1638 trigger.parent = 0;
1639 }
1640 self.drop_partition_depends(ObjRef::new(PG_TRIGGER, oid));
1641 }
1642
1643 pub fn set_trigger_enabled(&mut self, oid: u32, enabled: u8) {
1645 if let Some(trigger) = self.triggers.get_mut(&oid) {
1646 trigger.enabled = enabled;
1647 }
1648 }
1649
1650 pub fn rules(&self) -> impl Iterator<Item = &Rule> {
1652 self.rules.values()
1653 }
1654
1655 pub fn rule(&self, oid: u32) -> Option<&Rule> {
1657 self.rules.get(&oid)
1658 }
1659
1660 pub fn rule_by_name(&self, relation: u32, name: &str) -> Option<&Rule> {
1662 self.rules.values().find(|r| r.relation == relation && r.name == name)
1663 }
1664
1665 pub fn collations(&self) -> impl Iterator<Item = &Collation> {
1667 self.collations.values()
1668 }
1669
1670 pub fn collation(&self, oid: u32) -> Option<&Collation> {
1672 self.collations.get(&oid)
1673 }
1674
1675 pub fn collation_by_name(&self, namespace: u32, name: &str) -> Option<&Collation> {
1677 let find = |encoding: i32| {
1678 self.collations
1679 .values()
1680 .find(|c| c.namespace == namespace && c.name == name && c.encoding == encoding)
1681 };
1682 find(UTF8).or_else(|| find(-1))
1683 }
1684
1685 pub fn constraints_of_domain(&self, domain: u32) -> impl Iterator<Item = &Constraint> {
1687 self.constraints.values().filter(move |c| c.domain == domain)
1688 }
1689
1690 pub fn functions(&self) -> impl Iterator<Item = &Function> {
1692 self.functions.values()
1693 }
1694
1695 pub fn function(&self, oid: u32) -> Option<&Function> {
1697 self.functions.get(&oid)
1698 }
1699
1700 pub fn casts(&self) -> impl Iterator<Item = &Cast> {
1702 self.casts.values()
1703 }
1704
1705 pub fn depends(&self) -> &[Depend] {
1707 &self.depends
1708 }
1709
1710 pub fn descriptions(&self) -> impl Iterator<Item = (ObjRef, &str)> {
1712 self.descriptions.iter().map(|(object, text)| (*object, text.as_str()))
1713 }
1714
1715 pub fn description(&self, object: ObjRef) -> Option<&str> {
1717 self.descriptions.get(&object).map(String::as_str)
1718 }
1719
1720 pub fn set_description(&mut self, object: ObjRef, text: Option<String>) {
1722 match text {
1723 Some(text) => Arc::make_mut(&mut self.descriptions).insert(object, text),
1724 None if self.descriptions.contains_key(&object) => {
1725 Arc::make_mut(&mut self.descriptions).remove(&object)
1726 }
1727 None => None,
1728 };
1729 }
1730
1731 pub fn object_acls(&self) -> impl Iterator<Item = (ObjRef, &[String])> {
1733 self.acls.iter().map(|(object, acl)| (*object, acl.as_slice()))
1734 }
1735
1736 pub fn object_acl(&self, object: ObjRef) -> Option<&[String]> {
1738 self.acls.get(&object).map(Vec::as_slice)
1739 }
1740
1741 pub fn set_object_acl(&mut self, object: ObjRef, acl: Option<Vec<String>>) {
1743 match acl {
1744 Some(acl) => Arc::make_mut(&mut self.acls).insert(object, acl),
1745 None if self.acls.contains_key(&object) => {
1746 Arc::make_mut(&mut self.acls).remove(&object)
1747 }
1748 None => None,
1749 };
1750 }
1751
1752 fn constraint_name_used(&self, namespace: u32, name: &str) -> bool {
1754 self.constraints.values().any(|c| c.namespace == namespace && c.name == name)
1755 }
1756
1757 pub fn choose_relation_name(
1759 &self,
1760 name1: &str,
1761 name2: Option<&str>,
1762 label: &str,
1763 namespace: u32,
1764 constraint: bool,
1765 ) -> String {
1766 let mut pass = 0;
1767 let mut modlabel = label.to_string();
1768 loop {
1769 let name = make_object_name(name1, name2, Some(&modlabel));
1770 let collides = self.relation_by_name(namespace, &name).is_some()
1771 || (constraint && self.constraint_name_used(namespace, &name));
1772 if !collides {
1773 return name;
1774 }
1775 pass += 1;
1776 modlabel = format!("{label}{pass}");
1777 }
1778 }
1779
1780 pub fn choose_constraint_name(
1782 &self,
1783 name1: &str,
1784 name2: Option<&str>,
1785 label: &str,
1786 namespace: u32,
1787 ) -> String {
1788 let mut pass = 0;
1789 let mut modlabel = if label.is_empty() {
1790 pass += 1;
1791 format!("{label}{pass}")
1792 } else {
1793 label.to_string()
1794 };
1795 loop {
1796 let name = make_object_name(name1, name2, Some(&modlabel));
1797 if !self.constraint_name_used(namespace, &name) {
1798 return name;
1799 }
1800 pass += 1;
1801 modlabel = format!("{label}{pass}");
1802 }
1803 }
1804
1805 fn array_type_name(&self, name: &str, namespace: u32) -> String {
1807 let mut array = make_object_name("", Some(name), None);
1808 let mut pass = 0;
1809 while self.type_by_name(namespace, &array).is_some() {
1810 pass += 1;
1811 array = make_object_name("", Some(name), Some(&pass.to_string()));
1812 }
1813 array
1814 }
1815
1816 pub fn rename_relation(&mut self, oid: u32, name: &str) -> Result<()> {
1822 let rel = self.relation(oid).ok_or_else(|| no_object("relation", oid))?;
1823 let (namespace, row_type) = (rel.namespace, rel.row_type);
1824 let table = rel.index.as_ref().map_or(0, |info| info.table);
1825 if self.relation_by_name(namespace, name).is_some() {
1826 return Err(duplicate_table(name));
1827 }
1828 self.relation_mut(oid)?.name = name.to_string();
1829 if row_type != 0 {
1830 self.check_new_type(namespace, name)?;
1831 let array = self.types.get(&row_type).map_or(0, |t| t.array);
1832 let array_name = self.array_type_name(name, namespace);
1833 if let Some(ty) = self.types.get_mut(&row_type) {
1834 ty.name = name.to_string();
1835 }
1836 if let Some(ty) = self.types.get_mut(&array) {
1837 ty.name = array_name;
1838 }
1839 }
1840 let constraint = self
1841 .constraints
1842 .values()
1843 .find(|c| {
1844 c.index == oid
1845 && c.relation == table
1846 && matches!(c.kind, ConKind::Primary | ConKind::Unique)
1847 })
1848 .map(|c| c.oid);
1849 if let Some(constraint) = constraint {
1850 self.rename_constraint(constraint, name)?;
1851 }
1852 Ok(())
1853 }
1854
1855 pub fn rename_column(&mut self, relation: u32, number: i16, name: &str) -> Result<()> {
1861 self.column_mut(relation, number)?.name = name.to_string();
1862 Ok(())
1863 }
1864
1865 pub fn rename_constraint(&mut self, oid: u32, name: &str) -> Result<()> {
1871 let con = self.constraints.get(&oid).ok_or_else(|| no_object("constraint", oid))?;
1872 let relation = con.relation;
1873 if relation != 0 && self.constraints_of(relation).any(|c| c.name == name) {
1874 let table = self.relation(relation).map_or("", |r| r.name.as_str());
1875 return Err(duplicate_constraint(name, table));
1876 }
1877 if let Some(con) = self.constraints.get_mut(&oid) {
1878 con.name = name.to_string();
1879 }
1880 Ok(())
1881 }
1882
1883 pub fn rename_schema(&mut self, oid: u32, name: &str) -> Result<()> {
1889 let schema = self.schemas.get_mut(&oid).ok_or_else(|| no_object("schema", oid))?;
1890 schema.name = name.to_string();
1891 Ok(())
1892 }
1893
1894 pub fn create_schema(&mut self, name: &str, owner: u32) -> Result<u32> {
1896 if self.schema_by_name(name).is_some() {
1897 return Err(Error::new(
1898 SqlState::DUPLICATE_SCHEMA,
1899 format!("schema \"{name}\" already exists"),
1900 ));
1901 }
1902 let oid = self.new_oid();
1903 self.schemas.insert(oid, Schema { oid, name: name.to_string(), owner, acl: None });
1904 Ok(oid)
1905 }
1906
1907 fn check_new_relation(&mut self, namespace: u32, name: &str, row_type: bool) -> Result<()> {
1909 if self.relation_by_name(namespace, name).is_some() {
1910 return Err(duplicate_table(name));
1911 }
1912 if !row_type {
1913 return Ok(());
1914 }
1915 self.check_new_type(namespace, name).map_err(|e| e.with_hint(
1916 "A relation has an associated type of the same name, so you must use a name that doesn't conflict with any existing type.",
1917 ))
1918 }
1919
1920 fn check_new_type(&mut self, namespace: u32, name: &str) -> Result<()> {
1922 let Some(old) = self.type_by_name(namespace, name).map(|t| (t.oid, t.element)) else {
1923 return Ok(());
1924 };
1925 let is_auto_array = old.1 != 0 && self.types.get(&old.1).is_some_and(|e| e.array == old.0);
1926 if !is_auto_array {
1927 return Err(Error::new(
1928 SqlState::DUPLICATE_OBJECT,
1929 format!("type \"{name}\" already exists"),
1930 ));
1931 }
1932 let renamed = self.array_type_name(name, namespace);
1933 if let Some(array) = self.types.get_mut(&old.0) {
1934 array.name = renamed;
1935 }
1936 Ok(())
1937 }
1938
1939 fn check_columns(columns: &[Column]) -> Result<()> {
1940 if columns.len() > MAX_COLUMNS {
1941 return Err(Error::new(
1942 SqlState::TOO_MANY_COLUMNS,
1943 format!("tables can have at most {MAX_COLUMNS} columns"),
1944 ));
1945 }
1946 for (i, column) in columns.iter().enumerate() {
1947 if columns[..i].iter().any(|c| c.name == column.name) {
1948 return Err(Error::new(
1949 SqlState::DUPLICATE_COLUMN,
1950 format!("column \"{}\" specified more than once", column.name),
1951 ));
1952 }
1953 }
1954 Ok(())
1955 }
1956
1957 pub fn add_column(&mut self, table: u32, column: Column) -> Result<i16> {
1963 let refs = [(PG_TYPE, column.ty), (PG_COLLATION, column.collation)];
1964 let rel = self.relation_mut(table)?;
1965 if rel.columns.len() >= MAX_COLUMNS {
1966 return Err(Error::new(
1967 SqlState::TOO_MANY_COLUMNS,
1968 format!("tables can have at most {MAX_COLUMNS} columns"),
1969 ));
1970 }
1971 rel.columns.push(column);
1972 let number = i16::try_from(rel.columns.len()).unwrap_or(i16::MAX);
1973 for (class, found) in refs.into_iter().filter(|&(_, found)| found != 0) {
1974 self.depend(ObjRef::column(table, number), ObjRef::new(class, found), DepKind::Normal);
1975 }
1976 Ok(number)
1977 }
1978
1979 pub fn alter_column_type(&mut self, table: u32, number: i16, new: &Column) -> Result<()> {
1985 let column = self.column_mut(table, number)?;
1986 column.ty = new.ty;
1987 column.typmod = new.typmod;
1988 column.collation = new.collation;
1989 column.ndims = new.ndims;
1990 let me = ObjRef::column(table, number);
1991 self.depends.retain(|d| {
1992 d.object != me
1993 || d.kind != DepKind::Normal
1994 || !matches!(d.referenced.class, PG_TYPE | PG_COLLATION)
1995 });
1996 let refs = [(PG_TYPE, new.ty), (PG_COLLATION, new.collation)];
1997 for (class, found) in refs.into_iter().filter(|&(_, found)| found != 0) {
1998 self.depend(me, ObjRef::new(class, found), DepKind::Normal);
1999 }
2000 Ok(())
2001 }
2002
2003 pub fn set_index_column(
2009 &mut self,
2010 index: u32,
2011 column: usize,
2012 class: u32,
2013 collation: u32,
2014 from: &Column,
2015 ) -> Result<()> {
2016 let rel = self.relation_mut(index)?;
2017 let found = rel.columns.get_mut(column).map(|c| {
2018 c.ty = from.ty;
2019 c.typmod = from.typmod;
2020 c.ndims = from.ndims;
2021 c.collation = collation;
2022 });
2023 if let Some(info) = rel.index.as_mut()
2024 && let (Some(class_at), Some(collation_at)) =
2025 (info.classes.get_mut(column), info.collations.get_mut(column))
2026 {
2027 *class_at = class;
2028 *collation_at = collation;
2029 }
2030 found.ok_or_else(|| no_object(&format!("column {column} of index"), index))
2031 }
2032
2033 pub fn set_foreign_operators(
2039 &mut self,
2040 constraint: u32,
2041 pf_eq: Vec<u32>,
2042 pp_eq: Vec<u32>,
2043 ff_eq: Vec<u32>,
2044 ) -> Result<()> {
2045 let foreign = self.constraints.get_mut(&constraint).and_then(|c| c.foreign.as_mut());
2046 let Some(foreign) = foreign else {
2047 return Err(no_object("foreign key", constraint));
2048 };
2049 foreign.pf_eq = pf_eq;
2050 foreign.pp_eq = pp_eq;
2051 foreign.ff_eq = ff_eq;
2052 Ok(())
2053 }
2054
2055 pub fn create_table(&mut self, new: NewRelation) -> Result<u32> {
2057 self.create_relation(new, RelKind::Table)
2058 }
2059
2060 pub fn create_partitioned_table(&mut self, new: NewRelation) -> Result<u32> {
2062 self.create_relation(new, RelKind::Partitioned)
2063 }
2064
2065 pub fn set_partition_key(&mut self, table: u32, key: PartitionKey) -> Result<()> {
2067 const DEFAULT_COLLATION: u32 = 100;
2069 let class = ObjRef::new(PG_CLASS, table);
2070 let classes = key.classes.iter().map(|&c| ObjRef::new(PG_OPCLASS, c));
2071 let collations = key
2072 .collations
2073 .iter()
2074 .filter(|&&c| c != 0 && c != DEFAULT_COLLATION)
2075 .map(|&c| ObjRef::new(PG_COLLATION, c));
2076 let refs: Vec<ObjRef> = classes.chain(collations).collect();
2077 let Some(rel) = self.relations.get_mut(&table) else {
2078 return Err(no_object("relation", table));
2079 };
2080 rel.partition_key = Some(key);
2081 for found in refs {
2082 self.depend(class, found, DepKind::Normal);
2083 }
2084 Ok(())
2085 }
2086
2087 pub fn attach_partition(
2089 &mut self,
2090 table: u32,
2091 parent: u32,
2092 bound: PartitionBound,
2093 ) -> Result<()> {
2094 let Some(rel) = self.relations.get_mut(&table) else {
2095 return Err(no_object("relation", table));
2096 };
2097 rel.partition_of = Some(PartitionOf { parent, bound });
2098 self.depend(ObjRef::new(PG_CLASS, table), ObjRef::new(PG_CLASS, parent), DepKind::Auto);
2099 Ok(())
2100 }
2101
2102 pub fn set_inherits(&mut self, table: u32, parents: Vec<u32>) -> Result<()> {
2104 let me = ObjRef::new(PG_CLASS, table);
2105 for &parent in &parents {
2106 self.depend(me, ObjRef::new(PG_CLASS, parent), DepKind::Normal);
2107 }
2108 self.relation_mut(table)?.inherits = parents;
2109 Ok(())
2110 }
2111
2112 pub fn add_inherit(&mut self, table: u32, parent: u32) -> Result<()> {
2114 self.depend(ObjRef::new(PG_CLASS, table), ObjRef::new(PG_CLASS, parent), DepKind::Normal);
2115 self.relation_mut(table)?.inherits.push(parent);
2116 Ok(())
2117 }
2118
2119 pub fn set_of_type(&mut self, table: u32, ty: u32) -> Result<()> {
2121 let rel = self.relation_mut(table)?;
2122 let old = std::mem::replace(&mut rel.of_type, ty);
2123 let me = ObjRef::new(PG_CLASS, table);
2124 if old != 0 {
2125 let old = ObjRef::new(PG_TYPE, old);
2126 self.depends
2127 .retain(|d| d.object != me || d.referenced != old || d.kind != DepKind::Normal);
2128 }
2129 if ty != 0 {
2130 self.depend(me, ObjRef::new(PG_TYPE, ty), DepKind::Normal);
2131 }
2132 Ok(())
2133 }
2134
2135 pub fn remove_inherit(&mut self, table: u32, parent: u32) -> Result<()> {
2137 let rel = self.relation_mut(table)?;
2138 for p in &mut rel.inherits {
2139 if *p == parent {
2140 *p = 0;
2141 }
2142 }
2143 while rel.inherits.last() == Some(&0) {
2144 rel.inherits.pop();
2145 }
2146 let me = ObjRef::new(PG_CLASS, table);
2147 let parent = ObjRef::new(PG_CLASS, parent);
2148 self.depends
2149 .retain(|d| d.object != me || d.referenced != parent || d.kind != DepKind::Normal);
2150 Ok(())
2151 }
2152
2153 pub fn children(&self, parent: u32) -> Vec<&Relation> {
2155 let child = |r: &&Relation| {
2156 r.partition_of.as_ref().is_some_and(|p| p.parent == parent)
2157 || r.inherits.contains(&parent)
2158 };
2159 self.relations.values().filter(child).collect()
2160 }
2161
2162 pub fn all_inheritors(&self, table: u32) -> Vec<u32> {
2164 let mut out: Vec<u32> = Vec::new();
2165 let mut at = 0;
2166 let mut parent = table;
2167 loop {
2168 for child in self.children(parent) {
2169 if child.oid != table && !out.contains(&child.oid) {
2170 out.push(child.oid);
2171 }
2172 }
2173 let Some(&next) = out.get(at) else { break };
2174 parent = next;
2175 at += 1;
2176 }
2177 out
2178 }
2179
2180 pub fn partitions(&self, parent: u32) -> Vec<&Relation> {
2182 self.relations
2183 .values()
2184 .filter(|r| r.partition_of.as_ref().is_some_and(|p| p.parent == parent))
2185 .collect()
2186 }
2187
2188 pub fn set_index_parent(&mut self, index: u32, parent: u32) -> Result<()> {
2190 let rel = self.relation_mut(index)?;
2191 let table = rel.index.as_ref().map_or(0, |i| i.table);
2192 if let Some(info) = rel.index.as_mut() {
2193 info.parent = parent;
2194 }
2195 let me = ObjRef::new(PG_CLASS, index);
2196 self.depend(me, ObjRef::new(PG_CLASS, parent), DepKind::PartitionPri);
2197 self.depend(me, ObjRef::new(PG_CLASS, table), DepKind::PartitionSec);
2198 Ok(())
2199 }
2200
2201 pub fn set_constraint_parent(&mut self, constraint: u32, parent: u32) -> Result<()> {
2203 let con = self
2204 .constraints
2205 .get_mut(&constraint)
2206 .ok_or_else(|| no_object("constraint", constraint))?;
2207 con.parent = parent;
2208 con.local = false;
2209 con.inhcount = con.inhcount.saturating_add(1);
2210 con.no_inherit = false;
2211 let table = con.relation;
2212 let me = ObjRef::new(PG_CONSTRAINT, constraint);
2213 self.depend(me, ObjRef::new(PG_CONSTRAINT, parent), DepKind::PartitionPri);
2214 self.depend(me, ObjRef::new(PG_CLASS, table), DepKind::PartitionSec);
2215 Ok(())
2216 }
2217
2218 pub fn set_index_valid(&mut self, index: u32, valid: bool) -> Result<()> {
2220 if let Some(info) = self.relation_mut(index)?.index.as_mut() {
2221 info.valid = valid;
2222 }
2223 Ok(())
2224 }
2225
2226 pub fn set_index_ready(&mut self, index: u32, ready: bool) -> Result<()> {
2228 if let Some(info) = self.relation_mut(index)?.index.as_mut() {
2229 info.ready = ready;
2230 }
2231 Ok(())
2232 }
2233
2234 pub fn set_constraint_inherited(
2236 &mut self,
2237 constraint: u32,
2238 local: bool,
2239 inhcount: i16,
2240 ) -> Result<()> {
2241 let Some(con) = self.constraints.get_mut(&constraint) else {
2242 return Err(no_object("constraint", constraint));
2243 };
2244 con.local = local;
2245 con.inhcount = inhcount;
2246 Ok(())
2247 }
2248
2249 pub fn set_constraint_deferrability(
2251 &mut self,
2252 constraint: u32,
2253 deferrable: bool,
2254 deferred: bool,
2255 ) -> Result<()> {
2256 let Some(con) = self.constraints.get_mut(&constraint) else {
2257 return Err(no_object("constraint", constraint));
2258 };
2259 con.deferrable = deferrable;
2260 con.deferred = deferred;
2261 let deferring = [0, 1, 10, 11].map(|at| RI_FKEY_CHECK_INS + at);
2263 for trigger in self.triggers.values_mut() {
2264 if trigger.constraint == constraint && deferring.contains(&trigger.function) {
2265 trigger.deferrable = deferrable;
2266 trigger.deferred = deferred;
2267 }
2268 }
2269 Ok(())
2270 }
2271
2272 pub fn set_constraint_no_inherit(&mut self, constraint: u32, no_inherit: bool) -> Result<()> {
2274 let Some(con) = self.constraints.get_mut(&constraint) else {
2275 return Err(no_object("constraint", constraint));
2276 };
2277 con.no_inherit = no_inherit;
2278 Ok(())
2279 }
2280
2281 pub fn set_constraint_enforced(&mut self, constraint: u32, enforced: bool) -> Result<()> {
2283 let Some(con) = self.constraints.get_mut(&constraint) else {
2284 return Err(no_object("constraint", constraint));
2285 };
2286 con.enforced = enforced;
2287 con.validated = enforced;
2288 Ok(())
2289 }
2290
2291 pub fn set_constraint_validated(&mut self, constraint: u32, validated: bool) -> Result<()> {
2293 let Some(con) = self.constraints.get_mut(&constraint) else {
2294 return Err(no_object("constraint", constraint));
2295 };
2296 con.validated = validated;
2297 if con.kind == ConKind::NotNull
2299 && let [number] = con.keys[..]
2300 {
2301 let relation = con.relation;
2302 self.column_mut(relation, number)?.not_null_invalid = !validated;
2303 }
2304 Ok(())
2305 }
2306
2307 pub fn set_column_inherited(
2309 &mut self,
2310 table: u32,
2311 number: i16,
2312 local: bool,
2313 inhcount: i16,
2314 ) -> Result<()> {
2315 let rel = self.relation_mut(table)?;
2316 let at = usize::try_from(number).ok().and_then(|n| n.checked_sub(1));
2317 let Some(column) = at.and_then(|at| rel.columns.get_mut(at)) else {
2318 return Err(no_object("column", u32::try_from(number).unwrap_or_default()));
2319 };
2320 column.local = local;
2321 column.inhcount = inhcount;
2322 Ok(())
2323 }
2324
2325 pub fn detach_partition(&mut self, table: u32) -> Result<()> {
2327 let Some(of) = self.relation_mut(table)?.partition_of.take() else { return Ok(()) };
2328 let me = ObjRef::new(PG_CLASS, table);
2329 let parent = ObjRef::new(PG_CLASS, of.parent);
2330 self.depends
2331 .retain(|d| d.object != me || d.referenced != parent || d.kind != DepKind::Auto);
2332 Ok(())
2333 }
2334
2335 pub fn clear_index_parent(&mut self, index: u32) -> Result<()> {
2337 if let Some(info) = self.relation_mut(index)?.index.as_mut() {
2338 info.parent = 0;
2339 }
2340 self.drop_partition_depends(ObjRef::new(PG_CLASS, index));
2341 Ok(())
2342 }
2343
2344 pub fn clear_constraint_parent(&mut self, constraint: u32) -> Result<()> {
2346 let con = self
2347 .constraints
2348 .get_mut(&constraint)
2349 .ok_or_else(|| no_object("constraint", constraint))?;
2350 con.parent = 0;
2351 con.local = true;
2352 con.inhcount = con.inhcount.saturating_sub(1);
2353 self.drop_partition_depends(ObjRef::new(PG_CONSTRAINT, constraint));
2354 Ok(())
2355 }
2356
2357 fn drop_partition_depends(&mut self, object: ObjRef) {
2359 self.depends.retain(|d| {
2360 d.object != object || !matches!(d.kind, DepKind::PartitionPri | DepKind::PartitionSec)
2361 });
2362 }
2363
2364 fn create_relation(&mut self, new: NewRelation, kind: RelKind) -> Result<u32> {
2366 Catalog::check_columns(&new.columns)?;
2367 self.check_new_relation(new.namespace, &new.name, true)?;
2368 let oid = self.new_oid();
2369 let array = self.new_oid();
2370 let row_type = self.new_oid();
2371 let array_name = self.array_type_name(&new.name, new.namespace);
2372 let column_refs: Vec<(ObjRef, ObjRef)> = (1i16..)
2373 .zip(&new.columns)
2374 .flat_map(|(n, c)| {
2375 let types = [(PG_TYPE, c.ty), (PG_COLLATION, c.collation)];
2376 types
2377 .into_iter()
2378 .filter(|&(_, found)| found != 0)
2379 .map(move |(class, found)| (ObjRef::column(oid, n), ObjRef::new(class, found)))
2380 })
2381 .collect();
2382 self.types.insert(
2383 row_type,
2384 Type {
2385 oid: row_type,
2386 name: new.name.clone(),
2387 namespace: new.namespace,
2388 owner: new.owner,
2389 relation: oid,
2390 element: 0,
2391 array,
2392 domain: None,
2393 labels: None,
2394 range: None,
2395 },
2396 );
2397 self.types.insert(
2398 array,
2399 Type {
2400 oid: array,
2401 name: array_name,
2402 namespace: new.namespace,
2403 owner: new.owner,
2404 relation: 0,
2405 element: row_type,
2406 array: 0,
2407 domain: None,
2408 labels: None,
2409 range: None,
2410 },
2411 );
2412 self.relations.insert(
2413 oid,
2414 Relation {
2415 oid,
2416 file: oid,
2417 name: new.name,
2418 namespace: new.namespace,
2419 kind,
2420 owner: new.owner,
2421 row_type,
2422 columns: new.columns,
2423 has_index: false,
2424 has_triggers: false,
2425 toast: 0,
2426 index: None,
2427 sequence: None,
2428 view: None,
2429 options: Vec::new(),
2430 acl: None,
2431 replica_identity: 0,
2432 partition_key: None,
2433 partition_of: None,
2434 inherits: Vec::new(),
2435 of_type: 0,
2436 unlogged: false,
2437 },
2438 );
2439 let (class, ty) = (ObjRef::new(PG_CLASS, oid), ObjRef::new(PG_TYPE, row_type));
2440 let namespace = ObjRef::new(PG_NAMESPACE, new.namespace);
2441 if kind == RelKind::Composite {
2443 self.depend(ty, namespace, DepKind::Normal);
2444 self.depend(class, ty, DepKind::Internal);
2445 } else {
2446 self.depend(ty, class, DepKind::Internal);
2447 }
2448 self.depend(ObjRef::new(PG_TYPE, array), ty, DepKind::Internal);
2449 for (column, found) in column_refs {
2450 self.depend(column, found, DepKind::Normal);
2451 }
2452 if kind != RelKind::Composite {
2453 self.depend(class, namespace, DepKind::Normal);
2454 }
2455 Ok(oid)
2456 }
2457
2458 pub fn create_composite_type(&mut self, new: NewRelation) -> Result<u32> {
2460 let oid = self.create_relation(new, RelKind::Composite)?;
2461 Ok(self.relation(oid).map_or(0, |r| r.row_type))
2462 }
2463
2464 pub fn create_view(
2466 &mut self,
2467 new: NewRelation,
2468 text: String,
2469 path: Vec<u32>,
2470 refs: &[ObjRef],
2471 ) -> Result<u32> {
2472 let oid = self.create_relation(new, RelKind::View)?;
2473 let rule = self.new_oid();
2474 self.relation_mut(oid)?.view = Some(ViewInfo { rule, text, path, populated: true });
2475 self.depend_rule(rule, oid, refs);
2476 Ok(oid)
2477 }
2478
2479 pub fn make_matview(
2481 &mut self,
2482 oid: u32,
2483 text: String,
2484 path: Vec<u32>,
2485 refs: &[ObjRef],
2486 populated: bool,
2487 ) -> Result<()> {
2488 let rule = self.new_oid();
2489 let rel = self.relation_mut(oid)?;
2490 rel.kind = RelKind::MatView;
2491 rel.view = Some(ViewInfo { rule, text, path, populated });
2492 self.depend_rule(rule, oid, refs);
2493 Ok(())
2494 }
2495
2496 pub fn set_populated(&mut self, oid: u32, populated: bool) -> Result<()> {
2498 let view = self.relation_mut(oid)?.view.as_mut().ok_or_else(|| no_object("view", oid))?;
2499 view.populated = populated;
2500 Ok(())
2501 }
2502
2503 pub fn replace_view(
2505 &mut self,
2506 oid: u32,
2507 columns: Vec<Column>,
2508 text: String,
2509 path: Vec<u32>,
2510 refs: &[ObjRef],
2511 ) -> Result<()> {
2512 Catalog::check_columns(&columns)?;
2513 let rel = self.relation_mut(oid)?;
2514 let old = rel.columns.len();
2515 rel.columns.extend(columns.into_iter().skip(old));
2516 let view = rel.view.as_mut().ok_or_else(|| no_object("view", oid))?;
2517 view.text = text;
2518 view.path = path;
2519 let rule = view.rule;
2520 self.depends.retain(|d| d.object != ObjRef::new(PG_REWRITE, rule));
2521 self.depend_rule(rule, oid, refs);
2522 Ok(())
2523 }
2524
2525 pub fn set_view_text(&mut self, oid: u32, text: String, path: Vec<u32>) -> Result<()> {
2527 let view = self.relation_mut(oid)?.view.as_mut().ok_or_else(|| no_object("view", oid))?;
2528 view.text = text;
2529 view.path = path;
2530 Ok(())
2531 }
2532
2533 pub fn create_rule(
2539 &mut self,
2540 new: NewRule,
2541 replace: bool,
2542 actions: &[ObjRef],
2543 qual: &[ObjRef],
2544 ) -> Result<u32> {
2545 let old = self.rule_by_name(new.relation, &new.name).map(|r| r.oid);
2546 let oid = match old {
2547 Some(_) if !replace => {
2548 let relation = self.relation(new.relation).map_or("", |r| r.name.as_str());
2549 return Err(Error::new(
2550 SqlState::DUPLICATE_OBJECT,
2551 format!("rule \"{}\" for relation \"{relation}\" already exists", new.name),
2552 ));
2553 }
2554 Some(oid) => oid,
2555 None => self.new_oid(),
2556 };
2557 let enabled = self.rules.get(&oid).map_or(b'O', |r| r.enabled);
2558 let object = ObjRef::new(PG_REWRITE, oid);
2559 self.depends.retain(|d| d.object != object);
2560 let kind = if new.event == b'1' { DepKind::Internal } else { DepKind::Auto };
2561 self.depend(object, ObjRef::new(PG_CLASS, new.relation), kind);
2562 self.depend_refs(object, actions);
2563 self.depend_refs(object, qual);
2564 let NewRule { name, relation, event, instead, qualified, text, path } = new;
2565 let rule = Rule { oid, name, relation, event, instead, enabled, qualified, text, path };
2566 self.rules.insert(oid, rule);
2567 Ok(oid)
2568 }
2569
2570 pub fn create_collation(&mut self, collation: Collation, comment: Option<&str>) -> Option<u32> {
2572 let conflict = self.collations.values().any(|c| {
2573 c.namespace == collation.namespace
2574 && c.name == collation.name
2575 && collation_conflict(c.encoding, collation.encoding)
2576 });
2577 if conflict {
2578 return None;
2579 }
2580 let oid = self.new_oid();
2581 Arc::make_mut(&mut self.collations).insert(oid, Collation { oid, ..collation });
2582 if let Some(comment) = comment {
2583 self.set_description(ObjRef::new(PG_COLLATION, oid), Some(comment.to_string()));
2584 }
2585 Some(oid)
2586 }
2587
2588 fn depend_rule(&mut self, rule: u32, view: u32, refs: &[ObjRef]) {
2590 let object = ObjRef::new(PG_REWRITE, rule);
2591 self.depend(object, ObjRef::new(PG_CLASS, view), DepKind::Internal);
2592 self.depend_refs(object, refs);
2593 }
2594
2595 fn depend_refs(&mut self, object: ObjRef, refs: &[ObjRef]) {
2597 for referenced in eliminate_duplicates(refs) {
2598 self.depend(object, referenced, DepKind::Normal);
2599 }
2600 }
2601
2602 pub fn set_options(&mut self, oid: u32, options: Vec<String>) -> Result<()> {
2604 self.relation_mut(oid)?.options = options;
2605 Ok(())
2606 }
2607
2608 pub fn set_clustered(&mut self, table: u32, index: Option<u32>) {
2610 for rel in self.relations.values_mut() {
2611 if let Some(info) = rel.index.as_mut().filter(|i| i.table == table) {
2612 info.clustered = Some(rel.oid) == index;
2613 }
2614 }
2615 }
2616
2617 pub fn set_replica_identity(&mut self, table: u32, code: u8, index: Option<u32>) -> Result<()> {
2619 self.relation_mut(table)?.replica_identity = code;
2620 for rel in self.relations.values_mut() {
2621 if let Some(info) = rel.index.as_mut().filter(|i| i.table == table) {
2622 info.replica_identity = Some(rel.oid) == index;
2623 }
2624 }
2625 Ok(())
2626 }
2627
2628 pub fn set_schema_acl(&mut self, oid: u32, acl: Option<Vec<String>>) -> Result<()> {
2630 self.schemas.get_mut(&oid).ok_or_else(|| no_object("schema", oid))?.acl = acl;
2631 Ok(())
2632 }
2633
2634 pub fn create_domain(&mut self, new: NewDomain, refs: &[ObjRef]) -> Result<u32> {
2636 self.check_new_type(new.namespace, &new.name)?;
2637 let array = self.new_oid();
2638 let oid = self.new_oid();
2639 let array_name = self.array_type_name(&new.name, new.namespace);
2640 let base = new.domain.base;
2641 let collation = new.domain.collation;
2642 self.types.insert(
2643 oid,
2644 Type {
2645 oid,
2646 name: new.name,
2647 namespace: new.namespace,
2648 owner: new.owner,
2649 relation: 0,
2650 element: 0,
2651 array,
2652 domain: Some(new.domain),
2653 labels: None,
2654 range: None,
2655 },
2656 );
2657 self.types.insert(
2658 array,
2659 Type {
2660 oid: array,
2661 name: array_name,
2662 namespace: new.namespace,
2663 owner: new.owner,
2664 relation: 0,
2665 element: oid,
2666 array: 0,
2667 domain: None,
2668 labels: None,
2669 range: None,
2670 },
2671 );
2672 let me = ObjRef::new(PG_TYPE, oid);
2674 self.depend(me, ObjRef::new(PG_TYPE, base), DepKind::Normal);
2675 self.depend(me, ObjRef::new(PG_NAMESPACE, new.namespace), DepKind::Normal);
2676 if collation != 0 {
2677 self.depend(me, ObjRef::new(PG_COLLATION, collation), DepKind::Normal);
2678 }
2679 for &referenced in refs {
2680 self.depend(me, referenced, DepKind::Normal);
2681 }
2682 self.depend(ObjRef::new(PG_TYPE, array), me, DepKind::Internal);
2683 Ok(oid)
2684 }
2685
2686 pub fn create_enum(&mut self, new: NewEnum) -> Result<u32> {
2692 self.check_new_type(new.namespace, &new.name)?;
2693 let array = self.new_oid();
2694 let oid = self.new_oid();
2695 let mut labels = Vec::with_capacity(new.labels.len());
2696 for (i, label) in new.labels.into_iter().enumerate() {
2697 let mut label_oid = self.new_oid();
2698 while label_oid & 1 != 0 {
2699 label_oid = self.new_oid();
2700 }
2701 labels.push(EnumLabel { oid: label_oid, sort_order: (i + 1) as f32, label });
2702 }
2703 let array_name = self.array_type_name(&new.name, new.namespace);
2704 self.types.insert(
2705 oid,
2706 Type {
2707 oid,
2708 name: new.name,
2709 namespace: new.namespace,
2710 owner: new.owner,
2711 relation: 0,
2712 element: 0,
2713 array,
2714 domain: None,
2715 labels: Some(labels),
2716 range: None,
2717 },
2718 );
2719 self.types.insert(
2720 array,
2721 Type {
2722 oid: array,
2723 name: array_name,
2724 namespace: new.namespace,
2725 owner: new.owner,
2726 relation: 0,
2727 element: oid,
2728 array: 0,
2729 domain: None,
2730 labels: None,
2731 range: None,
2732 },
2733 );
2734 let me = ObjRef::new(PG_TYPE, oid);
2735 self.depend(me, ObjRef::new(PG_NAMESPACE, new.namespace), DepKind::Normal);
2736 self.depend(ObjRef::new(PG_TYPE, array), me, DepKind::Internal);
2737 self.uncommitted_types.push(oid);
2738 Ok(oid)
2739 }
2740
2741 pub fn create_range(&mut self, new: NewRange) -> Result<u32> {
2747 self.check_new_type(new.namespace, &new.name)?;
2748 let array = self.new_oid();
2749 let multirange = self.new_oid();
2750 let multirange_array = self.new_oid();
2751 let oid = self.new_oid();
2752 let mut info = new.info;
2753 info.multirange = multirange;
2754 let facts = info.clone();
2755 let type_of = |oid: u32, name: String, namespace: u32| Type {
2756 oid,
2757 name,
2758 namespace,
2759 owner: new.owner,
2760 relation: 0,
2761 element: 0,
2762 array: 0,
2763 domain: None,
2764 labels: None,
2765 range: None,
2766 };
2767 let me = ObjRef::new(PG_TYPE, oid);
2768 let multi = ObjRef::new(PG_TYPE, multirange);
2769 let range = Type {
2770 array,
2771 range: Some(RangePart::Range(info)),
2772 ..type_of(oid, new.name.clone(), new.namespace)
2773 };
2774 self.types.insert(oid, range);
2775 self.depend(me, ObjRef::new(PG_NAMESPACE, new.namespace), DepKind::Normal);
2776 self.check_new_type(new.multirange_namespace, &new.multirange_name)?;
2777 let multirange_type = Type {
2778 array: multirange_array,
2779 range: Some(RangePart::Multirange(oid)),
2780 ..type_of(multirange, new.multirange_name.clone(), new.multirange_namespace)
2781 };
2782 self.types.insert(multirange, multirange_type);
2783 self.depend(multi, ObjRef::new(PG_NAMESPACE, new.multirange_namespace), DepKind::Normal);
2784 let array_name = self.array_type_name(&new.name, new.namespace);
2785 self.types
2786 .insert(array, Type { element: oid, ..type_of(array, array_name, new.namespace) });
2787 self.depend(ObjRef::new(PG_TYPE, array), me, DepKind::Internal);
2788 let multirange_array_name = self.array_type_name(&new.multirange_name, new.namespace);
2790 let multirange_array_type = Type {
2791 element: multirange,
2792 ..type_of(multirange_array, multirange_array_name, new.multirange_namespace)
2793 };
2794 self.types.insert(multirange_array, multirange_array_type);
2795 self.depend(ObjRef::new(PG_TYPE, multirange_array), multi, DepKind::Internal);
2796 let constructor = |name: &str, src: &str, rettype: u32, argtypes: Vec<u32>| Function {
2797 oid: 0,
2798 name: name.to_string(),
2799 namespace: new.namespace,
2800 owner: BOOTSTRAP_SUPERUSER,
2801 lang: INTERNAL_LANGUAGE,
2802 cost: 1.0,
2803 rows: 0,
2804 support: 0,
2805 kind: b'f',
2806 strict: rettype == multirange,
2808 leakproof: false,
2809 volatile: b'i',
2810 parallel: b's',
2811 rettype,
2812 retset: false,
2813 argtypes,
2814 allargtypes: Vec::new(),
2815 argmodes: Vec::new(),
2816 argnames: Vec::new(),
2817 argdefaults: None,
2818 nargdefaults: 0,
2819 src: src.to_string(),
2820 bin: String::new(),
2821 body: None,
2822 config: Vec::new(),
2823 secdef: false,
2824 };
2825 let multirange_name = new.multirange_name.as_str();
2826 let variadic = Function {
2827 allargtypes: vec![array],
2828 argmodes: vec![b'v'],
2829 ..constructor(multirange_name, "multirange_constructor2", multirange, vec![array])
2830 };
2831 let functions = [
2832 (constructor(&new.name, "range_constructor2", oid, vec![facts.subtype; 2]), me),
2833 (
2834 constructor(
2835 &new.name,
2836 "range_constructor3",
2837 oid,
2838 vec![facts.subtype, facts.subtype, TEXT],
2839 ),
2840 me,
2841 ),
2842 (
2843 constructor(multirange_name, "multirange_constructor0", multirange, Vec::new()),
2844 multi,
2845 ),
2846 (constructor(multirange_name, "multirange_constructor1", multirange, vec![oid]), multi),
2847 (variadic, multi),
2848 ];
2849 let mut constructors = [0; 5];
2850 for (slot, (function, owner)) in constructors.iter_mut().zip(functions) {
2851 *slot = self.insert_constructor(function, owner);
2852 }
2853 let refs = [
2855 ObjRef::new(PG_TYPE, facts.subtype),
2856 ObjRef::new(PG_OPCLASS, facts.subopc),
2857 ObjRef::new(PG_COLLATION, facts.collation),
2858 ObjRef::new(PG_PROC, facts.canonical),
2859 ObjRef::new(PG_PROC, facts.subdiff),
2860 ];
2861 for referenced in refs {
2862 if referenced.oid != 0 {
2863 self.depend(me, referenced, DepKind::Normal);
2864 }
2865 }
2866 self.depend(multi, me, DepKind::Internal);
2867 if let Some(Type { range: Some(RangePart::Range(info)), .. }) = self.types.get_mut(&oid) {
2868 info.constructors = constructors;
2869 }
2870 let cast = self.new_oid();
2871 let row = Cast {
2872 oid: cast,
2873 source: oid,
2874 target: multirange,
2875 func: constructors[3],
2876 context: b'e',
2877 method: b'f',
2878 };
2879 self.casts.insert(cast, row);
2880 let object = ObjRef::new(PG_CAST, cast);
2881 for referenced in [me, multi, ObjRef::new(PG_PROC, constructors[3])] {
2882 self.depend(object, referenced, DepKind::Internal);
2883 }
2884 Ok(oid)
2885 }
2886
2887 fn insert_constructor(&mut self, mut function: Function, owner: ObjRef) -> u32 {
2889 let oid = self.new_oid();
2890 function.oid = oid;
2891 let me = ObjRef::new(PG_PROC, oid);
2892 self.depend(me, ObjRef::new(PG_NAMESPACE, function.namespace), DepKind::Normal);
2893 let mut types = vec![function.rettype];
2894 for &ty in function.argtypes.iter().chain(&function.allargtypes) {
2895 if !types.contains(&ty) {
2896 types.push(ty);
2897 }
2898 }
2899 for ty in types {
2900 self.depend(me, ObjRef::new(PG_TYPE, ty), DepKind::Normal);
2901 }
2902 self.depend(me, owner, DepKind::Internal);
2903 self.functions.insert(oid, function);
2904 oid
2905 }
2906
2907 pub fn create_function(&mut self, mut new: Function, refs: &[ObjRef]) -> Result<u32> {
2913 if self.functions.values().any(|f| {
2914 f.namespace == new.namespace && f.name == new.name && f.argtypes == new.argtypes
2915 }) {
2916 return Err(Error::new(
2917 SqlState::DUPLICATE_FUNCTION,
2918 format!("function \"{}\" already exists with same argument types", new.name),
2919 ));
2920 }
2921 let oid = self.new_oid();
2922 new.oid = oid;
2923 let me = ObjRef::new(PG_PROC, oid);
2924 self.depend(me, ObjRef::new(PG_NAMESPACE, new.namespace), DepKind::Normal);
2925 for &referenced in refs {
2926 self.depend(me, referenced, DepKind::Normal);
2927 }
2928 self.functions.insert(oid, new);
2929 Ok(oid)
2930 }
2931
2932 pub fn replace_function(&mut self, oid: u32, mut new: Function, refs: &[ObjRef]) -> Result<()> {
2938 let old = self.functions.get(&oid).ok_or_else(|| no_object("function", oid))?;
2939 new.oid = oid;
2940 new.owner = old.owner;
2941 let me = ObjRef::new(PG_PROC, oid);
2942 self.depends.retain(|d| d.object != me);
2943 self.depend(me, ObjRef::new(PG_NAMESPACE, new.namespace), DepKind::Normal);
2944 for &referenced in refs {
2945 self.depend(me, referenced, DepKind::Normal);
2946 }
2947 self.functions.insert(oid, new);
2948 Ok(())
2949 }
2950
2951 pub fn alter_function(&mut self, oid: u32, change: impl FnOnce(&mut Function)) -> Result<()> {
2957 let function = self.functions.get_mut(&oid).ok_or_else(|| no_object("function", oid))?;
2958 let old = function.namespace;
2959 change(function);
2960 let new = function.namespace;
2961 if old != new {
2962 self.change_namespace_dependency(ObjRef::new(PG_PROC, oid), old, new);
2963 }
2964 Ok(())
2965 }
2966
2967 pub fn create_extension(&mut self, mut new: Extension) -> Result<u32> {
2973 if self.extensions.values().any(|e| e.name == new.name) {
2974 return Err(Error::new(
2975 SqlState::DUPLICATE_OBJECT,
2976 format!("extension \"{}\" already exists", new.name),
2977 ));
2978 }
2979 let oid = self.new_oid();
2980 new.oid = oid;
2981 self.depend(
2982 ObjRef::new(PG_EXTENSION, oid),
2983 ObjRef::new(PG_NAMESPACE, new.namespace),
2984 DepKind::Normal,
2985 );
2986 self.extensions.insert(oid, new);
2987 Ok(oid)
2988 }
2989
2990 pub fn add_to_extension(&mut self, object: ObjRef, extension: u32) {
2992 self.depend(object, ObjRef::new(PG_EXTENSION, extension), DepKind::Extension);
2993 }
2994
2995 pub fn create_language(&mut self, mut new: Language) -> Result<u32> {
3001 if self.languages.values().any(|l| l.name == new.name) {
3002 return Err(Error::new(
3003 SqlState::DUPLICATE_OBJECT,
3004 format!("language \"{}\" already exists", new.name),
3005 ));
3006 }
3007 let oid = self.new_oid();
3008 new.oid = oid;
3009 let me = ObjRef::new(PG_LANGUAGE, oid);
3010 for handler in [new.handler, new.inline, new.validator] {
3011 if handler != 0 {
3012 self.depend(me, ObjRef::new(PG_PROC, handler), DepKind::Normal);
3013 }
3014 }
3015 self.languages.insert(oid, new);
3016 Ok(oid)
3017 }
3018
3019 pub fn languages(&self) -> impl Iterator<Item = &Language> {
3021 self.languages.values()
3022 }
3023
3024 pub fn extensions(&self) -> impl Iterator<Item = &Extension> {
3026 self.extensions.values()
3027 }
3028
3029 pub fn add_domain_check(
3031 &mut self,
3032 domain: u32,
3033 name: Option<&str>,
3034 expr: String,
3035 refs: &[ObjRef],
3036 ) -> Result<u32> {
3037 let ty = self.types.get(&domain).ok_or_else(|| no_object("type", domain))?;
3038 let (domain_name, namespace) = (ty.name.clone(), ty.namespace);
3039 let name = match name {
3040 Some(name) => self.new_domain_constraint_name(domain, &domain_name, name)?,
3041 None => self.choose_constraint_name(&domain_name, None, "check", namespace),
3042 };
3043 let mut constraint = self.new_constraint(name, namespace, ConKind::Check, 0, Vec::new());
3044 constraint.domain = domain;
3045 constraint.expr = Some(expr);
3046 let me = ObjRef::new(PG_CONSTRAINT, constraint.oid);
3047 let oid = constraint.oid;
3048 self.insert_constraint(constraint);
3049 self.depend(me, ObjRef::new(PG_TYPE, domain), DepKind::Auto);
3050 for &referenced in refs {
3051 self.depend(me, referenced, DepKind::Normal);
3052 }
3053 Ok(oid)
3054 }
3055
3056 fn new_domain_constraint_name(
3058 &self,
3059 domain: u32,
3060 domain_name: &str,
3061 name: &str,
3062 ) -> Result<String> {
3063 if self.constraints_of_domain(domain).any(|c| c.name == name) {
3064 return Err(Error::new(
3065 SqlState::DUPLICATE_OBJECT,
3066 format!("constraint \"{name}\" for domain \"{domain_name}\" already exists"),
3067 ));
3068 }
3069 Ok(name.to_string())
3070 }
3071
3072 pub fn add_domain_not_null(&mut self, domain: u32, name: Option<&str>) -> Result<u32> {
3074 let ty = self.types.get(&domain).ok_or_else(|| no_object("type", domain))?;
3075 let (domain_name, namespace) = (ty.name.clone(), ty.namespace);
3076 let name = match name {
3077 Some(name) => self.new_domain_constraint_name(domain, &domain_name, name)?,
3078 None => self.choose_constraint_name(&domain_name, None, "not_null", namespace),
3079 };
3080 let mut constraint = self.new_constraint(name, namespace, ConKind::NotNull, 0, Vec::new());
3081 constraint.domain = domain;
3082 let me = ObjRef::new(PG_CONSTRAINT, constraint.oid);
3083 let oid = constraint.oid;
3084 self.insert_constraint(constraint);
3085 self.depend(me, ObjRef::new(PG_TYPE, domain), DepKind::Auto);
3086 if let Some(Type { domain: Some(facts), .. }) = self.types.get_mut(&domain) {
3087 facts.not_null = true;
3088 }
3089 Ok(oid)
3090 }
3091
3092 pub fn set_new_file(&mut self, oid: u32) -> Result<()> {
3094 let file = self.new_oid();
3095 self.relation_mut(oid)?.file = file;
3096 Ok(())
3097 }
3098
3099 pub fn set_acl(&mut self, oid: u32, acl: Option<Vec<String>>) -> Result<()> {
3101 self.relation_mut(oid)?.acl = acl;
3102 Ok(())
3103 }
3104
3105 pub fn create_sequence(&mut self, mut new: NewRelation, mut info: SequenceInfo) -> Result<u32> {
3107 self.check_new_relation(new.namespace, &new.name, false)?;
3108 for column in &mut new.columns {
3109 column.not_null = true;
3110 }
3111 let oid = self.new_oid();
3112 info.file = oid;
3113 self.relations.insert(
3114 oid,
3115 Relation {
3116 oid,
3117 file: oid,
3118 name: new.name,
3119 namespace: new.namespace,
3120 kind: RelKind::Sequence,
3121 owner: new.owner,
3122 row_type: 0,
3123 columns: new.columns,
3124 has_index: false,
3125 has_triggers: false,
3126 toast: 0,
3127 index: None,
3128 sequence: Some(info),
3129 view: None,
3130 options: Vec::new(),
3131 acl: None,
3132 replica_identity: 0,
3133 partition_key: None,
3134 partition_of: None,
3135 inherits: Vec::new(),
3136 of_type: 0,
3137 unlogged: false,
3138 },
3139 );
3140 self.depend(
3141 ObjRef::new(PG_CLASS, oid),
3142 ObjRef::new(PG_NAMESPACE, new.namespace),
3143 DepKind::Normal,
3144 );
3145 Ok(oid)
3146 }
3147
3148 pub fn set_sequence_owner(&mut self, sequence: u32, table: u32, column: i16) {
3150 self.depend(ObjRef::new(PG_CLASS, sequence), ObjRef::column(table, column), DepKind::Auto);
3151 }
3152
3153 pub fn set_unlogged(&mut self, oid: u32, unlogged: bool) -> Result<()> {
3159 let rel = self.relation(oid).ok_or_else(|| no_object("relation", oid))?;
3160 let mut change = vec![oid];
3161 if rel.sequence.is_none() {
3162 let toast = rel.toast;
3163 change.extend(self.owned_sequences(oid));
3164 for (&index, rel) in &self.relations {
3165 if rel
3166 .index
3167 .as_ref()
3168 .is_some_and(|i| i.table == oid || (toast != 0 && i.table == toast))
3169 {
3170 change.push(index);
3171 }
3172 }
3173 if toast != 0 {
3174 change.push(toast);
3175 }
3176 }
3177 for oid in change {
3178 self.relation_mut(oid)?.unlogged = unlogged;
3179 }
3180 Ok(())
3181 }
3182
3183 fn relation_mut(&mut self, oid: u32) -> Result<&mut Relation> {
3184 self.relations.get_mut(&oid).ok_or_else(|| no_object("relation", oid))
3185 }
3186
3187 fn column_mut(&mut self, relation: u32, column: i16) -> Result<&mut Column> {
3188 let index = usize::try_from(column).ok().and_then(|n| n.checked_sub(1));
3189 let rel = self.relation_mut(relation)?;
3190 index
3191 .and_then(|i| rel.columns.get_mut(i))
3192 .ok_or_else(|| no_object(&format!("attribute {column} of relation"), relation))
3193 }
3194
3195 pub fn change_stored_exprs(
3201 &mut self,
3202 change: &mut dyn FnMut(&str, bool) -> Result<Option<String>>,
3203 ) -> Result<()> {
3204 for default in self.defaults.values_mut() {
3205 if let Some(new) = change(&default.expr, false)? {
3206 default.expr = new;
3207 }
3208 }
3209 for con in self.constraints.values_mut() {
3210 if let Some(expr) = &mut con.expr
3211 && let Some(new) = change(expr, false)?
3212 {
3213 *expr = new;
3214 }
3215 }
3216 for ty in self.types.values_mut() {
3217 if let Some(expr) = ty.domain.as_mut().and_then(|d| d.default.as_mut())
3218 && let Some(new) = change(expr, false)?
3219 {
3220 *expr = new;
3221 }
3222 }
3223 for info in self.relations.values_mut().filter_map(|r| r.index.as_mut()) {
3224 if let Some(exprs) = &mut info.exprs
3225 && let Some(new) = change(exprs, true)?
3226 {
3227 *exprs = new;
3228 }
3229 if let Some(predicate) = &mut info.predicate
3230 && let Some(new) = change(predicate, false)?
3231 {
3232 *predicate = new;
3233 }
3234 }
3235 Ok(())
3236 }
3237
3238 pub fn add_default(
3240 &mut self,
3241 relation: u32,
3242 column: i16,
3243 expr: String,
3244 refs: &[ObjRef],
3245 ) -> Result<u32> {
3246 let attr = self.column_mut(relation, column)?;
3247 attr.has_default = true;
3248 let kind = if attr.generated != 0 { DepKind::Internal } else { DepKind::Auto };
3250 let oid = self.new_oid();
3251 self.defaults.insert(oid, AttrDefault { oid, relation, column, expr });
3252 let me = ObjRef::new(PG_ATTRDEF, oid);
3253 self.depend(me, ObjRef::column(relation, column), kind);
3254 self.depend_on_expr(me, refs, relation, DepKind::Normal);
3255 Ok(oid)
3256 }
3257
3258 pub fn set_identity(&mut self, relation: u32, column: i16, identity: u8) -> Result<()> {
3260 self.column_mut(relation, column)?.identity = identity;
3261 Ok(())
3262 }
3263
3264 pub fn set_stat_target(
3266 &mut self,
3267 relation: u32,
3268 column: i16,
3269 target: Option<i16>,
3270 ) -> Result<()> {
3271 self.column_mut(relation, column)?.stat_target = target;
3272 Ok(())
3273 }
3274
3275 pub fn set_storage(&mut self, relation: u32, column: i16, storage: u8) -> Result<()> {
3277 self.column_mut(relation, column)?.storage = storage;
3278 for (index, number) in self.index_columns_of(relation, column) {
3279 self.column_mut(index, number)?.storage = storage;
3280 }
3281 Ok(())
3282 }
3283
3284 pub fn set_compression(&mut self, relation: u32, column: i16, compression: u8) -> Result<()> {
3286 self.column_mut(relation, column)?.compression = compression;
3287 for (index, number) in self.index_columns_of(relation, column) {
3288 self.column_mut(index, number)?.compression = compression;
3289 }
3290 Ok(())
3291 }
3292
3293 pub fn set_column_generated(
3299 &mut self,
3300 relation: u32,
3301 column: i16,
3302 generated: u8,
3303 ) -> Result<()> {
3304 self.column_mut(relation, column)?.generated = generated;
3305 Ok(())
3306 }
3307
3308 pub fn set_column_options(
3310 &mut self,
3311 relation: u32,
3312 column: i16,
3313 options: Vec<String>,
3314 ) -> Result<()> {
3315 self.column_mut(relation, column)?.options = options;
3316 Ok(())
3317 }
3318
3319 fn index_columns_of(&self, relation: u32, column: i16) -> Vec<(u32, i16)> {
3321 let mut found = Vec::new();
3322 for rel in self.relations.values() {
3323 let Some(info) = rel.index.as_ref().filter(|i| i.table == relation) else { continue };
3324 for (i, &key) in info.keys.iter().enumerate() {
3325 if key == column
3326 && let Ok(number) = i16::try_from(i + 1)
3327 {
3328 found.push((rel.oid, number));
3329 }
3330 }
3331 }
3332 found
3333 }
3334
3335 pub fn remove_default(&mut self, relation: u32, column: i16) {
3337 let Some(oid) = self.default_of(relation, column).map(|d| d.oid) else { return };
3338 self.defaults.remove(&oid);
3339 if let Ok(column) = self.column_mut(relation, column) {
3340 column.has_default = false;
3341 }
3342 let me = ObjRef::new(PG_ATTRDEF, oid);
3343 self.depends.retain(|d| d.object != me);
3344 }
3345
3346 fn relation_facts(&self, relation: u32) -> Result<(String, u32)> {
3347 let rel = self.relations.get(&relation).ok_or_else(|| no_object("relation", relation))?;
3348 Ok((rel.name.clone(), rel.namespace))
3349 }
3350
3351 fn check_constraint_name(&self, relation: u32, name: &str, relname: &str) -> Result<()> {
3352 if self.constraints_of(relation).any(|c| c.name == name) {
3353 return Err(duplicate_constraint(name, relname));
3354 }
3355 Ok(())
3356 }
3357
3358 fn insert_constraint(&mut self, constraint: Constraint) {
3359 let me = ObjRef::new(PG_CONSTRAINT, constraint.oid);
3360 let relation = constraint.relation;
3361 let keys = constraint.keys.clone();
3362 self.constraints.insert(constraint.oid, constraint);
3363 for key in keys {
3364 self.depend(me, ObjRef::column(relation, key), DepKind::Auto);
3365 }
3366 }
3367
3368 fn new_constraint(
3369 &mut self,
3370 name: String,
3371 namespace: u32,
3372 kind: ConKind,
3373 relation: u32,
3374 keys: Vec<i16>,
3375 ) -> Constraint {
3376 Constraint {
3377 oid: self.new_oid(),
3378 name,
3379 namespace,
3380 kind,
3381 relation,
3382 domain: 0,
3383 keys,
3384 index: 0,
3385 deferrable: false,
3386 deferred: false,
3387 validated: true,
3388 enforced: true,
3389 no_inherit: false,
3390 local: true,
3391 inhcount: 0,
3392 parent: 0,
3393 expr: None,
3394 foreign: None,
3395 }
3396 }
3397
3398 pub fn add_check(
3402 &mut self,
3403 relation: u32,
3404 name: Option<&str>,
3405 expr: String,
3406 keys: Vec<i16>,
3407 refs: &[ObjRef],
3408 no_inherit: bool,
3409 ) -> Result<u32> {
3410 let (relname, namespace) = self.relation_facts(relation)?;
3411 let name = match name {
3412 Some(name) => {
3413 self.check_constraint_name(relation, name, &relname)?;
3414 name.to_string()
3415 }
3416 None => {
3417 let column = match keys.as_slice() {
3418 [key] => self
3419 .relations
3420 .get(&relation)
3421 .and_then(|r| r.column(*key))
3422 .map(|c| c.name.clone()),
3423 _ => None,
3424 };
3425 self.choose_constraint_name(&relname, column.as_deref(), "check", namespace)
3426 }
3427 };
3428 let mut constraint = self.new_constraint(name, namespace, ConKind::Check, relation, keys);
3429 constraint.expr = Some(expr);
3430 constraint.no_inherit = no_inherit;
3431 let me = ObjRef::new(PG_CONSTRAINT, constraint.oid);
3432 let oid = constraint.oid;
3433 self.insert_constraint(constraint);
3434 self.depend_on_expr(me, refs, relation, DepKind::Normal);
3435 Ok(oid)
3436 }
3437
3438 pub fn add_not_null(
3440 &mut self,
3441 relation: u32,
3442 name: Option<&str>,
3443 column: i16,
3444 no_inherit: bool,
3445 ) -> Result<u32> {
3446 let (relname, namespace) = self.relation_facts(relation)?;
3447 let colname = self.column_mut(relation, column)?.name.clone();
3448 let name = match name {
3449 Some(name) => {
3450 self.check_constraint_name(relation, name, &relname)?;
3451 name.to_string()
3452 }
3453 None => self.choose_constraint_name(&relname, Some(&colname), "not_null", namespace),
3454 };
3455 let col = self.column_mut(relation, column)?;
3456 col.not_null = true;
3457 col.not_null_invalid = false;
3458 let mut constraint =
3459 self.new_constraint(name, namespace, ConKind::NotNull, relation, vec![column]);
3460 constraint.no_inherit = no_inherit;
3461 let oid = constraint.oid;
3462 self.insert_constraint(constraint);
3463 Ok(oid)
3464 }
3465
3466 pub fn create_index(&mut self, new: NewIndex) -> Result<(u32, Option<u32>)> {
3470 let (relname, namespace) = self.relation_facts(new.table)?;
3471 let owner = self.relations.get(&new.table).map_or(0, |r| r.owner);
3472 let unlogged = self.relations.get(&new.table).is_some_and(|r| r.unlogged);
3473 let column_names = index_column_names(new.columns.iter().map(|c| c.name.as_str()));
3474 let name = match &new.name {
3475 Some(name) => name.clone(),
3476 None => {
3477 let addition = name_addition(column_names.iter().map(String::as_str));
3478 match new.constraint {
3479 Some(ConKind::Primary) => {
3480 self.choose_relation_name(&relname, None, "pkey", namespace, true)
3481 }
3482 Some(_) => {
3483 self.choose_relation_name(&relname, Some(&addition), "key", namespace, true)
3484 }
3485 None => self.choose_relation_name(
3486 &relname,
3487 Some(&addition),
3488 "idx",
3489 namespace,
3490 false,
3491 ),
3492 }
3493 }
3494 };
3495 self.check_new_relation(namespace, &name, false)?;
3496 if new.constraint.is_some() {
3497 self.check_constraint_name(new.table, &name, &relname)?;
3498 }
3499 let oid = self.new_oid();
3500 let keys: Vec<i16> = new.columns.iter().map(|c| c.key).collect();
3501 let key_columns = &new.columns[..new.key_count.min(new.columns.len())];
3502 let column_refs: Vec<ObjRef> = key_columns
3504 .iter()
3505 .filter(|c| c.collation != 0)
3506 .map(|c| ObjRef::new(PG_COLLATION, c.collation))
3507 .chain(key_columns.iter().map(|c| ObjRef::new(PG_OPCLASS, c.class)))
3508 .collect();
3509 let info = IndexInfo {
3510 table: new.table,
3511 keys: keys.clone(),
3512 key_count: i16::try_from(new.key_count).unwrap_or(i16::MAX),
3513 unique: new.unique,
3514 nulls_not_distinct: new.nulls_not_distinct,
3515 primary: new.constraint == Some(ConKind::Primary),
3516 immediate: !new.deferrable,
3517 method: new.method,
3518 collations: key_columns.iter().map(|c| c.collation).collect(),
3519 classes: key_columns.iter().map(|c| c.class).collect(),
3520 options: key_columns.iter().map(|c| c.option).collect(),
3521 exprs: new.exprs,
3522 predicate: new.predicate,
3523 pages: new.pages,
3524 clustered: false,
3525 replica_identity: false,
3526 valid: true,
3527 ready: true,
3528 parent: 0,
3529 };
3530 let table_columns = self.relations.get(&new.table).map_or(&[][..], |r| &r.columns[..]);
3531 let partitioned =
3532 self.relations.get(&new.table).is_some_and(|r| r.kind == RelKind::Partitioned);
3533 let columns = new
3534 .columns
3535 .iter()
3536 .zip(column_names)
3537 .map(|(c, name)| {
3538 let mut column = Column::new(name, c.ty, c.typmod, c.collation);
3539 let from = usize::try_from(c.key).ok().and_then(|k| k.checked_sub(1));
3540 if let Some(from) = from.and_then(|k| table_columns.get(k)) {
3541 column.ndims = from.ndims;
3542 column.storage = from.storage;
3543 column.compression = from.compression;
3544 }
3545 column
3546 })
3547 .collect();
3548 self.relations.insert(
3549 oid,
3550 Relation {
3551 oid,
3552 file: oid,
3553 name: name.clone(),
3554 namespace,
3555 kind: if partitioned { RelKind::PartitionedIndex } else { RelKind::Index },
3556 owner,
3557 row_type: 0,
3558 columns,
3559 has_index: false,
3560 has_triggers: false,
3561 toast: 0,
3562 index: Some(info),
3563 sequence: None,
3564 view: None,
3565 options: Vec::new(),
3566 acl: None,
3567 replica_identity: 0,
3568 partition_key: None,
3569 partition_of: None,
3570 inherits: Vec::new(),
3571 of_type: 0,
3572 unlogged,
3573 },
3574 );
3575 let me = ObjRef::new(PG_CLASS, oid);
3576 let mut constraint_oid = None;
3577 if let Some(kind) = new.constraint {
3578 let key_keys = keys[..new.key_count.min(keys.len())].to_vec();
3579 let made =
3580 self.index_constraint(oid, name, kind, key_keys, (new.deferrable, new.deferred));
3581 constraint_oid = Some(made?);
3582 } else {
3583 let simple: Vec<i16> = keys.iter().copied().filter(|&k| k != 0).collect();
3584 if simple.is_empty() {
3585 self.depend(me, ObjRef::new(PG_CLASS, new.table), DepKind::Auto);
3586 }
3587 for key in simple {
3588 self.depend(me, ObjRef::column(new.table, key), DepKind::Auto);
3589 }
3590 }
3591 for referenced in column_refs {
3592 self.depend(me, referenced, DepKind::Normal);
3593 }
3594 self.depend_on_expr(me, &new.refs, new.table, DepKind::Auto);
3595 self.relation_mut(new.table)?.has_index = true;
3596 Ok((oid, constraint_oid))
3597 }
3598
3599 pub fn add_foreign_key(&mut self, new: NewForeignKey) -> Result<u32> {
3601 let oid = self.add_fk_constraint(new, 0, FkSide::Both)?;
3602 self.add_fk_action_triggers(oid, None)?;
3603 self.add_fk_check_triggers(oid, None)?;
3604 Ok(oid)
3605 }
3606
3607 pub fn add_fk_constraint(
3609 &mut self,
3610 new: NewForeignKey,
3611 parent: u32,
3612 side: FkSide,
3613 ) -> Result<u32> {
3614 let (relname, namespace) = self.relation_facts(new.table)?;
3615 let name = match &new.name {
3616 Some(name) if parent != 0 => {
3617 if self.constraints_of(new.table).any(|c| c.name == *name) {
3618 self.choose_constraint_name(name, None, "", namespace)
3619 } else {
3620 name.clone()
3621 }
3622 }
3623 Some(name) => {
3624 self.check_constraint_name(new.table, name, &relname)?;
3625 name.clone()
3626 }
3627 None => {
3628 let rel = self
3629 .relations
3630 .get(&new.table)
3631 .ok_or_else(|| no_object("relation", new.table))?;
3632 let columns: Vec<&str> = new
3633 .keys
3634 .iter()
3635 .filter_map(|&k| rel.column(k))
3636 .map(|c| c.name.as_str())
3637 .collect();
3638 let addition = name_addition(columns);
3639 self.choose_constraint_name(&relname, Some(&addition), "fkey", namespace)
3640 }
3641 };
3642 let partitioned =
3643 self.relations.get(&new.table).is_some_and(|r| r.kind == RelKind::Partitioned);
3644 let mut constraint =
3645 self.new_constraint(name, namespace, ConKind::Foreign, new.table, new.keys);
3646 constraint.index = new.index;
3647 constraint.no_inherit = !partitioned && parent == 0;
3648 constraint.deferrable = new.deferrable;
3649 constraint.deferred = new.deferred;
3650 if parent != 0 {
3651 constraint.parent = parent;
3652 constraint.local = false;
3653 constraint.inhcount = 1;
3654 constraint.validated = self.constraints.get(&parent).is_none_or(|p| p.validated);
3656 constraint.enforced = self.constraints.get(&parent).is_none_or(|p| p.enforced);
3657 }
3658 let oid = constraint.oid;
3659 let referenced = new.foreign.table;
3660 let referenced_keys = new.foreign.keys.clone();
3661 constraint.foreign = Some(new.foreign);
3662 self.insert_constraint(constraint);
3663 let me = ObjRef::new(PG_CONSTRAINT, oid);
3664 for key in referenced_keys {
3665 self.depend(me, ObjRef::column(referenced, key), DepKind::Normal);
3666 }
3667 self.depend(me, ObjRef::new(PG_CLASS, new.index), DepKind::Normal);
3668 match side {
3669 _ if parent == 0 => {}
3670 FkSide::Referenced => {
3671 self.depend(me, ObjRef::new(PG_CONSTRAINT, parent), DepKind::Internal);
3672 }
3673 FkSide::Both | FkSide::Referencing => {
3674 self.depend(me, ObjRef::new(PG_CONSTRAINT, parent), DepKind::PartitionPri);
3675 self.depend(me, ObjRef::new(PG_CLASS, new.table), DepKind::PartitionSec);
3676 }
3677 }
3678 Ok(oid)
3679 }
3680
3681 pub fn add_fk_action_triggers(
3683 &mut self,
3684 constraint: u32,
3685 parents: Option<(u32, u32)>,
3686 ) -> Result<(u32, u32)> {
3687 let (mut trigger, foreign) = self.fk_trigger(constraint)?;
3688 std::mem::swap(&mut trigger.relation, &mut trigger.constraint_relation);
3689 let (delete, update) = (foreign.delete, foreign.update);
3690 let (deferrable, deferred) = (trigger.deferrable, trigger.deferred);
3691 let mut oids = [0; 2];
3692 for (at, (event, action, offset)) in
3693 [(TRIGGER_DELETE, delete, 0), (TRIGGER_UPDATE, update, 1)].into_iter().enumerate()
3694 {
3695 let function = match action {
3696 'r' => 4,
3697 'c' => 2,
3698 'n' => 6,
3699 'd' => 8,
3700 _ => 10,
3701 };
3702 let no_action = function == 10;
3703 trigger.function = RI_FKEY_CHECK_INS + function + offset;
3704 trigger.kind = TRIGGER_ROW | event;
3705 trigger.deferrable = no_action && deferrable;
3706 trigger.deferred = no_action && deferred;
3707 trigger.parent = parents.map_or(0, |p| if at == 0 { p.0 } else { p.1 });
3708 self.add_trigger(&mut trigger, "RI_ConstraintTrigger_a");
3709 oids[at] = trigger.oid;
3710 }
3711 self.relation_mut(trigger.relation)?.has_triggers = true;
3712 Ok((oids[0], oids[1]))
3713 }
3714
3715 pub fn add_fk_check_triggers(
3717 &mut self,
3718 constraint: u32,
3719 parents: Option<(u32, u32)>,
3720 ) -> Result<(u32, u32)> {
3721 let (mut trigger, _) = self.fk_trigger(constraint)?;
3722 let mut oids = [0; 2];
3723 for (at, (event, offset)) in
3724 [(TRIGGER_INSERT, 0), (TRIGGER_UPDATE, 1)].into_iter().enumerate()
3725 {
3726 trigger.function = RI_FKEY_CHECK_INS + offset;
3727 trigger.kind = TRIGGER_ROW | event;
3728 trigger.parent = parents.map_or(0, |p| if at == 0 { p.0 } else { p.1 });
3729 self.add_trigger(&mut trigger, "RI_ConstraintTrigger_c");
3730 oids[at] = trigger.oid;
3731 }
3732 self.relation_mut(trigger.relation)?.has_triggers = true;
3733 Ok((oids[0], oids[1]))
3734 }
3735
3736 fn fk_trigger(&self, constraint: u32) -> Result<(Trigger, ForeignKey)> {
3738 let con =
3739 self.constraints.get(&constraint).ok_or_else(|| no_object("constraint", constraint))?;
3740 let Some(foreign) = con.foreign.clone() else {
3741 return Err(Error::internal(format!("constraint {constraint} is not a foreign key")));
3742 };
3743 let trigger = Trigger {
3744 relation: con.relation,
3745 constraint_relation: foreign.table,
3746 constraint_index: con.index,
3747 constraint,
3748 deferrable: con.deferrable,
3749 deferred: con.deferred,
3750 enabled: b'O',
3751 internal: true,
3752 ..Trigger::default()
3753 };
3754 Ok((trigger, foreign))
3755 }
3756
3757 pub fn set_trigger_parent(&mut self, trigger: u32, parent: u32) {
3759 let Some(found) = self.triggers.get_mut(&trigger) else { return };
3760 found.parent = parent;
3761 let table = found.relation;
3762 let me = ObjRef::new(PG_TRIGGER, trigger);
3763 self.depend(me, ObjRef::new(PG_TRIGGER, parent), DepKind::PartitionPri);
3764 self.depend(me, ObjRef::new(PG_CLASS, table), DepKind::PartitionSec);
3765 }
3766
3767 pub fn drop_depends_of(&mut self, object: ObjRef) {
3769 self.depends.retain(|d| d.object != object);
3770 }
3771
3772 fn add_trigger(&mut self, trigger: &mut Trigger, prefix: &str) {
3774 trigger.oid = self.new_oid();
3775 trigger.name = format!("{prefix}_{}", trigger.oid);
3776 self.triggers.insert(trigger.oid, trigger.clone());
3777 let me = ObjRef::new(PG_TRIGGER, trigger.oid);
3778 self.depend(me, ObjRef::new(PG_CONSTRAINT, trigger.constraint), DepKind::Internal);
3779 if trigger.parent != 0 {
3780 self.depend(me, ObjRef::new(PG_TRIGGER, trigger.parent), DepKind::PartitionPri);
3781 self.depend(me, ObjRef::new(PG_CLASS, trigger.relation), DepKind::PartitionSec);
3782 }
3783 }
3784
3785 fn index_constraint(
3787 &mut self,
3788 index: u32,
3789 name: String,
3790 kind: ConKind,
3791 keys: Vec<i16>,
3792 (deferrable, deferred): (bool, bool),
3793 ) -> Result<u32> {
3794 let table = self.relation(index).and_then(|r| r.index.as_ref()).map_or(0, |i| i.table);
3795 let namespace = self.relation_facts(table)?.1;
3796 let mut constraint = self.new_constraint(name, namespace, kind, table, keys);
3797 constraint.index = index;
3798 constraint.no_inherit = true;
3799 constraint.deferrable = deferrable;
3800 constraint.deferred = deferred;
3801 let referenced = ObjRef::new(PG_CONSTRAINT, constraint.oid);
3802 self.insert_constraint(constraint);
3803 self.depend(ObjRef::new(PG_CLASS, index), referenced, DepKind::Internal);
3804 if deferrable {
3805 let mut trigger = Trigger {
3806 relation: table,
3807 constraint_index: index,
3808 constraint: referenced.oid,
3809 function: UNIQUE_KEY_RECHECK,
3810 kind: TRIGGER_ROW | TRIGGER_INSERT | TRIGGER_UPDATE,
3811 deferrable: true,
3812 deferred,
3813 enabled: b'O',
3814 internal: true,
3815 ..Trigger::default()
3816 };
3817 let prefix = if kind == ConKind::Primary {
3818 "PK_ConstraintTrigger"
3819 } else {
3820 "Unique_ConstraintTrigger"
3821 };
3822 self.add_trigger(&mut trigger, prefix);
3823 self.relation_mut(table)?.has_triggers = true;
3824 }
3825 Ok(referenced.oid)
3826 }
3827
3828 pub fn attach_index_constraint(
3834 &mut self,
3835 index: u32,
3836 kind: ConKind,
3837 deferrable: bool,
3838 deferred: bool,
3839 ) -> Result<u32> {
3840 let rel = self.relation(index).ok_or_else(|| no_object("index", index))?;
3841 let info = rel.index.as_ref().ok_or_else(|| no_object("index", index))?;
3842 let name = rel.name.clone();
3843 let table = info.table;
3844 let keys =
3845 info.keys[..usize::try_from(info.key_count).unwrap_or(0).min(info.keys.len())].to_vec();
3846 let relname = self.relation_facts(table)?.0;
3847 self.check_constraint_name(table, &name, &relname)?;
3848 let me = ObjRef::new(PG_CLASS, index);
3849 self.depends.retain(|d| {
3850 !(d.object == me && d.kind == DepKind::Auto && d.referenced.class == PG_CLASS)
3851 });
3852 if let Some(info) = self.relation_mut(index)?.index.as_mut() {
3853 info.primary |= kind == ConKind::Primary;
3854 info.immediate &= !deferrable;
3855 }
3856 self.index_constraint(index, name, kind, keys, (deferrable, deferred))
3857 }
3858
3859 pub fn create_toast(&mut self, table: u32) -> Result<u32> {
3861 let rel = self.relations.get(&table).ok_or_else(|| no_object("relation", table))?;
3862 let (owner, unlogged) = (rel.owner, rel.unlogged);
3863 let namespace = self.toast_namespace(rel.namespace);
3864 let oid = self.new_oid();
3865 let index = self.new_oid();
3866 let name = format!("pg_toast_{table}");
3867 let chunk_id = Column::new("chunk_id", OID, -1, 0);
3868 let chunk_seq = Column::new("chunk_seq", INT4, -1, 0);
3869 let chunk_data = Column::new("chunk_data", BYTEA, -1, 0);
3870 self.relations.insert(
3871 oid,
3872 Relation {
3873 oid,
3874 file: oid,
3875 name: name.clone(),
3876 namespace,
3877 kind: RelKind::Toast,
3878 owner,
3879 row_type: 0,
3880 columns: vec![chunk_id.clone(), chunk_seq.clone(), chunk_data],
3881 has_index: true,
3882 has_triggers: false,
3883 toast: 0,
3884 index: None,
3885 sequence: None,
3886 view: None,
3887 options: Vec::new(),
3888 acl: None,
3889 replica_identity: 0,
3890 partition_key: None,
3891 partition_of: None,
3892 inherits: Vec::new(),
3893 of_type: 0,
3894 unlogged,
3895 },
3896 );
3897 let info = IndexInfo {
3898 table: oid,
3899 keys: vec![1, 2],
3900 key_count: 2,
3901 unique: true,
3902 nulls_not_distinct: false,
3903 primary: true,
3904 immediate: true,
3905 method: BTREE,
3906 collations: vec![0, 0],
3907 classes: vec![OID_OPS, INT4_OPS],
3908 options: vec![0, 0],
3909 exprs: None,
3910 predicate: None,
3911 pages: 1,
3912 clustered: false,
3913 replica_identity: false,
3914 valid: true,
3915 ready: true,
3916 parent: 0,
3917 };
3918 self.relations.insert(
3919 index,
3920 Relation {
3921 oid: index,
3922 file: index,
3923 name: format!("{name}_index"),
3924 namespace,
3925 kind: RelKind::Index,
3926 owner,
3927 row_type: 0,
3928 columns: vec![chunk_id, chunk_seq],
3929 has_index: false,
3930 has_triggers: false,
3931 toast: 0,
3932 index: Some(info),
3933 sequence: None,
3934 view: None,
3935 options: Vec::new(),
3936 acl: None,
3937 replica_identity: 0,
3938 partition_key: None,
3939 partition_of: None,
3940 inherits: Vec::new(),
3941 of_type: 0,
3942 unlogged,
3943 },
3944 );
3945 self.relation_mut(table)?.toast = oid;
3946 self.depend(ObjRef::new(PG_CLASS, oid), ObjRef::new(PG_CLASS, table), DepKind::Internal);
3947 for column in 1..=2 {
3948 self.depend(ObjRef::new(PG_CLASS, index), ObjRef::column(oid, column), DepKind::Auto);
3949 }
3950 Ok(oid)
3951 }
3952}
3953
3954#[cfg(test)]
3955mod tests;