Skip to main content

safe_migrate/analysis/
facts.rs

1// FILE: src/analysis/facts.rs
2use crate::analysis::expr_ir::ExprIr;
3use crate::ast::identifiers::{Ident, QualifiedName};
4
5#[derive(Clone, Debug, PartialEq)]
6pub enum PersistenceFact {
7    Permanent,
8    Temporary,
9    Unlogged,
10}
11
12#[derive(Clone, Debug, PartialEq)]
13pub enum PolicyCommand {
14    All,
15    Select,
16    Insert,
17    Update,
18    Delete,
19}
20
21#[derive(Clone, Debug, PartialEq)]
22pub enum SearchPathTarget {
23    Default,
24    Schemas(Vec<String>),
25}
26
27#[derive(Clone, Debug, PartialEq)]
28pub enum TypeCreationKind {
29    Enum,
30    Range,
31    Composite,
32    Base,
33}
34
35#[derive(Clone, Debug, PartialEq)]
36pub enum AlterViewAction {
37    RenameTo {
38        new_name: Ident,
39    },
40    OwnerTo {
41        new_owner: String,
42    },
43    SetSchema {
44        new_schema: String,
45    },
46    SetDefault {
47        column: String,
48        default: Option<ExprIr>,
49    },
50    DropDefault {
51        column: String,
52    },
53    RenameColumn {
54        from: Ident,
55        to: Ident,
56    },
57    SetOptions {
58        options: Vec<String>,
59    },
60    ResetOptions {
61        options: Vec<String>,
62    },
63}
64
65#[derive(Clone, Debug, PartialEq)]
66pub enum StatementFact {
67    CreateSchema {
68        name: QualifiedName,
69        if_not_exists: bool,
70    },
71    AlterSchema {
72        name: QualifiedName,
73        new_name: Option<Ident>,
74    },
75    DropSchema {
76        names: Vec<QualifiedName>,
77        if_exists: bool,
78        cascade: bool,
79    },
80    CreateTable {
81        name: QualifiedName,
82        if_not_exists: bool,
83        as_select: bool,
84        persistence: PersistenceFact,
85        columns: Vec<ColumnFact>,
86        foreign_keys: Vec<FkFact>,
87        table_constraints: Vec<TableConstraintFact>,
88        partition_by: Option<String>,
89        partition_of: Option<QualifiedName>,
90        partition_type: Option<String>,
91    },
92    CreateView {
93        name: QualifiedName,
94        or_replace: bool,
95        depends_on: Vec<QualifiedName>,
96    },
97    AlterView {
98        name: QualifiedName,
99        action: AlterViewAction,
100    },
101    CreateMaterializedView {
102        name: QualifiedName,
103        depends_on: Vec<QualifiedName>,
104    },
105    AlterMaterializedView {
106        name: QualifiedName,
107        new_name: Option<Ident>,
108    },
109    RefreshMaterializedView {
110        name: QualifiedName,
111        concurrently: bool,
112    },
113    CreateIndex {
114        name: QualifiedName,
115        relation: QualifiedName,
116        if_not_exists: bool,
117        concurrently: bool,
118        using_method: Option<String>,
119        has_predicate: bool,
120        unique: bool, // Added for CreateIndexFact
121    },
122    CreatePolicy {
123        name: String,
124        table: QualifiedName,
125        permissive: bool,
126        command: PolicyCommand,
127    },
128    DropPolicy {
129        name: String,
130        table: QualifiedName,
131        if_exists: bool,
132    },
133    CreateTrigger {
134        name: String,
135        table: QualifiedName,
136        function: Option<QualifiedName>,
137    },
138    DropTrigger {
139        name: String,
140        table: QualifiedName,
141        if_exists: bool,
142    },
143    AlterTable {
144        name: QualifiedName,
145        actions: Vec<AlterTableActionFact>,
146    },
147    AlterIndex {
148        name: QualifiedName,
149        actions: Vec<AlterIndexActionFact>,
150    },
151    CreateType(CreateTypeFact),
152    AlterType(AlterTypeFact),
153    CreateDomain {
154        name: QualifiedName,
155        base_type: String,
156    },
157    AlterDomain {
158        name: QualifiedName,
159        action: Option<AlterDomainActionFact>,
160    },
161    DropDomain {
162        names: Vec<QualifiedName>,
163        if_exists: bool,
164        cascade: bool,
165    },
166    CreateSequence {
167        name: QualifiedName,
168        if_not_exists: bool,
169        owned_by: Option<(QualifiedName, String)>,
170    },
171    AlterSequence {
172        name: QualifiedName,
173        owned_by: Option<(QualifiedName, String)>,
174    },
175    DropSequence {
176        names: Vec<QualifiedName>,
177        if_exists: bool,
178        cascade: bool,
179    },
180    DropTable {
181        name: QualifiedName,
182        if_exists: bool,
183        cascade: bool,
184    },
185    DropView {
186        name: QualifiedName,
187        if_exists: bool,
188        cascade: bool,
189    },
190    DropMaterializedView {
191        names: Vec<QualifiedName>,
192        if_exists: bool,
193        cascade: bool,
194    },
195    DropIndex {
196        names: Vec<QualifiedName>,
197        if_exists: bool,
198        concurrently: bool,
199    },
200    SetSearchPath {
201        target: SearchPathTarget,
202    },
203    BeginTransaction,
204    CommitTransaction,
205    RollbackTransaction,
206    RollbackToSavepoint {
207        name: String,
208    },
209    Savepoint {
210        name: String,
211    },
212    ReleaseSavepoint {
213        name: String,
214    },
215    PrepareTransaction {
216        name: String,
217    },
218    SetTransaction,
219    SetConstraints,
220    OpaqueBlock,
221    Execute,
222    Vacuum {
223        relation: Option<QualifiedName>,
224        is_full: bool,
225    },
226    CreateFunction(CreateFunctionFact),
227    AlterFunction(AlterFunctionFact),
228    DropFunction(DropFunctionFact),
229    CreateProcedure(CreateProcedureFact),
230    AlterProcedure(AlterProcedureFact),
231    DropProcedure(DropProcedureFact),
232    CreatePublication(CreatePublicationFact),
233    AlterPublication(AlterPublicationFact),
234    DropPublication(DropPublicationFact),
235    CreateSubscription(CreateSubscriptionFact),
236    AlterSubscription(AlterSubscriptionFact),
237    DropSubscription(DropSubscriptionFact),
238    CreateRole(CreateRoleFact),
239    AlterRole(AlterRoleFact),
240    DropRole(DropRoleFact),
241    Grant(GrantFact),
242    Revoke(RevokeFact),
243    CreateDatabase(CreateDatabaseFact),
244    AlterDatabase(AlterDatabaseFact),
245    DropDatabase(DropDatabaseFact),
246}
247
248#[derive(Clone, Debug, PartialEq)]
249pub enum AlterIndexActionFact {
250    RenameTo { new_name: Ident },
251}
252
253#[derive(Clone, Debug, PartialEq)]
254pub struct CreateTypeFact {
255    pub name: QualifiedName,
256    pub kind: TypeCreationKind,
257}
258
259#[derive(Clone, Debug, PartialEq)]
260pub struct AlterTypeFact {
261    pub name: QualifiedName,
262    pub actions: Vec<AlterTypeActionFact>,
263}
264
265#[derive(Clone, Debug, PartialEq)]
266pub enum AlterTypeActionFact {
267    AddValue { new_value: String },
268}
269
270#[derive(Clone, Debug, PartialEq, Default)]
271pub enum RoleFact {
272    #[default]
273    Unknown,
274    Named {
275        name: String,
276        via_legacy_group_syntax: bool,
277    },
278    CurrentUser,
279    CurrentRole,
280    SessionUser,
281}
282
283#[derive(Clone, Debug, PartialEq)]
284pub struct CreateRoleFact {
285    pub name: String,
286    pub inherits: bool,
287}
288
289#[derive(Clone, Debug, PartialEq)]
290pub struct AlterRoleFact {
291    pub name: RoleFact,
292    pub inherits: Option<bool>,
293}
294
295#[derive(Clone, Debug, PartialEq)]
296pub struct DropRoleFact {
297    pub names: Vec<String>,
298    pub if_exists: bool,
299}
300
301#[derive(Clone, Debug, PartialEq)]
302pub struct CreateFunctionFact {
303    pub name: QualifiedName,
304    pub or_replace: bool,
305    pub params: Vec<ParamFact>,
306    pub return_type: Option<RetTypeFact>,
307    pub options: Vec<FuncOptionFact>,
308}
309
310#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
311pub struct ParamFact {
312    pub mode: ParamModeFact,
313    pub name: Option<String>,
314    pub ty: String,
315    pub default: Option<ExprIr>,
316}
317
318#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
319pub enum ParamModeFact {
320    In,
321    Out,
322    InOut,
323    Variadic,
324}
325
326#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
327pub enum RetTypeFact {
328    Table(Vec<ColumnFact>),
329    Scalar(String),
330}
331
332#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
333pub enum FuncOptionFact {
334    Language(String),
335    Volatility(VolatilityKind),
336    Security(SecurityKind),
337    Strict(StrictKind),
338    Leakproof(bool),
339    Parallel(String),
340    Cost,
341    Rows,
342    Reset(String),
343    As {
344        definition: Option<String>,
345        obj_file: Option<String>,
346        link_symbol: Option<String>,
347    },
348    Transform,
349    Window,
350    Support,
351    Unknown,
352}
353
354#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
355pub enum VolatilityKind {
356    Immutable,
357    Stable,
358    Volatile,
359}
360#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
361pub enum SecurityKind {
362    Invoker,
363    Definer,
364}
365#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
366pub enum StrictKind {
367    Strict,
368    CalledOnNull,
369    ReturnsNullOnNull,
370}
371
372#[derive(Clone, Debug, PartialEq)]
373pub struct AlterFunctionFact {
374    pub name: QualifiedName,
375    pub params: Vec<String>,
376    pub action: AlterFunctionAction,
377}
378
379#[derive(Clone, Debug, PartialEq)]
380pub enum AlterFunctionAction {
381    Rename { from: String, to: String },
382    OwnerChange(RoleFact),
383    SchemaChange { new_schema: String },
384    DependsOnExtension { extension: String },
385    NoDependsOnExtension { extension: String },
386    OptionsChange(Vec<FuncOptionFact>),
387}
388
389#[derive(Clone, Debug, PartialEq)]
390pub struct DropFunctionFact {
391    pub signatures: Vec<FunctionSigFact>,
392    pub if_exists: bool,
393    pub cascade: bool,
394}
395
396#[derive(Clone, Debug, PartialEq)]
397pub struct FunctionSigFact {
398    pub name: QualifiedName,
399    pub params: Vec<String>,
400}
401
402#[derive(Clone, Debug, PartialEq)]
403pub struct CreateProcedureFact {
404    pub name: QualifiedName,
405    pub or_replace: bool,
406    pub params: Vec<ParamFact>,
407    pub options: Vec<FuncOptionFact>,
408}
409
410#[derive(Clone, Debug, PartialEq)]
411pub struct AlterProcedureFact {
412    pub name: QualifiedName,
413    pub params: Vec<String>,
414    pub action: AlterFunctionAction,
415}
416
417#[derive(Clone, Debug, PartialEq)]
418pub struct DropProcedureFact {
419    pub signatures: Vec<FunctionSigFact>,
420    pub if_exists: bool,
421    pub cascade: bool,
422}
423
424#[derive(Clone, Debug, PartialEq)]
425pub struct CreatePublicationFact {
426    pub name: String,
427    pub scope: PublicationScope,
428    pub params: Vec<AttributeFact>,
429}
430
431#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
432pub enum PublicationScope {
433    AllTables { except: Vec<String> },
434    Explicit(Vec<PublicationObjectFact>),
435}
436
437#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
438pub enum PublicationObjectFact {
439    Table {
440        name: QualifiedName,
441        only: bool,
442        include_partitions: bool,
443        columns: Option<Vec<String>>,
444        row_filter: Option<ExprIr>,
445    },
446    SchemaTables {
447        schema: String,
448        row_filter: Option<ExprIr>,
449    },
450    CurrentSchemaShorthand,
451    Unknown,
452}
453
454#[derive(Clone, Debug, PartialEq)]
455pub struct AlterPublicationFact {
456    pub name: String,
457}
458
459#[derive(Clone, Debug, PartialEq)]
460pub struct DropPublicationFact {
461    pub names: Vec<String>,
462    pub if_exists: bool,
463    pub cascade: bool,
464}
465
466#[derive(Clone, Debug, PartialEq)]
467pub struct CreateSubscriptionFact {
468    pub name: Option<String>,
469    pub connection: ConnectionTarget,
470    pub publications: Vec<String>,
471    pub params: Option<Vec<AttributeFact>>,
472}
473
474#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
475pub enum ConnectionTarget {
476    Literal(Option<String>),
477    Server(Option<String>),
478}
479
480#[derive(Clone, Debug, PartialEq)]
481pub struct AlterSubscriptionFact {
482    pub name: String,
483}
484
485#[derive(Clone, Debug, PartialEq)]
486pub struct DropSubscriptionFact {
487    pub name: String,
488    pub if_exists: bool,
489}
490
491#[derive(Clone, Debug, PartialEq)]
492pub struct GrantFact {
493    pub privileges: PrivilegeSpec,
494    pub target: GrantTarget,
495    pub grantees: Vec<RoleFact>,
496    pub with_grant_option: bool,
497    pub granted_by: Option<RoleFact>,
498}
499
500#[derive(Clone, Debug, PartialEq)]
501pub struct RevokeFact {
502    pub grant_option_only: bool,
503    pub privileges: PrivilegeSpec,
504    pub target: GrantTarget,
505    pub revokees: Vec<RoleFact>,
506    pub granted_by: Option<RoleFact>,
507    pub cascade: bool,
508}
509
510#[derive(Clone, Debug, PartialEq)]
511pub enum PrivilegeSpec {
512    All,
513    List(Vec<PrivilegeFact>),
514}
515
516#[derive(Clone, Debug, PartialEq)]
517pub enum PrivilegeFact {
518    Select,
519    Insert,
520    Update,
521    Delete,
522    Truncate,
523    References,
524    Trigger,
525    Execute,
526    Create,
527    Temporary,
528    AlterSystem,
529    All,
530    Named(String),
531    RoleMembership(String),
532    Unknown,
533}
534
535#[derive(Clone, Debug, PartialEq)]
536pub enum GrantTarget {
537    Tables(Vec<QualifiedName>),
538    AllTablesInSchema(Vec<String>),
539}
540
541#[derive(Clone, Debug, PartialEq)]
542pub struct CreateDatabaseFact {
543    pub name: String,
544    pub options: Vec<DatabaseOptionFact>,
545}
546
547#[derive(Clone, Debug, PartialEq)]
548pub enum DatabaseOptionFact {
549    Owner(DatabaseOptionValue),
550    Template(DatabaseOptionValue),
551    Encoding(DatabaseOptionValue),
552    Tablespace(DatabaseOptionValue),
553    ConnectionLimit(DatabaseOptionValue),
554    Named(String, DatabaseOptionValue),
555    Unknown(DatabaseOptionValue),
556}
557
558#[derive(Clone, Debug, PartialEq)]
559pub enum DatabaseOptionValue {
560    Default,
561    Literal(Option<String>),
562}
563
564#[derive(Clone, Debug, PartialEq)]
565pub struct AlterDatabaseFact {
566    pub name: QualifiedName,
567    pub action: AlterDatabaseAction,
568}
569
570#[derive(Clone, Debug, PartialEq)]
571pub enum AlterDatabaseAction {
572    Rename { to: String },
573    OwnerChange(RoleFact),
574    TablespaceChange { new_tablespace: String },
575    SetConfigParam { param: String },
576    ResetConfigParam { param: Option<String> },
577    RefreshCollationVersion,
578    OptionChanges(Vec<DatabaseOptionFact>),
579}
580
581#[derive(Clone, Debug, PartialEq)]
582pub struct DropDatabaseFact {
583    pub name: QualifiedName,
584    pub if_exists: bool,
585}
586
587#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
588pub struct AttributeFact {
589    pub name: String,
590    pub value: String,
591}
592
593#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
594pub struct ColumnFact {
595    pub name: String,
596    pub ty: Option<String>,
597    pub not_null: bool,
598    pub is_primary_key: bool,
599    pub default: Option<ExprIr>,
600}
601
602#[derive(Clone, Debug, PartialEq)]
603pub struct FkFact {
604    pub constraint_name: Option<String>,
605    pub references: QualifiedName,
606    pub from_columns: Vec<String>,
607    pub to_columns: Vec<String>,
608}
609
610#[derive(Clone, Debug, PartialEq)]
611pub enum TableConstraintFact {
612    PrimaryKey { columns: Vec<String> },
613    Unique { columns: Vec<String> },
614    Check,
615    Exclude,
616}
617
618#[derive(Clone, Debug, PartialEq)]
619pub enum AlterDomainActionFact {
620    AddConstraint,
621    DropConstraint,
622    DropDefault,
623    DropNotNull,
624    OwnerChange,
625    RenameConstraint,
626    RenameTo,
627    SetDefault,
628    SetNotNull,
629    SetSchema,
630    ValidateConstraint,
631}
632
633#[derive(Clone, Debug, PartialEq)]
634pub enum AlterTableActionFact {
635    AddColumn {
636        name: String,
637        ty: Option<String>,
638        if_not_exists: bool,
639        not_null: bool,
640        default: Option<ExprIr>,
641    },
642    DropColumn {
643        name: String,
644        if_exists: bool,
645    },
646    RenameColumn {
647        from: Ident,
648        to: Ident,
649    },
650    RenameTo {
651        new_name: Ident,
652    },
653    AddForeignKey {
654        constraint_name: Option<String>,
655        references: QualifiedName,
656        from_columns: Vec<String>,
657        to_columns: Vec<String>,
658        not_valid: bool,
659    },
660    AlterConstraint {
661        name: Option<String>,
662        deferrable: bool,
663    },
664    RenameConstraint {
665        old_name: String,
666        new_name: String,
667    },
668    DropConstraint {
669        name: String,
670    },
671    AddCheckConstraint {
672        constraint_name: Option<String>,
673        not_valid: bool,
674    },
675    AddUniqueConstraint,
676    AddPrimaryKeyConstraint,
677    AddExcludeConstraint,
678    SetNotNull {
679        column: String,
680    },
681    DropNotNull {
682        column: String,
683    },
684    SetType {
685        column: String,
686        ty: String,
687        has_using: bool,
688    },
689    SetDefault {
690        column: String,
691        default: Option<ExprIr>,
692    },
693    SetExpression {
694        column: String,
695        expr: ExprIr,
696    },
697    SetOptions {
698        column: String,
699        attributes: Vec<AttributeFact>,
700    },
701    Inherit {
702        column: String,
703        parent: QualifiedName,
704    },
705    NoInherit {
706        column: String,
707        parent: QualifiedName,
708    },
709    ValidateConstraint {
710        constraint_name: String,
711    },
712    DisableTrigger {
713        trigger_name: Option<String>,
714    },
715    EnableTrigger {
716        trigger_name: Option<String>,
717    },
718    AttachPartition {
719        child: QualifiedName,
720    },
721    DetachPartition {
722        child: QualifiedName,
723    },
724    SetStorage {
725        column: String,
726    },
727    SetAccessMethod,
728}