-
Notifications
You must be signed in to change notification settings - Fork 30
feat: support CONSTRAINT TRIGGER #63
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -971,17 +971,44 @@ func (td *tableDiff) generateAlterTableStatements(targetSchema string, collector | |||||
|
|
||||||
| // Modify triggers - already sorted by the Diff operation | ||||||
| for _, triggerDiff := range td.ModifiedTriggers { | ||||||
| // Use CREATE OR REPLACE for modified triggers | ||||||
| sql := generateTriggerSQLWithMode(triggerDiff.New, targetSchema) | ||||||
| // Constraint triggers don't support CREATE OR REPLACE, so we need to DROP and CREATE | ||||||
| if triggerDiff.New.IsConstraint { | ||||||
| tableName := getTableNameWithSchema(td.Table.Schema, td.Table.Name, targetSchema) | ||||||
|
|
||||||
| context := &diffContext{ | ||||||
| Type: DiffTypeTableTrigger, | ||||||
| Operation: DiffOperationAlter, | ||||||
| Path: fmt.Sprintf("%s.%s.%s", td.Table.Schema, td.Table.Name, triggerDiff.New.Name), | ||||||
| Source: triggerDiff, | ||||||
| CanRunInTransaction: true, | ||||||
| // Step 1: DROP the old trigger | ||||||
| dropSQL := fmt.Sprintf("DROP TRIGGER IF EXISTS %s ON %s;", triggerDiff.Old.Name, tableName) | ||||||
|
||||||
| dropSQL := fmt.Sprintf("DROP TRIGGER IF EXISTS %s ON %s;", triggerDiff.Old.Name, tableName) | |
| dropSQL := fmt.Sprintf("DROP TRIGGER %s ON %s;", triggerDiff.Old.Name, tableName) |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| CREATE CONSTRAINT TRIGGER prevent_code_update_trigger | ||
| AFTER UPDATE ON products | ||
| DEFERRABLE INITIALLY IMMEDIATE | ||
| FOR EACH ROW | ||
| EXECUTE FUNCTION prevent_code_update(); | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| CREATE TABLE public.products ( | ||
| id integer PRIMARY KEY, | ||
| code text NOT NULL | ||
| ); | ||
|
|
||
| CREATE OR REPLACE FUNCTION public.prevent_code_update() | ||
| RETURNS trigger AS $$ | ||
| BEGIN | ||
| IF OLD.code IS DISTINCT FROM NEW.code THEN | ||
| RAISE EXCEPTION 'Product code cannot be updated'; | ||
| END IF; | ||
| RETURN NEW; | ||
| END; | ||
| $$ LANGUAGE plpgsql; | ||
|
|
||
| CREATE CONSTRAINT TRIGGER prevent_code_update_trigger | ||
| AFTER UPDATE ON public.products | ||
| DEFERRABLE INITIALLY IMMEDIATE | ||
| FOR EACH ROW | ||
| EXECUTE FUNCTION public.prevent_code_update(); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| CREATE TABLE public.products ( | ||
| id integer PRIMARY KEY, | ||
| code text NOT NULL | ||
| ); | ||
|
|
||
| CREATE OR REPLACE FUNCTION public.prevent_code_update() | ||
| RETURNS trigger AS $$ | ||
| BEGIN | ||
| IF OLD.code IS DISTINCT FROM NEW.code THEN | ||
| RAISE EXCEPTION 'Product code cannot be updated'; | ||
| END IF; | ||
| RETURN NEW; | ||
| END; | ||
| $$ LANGUAGE plpgsql; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| { | ||
| "version": "1.0.0", | ||
| "pgschema_version": "1.2.1", | ||
| "created_at": "1970-01-01T00:00:00Z", | ||
| "source_fingerprint": { | ||
| "hash": "08f4c7258568484a7571fb1a332a97279e6dcb5336ddbbf021d777cc1b73730d" | ||
| }, | ||
| "groups": [ | ||
| { | ||
| "steps": [ | ||
| { | ||
| "sql": "CREATE CONSTRAINT TRIGGER prevent_code_update_trigger\n AFTER UPDATE ON products\n DEFERRABLE INITIALLY IMMEDIATE\n FOR EACH ROW\n EXECUTE FUNCTION prevent_code_update();", | ||
| "type": "table.trigger", | ||
| "operation": "create", | ||
| "path": "public.products.prevent_code_update_trigger" | ||
| } | ||
| ] | ||
| } | ||
| ] | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| CREATE CONSTRAINT TRIGGER prevent_code_update_trigger | ||
| AFTER UPDATE ON products | ||
| DEFERRABLE INITIALLY IMMEDIATE | ||
| FOR EACH ROW | ||
| EXECUTE FUNCTION prevent_code_update(); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| Plan: 1 to modify. | ||
|
|
||
| Summary by type: | ||
| tables: 1 to modify | ||
|
|
||
| Tables: | ||
| ~ products | ||
| + prevent_code_update_trigger (trigger) | ||
|
|
||
| DDL to be executed: | ||
| -------------------------------------------------- | ||
|
|
||
| CREATE CONSTRAINT TRIGGER prevent_code_update_trigger | ||
| AFTER UPDATE ON products | ||
| DEFERRABLE INITIALLY IMMEDIATE | ||
| FOR EACH ROW | ||
| EXECUTE FUNCTION prevent_code_update(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This logic only checks if the new trigger is a constraint trigger, but should also handle the case where the old trigger was a constraint trigger but the new one isn't. Both scenarios require DROP and CREATE since constraint triggers don't support CREATE OR REPLACE.