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