Skip to content

Commit

Permalink
PR Feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
Hydrocharged committed Oct 7, 2020
1 parent 11735ac commit 37fe1e3
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 63 deletions.
31 changes: 31 additions & 0 deletions enginetest/trigger_queries.go
Original file line number Diff line number Diff line change
Expand Up @@ -1281,6 +1281,37 @@ var TriggerTests = []ScriptTest{
},
},
},
{
Query: "show triggers where timing = 'BEFORE' and `Table` like '%bb'",
Expected: []sql.Row{
{
"t1", // Trigger
"INSERT", // Event
"abb", // Table
"set new.x = new.x + 1", // Statement
"BEFORE", // Timing
time.Unix(0, 0).UTC(), // Created
"", // sql_mode
"", // Definer
sql.Collation_Default.CharacterSet().String(), // character_set_client
sql.Collation_Default.String(), // collation_connection
sql.Collation_Default.String(), // Database Collation
},
{
"t2", // Trigger
"INSERT", // Event
"abb", // Table
"set new.x = new.x + 2", // Statement
"BEFORE", // Timing
time.Unix(0, 0).UTC(), // Created
"", // sql_mode
"", // Definer
sql.Collation_Default.CharacterSet().String(), // character_set_client
sql.Collation_Default.String(), // collation_connection
sql.Collation_Default.String(), // Database Collation
},
},
},
},
},
}
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/dolthub/go-mysql-server
require (
github.com/VividCortex/gohistogram v1.0.0 // indirect
github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878 // indirect
github.com/dolthub/vitess v0.0.0-20201006100455-a51dcc1cc2da
github.com/dolthub/vitess v0.0.0-20201007101039-863bfd8b584d
github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 // indirect
github.com/go-kit/kit v0.9.0
github.com/go-sql-driver/mysql v1.4.1
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ github.com/dolthub/vitess v0.0.0-20200925174744-823c7e177c3f h1:37HLaUKuZMDOxKT8
github.com/dolthub/vitess v0.0.0-20200925174744-823c7e177c3f/go.mod h1:hUE8oSk2H5JZnvtlLBhJPYC8WZCA5AoSntdLTcBvdBM=
github.com/dolthub/vitess v0.0.0-20201006100455-a51dcc1cc2da h1:2VuGtLb/uea8sI6SVMeODo59j7QvPNaXozKABJsIIMg=
github.com/dolthub/vitess v0.0.0-20201006100455-a51dcc1cc2da/go.mod h1:hUE8oSk2H5JZnvtlLBhJPYC8WZCA5AoSntdLTcBvdBM=
github.com/dolthub/vitess v0.0.0-20201007101039-863bfd8b584d h1:Nsa6U/g2u7qjvrYiGoGrUMTFSqbAk0U47iaMLZOk8Pc=
github.com/dolthub/vitess v0.0.0-20201007101039-863bfd8b584d/go.mod h1:hUE8oSk2H5JZnvtlLBhJPYC8WZCA5AoSntdLTcBvdBM=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 h1:Ghm4eQYC0nEPnSJdVkTrXpu9KtoVCSo1hg7mtI7G9KU=
Expand Down
28 changes: 16 additions & 12 deletions sql/analyzer/triggers.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ func applyTriggers(ctx *sql.Context, a *Analyzer, n sql.Node, scope *Scope) (sql
return n, nil
}

triggers := OrderTriggers(affectedTriggers)
triggers := orderTriggersAndReverseAfter(affectedTriggers)
originalNode := n

for _, trigger := range triggers {
Expand Down Expand Up @@ -320,7 +320,20 @@ func validateNoCircularUpdates(trigger *plan.CreateTrigger, n sql.Node, scope *S
return circularRef
}

func OrderTriggers(triggers []*plan.CreateTrigger) []*plan.CreateTrigger {
func orderTriggersAndReverseAfter(triggers []*plan.CreateTrigger) []*plan.CreateTrigger {
beforeTriggers, afterTriggers := OrderTriggers(triggers)

// Reverse the order of after triggers. This is because we always apply them to the Insert / Update / Delete node
// that initiated the trigger, so after triggers, which wrap the Insert, need be applied in reverse order for them to
// run in the correct order.
for left, right := 0, len(afterTriggers)-1; left < right; left, right = left+1, right-1 {
afterTriggers[left], afterTriggers[right] = afterTriggers[right], afterTriggers[left]
}

return append(beforeTriggers, afterTriggers...)
}

func OrderTriggers(triggers []*plan.CreateTrigger) (beforeTriggers []*plan.CreateTrigger, afterTriggers []*plan.CreateTrigger) {
orderedTriggers := make([]*plan.CreateTrigger, len(triggers))
copy(orderedTriggers, triggers)

Expand Down Expand Up @@ -352,8 +365,6 @@ Top:
}

// Now that we have ordered the triggers according to precedence, split them into BEFORE / AFTER triggers
var beforeTriggers []*plan.CreateTrigger
var afterTriggers []*plan.CreateTrigger
for _, trigger := range orderedTriggers {
if trigger.TriggerTime == sqlparser.BeforeStr {
beforeTriggers = append(beforeTriggers, trigger)
Expand All @@ -362,14 +373,7 @@ Top:
}
}

// Reverse the order of after triggers. This is because we always apply them to the Insert / Update / Delete node
// that initiated the trigger, so after triggers, which wrap the Insert, need be applied in reverse order for them to
// run in the correct order.
for left, right := 0, len(afterTriggers)-1; left < right; left, right = left+1, right-1 {
afterTriggers[left], afterTriggers[right] = afterTriggers[right], afterTriggers[left]
}

return append(beforeTriggers, afterTriggers...)
return beforeTriggers, afterTriggers
}

func triggerEventsMatch(event plan.TriggerEvent, event2 string) bool {
Expand Down
47 changes: 23 additions & 24 deletions sql/information_schema/information_schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -542,37 +542,36 @@ func triggersRowIter(ctx *Context, c *Catalog) (RowIter, error) {
triggerPlans = append(triggerPlans, triggerPlan)
}

triggerPlans = analyzer.OrderTriggers(triggerPlans)
beforeTriggers, afterTriggers := analyzer.OrderTriggers(triggerPlans)
var beforeDelete []*plan.CreateTrigger
var beforeInsert []*plan.CreateTrigger
var beforeUpdate []*plan.CreateTrigger
var afterDelete []*plan.CreateTrigger
var afterInsert []*plan.CreateTrigger
var afterUpdate []*plan.CreateTrigger
for _, triggerPlan := range triggerPlans {
switch triggerPlan.TriggerTime {
case sqlparser.BeforeStr:
switch triggerPlan.TriggerEvent {
case sqlparser.DeleteStr:
beforeDelete = append(beforeDelete, triggerPlan)
case sqlparser.InsertStr:
beforeInsert = append(beforeInsert, triggerPlan)
case sqlparser.UpdateStr:
beforeUpdate = append(beforeUpdate, triggerPlan)
}
case sqlparser.AfterStr:
// OrderTriggers reverses AFTER, so we must reverse them again
switch triggerPlan.TriggerEvent {
case sqlparser.DeleteStr:
afterDelete = append([]*plan.CreateTrigger{triggerPlan}, afterDelete...)
case sqlparser.InsertStr:
afterInsert = append([]*plan.CreateTrigger{triggerPlan}, afterInsert...)
case sqlparser.UpdateStr:
afterUpdate = append([]*plan.CreateTrigger{triggerPlan}, afterUpdate...)
}
for _, triggerPlan := range beforeTriggers {
switch triggerPlan.TriggerEvent {
case sqlparser.DeleteStr:
beforeDelete = append(beforeDelete, triggerPlan)
case sqlparser.InsertStr:
beforeInsert = append(beforeInsert, triggerPlan)
case sqlparser.UpdateStr:
beforeUpdate = append(beforeUpdate, triggerPlan)
}
}
for _, triggerPlan := range afterTriggers {
switch triggerPlan.TriggerEvent {
case sqlparser.DeleteStr:
afterDelete = append(afterDelete, triggerPlan)
case sqlparser.InsertStr:
afterInsert = append(afterInsert, triggerPlan)
case sqlparser.UpdateStr:
afterUpdate = append(afterUpdate, triggerPlan)
}
}

// These are grouped as such just to use the index as the action order. No special importance on the arrangement,
// or the fact that these are slices in a larger slice rather than separate counts.
for _, planGroup := range [][]*plan.CreateTrigger{beforeDelete, beforeInsert, beforeUpdate, afterDelete, afterInsert, afterUpdate} {
for order, triggerPlan := range planGroup {
triggerEvent := strings.ToUpper(triggerPlan.TriggerEvent)
Expand Down Expand Up @@ -600,8 +599,8 @@ func triggersRowIter(ctx *Context, c *Catalog) (RowIter, error) {
time.Unix(0, 0).UTC(), // created
"", // sql_mode
"", // definer
characterSetClient, // character_set_client
collationConnection, // collation_connection
characterSetClient, // character_set_client //TODO: allow these to be retrieved from integrators
collationConnection, // collation_connection //TODO: allow these to be retrieved from integrators
Collation_Default.String(), // database_collation //TODO: add support for databases to set collation
})
}
Expand Down
24 changes: 13 additions & 11 deletions sql/plan/show_create_trigger.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@ type ShowCreateTrigger struct {
var _ sql.Databaser = (*ShowCreateTrigger)(nil)
var _ sql.Node = (*ShowCreateTrigger)(nil)

var showCreateTriggerSchema = sql.Schema{
&sql.Column{Name: "Trigger", Type: sql.LongText, Nullable: false},
&sql.Column{Name: "sql_mode", Type: sql.LongText, Nullable: false},
&sql.Column{Name: "SQL Original Statement", Type: sql.LongText, Nullable: false},
&sql.Column{Name: "character_set_client", Type: sql.LongText, Nullable: false},
&sql.Column{Name: "collation_connection", Type: sql.LongText, Nullable: false},
&sql.Column{Name: "Database Collation", Type: sql.LongText, Nullable: false},
&sql.Column{Name: "Created", Type: sql.Datetime, Nullable: false},
}

// NewShowCreateTrigger creates a new ShowCreateTrigger node for SHOW CREATE TRIGGER statements.
func NewShowCreateTrigger(db sql.Database, trigger string) *ShowCreateTrigger {
return &ShowCreateTrigger{
Expand All @@ -56,15 +66,7 @@ func (s *ShowCreateTrigger) Children() []sql.Node {

// Schema implements the sql.Node interface.
func (s *ShowCreateTrigger) Schema() sql.Schema {
return sql.Schema{
&sql.Column{Name: "Trigger", Type: sql.LongText, Nullable: false},
&sql.Column{Name: "sql_mode", Type: sql.LongText, Nullable: false},
&sql.Column{Name: "SQL Original Statement", Type: sql.LongText, Nullable: false},
&sql.Column{Name: "character_set_client", Type: sql.LongText, Nullable: false},
&sql.Column{Name: "collation_connection", Type: sql.LongText, Nullable: false},
&sql.Column{Name: "Database Collation", Type: sql.LongText, Nullable: false},
&sql.Column{Name: "Created", Type: sql.Datetime, Nullable: false},
}
return showCreateTriggerSchema
}

// RowIter implements the sql.Node interface.
Expand All @@ -85,8 +87,8 @@ func (s *ShowCreateTrigger) RowIter(ctx *sql.Context, row sql.Row) (sql.RowIter,
trigger.Name, // Trigger
"", // sql_mode
trigger.CreateStatement, // SQL Original Statement
characterSetClient, // character_set_client
collationConnection, // collation_connection
characterSetClient, // character_set_client //TODO: allow these to be retrieved from integrators
collationConnection, // collation_connection //TODO: allow these to be retrieved from integrators
sql.Collation_Default.String(), // Database Collation //TODO: add support for databases to set collation
time.Unix(0, 0).UTC(), // Created
}), nil
Expand Down
32 changes: 17 additions & 15 deletions sql/plan/show_triggers.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,20 @@ type ShowTriggers struct {
var _ sql.Databaser = (*ShowTriggers)(nil)
var _ sql.Node = (*ShowTriggers)(nil)

var showTriggersSchema = sql.Schema{
&sql.Column{Name: "Trigger", Type: sql.LongText, Nullable: false},
&sql.Column{Name: "Event", Type: sql.LongText, Nullable: false},
&sql.Column{Name: "Table", Type: sql.LongText, Nullable: false},
&sql.Column{Name: "Statement", Type: sql.LongText, Nullable: false},
&sql.Column{Name: "Timing", Type: sql.LongText, Nullable: false},
&sql.Column{Name: "Created", Type: sql.Datetime, Nullable: false},
&sql.Column{Name: "sql_mode", Type: sql.LongText, Nullable: false},
&sql.Column{Name: "Definer", Type: sql.LongText, Nullable: false},
&sql.Column{Name: "character_set_client", Type: sql.LongText, Nullable: false},
&sql.Column{Name: "collation_connection", Type: sql.LongText, Nullable: false},
&sql.Column{Name: "Database Collation", Type: sql.LongText, Nullable: false},
}

// NewShowCreateTrigger creates a new ShowCreateTrigger node for SHOW TRIGGER statements.
func NewShowTriggers(db sql.Database) *ShowTriggers {
return &ShowTriggers{
Expand All @@ -53,19 +67,7 @@ func (s *ShowTriggers) Children() []sql.Node {

// Schema implements the sql.Node interface.
func (s *ShowTriggers) Schema() sql.Schema {
return sql.Schema{
&sql.Column{Name: "Trigger", Type: sql.LongText, Nullable: false},
&sql.Column{Name: "Event", Type: sql.LongText, Nullable: false},
&sql.Column{Name: "Table", Type: sql.LongText, Nullable: false},
&sql.Column{Name: "Statement", Type: sql.LongText, Nullable: false},
&sql.Column{Name: "Timing", Type: sql.LongText, Nullable: false},
&sql.Column{Name: "Created", Type: sql.Datetime, Nullable: false},
&sql.Column{Name: "sql_mode", Type: sql.LongText, Nullable: false},
&sql.Column{Name: "Definer", Type: sql.LongText, Nullable: false},
&sql.Column{Name: "character_set_client", Type: sql.LongText, Nullable: false},
&sql.Column{Name: "collation_connection", Type: sql.LongText, Nullable: false},
&sql.Column{Name: "Database Collation", Type: sql.LongText, Nullable: false},
}
return showTriggersSchema
}

// RowIter implements the sql.Node interface.
Expand All @@ -86,8 +88,8 @@ func (s *ShowTriggers) RowIter(ctx *sql.Context, row sql.Row) (sql.RowIter, erro
time.Unix(0, 0).UTC(), // Created
"", // sql_mode
"", // Definer
characterSetClient, // character_set_client
collationConnection, // collation_connection
characterSetClient, // character_set_client //TODO: allow these to be retrieved from integrators
collationConnection, // collation_connection //TODO: allow these to be retrieved from integrators
sql.Collation_Default.String(), // Database Collation
})
}
Expand Down

0 comments on commit 37fe1e3

Please sign in to comment.