Skip to content

Commit 53a2edb

Browse files
authored
Merge pull request #3115 from dolthub/fulghum/info_schema_triggers
Bug fix: correctly parse/resolve trigger definitions across multiple databases
2 parents 18eebe5 + bf26b26 commit 53a2edb

File tree

2 files changed

+45
-0
lines changed

2 files changed

+45
-0
lines changed

enginetest/queries/information_schema_queries.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -830,6 +830,40 @@ var SkippedInfoSchemaQueries = []QueryTest{
830830
}
831831

832832
var InfoSchemaScripts = []ScriptTest{
833+
{
834+
Name: "List triggers across multiple databases",
835+
SetUpScript: []string{
836+
"CREATE DATABASE db1;",
837+
"CREATE DATABASE db2;",
838+
"USE db1;",
839+
"CREATE TABLE main1(pk int primary key, c1 varchar(100));",
840+
"CREATE TABLE main2(pk int primary key);",
841+
"CREATE TRIGGER before_insert_main1 BEFORE INSERT ON main1 FOR EACH ROW BEGIN DECLARE row_count INT; SELECT COUNT(*) INTO row_count FROM main2; IF row_count > 0 THEN SET NEW.c1 = 'has data'; ELSE SET NEW.c1 = 'empty'; END IF; END",
842+
"USE db2;",
843+
"CREATE TABLE b1(pk int primary key, c1 varchar(100));",
844+
"CREATE TABLE b2(pk int primary key);",
845+
"CREATE TRIGGER before_insert_b1 BEFORE INSERT ON b1 FOR EACH ROW BEGIN DECLARE row_count INT; SELECT COUNT(*) INTO row_count FROM b2; IF row_count > 0 THEN SET NEW.c1 = 'has data'; ELSE SET NEW.c1 = 'empty'; END IF; END",
846+
},
847+
Assertions: []ScriptTestAssertion{
848+
{
849+
Query: "USE db1;",
850+
Expected: []sql.Row{},
851+
},
852+
{
853+
Query: "SELECT database();",
854+
Expected: []sql.Row{{"db1"}},
855+
},
856+
{
857+
Query: "SELECT trigger_catalog, trigger_schema, trigger_name FROM information_schema.triggers;",
858+
Expected: []sql.Row{{"def", "db1", "before_insert_main1"}, {"def", "db2", "before_insert_b1"}},
859+
},
860+
{
861+
// Ensure the current database is still db1
862+
Query: "SELECT database();",
863+
Expected: []sql.Row{{"db1"}},
864+
},
865+
},
866+
},
833867
{
834868
Name: "foreign key that references dropped table",
835869
SetUpScript: []string{

sql/information_schema/information_schema.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1937,8 +1937,16 @@ func triggersRowIter(ctx *Context, c Catalog) (RowIter, error) {
19371937
continue
19381938
}
19391939

1940+
// Capture the current database, so that we can ensure it gets set back to this value
1941+
// after we adjust it to parse each database's triggers.
1942+
originalDatabase := ctx.GetCurrentDatabase()
1943+
defer ctx.SetCurrentDatabase(originalDatabase)
1944+
19401945
var triggerPlans []*plan.CreateTrigger
19411946
for _, trigger := range triggers {
1947+
// Because we have to parse/resolve the CREATE TRIGGER statement again, we update the
1948+
// session's current database so that ParseWithOptions can correctly resolve references.
1949+
ctx.SetCurrentDatabase(db.Database.Name())
19421950
triggerSqlMode := NewSqlModeFromString(trigger.SqlMode)
19431951
// TODO: figure out how auth works in this case
19441952
parsedTrigger, _, err := planbuilder.ParseWithOptions(ctx, c, trigger.CreateStatement, triggerSqlMode.ParserOptions())
@@ -1954,6 +1962,9 @@ func triggersRowIter(ctx *Context, c Catalog) (RowIter, error) {
19541962
triggerPlans = append(triggerPlans, triggerPlan)
19551963
}
19561964

1965+
// Set the context back to the original database, since we changed it to parse each database's triggers
1966+
ctx.SetCurrentDatabase(originalDatabase)
1967+
19571968
beforeTriggers, afterTriggers := plan.OrderTriggers(triggerPlans)
19581969
var beforeDelete []*plan.CreateTrigger
19591970
var beforeInsert []*plan.CreateTrigger

0 commit comments

Comments
 (0)