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