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    DropType {
167        names: Vec<QualifiedName>,
168        if_exists: bool,
169        cascade: bool,
170    },
171    CreateSequence {
172        name: QualifiedName,
173        if_not_exists: bool,
174        owned_by: Option<(QualifiedName, String)>,
175    },
176    AlterSequence {
177        name: QualifiedName,
178        owned_by: Option<(QualifiedName, String)>,
179    },
180    DropSequence {
181        names: Vec<QualifiedName>,
182        if_exists: bool,
183        cascade: bool,
184    },
185    DropTable {
186        name: QualifiedName,
187        if_exists: bool,
188        cascade: bool,
189    },
190    DropView {
191        name: QualifiedName,
192        if_exists: bool,
193        cascade: bool,
194    },
195    DropMaterializedView {
196        names: Vec<QualifiedName>,
197        if_exists: bool,
198        cascade: bool,
199    },
200    DropIndex {
201        names: Vec<QualifiedName>,
202        if_exists: bool,
203        concurrently: bool,
204    },
205    SetSearchPath {
206        target: SearchPathTarget,
207    },
208    BeginTransaction,
209    CommitTransaction,
210    CommitAndChain,
211    RollbackTransaction,
212    RollbackAndChain,
213    RollbackToSavepoint {
214        name: String,
215    },
216    Savepoint {
217        name: String,
218    },
219    ReleaseSavepoint {
220        name: String,
221    },
222    PrepareTransaction {
223        name: String,
224    },
225    SetTransaction,
226    SetConstraints,
227    OpaqueBlock,
228    Execute,
229    Vacuum {
230        relation: Option<QualifiedName>,
231        is_full: bool,
232    },
233    CreateFunction(CreateFunctionFact),
234    AlterFunction(AlterFunctionFact),
235    DropFunction(DropFunctionFact),
236    CreateProcedure(CreateProcedureFact),
237    AlterProcedure(AlterProcedureFact),
238    DropProcedure(DropProcedureFact),
239    CreatePublication(CreatePublicationFact),
240    AlterPublication(AlterPublicationFact),
241    DropPublication(DropPublicationFact),
242    CreateSubscription(CreateSubscriptionFact),
243    AlterSubscription(AlterSubscriptionFact),
244    DropSubscription(DropSubscriptionFact),
245    CreateRole(CreateRoleFact),
246    AlterRole(AlterRoleFact),
247    DropRole(DropRoleFact),
248    Grant(GrantFact),
249    Revoke(RevokeFact),
250    CreateDatabase(CreateDatabaseFact),
251    AlterDatabase(AlterDatabaseFact),
252    DropDatabase(DropDatabaseFact),
253}
254
255#[derive(Clone, Debug, PartialEq)]
256pub enum AlterIndexActionFact {
257    RenameTo { new_name: Ident },
258}
259
260#[derive(Clone, Debug, PartialEq)]
261pub struct CreateTypeFact {
262    pub name: QualifiedName,
263    pub kind: TypeCreationKind,
264}
265
266#[derive(Clone, Debug, PartialEq)]
267pub struct AlterTypeFact {
268    pub name: QualifiedName,
269    pub actions: Vec<AlterTypeActionFact>,
270}
271
272#[derive(Clone, Debug, PartialEq)]
273pub enum AlterTypeActionFact {
274    AddValue {
275        new_value: String,
276        neighbor: Option<String>,
277        before: bool,
278    },
279}
280
281#[derive(Clone, Debug, PartialEq, Default)]
282pub enum RoleFact {
283    #[default]
284    Unknown,
285    Named {
286        name: String,
287        via_legacy_group_syntax: bool,
288    },
289    CurrentUser,
290    CurrentRole,
291    SessionUser,
292}
293
294#[derive(Clone, Debug, PartialEq)]
295pub struct CreateRoleFact {
296    pub name: String,
297    pub inherits: bool,
298}
299
300#[derive(Clone, Debug, PartialEq)]
301pub struct AlterRoleFact {
302    pub name: RoleFact,
303    pub inherits: Option<bool>,
304}
305
306#[derive(Clone, Debug, PartialEq)]
307pub struct DropRoleFact {
308    pub names: Vec<String>,
309    pub if_exists: bool,
310}
311
312#[derive(Clone, Debug, PartialEq)]
313pub struct CreateFunctionFact {
314    pub name: QualifiedName,
315    pub or_replace: bool,
316    pub params: Vec<ParamFact>,
317    pub return_type: Option<RetTypeFact>,
318    pub options: Vec<FuncOptionFact>,
319}
320
321#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
322pub struct ParamFact {
323    pub mode: ParamModeFact,
324    pub name: Option<String>,
325    pub ty: String,
326    pub default: Option<ExprIr>,
327}
328
329#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
330pub enum ParamModeFact {
331    In,
332    Out,
333    InOut,
334    Variadic,
335}
336
337#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
338pub enum RetTypeFact {
339    Table(Vec<ColumnFact>),
340    Scalar(String),
341}
342
343#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
344pub enum FuncOptionFact {
345    Language(String),
346    Volatility(VolatilityKind),
347    Security(SecurityKind),
348    Strict(StrictKind),
349    Leakproof(bool),
350    Parallel(String),
351    Cost,
352    Rows,
353    Reset(String),
354    As {
355        definition: Option<String>,
356        obj_file: Option<String>,
357        link_symbol: Option<String>,
358    },
359    Transform,
360    Window,
361    Support,
362    Unknown,
363}
364
365#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
366pub enum VolatilityKind {
367    Immutable,
368    Stable,
369    Volatile,
370}
371#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
372pub enum SecurityKind {
373    Invoker,
374    Definer,
375}
376#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
377pub enum StrictKind {
378    Strict,
379    CalledOnNull,
380    ReturnsNullOnNull,
381}
382
383#[derive(Clone, Debug, PartialEq)]
384pub struct AlterFunctionFact {
385    pub name: QualifiedName,
386    pub params: Vec<String>,
387    pub action: AlterFunctionAction,
388}
389
390#[derive(Clone, Debug, PartialEq)]
391pub enum AlterFunctionAction {
392    Rename { from: String, to: String },
393    OwnerChange(RoleFact),
394    SchemaChange { new_schema: String },
395    DependsOnExtension { extension: String },
396    NoDependsOnExtension { extension: String },
397    OptionsChange(Vec<FuncOptionFact>),
398}
399
400#[derive(Clone, Debug, PartialEq)]
401pub struct DropFunctionFact {
402    pub signatures: Vec<FunctionSigFact>,
403    pub if_exists: bool,
404    pub cascade: bool,
405}
406
407#[derive(Clone, Debug, PartialEq)]
408pub struct FunctionSigFact {
409    pub name: QualifiedName,
410    pub params: Vec<String>,
411}
412
413#[derive(Clone, Debug, PartialEq)]
414pub struct CreateProcedureFact {
415    pub name: QualifiedName,
416    pub or_replace: bool,
417    pub params: Vec<ParamFact>,
418    pub options: Vec<FuncOptionFact>,
419}
420
421#[derive(Clone, Debug, PartialEq)]
422pub struct AlterProcedureFact {
423    pub name: QualifiedName,
424    pub params: Vec<String>,
425    pub action: AlterFunctionAction,
426}
427
428#[derive(Clone, Debug, PartialEq)]
429pub struct DropProcedureFact {
430    pub signatures: Vec<FunctionSigFact>,
431    pub if_exists: bool,
432    pub cascade: bool,
433}
434
435#[derive(Clone, Debug, PartialEq)]
436pub struct CreatePublicationFact {
437    pub name: String,
438    pub scope: PublicationScope,
439    pub params: Vec<AttributeFact>,
440}
441
442#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
443pub enum PublicationScope {
444    AllTables { except: Vec<String> },
445    Explicit(Vec<PublicationObjectFact>),
446}
447
448#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
449pub enum PublicationObjectFact {
450    Table {
451        name: QualifiedName,
452        only: bool,
453        include_partitions: bool,
454        columns: Option<Vec<String>>,
455        row_filter: Option<ExprIr>,
456    },
457    SchemaTables {
458        schema: String,
459        row_filter: Option<ExprIr>,
460    },
461    CurrentSchemaShorthand,
462    Unknown,
463}
464
465#[derive(Clone, Debug, PartialEq)]
466pub struct AlterPublicationFact {
467    pub name: String,
468}
469
470#[derive(Clone, Debug, PartialEq)]
471pub struct DropPublicationFact {
472    pub names: Vec<String>,
473    pub if_exists: bool,
474    pub cascade: bool,
475}
476
477#[derive(Clone, Debug, PartialEq)]
478pub struct CreateSubscriptionFact {
479    pub name: Option<String>,
480    pub connection: ConnectionTarget,
481    pub publications: Vec<String>,
482    pub params: Option<Vec<AttributeFact>>,
483}
484
485#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
486pub enum ConnectionTarget {
487    Literal(Option<String>),
488    Server(Option<String>),
489}
490
491#[derive(Clone, Debug, PartialEq)]
492pub struct AlterSubscriptionFact {
493    pub name: String,
494}
495
496#[derive(Clone, Debug, PartialEq)]
497pub struct DropSubscriptionFact {
498    pub name: String,
499    pub if_exists: bool,
500}
501
502#[derive(Clone, Debug, PartialEq)]
503pub struct GrantFact {
504    pub privileges: PrivilegeSpec,
505    pub target: GrantTarget,
506    pub grantees: Vec<RoleFact>,
507    pub with_grant_option: bool,
508    pub granted_by: Option<RoleFact>,
509}
510
511#[derive(Clone, Debug, PartialEq)]
512pub struct RevokeFact {
513    pub grant_option_only: bool,
514    pub privileges: PrivilegeSpec,
515    pub target: GrantTarget,
516    pub revokees: Vec<RoleFact>,
517    pub granted_by: Option<RoleFact>,
518    pub cascade: bool,
519}
520
521#[derive(Clone, Debug, PartialEq)]
522pub enum PrivilegeSpec {
523    All,
524    List(Vec<PrivilegeFact>),
525}
526
527#[derive(Clone, Debug, PartialEq)]
528pub enum PrivilegeFact {
529    Select,
530    Insert,
531    Update,
532    Delete,
533    Truncate,
534    References,
535    Trigger,
536    Execute,
537    Create,
538    Temporary,
539    AlterSystem,
540    All,
541    Named(String),
542    RoleMembership(String),
543    Unknown,
544}
545
546#[derive(Clone, Debug, PartialEq)]
547pub enum GrantTarget {
548    Tables(Vec<QualifiedName>),
549    AllTablesInSchema(Vec<String>),
550}
551
552#[derive(Clone, Debug, PartialEq)]
553pub struct CreateDatabaseFact {
554    pub name: String,
555    pub options: Vec<DatabaseOptionFact>,
556}
557
558#[derive(Clone, Debug, PartialEq)]
559pub enum DatabaseOptionFact {
560    Owner(DatabaseOptionValue),
561    Template(DatabaseOptionValue),
562    Encoding(DatabaseOptionValue),
563    Tablespace(DatabaseOptionValue),
564    ConnectionLimit(DatabaseOptionValue),
565    Named(String, DatabaseOptionValue),
566    Unknown(DatabaseOptionValue),
567}
568
569#[derive(Clone, Debug, PartialEq)]
570pub enum DatabaseOptionValue {
571    Default,
572    Literal(Option<String>),
573}
574
575#[derive(Clone, Debug, PartialEq)]
576pub struct AlterDatabaseFact {
577    pub name: QualifiedName,
578    pub action: AlterDatabaseAction,
579}
580
581#[derive(Clone, Debug, PartialEq)]
582pub enum AlterDatabaseAction {
583    Rename { to: String },
584    OwnerChange(RoleFact),
585    TablespaceChange { new_tablespace: String },
586    SetConfigParam { param: String },
587    ResetConfigParam { param: Option<String> },
588    RefreshCollationVersion,
589    OptionChanges(Vec<DatabaseOptionFact>),
590}
591
592#[derive(Clone, Debug, PartialEq)]
593pub struct DropDatabaseFact {
594    pub name: QualifiedName,
595    pub if_exists: bool,
596}
597
598#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
599pub struct AttributeFact {
600    pub name: String,
601    pub value: String,
602}
603
604#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
605pub struct ColumnFact {
606    pub name: String,
607    pub ty: Option<String>,
608    pub not_null: bool,
609    pub is_primary_key: bool,
610    pub default: Option<ExprIr>,
611}
612
613#[derive(Clone, Debug, PartialEq)]
614pub struct FkFact {
615    pub constraint_name: Option<String>,
616    pub references: QualifiedName,
617    pub from_columns: Vec<String>,
618    pub to_columns: Vec<String>,
619}
620
621#[derive(Clone, Debug, PartialEq)]
622pub enum TableConstraintFact {
623    PrimaryKey { columns: Vec<String> },
624    Unique { columns: Vec<String> },
625    Check,
626    Exclude,
627}
628
629#[derive(Clone, Debug, PartialEq)]
630pub enum AlterDomainActionFact {
631    AddConstraint,
632    DropConstraint,
633    DropDefault,
634    DropNotNull,
635    OwnerChange,
636    RenameConstraint,
637    RenameTo,
638    SetDefault,
639    SetNotNull,
640    SetSchema,
641    ValidateConstraint,
642}
643
644#[derive(Clone, Debug, PartialEq)]
645pub enum AlterTableActionFact {
646    AddColumn {
647        name: String,
648        ty: Option<String>,
649        if_not_exists: bool,
650        not_null: bool,
651        default: Option<ExprIr>,
652    },
653    DropColumn {
654        name: String,
655        if_exists: bool,
656    },
657    RenameColumn {
658        from: Ident,
659        to: Ident,
660    },
661    RenameTo {
662        new_name: Ident,
663    },
664    AddForeignKey {
665        constraint_name: Option<String>,
666        references: QualifiedName,
667        from_columns: Vec<String>,
668        to_columns: Vec<String>,
669        not_valid: bool,
670    },
671    AlterConstraint {
672        name: Option<String>,
673        deferrable: bool,
674    },
675    RenameConstraint {
676        old_name: String,
677        new_name: String,
678    },
679    DropConstraint {
680        name: String,
681    },
682    AddCheckConstraint {
683        constraint_name: Option<String>,
684        not_valid: bool,
685    },
686    AddUniqueConstraint {
687        constraint_name: Option<String>,
688    },
689    AddPrimaryKeyConstraint,
690    AddExcludeConstraint,
691    SetNotNull {
692        column: String,
693    },
694    DropNotNull {
695        column: String,
696    },
697    SetType {
698        column: String,
699        ty: String,
700        has_using: bool,
701    },
702    SetDefault {
703        column: String,
704        default: Option<ExprIr>,
705    },
706    SetExpression {
707        column: String,
708        expr: ExprIr,
709    },
710    SetOptions {
711        column: String,
712        attributes: Vec<AttributeFact>,
713    },
714    Inherit {
715        column: String,
716        parent: QualifiedName,
717    },
718    NoInherit {
719        column: String,
720        parent: QualifiedName,
721    },
722    ValidateConstraint {
723        constraint_name: String,
724    },
725    DisableTrigger {
726        trigger_name: Option<String>,
727    },
728    EnableTrigger {
729        trigger_name: Option<String>,
730    },
731    AttachPartition {
732        child: QualifiedName,
733    },
734    DetachPartition {
735        child: QualifiedName,
736    },
737    SetStorage {
738        column: String,
739    },
740    SetAccessMethod,
741    ClusterOn {
742        index: String,
743    },
744    InheritTable {
745        parent: QualifiedName,
746    },
747    NoInheritTable {
748        parent: QualifiedName,
749    },
750    MergePartitions {
751        parent: QualifiedName,
752    },
753    SplitPartition,
754    SetSchema {
755        new_schema: String,
756    },
757    SetTablespace {
758        tablespace: String,
759    },
760    SetLogged,
761    SetUnlogged,
762    OwnerTo {
763        new_owner: String,
764    },
765    ReplicaIdentity {
766        option: String,
767    },
768    ForceRls,
769    EnableRls,
770    DisableRls,
771    EnableAlwaysTrigger {
772        trigger_name: Option<String>,
773    },
774    EnableReplicaTrigger {
775        trigger_name: Option<String>,
776    },
777}