github.com/dolthub/go-mysql-server@v0.18.0/enginetest/queries/trigger_queries.go (about)

     1  // Copyright 2020-2021 Dolthub, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package queries
    16  
    17  import (
    18  	"time"
    19  
    20  	"github.com/dolthub/go-mysql-server/sql"
    21  	"github.com/dolthub/go-mysql-server/sql/plan"
    22  	"github.com/dolthub/go-mysql-server/sql/types"
    23  )
    24  
    25  var TriggerTests = []ScriptTest{
    26  	// INSERT triggers
    27  	{
    28  		Name: "trigger before inserts, use updated reference to other table",
    29  		SetUpScript: []string{
    30  			"create table a (i int primary key, j int)",
    31  			"create table b (x int primary key)",
    32  			"create trigger trig before insert on a for each row begin set new.j = (select coalesce(max(x),1) from b); update b set x = x + 1; end;",
    33  			"insert into b values (1)",
    34  			"insert into a values (1,0), (2,0), (3,0)",
    35  		},
    36  		Assertions: []ScriptTestAssertion{
    37  			{
    38  				Query: "select * from a order by i",
    39  				Expected: []sql.Row{
    40  					{1, 1}, {2, 2}, {3, 3},
    41  				},
    42  			},
    43  			{
    44  				Query: "select x from b",
    45  				Expected: []sql.Row{
    46  					{4},
    47  				},
    48  			},
    49  			{
    50  				Query: "insert into a values (4,0), (5,0)",
    51  				Expected: []sql.Row{
    52  					{types.OkResult{RowsAffected: 2}},
    53  				},
    54  			},
    55  		},
    56  	},
    57  	{
    58  		Name: "trigger before inserts, use count updated reference to other table",
    59  		SetUpScript: []string{
    60  			"create table a (i int, j int)",
    61  			"create table b (x int)",
    62  			"create trigger trig before insert on a for each row begin set new.j = (select count(x) from b); insert into b values (new.i + new.j); end;",
    63  			"insert into a values (0,0), (0,0), (0,0)",
    64  		},
    65  		Assertions: []ScriptTestAssertion{
    66  			{
    67  				Query: "select * from a order by j",
    68  				Expected: []sql.Row{
    69  					{0, 0}, {0, 1}, {0, 2},
    70  				},
    71  			},
    72  			{
    73  				Query: "select x from b",
    74  				Expected: []sql.Row{
    75  					{0}, {1}, {2},
    76  				},
    77  			},
    78  			{
    79  				Query: "insert into a values (0,0), (0,0)",
    80  				Expected: []sql.Row{
    81  					{types.OkResult{RowsAffected: 2}},
    82  				},
    83  			},
    84  		},
    85  	},
    86  	{
    87  		Name: "trigger after insert, insert into other table",
    88  		SetUpScript: []string{
    89  			"create table a (x int primary key)",
    90  			"create table b (y int primary key)",
    91  			"create trigger insert_into_b after insert on a for each row insert into b values (new.x + 1)",
    92  			"insert into a values (1), (3), (5)",
    93  		},
    94  		Assertions: []ScriptTestAssertion{
    95  			{
    96  				Query: "select x from a order by 1",
    97  				Expected: []sql.Row{
    98  					{1}, {3}, {5},
    99  				},
   100  			},
   101  			{
   102  				Query: "select y from b order by 1",
   103  				Expected: []sql.Row{
   104  					{2}, {4}, {6},
   105  				},
   106  			},
   107  			{
   108  				Query: "insert into a values (7), (9)",
   109  				Expected: []sql.Row{
   110  					{types.OkResult{RowsAffected: 2}},
   111  				},
   112  			},
   113  		},
   114  	},
   115  	{
   116  		Name: "trigger after insert, delete from other table",
   117  		SetUpScript: []string{
   118  			"create table a (x int primary key)",
   119  			"create table b (y int primary key)",
   120  			"insert into b values (0), (2), (4), (6), (8)",
   121  			"create trigger insert_into_b after insert on a for each row delete from b where y = (new.x + 1)",
   122  			"insert into a values (1), (3), (5)",
   123  		},
   124  		Assertions: []ScriptTestAssertion{
   125  			{
   126  				Query: "select x from a order by 1",
   127  				Expected: []sql.Row{
   128  					{1}, {3}, {5},
   129  				},
   130  			},
   131  			{
   132  				Query: "select y from b order by 1",
   133  				Expected: []sql.Row{
   134  					{0}, {8},
   135  				},
   136  			},
   137  			{
   138  				Query: "insert into a values (7), (9)",
   139  				Expected: []sql.Row{
   140  					{types.OkResult{RowsAffected: 2}},
   141  				},
   142  			},
   143  		},
   144  	},
   145  	{
   146  		Name: "trigger after insert, update other table",
   147  		SetUpScript: []string{
   148  			"create table a (x int primary key)",
   149  			"create table b (y int primary key)",
   150  			"insert into b values (0), (2), (4), (6), (8)",
   151  			"create trigger insert_into_b after insert on a for each row update b set y = new.x where y = new.x + 1",
   152  			"insert into a values (1), (3), (5)",
   153  		},
   154  		Assertions: []ScriptTestAssertion{
   155  			{
   156  				Query: "select x from a order by 1",
   157  				Expected: []sql.Row{
   158  					{1}, {3}, {5},
   159  				},
   160  			},
   161  			{
   162  				Query: "select y from b order by 1",
   163  				Expected: []sql.Row{
   164  					{0}, {1}, {3}, {5}, {8},
   165  				},
   166  			},
   167  		},
   168  	},
   169  	{
   170  		Name: "trigger before insert, insert into other table",
   171  		SetUpScript: []string{
   172  			"create table a (x int primary key)",
   173  			"create table b (y int primary key)",
   174  			"create trigger insert_into_b before insert on a for each row insert into b values (new.x + 1)",
   175  			"insert into a values (1), (3), (5)",
   176  		},
   177  		Assertions: []ScriptTestAssertion{
   178  			{
   179  				Query: "select x from a order by 1",
   180  				Expected: []sql.Row{
   181  					{1}, {3}, {5},
   182  				},
   183  			},
   184  			{
   185  				Query: "select y from b order by 1",
   186  				Expected: []sql.Row{
   187  					{2}, {4}, {6},
   188  				},
   189  			},
   190  			{
   191  				Query: "insert into a values (7), (9)",
   192  				Expected: []sql.Row{
   193  					{types.OkResult{RowsAffected: 2}},
   194  				},
   195  			},
   196  		},
   197  	},
   198  	{
   199  		Name: "trigger before insert, insert into other table with different schema",
   200  		SetUpScript: []string{
   201  			"create table a (x int primary key, y int)",
   202  			"create table b (z int primary key)",
   203  			"create trigger insert_into_b before insert on a for each row insert into b values (new.x + 1)",
   204  			"insert into a values (1,2), (3,4), (5,6)",
   205  		},
   206  		Assertions: []ScriptTestAssertion{
   207  			{
   208  				Query: "select x from a order by 1",
   209  				Expected: []sql.Row{
   210  					{1}, {3}, {5},
   211  				},
   212  			},
   213  			{
   214  				Query: "select z from b order by 1",
   215  				Expected: []sql.Row{
   216  					{2}, {4}, {6},
   217  				},
   218  			},
   219  			{
   220  				Query: "insert into a values (7,8), (9,10)",
   221  				Expected: []sql.Row{
   222  					{types.OkResult{RowsAffected: 2}},
   223  				},
   224  			},
   225  		},
   226  	},
   227  	{
   228  		Name: "trigger before insert, delete from other table",
   229  		SetUpScript: []string{
   230  			"create table a (x int primary key)",
   231  			"create table b (y int primary key)",
   232  			"insert into b values (0), (2), (4), (6), (8)",
   233  			"create trigger insert_into_b before insert on a for each row delete from b where y = (new.x + 1)",
   234  			"insert into a values (1), (3), (5)",
   235  		},
   236  		Assertions: []ScriptTestAssertion{
   237  			{
   238  				Query: "select x from a order by 1",
   239  				Expected: []sql.Row{
   240  					{1}, {3}, {5},
   241  				},
   242  			},
   243  			{
   244  				Query: "select y from b order by 1",
   245  				Expected: []sql.Row{
   246  					{0}, {8},
   247  				},
   248  			},
   249  			{
   250  				Query: "insert into a values (7), (9)",
   251  				Expected: []sql.Row{
   252  					{types.OkResult{RowsAffected: 2}},
   253  				},
   254  			},
   255  		},
   256  	},
   257  	{
   258  		Name: "trigger before insert, update other table",
   259  		SetUpScript: []string{
   260  			"create table a (x int primary key)",
   261  			"create table b (y int primary key)",
   262  			"insert into b values (0), (2), (4), (6), (8)",
   263  			"create trigger insert_into_b before insert on a for each row update b set y = new.x where y = new.x + 1",
   264  			"insert into a values (1), (3), (5)",
   265  		},
   266  		Assertions: []ScriptTestAssertion{
   267  			{
   268  				Query: "select x from a order by 1",
   269  				Expected: []sql.Row{
   270  					{1}, {3}, {5},
   271  				},
   272  			},
   273  			{
   274  				Query: "select y from b order by 1",
   275  				Expected: []sql.Row{
   276  					{0}, {1}, {3}, {5}, {8},
   277  				},
   278  			},
   279  		},
   280  	},
   281  	{
   282  		Name: "trigger before insert, updates references to 2 tables",
   283  		SetUpScript: []string{
   284  			"create table a (i int, j int, k int)",
   285  			"create table b (x int)",
   286  			"create table c (y int)",
   287  			"insert into b values (0)",
   288  			"insert into c values (0)",
   289  			"create trigger trig before insert on a for each row begin set new.j = (select x from b); set new.k = (select y from c); update b set x = x + 1; update c set y = y + 2; end;",
   290  			"insert into a values (0, 0, 0), (1, 0, 0), (2, 0, 0), (3, 0, 0), (4, 0, 0)",
   291  		},
   292  		Assertions: []ScriptTestAssertion{
   293  			{
   294  				Query: "select * from a order by 1",
   295  				Expected: []sql.Row{
   296  					{0, 0, 0}, {1, 1, 2}, {2, 2, 4}, {3, 3, 6}, {4, 4, 8},
   297  				},
   298  			},
   299  			{
   300  				Query: "select x from b order by 1",
   301  				Expected: []sql.Row{
   302  					{5},
   303  				},
   304  			},
   305  			{
   306  				Query: "select y from c order by 1",
   307  				Expected: []sql.Row{
   308  					{10},
   309  				},
   310  			},
   311  		},
   312  	},
   313  	{
   314  		Name: "trigger before insert, alter inserted value",
   315  		SetUpScript: []string{
   316  			"create table a (x int primary key)",
   317  			"create trigger insert_into_a before insert on a for each row set new.x = new.x + 1",
   318  			"insert into a values (1)",
   319  		},
   320  		Query: "select x from a order by 1",
   321  		Expected: []sql.Row{
   322  			{2},
   323  		},
   324  	},
   325  	{
   326  		Name: "trigger before insert, alter inserted value, multiple columns",
   327  		SetUpScript: []string{
   328  			"create table x (a int primary key, b int, c int)",
   329  			"create trigger insert_into_x before insert on x for each row set new.a = new.a + 1, new.b = new.c, new.c = 0",
   330  			"insert into x values (1, 10, 100)",
   331  		},
   332  		Query: "select * from x order by 1",
   333  		Expected: []sql.Row{
   334  			{2, 100, 0},
   335  		},
   336  	},
   337  	{
   338  		Name: "trigger before insert, alter inserted value, multiple columns, system var",
   339  		SetUpScript: []string{
   340  			"create table x (a int primary key, b int, c int)",
   341  			"set @@auto_increment_increment = 1",
   342  			"create trigger insert_into_x before insert on x for each row " +
   343  				"set new.a = new.a + 1, new.b = new.c, new.c = 0, @@auto_increment_increment = @@auto_increment_increment + 1",
   344  			"insert into x values (1, 10, 100), (2, 20, 200)",
   345  		},
   346  		Query: "select *, @@auto_increment_increment from x order by 1",
   347  		Expected: []sql.Row{
   348  			{2, 100, 0, 3},
   349  			{3, 200, 0, 3},
   350  		},
   351  	},
   352  	{
   353  		Name: "trigger before insert, alter inserted value, out of order insertion",
   354  		SetUpScript: []string{
   355  			"create table a (x int primary key, y int)",
   356  			"create trigger a1 before insert on a for each row set new.x = new.x * 2, new.y = new.y * 3",
   357  		},
   358  		Assertions: []ScriptTestAssertion{
   359  			{
   360  				Query: "insert into a (y, x) values (5,7), (9,11)",
   361  				Expected: []sql.Row{
   362  					{types.OkResult{RowsAffected: 2}},
   363  				},
   364  			},
   365  			{
   366  				Query: "select x, y from a order by 1",
   367  				Expected: []sql.Row{
   368  					{14, 15},
   369  					{22, 27},
   370  				},
   371  			},
   372  		},
   373  	},
   374  	{
   375  		Name: "trigger before insert, alter inserted value, incomplete insertion",
   376  		SetUpScript: []string{
   377  			"create table a (x int primary key, y int, z int default 5)",
   378  			"create trigger a1 before insert on a for each row set new.x = new.x * 2, new.y = new.y * 3, new.z = new.z * 5",
   379  		},
   380  		Assertions: []ScriptTestAssertion{
   381  			{
   382  				Query: "insert into a (y, x) values (5,7), (9,11)",
   383  				Expected: []sql.Row{
   384  					{types.OkResult{RowsAffected: 2}},
   385  				},
   386  			},
   387  			{
   388  				Query: "select x, y, z from a order by 1",
   389  				Expected: []sql.Row{
   390  					{14, 15, 25},
   391  					{22, 27, 25},
   392  				},
   393  			},
   394  		},
   395  	},
   396  	{
   397  		Name: "trigger before insert, begin block with multiple set statements",
   398  		SetUpScript: []string{
   399  			"CREATE TABLE test(pk BIGINT PRIMARY KEY, v1 BIGINT);",
   400  			"INSERT INTO test VALUES (0,2),(1,3)",
   401  			`CREATE TRIGGER tt BEFORE INSERT ON test FOR EACH ROW 
   402  				BEGIN 
   403  					SET NEW.v1 = NEW.v1 * 11;
   404  					SET NEW.v1 = NEW.v1 * -10;
   405  				END;`,
   406  			"INSERT INTO test VALUES (2,4), (6,8);",
   407  		},
   408  		Assertions: []ScriptTestAssertion{
   409  			{
   410  				Query: "SELECT * FROM test ORDER BY 1",
   411  				Expected: []sql.Row{
   412  					{0, 2}, {1, 3}, {2, -440}, {6, -880},
   413  				},
   414  			},
   415  		},
   416  	},
   417  	{
   418  		Name: "trigger before insert, begin block with multiple set statements and inserts",
   419  		SetUpScript: []string{
   420  			"CREATE TABLE test(pk BIGINT PRIMARY KEY, v1 BIGINT);",
   421  			"CREATE TABLE test2(pk BIGINT PRIMARY KEY, v1 BIGINT);",
   422  			"CREATE TABLE test3(pk BIGINT PRIMARY KEY, v1 BIGINT);",
   423  			"INSERT INTO test VALUES (0,2),(1,3)",
   424  			`CREATE TRIGGER tt BEFORE INSERT ON test FOR EACH ROW 
   425  				BEGIN 
   426  					SET NEW.v1 = NEW.v1 * 11;
   427  					insert into test2 values (new.pk * 3, new.v1);
   428  					SET NEW.v1 = NEW.v1 * -10;
   429  					insert into test3 values (new.pk * 5, new.v1);
   430  					set @var = 0;
   431  				END;`,
   432  			"INSERT INTO test VALUES (2,4), (6,8);",
   433  		},
   434  		Assertions: []ScriptTestAssertion{
   435  			{
   436  				Query: "SELECT * FROM test ORDER BY 1",
   437  				Expected: []sql.Row{
   438  					{0, 2}, {1, 3}, {2, -440}, {6, -880},
   439  				},
   440  			},
   441  			{
   442  				Query: "SELECT * FROM test2 ORDER BY 1",
   443  				Expected: []sql.Row{
   444  					{6, 44}, {18, 88},
   445  				},
   446  			},
   447  			{
   448  				Query: "SELECT * FROM test3 ORDER BY 1",
   449  				Expected: []sql.Row{
   450  					{10, -440}, {30, -880},
   451  				},
   452  			},
   453  		},
   454  	},
   455  	{
   456  		Name: "Create a trigger on a new database and verify that the trigger works when selected on another database",
   457  		SetUpScript: []string{
   458  			"create table foo.a (x int primary key)",
   459  			"create table foo.b (y int primary key)",
   460  			"use foo",
   461  			"create trigger insert_into_b after insert on foo.a for each row insert into foo.b values (new.x + 1)",
   462  			"use mydb",
   463  			"insert into foo.a values (1), (3), (5)",
   464  		},
   465  		Assertions: []ScriptTestAssertion{
   466  			{
   467  				Query: "select x from foo.a order by 1",
   468  				Expected: []sql.Row{
   469  					{1}, {3}, {5},
   470  				},
   471  			},
   472  			{
   473  				Query: "select y from foo.b order by 1",
   474  				Expected: []sql.Row{
   475  					{2}, {4}, {6},
   476  				},
   477  			},
   478  			{
   479  				Query: "insert into foo.a values (7), (9)",
   480  				Expected: []sql.Row{
   481  					{types.OkResult{RowsAffected: 2}},
   482  				},
   483  			},
   484  		},
   485  	},
   486  	{
   487  		Name: "trigger with escaped chars",
   488  		SetUpScript: []string{
   489  			"CREATE TABLE testInt(v1 BIGINT);",
   490  			"CREATE TABLE testStr(s1 VARCHAR(255), s2 VARCHAR(255), s3 VARCHAR(255));",
   491  			`CREATE TRIGGER tt BEFORE INSERT ON testInt FOR EACH ROW
   492  				BEGIN
   493  					insert into testStr values (CONCAT('joe''s:', NEW.v1),
   494                                                  CONCAT('jill\'s:', NEW.v1 + 1),
   495                                                  CONCAT("stan""s:", NEW.v1 + 2)
   496                                                 );
   497  				END;`,
   498  			"INSERT INTO testInt VALUES (1);",
   499  		},
   500  		Assertions: []ScriptTestAssertion{
   501  			{
   502  				Query: "SELECT * FROM testStr",
   503  				Expected: []sql.Row{
   504  					{"joe's:1", "jill's:2", "stan\"s:3"},
   505  				},
   506  			},
   507  		},
   508  	},
   509  
   510  	// UPDATE triggers
   511  	{
   512  		Name: "trigger after update, insert into other table",
   513  		SetUpScript: []string{
   514  			"create table a (x int primary key)",
   515  			"create table b (y int primary key)",
   516  			"insert into a values (1), (3), (5)",
   517  			"create trigger insert_into_b after update on a for each row insert into b values (old.x + new.x + 1)",
   518  			"update a set x = x + 1 where x in (1, 3)",
   519  		},
   520  		Assertions: []ScriptTestAssertion{
   521  			{
   522  				Query: "select x from a order by 1",
   523  				Expected: []sql.Row{
   524  					{2}, {4}, {5},
   525  				},
   526  			},
   527  			{
   528  				Query: "select y from b order by 1",
   529  				Expected: []sql.Row{
   530  					{4}, {8},
   531  				},
   532  			},
   533  			{
   534  				Query: "update a set x = x + 1 where x = 5",
   535  				Expected: []sql.Row{
   536  					{types.OkResult{
   537  						RowsAffected: 1,
   538  						Info: plan.UpdateInfo{
   539  							Matched: 1,
   540  							Updated: 1,
   541  						},
   542  					}},
   543  				},
   544  			},
   545  		},
   546  	},
   547  	{
   548  		Name: "trigger after update, delete from other table",
   549  		SetUpScript: []string{
   550  			"create table a (x int primary key)",
   551  			"create table b (y int primary key)",
   552  			"insert into a values (0), (2), (4), (6), (8)",
   553  			"insert into b values (1), (3), (5), (7), (9)",
   554  			"create trigger delete_from_b after update on a for each row delete from b where y = old.x + new.x",
   555  			"update a set x = x + 1 where x in (2,4)",
   556  		},
   557  		Assertions: []ScriptTestAssertion{
   558  			{
   559  				Query: "select x from a order by 1",
   560  				Expected: []sql.Row{
   561  					{0}, {3}, {5}, {6}, {8},
   562  				},
   563  			},
   564  			{
   565  				Query: "select y from b order by 1",
   566  				Expected: []sql.Row{
   567  					{1}, {3}, {7},
   568  				},
   569  			},
   570  		},
   571  	},
   572  	{
   573  		Name: "trigger after update, update other table",
   574  		SetUpScript: []string{
   575  			"create table a (x int primary key)",
   576  			"create table b (y int primary key)",
   577  			"insert into a values (0), (2), (4), (6), (8)",
   578  			"insert into b values (0), (2), (4), (8)",
   579  			"create trigger update_b after update on a for each row update b set y = old.x + new.x + 1 where y = old.x",
   580  			"update a set x = x + 1 where x in (2, 4)",
   581  		},
   582  		Assertions: []ScriptTestAssertion{
   583  			{
   584  				Query: "select x from a order by 1",
   585  				Expected: []sql.Row{
   586  					{0}, {3}, {5}, {6}, {8},
   587  				},
   588  			},
   589  			{
   590  				Query: "select y from b order by 1",
   591  				Expected: []sql.Row{
   592  					{0}, {6}, {8}, {10},
   593  				},
   594  			},
   595  		},
   596  	},
   597  	{
   598  		Name: "trigger before update, insert into other table",
   599  		SetUpScript: []string{
   600  			"create table a (x int primary key)",
   601  			"create table b (y int primary key)",
   602  			"insert into a values (1), (3), (5)",
   603  			"create trigger insert_into_b before update on a for each row insert into b values (old.x + new.x + 1)",
   604  			"update a set x = x + 1 where x in (1, 3)",
   605  		},
   606  		Assertions: []ScriptTestAssertion{
   607  			{
   608  				Query: "select x from a order by 1",
   609  				Expected: []sql.Row{
   610  					{2}, {4}, {5},
   611  				},
   612  			},
   613  			{
   614  				Query: "select y from b order by 1",
   615  				Expected: []sql.Row{
   616  					{4}, {8},
   617  				},
   618  			},
   619  			{
   620  				Query: "update a set x = x + 1 where x = 5",
   621  				Expected: []sql.Row{
   622  					{types.OkResult{
   623  						RowsAffected: 1,
   624  						Info: plan.UpdateInfo{
   625  							Matched: 1,
   626  							Updated: 1,
   627  						},
   628  					}},
   629  				},
   630  			},
   631  		},
   632  	},
   633  	{
   634  		Name: "trigger before update, delete from other table",
   635  		SetUpScript: []string{
   636  			"create table a (x int primary key)",
   637  			"create table b (y int primary key)",
   638  			"insert into a values (0), (2), (4), (6), (8)",
   639  			"insert into b values (1), (3), (5), (7), (9)",
   640  			"create trigger delete_from_b before update on a for each row delete from b where y = old.x + new.x",
   641  			"update a set x = x + 1 where x in (2,4)",
   642  		},
   643  		Assertions: []ScriptTestAssertion{
   644  			{
   645  				Query: "select x from a order by 1",
   646  				Expected: []sql.Row{
   647  					{0}, {3}, {5}, {6}, {8},
   648  				},
   649  			},
   650  			{
   651  				Query: "select y from b order by 1",
   652  				Expected: []sql.Row{
   653  					{1}, {3}, {7},
   654  				},
   655  			},
   656  		},
   657  	},
   658  	{
   659  		Name: "trigger before update, update other table",
   660  		SetUpScript: []string{
   661  			"create table a (x int primary key)",
   662  			"create table b (y int primary key)",
   663  			"insert into a values (0), (2), (4), (6), (8)",
   664  			"insert into b values (0), (2), (4), (8)",
   665  			"create trigger update_b before update on a for each row update b set y = old.x + new.x + 1 where y = old.x",
   666  			"update a set x = x + 1 where x in (2, 4)",
   667  		},
   668  		Assertions: []ScriptTestAssertion{
   669  			{
   670  				Query: "select x from a order by 1",
   671  				Expected: []sql.Row{
   672  					{0}, {3}, {5}, {6}, {8},
   673  				},
   674  			},
   675  			{
   676  				Query: "select y from b order by 1",
   677  				Expected: []sql.Row{
   678  					{0}, {6}, {8}, {10},
   679  				},
   680  			},
   681  		},
   682  	},
   683  	{
   684  		Name: "trigger before update, set new value",
   685  		SetUpScript: []string{
   686  			"create table a (x int primary key)",
   687  			"insert into a values (1), (10)",
   688  			"create trigger update_a before update on a for each row set new.x = new.x + old.x",
   689  			"update a set x = x + 1",
   690  		},
   691  		Query: "select x from a order by 1",
   692  		Expected: []sql.Row{
   693  			{3}, {21},
   694  		},
   695  	},
   696  	{
   697  		Name: "trigger before update, set new value to old value",
   698  		SetUpScript: []string{
   699  			"create table a (x int primary key)",
   700  			"insert into a values (1), (10)",
   701  			"create trigger no_step_on_snek before update on a for each row set new.x = old.x",
   702  			"update a set x = x + 1",
   703  		},
   704  		Query: "select x from a order by 1",
   705  		Expected: []sql.Row{
   706  			{1}, {10},
   707  		},
   708  	},
   709  	{
   710  		Name: "trigger before update, set new values, multiple cols",
   711  		SetUpScript: []string{
   712  			"create table a (x int primary key, y int)",
   713  			"insert into a values (1,3), (10,20)",
   714  			"create trigger update_a before update on a for each row set new.x = new.x + old.y, new.y = new.y + old.x",
   715  			"update a set x = x + 1, y = y + 1",
   716  		},
   717  		Query: "select x, y from a order by 1",
   718  		Expected: []sql.Row{
   719  			{5, 5},
   720  			{31, 31},
   721  		},
   722  	},
   723  	{
   724  		Name: "trigger before update, set new values, multiple cols (2)",
   725  		SetUpScript: []string{
   726  			"create table a (x int primary key, y int)",
   727  			"insert into a values (1,3), (10,20)",
   728  			"create trigger update_a before update on a for each row set new.x = new.x + new.y, new.y = new.y + old.y",
   729  			"update a set x = x + 1, y = y + 1",
   730  		},
   731  		Query: "select x, y from a order by 1",
   732  		Expected: []sql.Row{
   733  			{6, 7},
   734  			{32, 41},
   735  		},
   736  	},
   737  	{
   738  		Name: "trigger before update, with indexed update",
   739  		SetUpScript: []string{
   740  			"create table a (x int primary key, y int, unique key (y))",
   741  			"create table b (z int primary key)",
   742  			"insert into a values (1,3), (10,20)",
   743  			"create trigger insert_b before update on a for each row insert into b values (old.x * 10)",
   744  			"update a set x = x + 1 where y = 20",
   745  		},
   746  		Assertions: []ScriptTestAssertion{
   747  			{
   748  				Query: "select x, y from a order by 1",
   749  				Expected: []sql.Row{
   750  					{1, 3},
   751  					{11, 20},
   752  				},
   753  			},
   754  			{
   755  				Query: "select z from b",
   756  				Expected: []sql.Row{
   757  					{100},
   758  				},
   759  			},
   760  		},
   761  	},
   762  	{
   763  		Name: "trigger before update, begin block with multiple set statements",
   764  		SetUpScript: []string{
   765  			"CREATE TABLE test(pk BIGINT PRIMARY KEY, v1 BIGINT);",
   766  			"INSERT INTO test VALUES (0,2),(1,3)",
   767  			"CREATE TRIGGER tt BEFORE UPDATE ON test FOR EACH ROW BEGIN SET NEW.v1 = (OLD.v1 * 2) + NEW.v1; SET NEW.v1 = NEW.v1 * -10; END;",
   768  			"UPDATE test SET v1 = v1 + 1;",
   769  		},
   770  		Assertions: []ScriptTestAssertion{
   771  			{
   772  				Query: "SELECT * FROM test ORDER BY 1",
   773  				Expected: []sql.Row{
   774  					{0, -70}, {1, -100},
   775  				},
   776  			},
   777  		},
   778  	},
   779  	{
   780  		Name: "trigger before update with set clause inside if statement with '!' operator",
   781  		SetUpScript: []string{
   782  			"CREATE TABLE test (stat_id INT);",
   783  			"INSERT INTO test VALUES (-1), (1);",
   784  		},
   785  		Assertions: []ScriptTestAssertion{
   786  			{
   787  				Query: `
   788  CREATE TRIGGER before_test_stat_update BEFORE UPDATE ON test FOR EACH ROW
   789  BEGIN
   790  	IF !(new.stat_id < 0)
   791  		THEN SET new.stat_id = new.stat_id * -1;
   792  	END IF;
   793  END;`,
   794  				Expected: []sql.Row{{types.OkResult{}}},
   795  			},
   796  			{
   797  				Query:    "update test set stat_id=2 where stat_id=1;",
   798  				Expected: []sql.Row{{types.OkResult{RowsAffected: 1, Info: plan.UpdateInfo{Matched: 1, Updated: 1}}}},
   799  			},
   800  			{
   801  				Query:    "select * from test order by stat_id;",
   802  				Expected: []sql.Row{{-2}, {-1}},
   803  			},
   804  			{
   805  				Query:    "update test set stat_id=-2 where stat_id=-1;",
   806  				Expected: []sql.Row{{types.OkResult{RowsAffected: 1, Info: plan.UpdateInfo{Matched: 1, Updated: 1}}}},
   807  			},
   808  			{
   809  				Query:    "select * from test;",
   810  				Expected: []sql.Row{{-2}, {-2}},
   811  			},
   812  		},
   813  	},
   814  	{
   815  		Name: "trigger before update with set clause inside if statement with 'NOT'",
   816  		SetUpScript: []string{
   817  			"CREATE TABLE test (stat_id INT);",
   818  			"INSERT INTO test VALUES (-1), (1);",
   819  		},
   820  		Assertions: []ScriptTestAssertion{
   821  			{
   822  				Query: `
   823  CREATE TRIGGER before_test_stat_update BEFORE UPDATE ON test FOR EACH ROW
   824  BEGIN
   825  	IF NOT(new.stat_id < 0)
   826  		THEN SET new.stat_id = new.stat_id * -1;
   827  	END IF;
   828  END;`,
   829  				Expected: []sql.Row{{types.OkResult{}}},
   830  			},
   831  			{
   832  				Query:    "update test set stat_id=2 where stat_id=1;",
   833  				Expected: []sql.Row{{types.OkResult{RowsAffected: 1, Info: plan.UpdateInfo{Matched: 1, Updated: 1}}}},
   834  			},
   835  			{
   836  				Query:    "select * from test order by stat_id;",
   837  				Expected: []sql.Row{{-2}, {-1}},
   838  			},
   839  			{
   840  				Query:    "update test set stat_id=-2 where stat_id=-1;",
   841  				Expected: []sql.Row{{types.OkResult{RowsAffected: 1, Info: plan.UpdateInfo{Matched: 1, Updated: 1}}}},
   842  			},
   843  			{
   844  				Query:    "select * from test;",
   845  				Expected: []sql.Row{{-2}, {-2}},
   846  			},
   847  		},
   848  	},
   849  	// DELETE triggers
   850  	{
   851  		Name: "trigger after delete, insert into other table",
   852  		SetUpScript: []string{
   853  			"create table a (x int primary key)",
   854  			"create table b (y int primary key)",
   855  			"insert into a values (1), (3), (5)",
   856  			"create trigger insert_into_b after delete on a for each row insert into b values (old.x + 1)",
   857  			"delete from a where x in (1, 3)",
   858  		},
   859  		Assertions: []ScriptTestAssertion{
   860  			{
   861  				Query: "select x from a order by 1",
   862  				Expected: []sql.Row{
   863  					{5},
   864  				},
   865  			},
   866  			{
   867  				Query: "select y from b order by 1",
   868  				Expected: []sql.Row{
   869  					{2}, {4},
   870  				},
   871  			},
   872  			{
   873  				Query: "delete from a where x = 5",
   874  				Expected: []sql.Row{
   875  					{types.OkResult{RowsAffected: 1}},
   876  				},
   877  			},
   878  		},
   879  	},
   880  	{
   881  		Name: "trigger after delete, delete from other table",
   882  		SetUpScript: []string{
   883  			"create table a (x int primary key)",
   884  			"create table b (y int primary key)",
   885  			"insert into a values (0), (2), (4), (6), (8)",
   886  			"insert into b values (0), (2), (4), (6), (8)",
   887  			"create trigger delete_from_b after delete on a for each row delete from b where y = old.x",
   888  			"delete from a where x in (2,4,6)",
   889  		},
   890  		Assertions: []ScriptTestAssertion{
   891  			{
   892  				Query: "select x from a order by 1",
   893  				Expected: []sql.Row{
   894  					{0}, {8},
   895  				},
   896  			},
   897  			{
   898  				Query: "select y from b order by 1",
   899  				Expected: []sql.Row{
   900  					{0}, {8},
   901  				},
   902  			},
   903  		},
   904  	},
   905  	{
   906  		Name: "trigger after delete, update other table",
   907  		SetUpScript: []string{
   908  			"create table a (x int primary key)",
   909  			"create table b (y int primary key)",
   910  			"insert into a values (0), (2), (4), (6), (8)",
   911  			"insert into b values (0), (2), (4), (6), (8)",
   912  			"create trigger update_b after delete on a for each row update b set y = old.x + 1 where y = old.x",
   913  			"delete from a where x in (2,4,6)",
   914  		},
   915  		Assertions: []ScriptTestAssertion{
   916  			{
   917  				Query: "select x from a order by 1",
   918  				Expected: []sql.Row{
   919  					{0}, {8},
   920  				},
   921  			},
   922  			{
   923  				Query: "select y from b order by 1",
   924  				Expected: []sql.Row{
   925  					{0}, {3}, {5}, {7}, {8},
   926  				},
   927  			},
   928  		},
   929  	},
   930  	{
   931  		Name: "trigger before delete, insert into other table",
   932  		SetUpScript: []string{
   933  			"create table a (x int primary key)",
   934  			"create table b (y int primary key)",
   935  			"insert into a values (0), (2), (4), (6), (8)",
   936  			"create trigger insert_into_b before delete on a for each row insert into b values (old.x + 1)",
   937  			"delete from a where x in (2, 4, 6)",
   938  		},
   939  		Assertions: []ScriptTestAssertion{
   940  			{
   941  				Query: "select x from a order by 1",
   942  				Expected: []sql.Row{
   943  					{0}, {8},
   944  				},
   945  			},
   946  			{
   947  				Query: "select y from b order by 1",
   948  				Expected: []sql.Row{
   949  					{3}, {5}, {7},
   950  				},
   951  			},
   952  			{
   953  				Query: "delete from a where x = 0",
   954  				Expected: []sql.Row{
   955  					{types.OkResult{RowsAffected: 1}},
   956  				},
   957  			},
   958  		},
   959  	},
   960  	{
   961  		Name: "trigger before delete, delete from other table",
   962  		SetUpScript: []string{
   963  			"create table a (x int primary key)",
   964  			"create table b (y int primary key)",
   965  			"insert into a values (0), (2), (4), (6), (8)",
   966  			"insert into b values (1), (3), (5), (7), (9)",
   967  			"create trigger delete_from_b before delete on a for each row delete from b where y = (old.x + 1)",
   968  			"delete from a where x in (2, 4, 6)",
   969  		},
   970  		Assertions: []ScriptTestAssertion{
   971  			{
   972  				Query: "select x from a order by 1",
   973  				Expected: []sql.Row{
   974  					{0}, {8},
   975  				},
   976  			},
   977  			{
   978  				Query: "select y from b order by 1",
   979  				Expected: []sql.Row{
   980  					{1}, {9},
   981  				},
   982  			},
   983  		},
   984  	},
   985  	{
   986  		Name: "trigger before delete, update other table",
   987  		SetUpScript: []string{
   988  			"create table a (x int primary key)",
   989  			"create table b (y int primary key)",
   990  			"insert into a values (0), (2), (4), (6), (8)",
   991  			"insert into b values (1), (3), (5), (7), (9)",
   992  			"create trigger update_b before delete on a for each row update b set y = old.x where y = old.x + 1",
   993  			"delete from a where x in (2, 4, 6)",
   994  		},
   995  		Assertions: []ScriptTestAssertion{
   996  			{
   997  				Query: "select x from a order by 1",
   998  				Expected: []sql.Row{
   999  					{0}, {8},
  1000  				},
  1001  			},
  1002  			{
  1003  				Query: "select y from b order by 1",
  1004  				Expected: []sql.Row{
  1005  					{1}, {2}, {4}, {6}, {9},
  1006  				},
  1007  			},
  1008  		},
  1009  	},
  1010  	{
  1011  		Name: "trigger before delete, delete with index",
  1012  		SetUpScript: []string{
  1013  			"create table a (x int primary key, z int, unique key (z))",
  1014  			"create table b (y int primary key)",
  1015  			"insert into a values (0,1), (2,3), (4,5)",
  1016  			"create trigger insert_b before delete on a for each row insert into b values (old.x * 2)",
  1017  			"delete from a where z > 2",
  1018  		},
  1019  		Assertions: []ScriptTestAssertion{
  1020  			{
  1021  				Query: "select x from a order by 1",
  1022  				Expected: []sql.Row{
  1023  					{0},
  1024  				},
  1025  			},
  1026  			{
  1027  				Query: "select y from b order by 1",
  1028  				Expected: []sql.Row{
  1029  					{4}, {8},
  1030  				},
  1031  			},
  1032  		},
  1033  	},
  1034  	{
  1035  		Name: "trigger before delete, update other table",
  1036  		SetUpScript: []string{
  1037  			"create table a (i int primary key, j int)",
  1038  			"insert into a values (0,1), (2,3), (4,5)",
  1039  			"create table b (x int)",
  1040  			"insert into b values (0)",
  1041  			"create trigger trig before delete on a for each row begin update b set x = x + old.j; end;",
  1042  			"delete from a where true",
  1043  		},
  1044  		Assertions: []ScriptTestAssertion{
  1045  			{
  1046  				Query:    "select * from a order by 1",
  1047  				Expected: []sql.Row{},
  1048  			},
  1049  			{
  1050  				Query: "select x from b order by 1",
  1051  				Expected: []sql.Row{
  1052  					{9},
  1053  				},
  1054  			},
  1055  		},
  1056  	},
  1057  	{
  1058  		Name: "single trigger before single target table delete from join",
  1059  		SetUpScript: []string{
  1060  			"create table a (i int primary key, j int)",
  1061  			"insert into a values (0,1), (2,3), (4,5)",
  1062  			"create table b (i int primary key)",
  1063  			"insert into b values (1), (3), (5)",
  1064  			"create table c (x int)",
  1065  			"insert into c values (0)",
  1066  			"create trigger trig before delete on a for each row begin update c set x = x + 1; end;",
  1067  		},
  1068  		Assertions: []ScriptTestAssertion{
  1069  			{
  1070  				Query:          "delete a from a inner join b on a.j=b.i;",
  1071  				ExpectedErrStr: "delete from with explicit target tables does not support triggers; retry with single table deletes",
  1072  			},
  1073  		},
  1074  	},
  1075  	{
  1076  		Name: "multiple trigger before single target table delete from join",
  1077  		SetUpScript: []string{
  1078  			"create table a (i int primary key, j int)",
  1079  			"insert into a values (0,1), (2,3), (4,5)",
  1080  			"create table b (i int primary key)",
  1081  			"insert into b values (1), (3), (5)",
  1082  			"create table c (x int)",
  1083  			"insert into c values (0)",
  1084  			"create trigger trig1 before delete on a for each row begin update c set x = x + 1; end;",
  1085  			"create trigger trig2 before delete on b for each row begin update c set x = x + 1; end;",
  1086  		},
  1087  		Assertions: []ScriptTestAssertion{
  1088  			{
  1089  				Query:          "delete a from a inner join b on a.j=b.i where a.i >= 0;",
  1090  				ExpectedErrStr: "delete from with explicit target tables does not support triggers; retry with single table deletes",
  1091  			},
  1092  		},
  1093  	},
  1094  	{
  1095  		Name: "multiple trigger before multiple target table delete from join",
  1096  		SetUpScript: []string{
  1097  			"create table a (i int primary key, j int)",
  1098  			"insert into a values (0,1), (2,3), (4,5)",
  1099  			"create table b (i int primary key)",
  1100  			"insert into b values (1), (3), (5)",
  1101  			"create table c (x int)",
  1102  			"insert into c values (0)",
  1103  			"create trigger trig1 before delete on a for each row begin update c set x = x + 1; end;",
  1104  			"create trigger trig2 before delete on b for each row begin update c set x = x + 1; end;",
  1105  		},
  1106  		Assertions: []ScriptTestAssertion{
  1107  			{
  1108  				Query:          "delete a, b from a inner join b on a.j=b.i where a.i >= 0;",
  1109  				ExpectedErrStr: "delete from with explicit target tables does not support triggers; retry with single table deletes",
  1110  			},
  1111  		},
  1112  	},
  1113  	// Multiple triggers defined
  1114  	{
  1115  		Name: "triggers before and after insert",
  1116  		SetUpScript: []string{
  1117  			"create table a (x int primary key)",
  1118  			"create table b (y int primary key)",
  1119  			"create trigger a1 before insert on a for each row insert into b values (NEW.x * 7)",
  1120  			"create trigger a2 after insert on a for each row insert into b values (New.x * 11)",
  1121  		},
  1122  		Assertions: []ScriptTestAssertion{
  1123  			{
  1124  				Query: "insert into a values (2), (3), (5)",
  1125  				Expected: []sql.Row{
  1126  					{types.NewOkResult(3)},
  1127  				},
  1128  			},
  1129  			{
  1130  				Query: "select x from a order by 1",
  1131  				Expected: []sql.Row{
  1132  					{2}, {3}, {5},
  1133  				},
  1134  			},
  1135  			{
  1136  				Query: "select y from b order by 1",
  1137  				Expected: []sql.Row{
  1138  					{14}, {21}, {22}, {33}, {35}, {55},
  1139  				},
  1140  			},
  1141  		},
  1142  	},
  1143  	{
  1144  		Name: "multiple triggers before insert",
  1145  		SetUpScript: []string{
  1146  			"create table a (x int primary key)",
  1147  			"create trigger a1 before insert on a for each row set new.x = New.x + 1",
  1148  			"create trigger a2 before insert on a for each row set new.x = New.x * 2",
  1149  			"create trigger a3 before insert on a for each row set new.x = New.x - 5",
  1150  		},
  1151  		Assertions: []ScriptTestAssertion{
  1152  			{
  1153  				Query: "insert into a values (1), (3)",
  1154  				Expected: []sql.Row{
  1155  					{types.NewOkResult(2)},
  1156  				},
  1157  			},
  1158  			{
  1159  				Query: "select x from a order by 1",
  1160  				Expected: []sql.Row{
  1161  					{-1}, {3},
  1162  				},
  1163  			},
  1164  		},
  1165  	},
  1166  	{
  1167  		Name: "multiple triggers before insert, with precedes / follows",
  1168  		SetUpScript: []string{
  1169  			"create table a (x int primary key)",
  1170  			"create trigger a1 before insert on a for each row set new.x = New.x + 1",
  1171  			"create trigger a2 before insert on a for each row precedes a1 set new.x = New.x * 2",
  1172  			"create trigger a3 before insert on a for each row precedes a2 set new.x = New.x - 5",
  1173  			"create trigger a4 before insert on a for each row follows a2 set new.x = New.x * 3",
  1174  			// order of execution should be: a3, a2, a4, a1
  1175  		},
  1176  		Assertions: []ScriptTestAssertion{
  1177  			{
  1178  				Query: "insert into a values (1), (3)",
  1179  				Expected: []sql.Row{
  1180  					{types.NewOkResult(2)},
  1181  				},
  1182  			},
  1183  			{
  1184  				Query: "select x from a order by 1",
  1185  				Expected: []sql.Row{
  1186  					{-23}, {-11},
  1187  				},
  1188  			},
  1189  		},
  1190  	},
  1191  	{
  1192  		Name: "triggers before and after update",
  1193  		SetUpScript: []string{
  1194  			"create table a (x int primary key)",
  1195  			"create table b (y int primary key)",
  1196  			"create trigger a1 before update on a for each row insert into b values (old.x * 7)",
  1197  			"create trigger a2 after update on a for each row insert into b values (old.x * 11)",
  1198  			"insert into a values (2), (3), (5)",
  1199  		},
  1200  		Assertions: []ScriptTestAssertion{
  1201  			{
  1202  				Query: "update a set x = x * 2",
  1203  				Expected: []sql.Row{
  1204  					{types.OkResult{
  1205  						RowsAffected: 3,
  1206  						Info: plan.UpdateInfo{
  1207  							Matched: 3,
  1208  							Updated: 3,
  1209  						},
  1210  					}},
  1211  				},
  1212  			},
  1213  			{
  1214  				Query: "select x from a order by 1",
  1215  				Expected: []sql.Row{
  1216  					{4}, {6}, {10},
  1217  				},
  1218  			},
  1219  			{
  1220  				Query: "select y from b order by 1",
  1221  				Expected: []sql.Row{
  1222  					{14}, {21}, {22}, {33}, {35}, {55},
  1223  				},
  1224  			},
  1225  		},
  1226  	},
  1227  	{
  1228  		Name: "multiple triggers before and after update",
  1229  		SetUpScript: []string{
  1230  			"create table a (x int primary key)",
  1231  			"create table b (y int primary key)",
  1232  			"create trigger a1 before update on a for each row insert into b values (old.x * 7)",
  1233  			"create trigger a2 after update on a for each row insert into b values (old.x * 11)",
  1234  			"create trigger a3 before update on a for each row insert into b values (old.x * 13)",
  1235  			"create trigger a4 after update on a for each row insert into b values (old.x * 17)",
  1236  			"insert into a values (2), (3), (5)",
  1237  		},
  1238  		Assertions: []ScriptTestAssertion{
  1239  			{
  1240  				Query: "update a set x = x * 2",
  1241  				Expected: []sql.Row{
  1242  					{types.OkResult{
  1243  						RowsAffected: 3,
  1244  						Info: plan.UpdateInfo{
  1245  							Matched: 3,
  1246  							Updated: 3,
  1247  						},
  1248  					}},
  1249  				},
  1250  			},
  1251  			{
  1252  				Query: "select x from a order by 1",
  1253  				Expected: []sql.Row{
  1254  					{4}, {6}, {10},
  1255  				},
  1256  			},
  1257  			{
  1258  				Query: "select y from b order by 1",
  1259  				Expected: []sql.Row{
  1260  					{14}, {21}, {22}, {26}, {33}, {34}, {35}, {39}, {51}, {55}, {65}, {85},
  1261  				},
  1262  			},
  1263  		},
  1264  	},
  1265  	{
  1266  		Name: "triggers before and after delete",
  1267  		SetUpScript: []string{
  1268  			"create table a (x int primary key)",
  1269  			"create table b (y int primary key)",
  1270  			"create trigger a1 before delete on a for each row insert into b values (old.x * 7)",
  1271  			"create trigger a2 after delete on a for each row insert into b values (old.x * 11)",
  1272  			"insert into a values (2), (3), (5)",
  1273  		},
  1274  		Assertions: []ScriptTestAssertion{
  1275  			{
  1276  				Query: "delete from a",
  1277  				Expected: []sql.Row{
  1278  					{types.NewOkResult(3)},
  1279  				},
  1280  			},
  1281  			{
  1282  				Query:    "select x from a order by 1",
  1283  				Expected: []sql.Row{},
  1284  			},
  1285  			{
  1286  				Query: "select y from b order by 1",
  1287  				Expected: []sql.Row{
  1288  					{14}, {21}, {22}, {33}, {35}, {55},
  1289  				},
  1290  			},
  1291  		},
  1292  	},
  1293  	{
  1294  		Name: "multiple triggers before and after delete",
  1295  		SetUpScript: []string{
  1296  			"create table a (x int primary key)",
  1297  			"create table b (y int primary key)",
  1298  			"create trigger a1 before delete on a for each row insert into b values (old.x * 7)",
  1299  			"create trigger a2 after delete on a for each row insert into b values (old.x * 11)",
  1300  			"create trigger a3 before delete on a for each row insert into b values (old.x * 13)",
  1301  			"create trigger a4 after delete on a for each row insert into b values (old.x * 17)",
  1302  			"insert into a values (2), (3), (5)",
  1303  		},
  1304  		Assertions: []ScriptTestAssertion{
  1305  			{
  1306  				Query: "delete from a",
  1307  				Expected: []sql.Row{
  1308  					{types.NewOkResult(3)},
  1309  				},
  1310  			},
  1311  			{
  1312  				Query:    "select x from a order by 1",
  1313  				Expected: []sql.Row{},
  1314  			},
  1315  			{
  1316  				Query: "select y from b order by 1",
  1317  				Expected: []sql.Row{
  1318  					{14}, {21}, {22}, {26}, {33}, {34}, {35}, {39}, {51}, {55}, {65}, {85},
  1319  				},
  1320  			},
  1321  		},
  1322  	},
  1323  	{
  1324  		Name: "multiple triggers before and after insert, with precedes / follows",
  1325  		SetUpScript: []string{
  1326  			"create table a (x int primary key)",
  1327  			"create table b (y int primary key)",
  1328  			"insert into b values (1), (3)",
  1329  			"create trigger a1 before insert on a for each row set new.x = New.x + 1",
  1330  			"create trigger a2 before insert on a for each row precedes a1 set new.x = New.x * 2",
  1331  			"create trigger a3 before insert on a for each row precedes a2 set new.x = New.x - 5",
  1332  			"create trigger a4 before insert on a for each row follows a2 set new.x = New.x * 3",
  1333  			// order of execution should be: a3, a2, a4, a1
  1334  			"create trigger a5 after insert on a for each row update b set y = y + 1 order by y asc",
  1335  			"create trigger a6 after insert on a for each row precedes a5 update b set y = y * 2 order by y asc",
  1336  			"create trigger a7 after insert on a for each row precedes a6 update b set y = y - 5 order by y asc",
  1337  			"create trigger a8 after insert on a for each row follows a6 update b set y = y * 3 order by y asc",
  1338  			// order of execution should be: a7, a6, a8, a5
  1339  		},
  1340  		Assertions: []ScriptTestAssertion{
  1341  			{
  1342  				Query: "insert into a values (1), (3)",
  1343  				Expected: []sql.Row{
  1344  					{types.NewOkResult(2)},
  1345  				},
  1346  			},
  1347  			{
  1348  				Query: "select x from a order by 1",
  1349  				Expected: []sql.Row{
  1350  					{-23}, {-11},
  1351  				},
  1352  			},
  1353  			{
  1354  				Query: "select y from b order by 1",
  1355  				// This result is a bit counter-intutitive: it doesn't match the inserted row, because all 4 triggers run their
  1356  				// update statement twice on the rows in b, once for each row inserted into a
  1357  				Expected: []sql.Row{
  1358  					{-167}, {-95},
  1359  				},
  1360  			},
  1361  		},
  1362  	},
  1363  	{
  1364  		Name: "triggered update query which could project",
  1365  		SetUpScript: []string{
  1366  			"create table trigger_on_update (id int primary key, first varchar(25), last varchar(25))",
  1367  			"create table is_dirty (id int primary key, is_dirty bool)",
  1368  			"insert into is_dirty values (1, false)",
  1369  			"insert into trigger_on_update values (1, 'george', 'smith')",
  1370  			`create trigger trigger_on_update_on_update before update on trigger_on_update for each row
  1371  begin
  1372    update is_dirty set is_dirty = true;
  1373  end;`,
  1374  		},
  1375  		Assertions: []ScriptTestAssertion{
  1376  			{
  1377  				Query: "select id, is_dirty from is_dirty",
  1378  				Expected: []sql.Row{
  1379  					{1, 0},
  1380  				},
  1381  			},
  1382  			{
  1383  				Query: "update trigger_on_update set id = 1, first = 'george', last = 'smith' where id = 1",
  1384  				Expected: []sql.Row{
  1385  					{
  1386  						types.OkResult{
  1387  							RowsAffected: 0,
  1388  							Info: plan.UpdateInfo{
  1389  								Matched: 1,
  1390  								Updated: 0,
  1391  							},
  1392  						},
  1393  					},
  1394  				},
  1395  			},
  1396  			{
  1397  				Query: "select id, is_dirty from is_dirty",
  1398  				Expected: []sql.Row{
  1399  					{1, 1},
  1400  				},
  1401  			},
  1402  		},
  1403  	},
  1404  	// Trigger with subquery
  1405  	{
  1406  		Name: "trigger before insert with subquery expressions",
  1407  		SetUpScript: []string{
  1408  			"create table rn (id int primary key, upstream_edge_id int, downstream_edge_id int)",
  1409  			"create table sn (id int primary key, target_id int, source_id int)",
  1410  			`
  1411  create trigger rn_on_insert before insert on rn
  1412  for each row
  1413  begin
  1414    if
  1415      (select target_id from sn where id = NEW.upstream_edge_id) <> (select source_id from sn where id = NEW.downstream_edge_id)
  1416    then
  1417      set @myvar = concat('bro', 'ken');
  1418      SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = @myvar;
  1419    end if;
  1420  end;`,
  1421  		},
  1422  		Assertions: []ScriptTestAssertion{
  1423  			{
  1424  				Query: "insert into rn values (1,1,1)",
  1425  			},
  1426  			{
  1427  				Query:    "select id from rn",
  1428  				Expected: []sql.Row{{1}},
  1429  			},
  1430  		},
  1431  	},
  1432  	{
  1433  		Name: "trigger with signal and user var",
  1434  		SetUpScript: []string{
  1435  			"create table t1 (id int primary key)",
  1436  			"create table t2 (id int primary key)",
  1437  			`
  1438  create trigger trigger1 before insert on t1
  1439  for each row
  1440  begin
  1441  	set @myvar = concat('bro', 'ken');
  1442  	SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = @myvar;
  1443  end;`,
  1444  		},
  1445  		Assertions: []ScriptTestAssertion{
  1446  			{
  1447  				Query:          "insert into t1 values (1)",
  1448  				ExpectedErrStr: "broken (errno 1644) (sqlstate 45000)",
  1449  			},
  1450  			{
  1451  				Query:    "select id from t1",
  1452  				Expected: []sql.Row{},
  1453  			},
  1454  		},
  1455  	},
  1456  	// Complex trigger scripts
  1457  	{
  1458  		Name: "trigger before insert, multiple triggers defined",
  1459  		SetUpScript: []string{
  1460  			"create table a (x int primary key)",
  1461  			"create table b (y int primary key)",
  1462  			"create table c (z int primary key)",
  1463  			// Only one of these triggers should run for each table
  1464  			"create trigger a1 before insert on a for each row insert into b values (new.x * 2)",
  1465  			"create trigger a2 before update on a for each row insert into b values (new.x * 3)",
  1466  			"create trigger a3 before delete on a for each row insert into b values (old.x * 5)",
  1467  			"create trigger b1 before insert on b for each row insert into c values (new.y * 7)",
  1468  			"create trigger b2 before update on b for each row insert into c values (new.y * 11)",
  1469  			"create trigger b3 before delete on b for each row insert into c values (old.y * 13)",
  1470  			"insert into a values (1), (2), (3)",
  1471  		},
  1472  		Assertions: []ScriptTestAssertion{
  1473  			{
  1474  				Query: "select x from a order by 1",
  1475  				Expected: []sql.Row{
  1476  					{1}, {2}, {3},
  1477  				},
  1478  			},
  1479  			{
  1480  				Query: "select y from b order by 1",
  1481  				Expected: []sql.Row{
  1482  					{2}, {4}, {6},
  1483  				},
  1484  			},
  1485  			{
  1486  				Query: "select z from c order by 1",
  1487  				Expected: []sql.Row{
  1488  					{14}, {28}, {42},
  1489  				},
  1490  			},
  1491  		},
  1492  	},
  1493  	{
  1494  		Name: "trigger with signal",
  1495  		SetUpScript: []string{
  1496  			"create table a (x int primary key)",
  1497  			"create table b (y int primary key)",
  1498  			"create table c (z int primary key)",
  1499  			"insert into c values (-1)",
  1500  			`create trigger trig_with_signal before insert on a for each row
  1501  begin
  1502  	declare cond_name condition for sqlstate '45000';
  1503  	if new.x = 5 then signal cond_name set message_text = 'trig err';
  1504  	end if;
  1505  	insert into b values (new.x + 1);
  1506  	update c set z = new.x;
  1507  end;`,
  1508  		},
  1509  		Assertions: []ScriptTestAssertion{
  1510  			{
  1511  				Query: "insert into a values (1), (3)",
  1512  				Expected: []sql.Row{
  1513  					{types.OkResult{RowsAffected: 2}},
  1514  				},
  1515  			},
  1516  			{
  1517  				Query:          "insert into a values (5)",
  1518  				ExpectedErrStr: "trig err (errno 1644) (sqlstate 45000)",
  1519  			},
  1520  			{
  1521  				Query: "select x from a order by 1",
  1522  				Expected: []sql.Row{
  1523  					{1}, {3},
  1524  				},
  1525  			},
  1526  			{
  1527  				Query: "select y from b order by 1",
  1528  				Expected: []sql.Row{
  1529  					{2}, {4},
  1530  				},
  1531  			},
  1532  			{
  1533  				Query: "select z from c order by 1",
  1534  				Expected: []sql.Row{
  1535  					{3},
  1536  				},
  1537  			},
  1538  		},
  1539  	},
  1540  	// SHOW CREATE TRIGGER scripts
  1541  	{
  1542  		Name: "show create triggers",
  1543  		SetUpScript: []string{
  1544  			"create table a (x int primary key)",
  1545  			"create trigger a1 before insert on a for each row set new.x = new.x + 1",
  1546  			"create table b (y int primary key)",
  1547  			"create trigger b1 before insert on b for each row set new.y = new.y + 2",
  1548  		},
  1549  		Assertions: []ScriptTestAssertion{
  1550  			{
  1551  				Query: "show create trigger a1",
  1552  				Expected: []sql.Row{
  1553  					{
  1554  						"a1", // Trigger
  1555  						"",   // sql_mode
  1556  						"create trigger a1 before insert on a for each row set new.x = new.x + 1", // SQL Original Statement
  1557  						sql.Collation_Default.CharacterSet().String(),                             // character_set_client
  1558  						sql.Collation_Default.String(),                                            // collation_connection
  1559  						sql.Collation_Default.String(),                                            // Database Collation
  1560  						time.Unix(0, 0).UTC(),                                                     // Created
  1561  					},
  1562  				},
  1563  			},
  1564  			{
  1565  				Query: "show create trigger b1",
  1566  				Expected: []sql.Row{
  1567  					{
  1568  						"b1", // Trigger
  1569  						"",   // sql_mode
  1570  						"create trigger b1 before insert on b for each row set new.y = new.y + 2", // SQL Original Statement
  1571  						sql.Collation_Default.CharacterSet().String(),                             // character_set_client
  1572  						sql.Collation_Default.String(),                                            // collation_connection
  1573  						sql.Collation_Default.String(),                                            // Database Collation
  1574  						time.Unix(0, 0).UTC(),                                                     // Created
  1575  					},
  1576  				},
  1577  			},
  1578  			{
  1579  				Query:       "show create trigger b2",
  1580  				ExpectedErr: sql.ErrTriggerDoesNotExist,
  1581  			},
  1582  		},
  1583  	},
  1584  	// SHOW TRIGGERS scripts
  1585  	{
  1586  		Name: "show triggers",
  1587  		SetUpScript: []string{
  1588  			"create table abb (x int primary key)",
  1589  			"create table acc (y int primary key)",
  1590  			"create trigger t1 before insert on abb for each row set new.x = new.x + 1",
  1591  			"create trigger t2 before insert on abb for each row set new.x = new.x + 2",
  1592  			"create trigger t3 after insert on acc for each row insert into abb values (new.y)",
  1593  			"create trigger t4 before update on acc for each row set new.y = old.y + 2",
  1594  		},
  1595  		Assertions: []ScriptTestAssertion{
  1596  			{
  1597  				Query: "show triggers",
  1598  				Expected: []sql.Row{
  1599  					{
  1600  						"t1",                    // Trigger
  1601  						"INSERT",                // Event
  1602  						"abb",                   // Table
  1603  						"set new.x = new.x + 1", // Statement
  1604  						"BEFORE",                // Timing
  1605  						time.Unix(0, 0).UTC(),   // Created
  1606  						"",                      // sql_mode
  1607  						"",                      // Definer
  1608  						sql.Collation_Default.CharacterSet().String(), // character_set_client
  1609  						sql.Collation_Default.String(),                // collation_connection
  1610  						sql.Collation_Default.String(),                // Database Collation
  1611  					},
  1612  					{
  1613  						"t2",                    // Trigger
  1614  						"INSERT",                // Event
  1615  						"abb",                   // Table
  1616  						"set new.x = new.x + 2", // Statement
  1617  						"BEFORE",                // Timing
  1618  						time.Unix(0, 0).UTC(),   // Created
  1619  						"",                      // sql_mode
  1620  						"",                      // Definer
  1621  						sql.Collation_Default.CharacterSet().String(), // character_set_client
  1622  						sql.Collation_Default.String(),                // collation_connection
  1623  						sql.Collation_Default.String(),                // Database Collation
  1624  					},
  1625  					{
  1626  						"t3",                             // Trigger
  1627  						"INSERT",                         // Event
  1628  						"acc",                            // Table
  1629  						"insert into abb values (new.y)", // Statement
  1630  						"AFTER",                          // Timing
  1631  						time.Unix(0, 0).UTC(),            // Created
  1632  						"",                               // sql_mode
  1633  						"",                               // Definer
  1634  						sql.Collation_Default.CharacterSet().String(), // character_set_client
  1635  						sql.Collation_Default.String(),                // collation_connection
  1636  						sql.Collation_Default.String(),                // Database Collation
  1637  					},
  1638  					{
  1639  						"t4",                    // Trigger
  1640  						"UPDATE",                // Event
  1641  						"acc",                   // Table
  1642  						"set new.y = old.y + 2", // Statement
  1643  						"BEFORE",                // Timing
  1644  						time.Unix(0, 0).UTC(),   // Created
  1645  						"",                      // sql_mode
  1646  						"",                      // Definer
  1647  						sql.Collation_Default.CharacterSet().String(), // character_set_client
  1648  						sql.Collation_Default.String(),                // collation_connection
  1649  						sql.Collation_Default.String(),                // Database Collation
  1650  					},
  1651  				},
  1652  			},
  1653  			{
  1654  				Query: "show triggers from mydb",
  1655  				Expected: []sql.Row{
  1656  					{
  1657  						"t1",                    // Trigger
  1658  						"INSERT",                // Event
  1659  						"abb",                   // Table
  1660  						"set new.x = new.x + 1", // Statement
  1661  						"BEFORE",                // Timing
  1662  						time.Unix(0, 0).UTC(),   // Created
  1663  						"",                      // sql_mode
  1664  						"",                      // Definer
  1665  						sql.Collation_Default.CharacterSet().String(), // character_set_client
  1666  						sql.Collation_Default.String(),                // collation_connection
  1667  						sql.Collation_Default.String(),                // Database Collation
  1668  					},
  1669  					{
  1670  						"t2",                    // Trigger
  1671  						"INSERT",                // Event
  1672  						"abb",                   // Table
  1673  						"set new.x = new.x + 2", // Statement
  1674  						"BEFORE",                // Timing
  1675  						time.Unix(0, 0).UTC(),   // Created
  1676  						"",                      // sql_mode
  1677  						"",                      // Definer
  1678  						sql.Collation_Default.CharacterSet().String(), // character_set_client
  1679  						sql.Collation_Default.String(),                // collation_connection
  1680  						sql.Collation_Default.String(),                // Database Collation
  1681  					},
  1682  					{
  1683  						"t3",                             // Trigger
  1684  						"INSERT",                         // Event
  1685  						"acc",                            // Table
  1686  						"insert into abb values (new.y)", // Statement
  1687  						"AFTER",                          // Timing
  1688  						time.Unix(0, 0).UTC(),            // Created
  1689  						"",                               // sql_mode
  1690  						"",                               // Definer
  1691  						sql.Collation_Default.CharacterSet().String(), // character_set_client
  1692  						sql.Collation_Default.String(),                // collation_connection
  1693  						sql.Collation_Default.String(),                // Database Collation
  1694  					},
  1695  					{
  1696  						"t4",                    // Trigger
  1697  						"UPDATE",                // Event
  1698  						"acc",                   // Table
  1699  						"set new.y = old.y + 2", // Statement
  1700  						"BEFORE",                // Timing
  1701  						time.Unix(0, 0).UTC(),   // Created
  1702  						"",                      // sql_mode
  1703  						"",                      // Definer
  1704  						sql.Collation_Default.CharacterSet().String(), // character_set_client
  1705  						sql.Collation_Default.String(),                // collation_connection
  1706  						sql.Collation_Default.String(),                // Database Collation
  1707  					},
  1708  				},
  1709  			},
  1710  			{
  1711  				Query: "show triggers like '%cc'",
  1712  				Expected: []sql.Row{
  1713  					{
  1714  						"t3",                             // Trigger
  1715  						"INSERT",                         // Event
  1716  						"acc",                            // Table
  1717  						"insert into abb values (new.y)", // Statement
  1718  						"AFTER",                          // Timing
  1719  						time.Unix(0, 0).UTC(),            // Created
  1720  						"",                               // sql_mode
  1721  						"",                               // Definer
  1722  						sql.Collation_Default.CharacterSet().String(), // character_set_client
  1723  						sql.Collation_Default.String(),                // collation_connection
  1724  						sql.Collation_Default.String(),                // Database Collation
  1725  					},
  1726  					{
  1727  						"t4",                    // Trigger
  1728  						"UPDATE",                // Event
  1729  						"acc",                   // Table
  1730  						"set new.y = old.y + 2", // Statement
  1731  						"BEFORE",                // Timing
  1732  						time.Unix(0, 0).UTC(),   // Created
  1733  						"",                      // sql_mode
  1734  						"",                      // Definer
  1735  						sql.Collation_Default.CharacterSet().String(), // character_set_client
  1736  						sql.Collation_Default.String(),                // collation_connection
  1737  						sql.Collation_Default.String(),                // Database Collation
  1738  					},
  1739  				},
  1740  			},
  1741  			{
  1742  				Query: "show triggers where `event` = 'INSERT'",
  1743  				Expected: []sql.Row{
  1744  					{
  1745  						"t1",                    // Trigger
  1746  						"INSERT",                // Event
  1747  						"abb",                   // Table
  1748  						"set new.x = new.x + 1", // Statement
  1749  						"BEFORE",                // Timing
  1750  						time.Unix(0, 0).UTC(),   // Created
  1751  						"",                      // sql_mode
  1752  						"",                      // Definer
  1753  						sql.Collation_Default.CharacterSet().String(), // character_set_client
  1754  						sql.Collation_Default.String(),                // collation_connection
  1755  						sql.Collation_Default.String(),                // Database Collation
  1756  					},
  1757  					{
  1758  						"t2",                    // Trigger
  1759  						"INSERT",                // Event
  1760  						"abb",                   // Table
  1761  						"set new.x = new.x + 2", // Statement
  1762  						"BEFORE",                // Timing
  1763  						time.Unix(0, 0).UTC(),   // Created
  1764  						"",                      // sql_mode
  1765  						"",                      // Definer
  1766  						sql.Collation_Default.CharacterSet().String(), // character_set_client
  1767  						sql.Collation_Default.String(),                // collation_connection
  1768  						sql.Collation_Default.String(),                // Database Collation
  1769  					},
  1770  					{
  1771  						"t3",                             // Trigger
  1772  						"INSERT",                         // Event
  1773  						"acc",                            // Table
  1774  						"insert into abb values (new.y)", // Statement
  1775  						"AFTER",                          // Timing
  1776  						time.Unix(0, 0).UTC(),            // Created
  1777  						"",                               // sql_mode
  1778  						"",                               // Definer
  1779  						sql.Collation_Default.CharacterSet().String(), // character_set_client
  1780  						sql.Collation_Default.String(),                // collation_connection
  1781  						sql.Collation_Default.String(),                // Database Collation
  1782  					},
  1783  				},
  1784  			},
  1785  			{
  1786  				Query: "show triggers where timing = 'AFTER'",
  1787  				Expected: []sql.Row{
  1788  					{
  1789  						"t3",                             // Trigger
  1790  						"INSERT",                         // Event
  1791  						"acc",                            // Table
  1792  						"insert into abb values (new.y)", // Statement
  1793  						"AFTER",                          // Timing
  1794  						time.Unix(0, 0).UTC(),            // Created
  1795  						"",                               // sql_mode
  1796  						"",                               // Definer
  1797  						sql.Collation_Default.CharacterSet().String(), // character_set_client
  1798  						sql.Collation_Default.String(),                // collation_connection
  1799  						sql.Collation_Default.String(),                // Database Collation
  1800  					},
  1801  				},
  1802  			},
  1803  			{
  1804  				Query: "show triggers where timing = 'BEFORE' and `Table` like '%bb'",
  1805  				Expected: []sql.Row{
  1806  					{
  1807  						"t1",                    // Trigger
  1808  						"INSERT",                // Event
  1809  						"abb",                   // Table
  1810  						"set new.x = new.x + 1", // Statement
  1811  						"BEFORE",                // Timing
  1812  						time.Unix(0, 0).UTC(),   // Created
  1813  						"",                      // sql_mode
  1814  						"",                      // Definer
  1815  						sql.Collation_Default.CharacterSet().String(), // character_set_client
  1816  						sql.Collation_Default.String(),                // collation_connection
  1817  						sql.Collation_Default.String(),                // Database Collation
  1818  					},
  1819  					{
  1820  						"t2",                    // Trigger
  1821  						"INSERT",                // Event
  1822  						"abb",                   // Table
  1823  						"set new.x = new.x + 2", // Statement
  1824  						"BEFORE",                // Timing
  1825  						time.Unix(0, 0).UTC(),   // Created
  1826  						"",                      // sql_mode
  1827  						"",                      // Definer
  1828  						sql.Collation_Default.CharacterSet().String(), // character_set_client
  1829  						sql.Collation_Default.String(),                // collation_connection
  1830  						sql.Collation_Default.String(),                // Database Collation
  1831  					},
  1832  				},
  1833  			},
  1834  		},
  1835  	},
  1836  	// DROP TRIGGER
  1837  	{
  1838  		Name: "drop trigger",
  1839  		SetUpScript: []string{
  1840  			"create table a (x int primary key)",
  1841  			"create trigger t1 before insert on a for each row set new.x = new.x * 1",
  1842  			"create trigger t2 before insert on a for each row follows t1 set new.x = new.x * 2",
  1843  			"create trigger t3 before insert on a for each row set new.x = new.x * 3",
  1844  			"create trigger t4 before insert on a for each row precedes t3 set new.x = new.x * 5",
  1845  		},
  1846  		Assertions: []ScriptTestAssertion{
  1847  			{
  1848  				Query:       "drop trigger t1",
  1849  				ExpectedErr: sql.ErrTriggerCannotBeDropped,
  1850  			},
  1851  			{
  1852  				Query:       "drop trigger t3",
  1853  				ExpectedErr: sql.ErrTriggerCannotBeDropped,
  1854  			},
  1855  			{
  1856  				Query:    "drop trigger t4",
  1857  				Expected: []sql.Row{{types.OkResult{}}},
  1858  			},
  1859  			{
  1860  				Query:    "drop trigger t3",
  1861  				Expected: []sql.Row{{types.OkResult{}}},
  1862  			},
  1863  			{
  1864  				Query:    "drop trigger if exists t5",
  1865  				Expected: []sql.Row{{types.OkResult{}}},
  1866  			},
  1867  			{
  1868  				Query:       "drop trigger t5",
  1869  				ExpectedErr: sql.ErrTriggerDoesNotExist,
  1870  			},
  1871  			{
  1872  				Query: "select trigger_name from information_schema.triggers order by 1",
  1873  				Expected: []sql.Row{
  1874  					{"t1"},
  1875  					{"t2"},
  1876  				},
  1877  			},
  1878  			{
  1879  				Query:    "drop trigger if exists t2",
  1880  				Expected: []sql.Row{{types.OkResult{}}},
  1881  			},
  1882  			{
  1883  				Query: "select trigger_name from information_schema.triggers order by 1",
  1884  				Expected: []sql.Row{
  1885  					{"t1"},
  1886  				},
  1887  			},
  1888  		},
  1889  	},
  1890  	// DROP TABLE referenced in triggers
  1891  	{
  1892  		Name: "drop table referenced in triggers",
  1893  		SetUpScript: []string{
  1894  			"create table a (w int primary key)",
  1895  			"create table b (x int primary key)",
  1896  			"create table c (y int primary key)",
  1897  			"create table d (z int primary key)",
  1898  			"create trigger t1 before insert on a for each row set new.w = new.w",
  1899  			"create trigger t2 before insert on a for each row set new.w = new.w * 100",
  1900  			"create trigger t3 before insert on b for each row set new.x = new.x",
  1901  			"create trigger t4 before insert on b for each row set new.x = new.x * 100",
  1902  			"create trigger t5 before insert on c for each row set new.y = new.y",
  1903  			"create trigger t6 before insert on c for each row set new.y = new.y * 100",
  1904  			"create trigger t7 before insert on d for each row set new.z = new.z",
  1905  			"create trigger t8 before insert on d for each row set new.z = new.z * 100",
  1906  		},
  1907  		Assertions: []ScriptTestAssertion{
  1908  			{
  1909  				Query:    "drop table a",
  1910  				Expected: []sql.Row{{types.NewOkResult(0)}},
  1911  			},
  1912  			{
  1913  				Query: "select trigger_name from information_schema.triggers order by 1",
  1914  				Expected: []sql.Row{
  1915  					{"t3"},
  1916  					{"t4"},
  1917  					{"t5"},
  1918  					{"t6"},
  1919  					{"t7"},
  1920  					{"t8"},
  1921  				},
  1922  			},
  1923  			{
  1924  				Query:    "drop table if exists b, d, e",
  1925  				Expected: []sql.Row{{types.NewOkResult(0)}},
  1926  			},
  1927  			{
  1928  				Query: "select trigger_name from information_schema.triggers order by 1",
  1929  				Expected: []sql.Row{
  1930  					{"t5"},
  1931  					{"t6"},
  1932  				},
  1933  			},
  1934  		},
  1935  	},
  1936  	{
  1937  		Name: "drop table referenced in triggers with follows/precedes",
  1938  		SetUpScript: []string{
  1939  			"create table a (x int primary key)",
  1940  			"create trigger t1 before insert on a for each row set new.x = new.x",
  1941  			"create trigger t2 before insert on a for each row follows t1 set new.x = new.x * 10",
  1942  			"create trigger t3 before insert on a for each row precedes t1 set new.x = new.x * 100",
  1943  			"create trigger t4 before insert on a for each row follows t3 set new.x = new.x * 1000",
  1944  			"create trigger t5 before insert on a for each row precedes t2 set new.x = new.x * 10000",
  1945  			"create trigger t6 before insert on a for each row follows t4 set new.x = new.x * 100000",
  1946  			"create trigger t7 before insert on a for each row precedes t1 set new.x = new.x * 1000000",
  1947  			"create trigger t8 before insert on a for each row follows t6 set new.x = new.x * 10000000",
  1948  		},
  1949  		Assertions: []ScriptTestAssertion{
  1950  			{
  1951  				Query:    "drop table a",
  1952  				Expected: []sql.Row{{types.NewOkResult(0)}},
  1953  			},
  1954  			{
  1955  				Query:    "show triggers",
  1956  				Expected: []sql.Row{},
  1957  			},
  1958  		},
  1959  	},
  1960  	{
  1961  		Name: "triggers with subquery expressions analyze",
  1962  		SetUpScript: []string{
  1963  			"create table a (x int primary key)",
  1964  			"create trigger t1 before insert on a for each row begin if NEW.x in (select 2+2 from dual) then signal SQLSTATE '45000' SET MESSAGE_TEXT = 'String field contains invalid value, like empty string, ''none'', ''null'', ''n/a'', ''nan'' etc.'; end if; end;",
  1965  		},
  1966  		Assertions: nil,
  1967  	},
  1968  	{
  1969  		Name: "insert into common sequence table (https://github.com/dolthub/dolt/issues/2534)",
  1970  		SetUpScript: []string{
  1971  			"create table mytable (id integer PRIMARY KEY DEFAULT 0, sometext text);",
  1972  			"create table sequence_table (max_id integer PRIMARY KEY);",
  1973  			"create trigger update_position_id before insert on mytable for each row begin set new.id = (select coalesce(max(max_id),1) from sequence_table); update sequence_table set max_id = max_id + 1; end;",
  1974  			"insert into sequence_table values (1);",
  1975  		},
  1976  		Assertions: []ScriptTestAssertion{
  1977  			{
  1978  				Query:    "insert into mytable () values ();",
  1979  				Expected: []sql.Row{{types.NewOkResult(1)}},
  1980  			},
  1981  			{
  1982  				Query:    "insert into mytable (sometext) values ('hello');",
  1983  				Expected: []sql.Row{{types.NewOkResult(1)}},
  1984  			},
  1985  			{
  1986  				Query:    "insert into mytable values (10, 'goodbye');",
  1987  				Expected: []sql.Row{{types.NewOkResult(1)}},
  1988  			},
  1989  			{
  1990  				Query: "select * from mytable order by id",
  1991  				Expected: []sql.Row{
  1992  					{1, nil},
  1993  					{2, "hello"},
  1994  					{3, "goodbye"},
  1995  				},
  1996  			},
  1997  		},
  1998  	},
  1999  	{
  2000  		Name: "insert into common sequence table workaround",
  2001  		SetUpScript: []string{
  2002  			"create table mytable (id integer PRIMARY KEY DEFAULT 0, sometext text);",
  2003  			"create table sequence_table (max_id integer PRIMARY KEY);",
  2004  			`create trigger update_position_id before insert on mytable for each row 
  2005  			begin 
  2006  				if @max_id is null then set @max_id = (select coalesce(max(max_id),1) from sequence_table);
  2007  				end if;
  2008  				set new.id = @max_id;
  2009  				set @max_id = @max_id + 1;
  2010  				update sequence_table set max_id = @max_id; 
  2011  			end;`,
  2012  			"insert into sequence_table values (1);",
  2013  		},
  2014  		Assertions: []ScriptTestAssertion{
  2015  			{
  2016  				Query:    "insert into mytable () values ();",
  2017  				Expected: []sql.Row{{types.NewOkResult(1)}},
  2018  			},
  2019  			{
  2020  				Query:    "insert into mytable (sometext) values ('hello');",
  2021  				Expected: []sql.Row{{types.NewOkResult(1)}},
  2022  			},
  2023  			{
  2024  				Query:    "insert into mytable values (10, 'goodbye');",
  2025  				Expected: []sql.Row{{types.NewOkResult(1)}},
  2026  			},
  2027  			{
  2028  				Query:    "insert into mytable () values (), ();",
  2029  				Expected: []sql.Row{{types.NewOkResult(2)}},
  2030  			},
  2031  			{
  2032  				Query: "select * from mytable order by id",
  2033  				Expected: []sql.Row{
  2034  					{1, nil},
  2035  					{2, "hello"},
  2036  					{3, "goodbye"},
  2037  					{4, nil},
  2038  					{5, nil},
  2039  				},
  2040  			},
  2041  		},
  2042  	},
  2043  	{
  2044  		Name: "simple trigger with non-existent table in trigger body",
  2045  		SetUpScript: []string{
  2046  			"create table a (x int primary key)",
  2047  		},
  2048  		Assertions: []ScriptTestAssertion{
  2049  			{
  2050  				Query:    "create trigger insert_into_b after insert on a for each row insert into b values (new.x + 1)",
  2051  				Expected: []sql.Row{{types.OkResult{}}},
  2052  			},
  2053  			{
  2054  				Query:       "insert into a values (1), (3), (5)",
  2055  				ExpectedErr: sql.ErrTableNotFound,
  2056  			},
  2057  			{
  2058  				Query:    "create table b (y int primary key)",
  2059  				Expected: []sql.Row{{types.OkResult{}}},
  2060  			},
  2061  			{
  2062  				Query: "insert into a values (1), (3), (5)",
  2063  				Expected: []sql.Row{
  2064  					{types.OkResult{RowsAffected: 3}},
  2065  				},
  2066  			},
  2067  			{
  2068  				Query: "select x from a order by 1",
  2069  				Expected: []sql.Row{
  2070  					{1}, {3}, {5},
  2071  				},
  2072  			},
  2073  			{
  2074  				Query: "select y from b order by 1",
  2075  				Expected: []sql.Row{
  2076  					{2}, {4}, {6},
  2077  				},
  2078  			},
  2079  		},
  2080  	},
  2081  	{
  2082  		Name: "insert, update, delete triggers with non-existent table in trigger body",
  2083  		SetUpScript: []string{
  2084  			"CREATE TABLE film (film_id smallint unsigned NOT NULL AUTO_INCREMENT, title varchar(128) NOT NULL, description text, PRIMARY KEY (film_id))",
  2085  			"INSERT INTO `film` VALUES (1,'ACADEMY DINOSAUR','A Epic Drama in The Canadian Rockies'),(2,'ACE GOLDFINGER','An Astounding Epistle of a Database Administrator in Ancient China');",
  2086  		},
  2087  		Assertions: []ScriptTestAssertion{
  2088  			{
  2089  				Query:    "CREATE TRIGGER ins_film AFTER INSERT ON film FOR EACH ROW BEGIN INSERT INTO film_text (film_id, title, description) VALUES (new.film_id, new.title, new.description); END;",
  2090  				Expected: []sql.Row{{types.OkResult{}}},
  2091  			},
  2092  			{
  2093  				Query: `CREATE TRIGGER upd_film AFTER UPDATE ON film FOR EACH ROW BEGIN
  2094      IF (old.title != new.title) OR (old.description != new.description) OR (old.film_id != new.film_id)
  2095      THEN
  2096          UPDATE film_text
  2097              SET title=new.title,
  2098                  description=new.description,
  2099                  film_id=new.film_id
  2100          WHERE film_id=old.film_id;
  2101      END IF; END;`,
  2102  				Expected: []sql.Row{{types.OkResult{}}},
  2103  			},
  2104  			{
  2105  				Query:    "CREATE TRIGGER del_film AFTER DELETE ON film FOR EACH ROW BEGIN DELETE FROM film_text WHERE film_id = old.film_id; END;",
  2106  				Expected: []sql.Row{{types.OkResult{}}},
  2107  			},
  2108  			{
  2109  				Query:       "INSERT INTO `film` VALUES (3,'ADAPTATION HOLES','An Astounding Reflection in A Baloon Factory'),(4,'AFFAIR PREJUDICE','A Fanciful Documentary in A Shark Tank')",
  2110  				ExpectedErr: sql.ErrTableNotFound,
  2111  			},
  2112  			{
  2113  				Query:       "UPDATE film SET title = 'THE ACADEMY DINOSAUR' WHERE title = 'ACADEMY DINOSAUR'",
  2114  				ExpectedErr: sql.ErrTableNotFound,
  2115  			},
  2116  			{
  2117  				Query:       "DELETE FROM film WHERE title = 'ACE GOLDFINGER'",
  2118  				ExpectedErr: sql.ErrTableNotFound,
  2119  			},
  2120  			{
  2121  				Query:    "CREATE TABLE film_text (film_id smallint NOT NULL, title varchar(255) NOT NULL, description text, PRIMARY KEY (film_id))",
  2122  				Expected: []sql.Row{{types.OkResult{}}},
  2123  			},
  2124  			{
  2125  				Query:    "SELECT COUNT(*) FROM film",
  2126  				Expected: []sql.Row{{2}},
  2127  			},
  2128  			{
  2129  				Query:    "INSERT INTO `film` VALUES (3,'ADAPTATION HOLES','An Astounding Reflection in A Baloon Factory'),(4,'AFFAIR PREJUDICE','A Fanciful Documentary in A Shark Tank')",
  2130  				Expected: []sql.Row{{types.OkResult{RowsAffected: 2, InsertID: 3}}},
  2131  			},
  2132  			{
  2133  				Query:    "SELECT COUNT(*) FROM film",
  2134  				Expected: []sql.Row{{4}},
  2135  			},
  2136  			{
  2137  				Query:    "SELECT COUNT(*) FROM film_text",
  2138  				Expected: []sql.Row{{2}},
  2139  			},
  2140  			{
  2141  				Query:    "UPDATE film SET title = 'DIFFERENT MOVIE' WHERE title = 'ADAPTATION HOLES'",
  2142  				Expected: []sql.Row{{types.OkResult{RowsAffected: 1, InsertID: 0, Info: plan.UpdateInfo{Matched: 1, Updated: 1, Warnings: 0}}}},
  2143  			},
  2144  			{
  2145  				Query:    "SELECT COUNT(*) FROM film_text WHERE title = 'DIFFERENT MOVIE'",
  2146  				Expected: []sql.Row{{1}},
  2147  			},
  2148  			{
  2149  				Query:    "DELETE FROM film WHERE title = 'DIFFERENT MOVIE'",
  2150  				Expected: []sql.Row{{types.OkResult{RowsAffected: 1}}},
  2151  			},
  2152  			{
  2153  				Query:    "SELECT COUNT(*) FROM film_text WHERE title = 'DIFFERENT MOVIE'",
  2154  				Expected: []sql.Row{{0}},
  2155  			},
  2156  		},
  2157  	},
  2158  	{
  2159  		Name: "non-existent procedure in trigger body",
  2160  		SetUpScript: []string{
  2161  			"CREATE TABLE t0 (id INT PRIMARY KEY AUTO_INCREMENT, v1 INT, v2 TEXT);",
  2162  			"CREATE TABLE t1 (id INT PRIMARY KEY AUTO_INCREMENT, v1 INT, v2 TEXT);",
  2163  			"INSERT INTO t0 VALUES (1, 2, 'abc'), (2, 3, 'def');",
  2164  		},
  2165  		Assertions: []ScriptTestAssertion{
  2166  			{
  2167  				Query:    "SELECT * FROM t0;",
  2168  				Expected: []sql.Row{{1, 2, "abc"}, {2, 3, "def"}},
  2169  			},
  2170  			{
  2171  				Query: `CREATE PROCEDURE add_entry(i INT, s TEXT) BEGIN IF i > 50 THEN 
  2172  SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'too big number'; END IF;
  2173  INSERT INTO t0 (v1, v2) VALUES (i, s); END;`,
  2174  				Expected: []sql.Row{{types.OkResult{}}},
  2175  			},
  2176  			{
  2177  				Query:    "CREATE TRIGGER trig AFTER INSERT ON t0 FOR EACH ROW BEGIN CALL back_up(NEW.v1, NEW.v2); END;",
  2178  				Expected: []sql.Row{{types.OkResult{}}},
  2179  			},
  2180  			{
  2181  				Query:       "INSERT INTO t0 (v1, v2) VALUES (5, 'ggg');",
  2182  				ExpectedErr: sql.ErrStoredProcedureDoesNotExist,
  2183  			},
  2184  			{
  2185  				Query:    "CREATE PROCEDURE back_up(num INT, msg TEXT) INSERT INTO t1 (v1, v2) VALUES (num*2, msg);",
  2186  				Expected: []sql.Row{{types.OkResult{}}},
  2187  			},
  2188  			{
  2189  				SkipResultCheckOnServerEngine: true, // call depends on stored procedure stmt for whether to use 'query' or 'exec' from go sql driver.
  2190  				Query:                         "CALL add_entry(4, 'aaa');",
  2191  				Expected:                      []sql.Row{{types.OkResult{RowsAffected: 1, InsertID: 3}}},
  2192  			},
  2193  			{
  2194  				Query:    "SELECT * FROM t0;",
  2195  				Expected: []sql.Row{{1, 2, "abc"}, {2, 3, "def"}, {3, 4, "aaa"}},
  2196  			},
  2197  			{
  2198  				Query:    "SELECT * FROM t1;",
  2199  				Expected: []sql.Row{{1, 8, "aaa"}},
  2200  			},
  2201  			{
  2202  				Query:          "CALL add_entry(54, 'bbb');",
  2203  				ExpectedErrStr: "too big number (errno 1644) (sqlstate 45000)",
  2204  			},
  2205  		},
  2206  	},
  2207  }
  2208  
  2209  // RollbackTriggerTests are trigger tests that require rollback logic to work correctly
  2210  var RollbackTriggerTests = []ScriptTest{
  2211  	// Insert Queries that fail, test trigger reverts
  2212  	{
  2213  		Name: "trigger before insert, reverts insert when query fails",
  2214  		SetUpScript: []string{
  2215  			"create table a (i int primary key)",
  2216  			"create table b (x int)",
  2217  			"create trigger trig before insert on a for each row insert into b values (new.i);",
  2218  		},
  2219  		Assertions: []ScriptTestAssertion{
  2220  			{
  2221  				Query: "insert into a values (1), (2)",
  2222  				Expected: []sql.Row{
  2223  					{types.OkResult{RowsAffected: 2}},
  2224  				},
  2225  			},
  2226  			{
  2227  				Query: "select x from b order by x",
  2228  				Expected: []sql.Row{
  2229  					{1}, {2},
  2230  				},
  2231  			},
  2232  			{
  2233  				Query:       "insert into a values (1)",
  2234  				ExpectedErr: sql.ErrPrimaryKeyViolation,
  2235  			},
  2236  			{
  2237  				Query: "select * from b",
  2238  				Expected: []sql.Row{
  2239  					{1}, {2},
  2240  				},
  2241  			},
  2242  		},
  2243  	},
  2244  	{
  2245  		Name: "trigger after insert, reverts insert when query fails",
  2246  		SetUpScript: []string{
  2247  			"create table a (i int primary key)",
  2248  			"create table b (x int)",
  2249  			"create trigger trig after insert on a for each row insert into b values (new.i);",
  2250  		},
  2251  		Assertions: []ScriptTestAssertion{
  2252  			{
  2253  				Query: "insert into a values (1), (2)",
  2254  				Expected: []sql.Row{
  2255  					{types.OkResult{RowsAffected: 2}},
  2256  				},
  2257  			},
  2258  			{
  2259  				Query: "select x from b order by x",
  2260  				Expected: []sql.Row{
  2261  					{1}, {2},
  2262  				},
  2263  			},
  2264  			{
  2265  				Query:       "insert into a values (1)",
  2266  				ExpectedErr: sql.ErrPrimaryKeyViolation,
  2267  			},
  2268  			{
  2269  				Query: "select * from b",
  2270  				Expected: []sql.Row{
  2271  					{1}, {2},
  2272  				},
  2273  			},
  2274  		},
  2275  	},
  2276  	{
  2277  		Name: "trigger before insert, reverts update when query fails",
  2278  		SetUpScript: []string{
  2279  			"create table a (i int primary key)",
  2280  			"create table b (x int)",
  2281  			"insert into b values (0)",
  2282  			"create trigger trig before insert on a for each row update b set x = x + 1;",
  2283  		},
  2284  		Assertions: []ScriptTestAssertion{
  2285  			{
  2286  				Query: "insert into a values (1), (2)",
  2287  				Expected: []sql.Row{
  2288  					{types.OkResult{RowsAffected: 2}},
  2289  				},
  2290  			},
  2291  			{
  2292  				Query: "select * from b",
  2293  				Expected: []sql.Row{
  2294  					{2},
  2295  				},
  2296  			},
  2297  			{
  2298  				Query:       "insert into a values (1)",
  2299  				ExpectedErr: sql.ErrPrimaryKeyViolation,
  2300  			},
  2301  			{
  2302  				Query: "select * from b",
  2303  				Expected: []sql.Row{
  2304  					{2},
  2305  				},
  2306  			},
  2307  		},
  2308  	},
  2309  	{
  2310  		Name: "trigger after insert, reverts update when query fails",
  2311  		SetUpScript: []string{
  2312  			"create table a (i int primary key)",
  2313  			"create table b (x int)",
  2314  			"insert into b values (0)",
  2315  			"create trigger trig after insert on a for each row update b set x = x + 1;",
  2316  		},
  2317  		Assertions: []ScriptTestAssertion{
  2318  			{
  2319  				Query: "insert into a values (1), (2)",
  2320  				Expected: []sql.Row{
  2321  					{types.OkResult{RowsAffected: 2}},
  2322  				},
  2323  			},
  2324  			{
  2325  				Query: "select * from b",
  2326  				Expected: []sql.Row{
  2327  					{2},
  2328  				},
  2329  			},
  2330  			{
  2331  				Query:       "insert into a values (1)",
  2332  				ExpectedErr: sql.ErrPrimaryKeyViolation,
  2333  			},
  2334  			{
  2335  				Query: "select * from b",
  2336  				Expected: []sql.Row{
  2337  					{2},
  2338  				},
  2339  			},
  2340  		},
  2341  	},
  2342  	{
  2343  		Name: "trigger before insert, reverts delete when query fails",
  2344  		SetUpScript: []string{
  2345  			"create table a (i int primary key)",
  2346  			"create table b (x int)",
  2347  			"insert into a values (1)",
  2348  			"insert into b values (1), (2)",
  2349  			"create trigger trig before insert on a for each row delete from b where x = new.i;",
  2350  		},
  2351  		Assertions: []ScriptTestAssertion{
  2352  			{
  2353  				Query: "insert into a values (2)",
  2354  				Expected: []sql.Row{
  2355  					{types.OkResult{RowsAffected: 1}},
  2356  				},
  2357  			},
  2358  			{
  2359  				Query: "select x from b order by x",
  2360  				Expected: []sql.Row{
  2361  					{1},
  2362  				},
  2363  			},
  2364  			{
  2365  				Query:       "insert into a values (1)",
  2366  				ExpectedErr: sql.ErrPrimaryKeyViolation,
  2367  			},
  2368  			{
  2369  				Query: "select * from b",
  2370  				Expected: []sql.Row{
  2371  					{1},
  2372  				},
  2373  			},
  2374  		},
  2375  	},
  2376  	{
  2377  		Name: "trigger after insert, reverts delete when query fails",
  2378  		SetUpScript: []string{
  2379  			"create table a (i int primary key)",
  2380  			"create table b (x int)",
  2381  			"insert into a values (1)",
  2382  			"insert into b values (1), (2)",
  2383  			"create trigger trig after insert on a for each row delete from b where x = new.i;",
  2384  		},
  2385  		Assertions: []ScriptTestAssertion{
  2386  			{
  2387  				Query: "insert into a values (2)",
  2388  				Expected: []sql.Row{
  2389  					{types.OkResult{RowsAffected: 1}},
  2390  				},
  2391  			},
  2392  			{
  2393  				Query: "select x from b order by x",
  2394  				Expected: []sql.Row{
  2395  					{1},
  2396  				},
  2397  			},
  2398  			{
  2399  				Query:       "insert into a values (1)",
  2400  				ExpectedErr: sql.ErrPrimaryKeyViolation,
  2401  			},
  2402  			{
  2403  				Query: "select * from b",
  2404  				Expected: []sql.Row{
  2405  					{1},
  2406  				},
  2407  			},
  2408  		},
  2409  	},
  2410  	{
  2411  		Name: "trigger before insert, reverts multiple inserts when query fails",
  2412  		SetUpScript: []string{
  2413  			"create table a (i int primary key)",
  2414  			"create table b (x int)",
  2415  			"create trigger trig before insert on a for each row insert into b values (new.i);",
  2416  		},
  2417  		Assertions: []ScriptTestAssertion{
  2418  			{
  2419  				Query:       "insert into a values (1), (1)",
  2420  				ExpectedErr: sql.ErrPrimaryKeyViolation,
  2421  			},
  2422  			{
  2423  				Query:    "select * from a",
  2424  				Expected: []sql.Row{},
  2425  			},
  2426  			{
  2427  				Query:    "select * from b",
  2428  				Expected: []sql.Row{},
  2429  			},
  2430  			{
  2431  				Query: "insert into a values (0)",
  2432  				Expected: []sql.Row{
  2433  					{types.OkResult{RowsAffected: 1}},
  2434  				},
  2435  			},
  2436  			{
  2437  				Query:       "insert into a values (1), (2), (0)",
  2438  				ExpectedErr: sql.ErrPrimaryKeyViolation,
  2439  			},
  2440  			{
  2441  				Query: "select * from a",
  2442  				Expected: []sql.Row{
  2443  					{0},
  2444  				},
  2445  			},
  2446  			{
  2447  				Query: "select * from b",
  2448  				Expected: []sql.Row{
  2449  					{0},
  2450  				},
  2451  			},
  2452  		},
  2453  	},
  2454  	{
  2455  		Name: "trigger after insert, reverts multiple inserts when query fails",
  2456  		SetUpScript: []string{
  2457  			"create table a (i int primary key)",
  2458  			"create table b (x int)",
  2459  			"create trigger trig after insert on a for each row insert into b values (new.i);",
  2460  		},
  2461  		Assertions: []ScriptTestAssertion{
  2462  			{
  2463  				Query:       "insert into a values (1), (1)",
  2464  				ExpectedErr: sql.ErrPrimaryKeyViolation,
  2465  			},
  2466  			{
  2467  				Query:    "select * from a",
  2468  				Expected: []sql.Row{},
  2469  			},
  2470  			{
  2471  				Query:    "select * from b",
  2472  				Expected: []sql.Row{},
  2473  			},
  2474  			{
  2475  				Query: "insert into a values (0)",
  2476  				Expected: []sql.Row{
  2477  					{types.OkResult{RowsAffected: 1}},
  2478  				},
  2479  			},
  2480  			{
  2481  				Query:       "insert into a values (1), (2), (0)",
  2482  				ExpectedErr: sql.ErrPrimaryKeyViolation,
  2483  			},
  2484  			{
  2485  				Query: "select * from a",
  2486  				Expected: []sql.Row{
  2487  					{0},
  2488  				},
  2489  			},
  2490  			{
  2491  				Query: "select * from b",
  2492  				Expected: []sql.Row{
  2493  					{0},
  2494  				},
  2495  			},
  2496  		},
  2497  	},
  2498  	// Update Queries that fail, test trigger reverts
  2499  	{
  2500  		Name: "trigger before update, reverts insert when query fails",
  2501  		SetUpScript: []string{
  2502  			"create table a (i int primary key)",
  2503  			"create table b (x int)",
  2504  			"insert into a values (0)",
  2505  			"create trigger trig before update on a for each row insert into b values (new.i);",
  2506  		},
  2507  		Assertions: []ScriptTestAssertion{
  2508  			{
  2509  				Query: "update a set i = 1",
  2510  				Expected: []sql.Row{
  2511  					{types.OkResult{
  2512  						RowsAffected: 1,
  2513  						Info: plan.UpdateInfo{
  2514  							Matched: 1,
  2515  							Updated: 1,
  2516  						},
  2517  					}},
  2518  				},
  2519  			},
  2520  			{
  2521  				Query: "select x from b",
  2522  				Expected: []sql.Row{
  2523  					{1},
  2524  				},
  2525  			},
  2526  			{
  2527  				Query:          "update a set i = 'not int'",
  2528  				ExpectedErrStr: "error: 'not int' is not a valid value for 'int'",
  2529  			},
  2530  			{
  2531  				Query: "select * from b",
  2532  				Expected: []sql.Row{
  2533  					{1},
  2534  				},
  2535  			},
  2536  		},
  2537  	},
  2538  	{
  2539  		Name: "trigger after update, reverts insert when query fails",
  2540  		SetUpScript: []string{
  2541  			"create table a (i int primary key)",
  2542  			"create table b (x int)",
  2543  			"insert into a values (0)",
  2544  			"create trigger trig after update on a for each row insert into b values (new.i);",
  2545  		},
  2546  		Assertions: []ScriptTestAssertion{
  2547  			{
  2548  				Query: "update a set i = 1",
  2549  				Expected: []sql.Row{
  2550  					{types.OkResult{
  2551  						RowsAffected: 1,
  2552  						Info: plan.UpdateInfo{
  2553  							Matched: 1,
  2554  							Updated: 1,
  2555  						},
  2556  					}},
  2557  				},
  2558  			},
  2559  			{
  2560  				Query: "select x from b",
  2561  				Expected: []sql.Row{
  2562  					{1},
  2563  				},
  2564  			},
  2565  			{
  2566  				Query:          "update a set i = 'not int'",
  2567  				ExpectedErrStr: "error: 'not int' is not a valid value for 'int'",
  2568  			},
  2569  			{
  2570  				Query: "select * from b",
  2571  				Expected: []sql.Row{
  2572  					{1},
  2573  				},
  2574  			},
  2575  		},
  2576  	},
  2577  	{
  2578  		Name: "trigger before update, reverts update when query fails",
  2579  		SetUpScript: []string{
  2580  			"create table a (i int primary key)",
  2581  			"create table b (x int)",
  2582  			"insert into a values (0)",
  2583  			"insert into b values (0)",
  2584  			"create trigger trig before update on a for each row update b set x = x + new.i;",
  2585  		},
  2586  		Assertions: []ScriptTestAssertion{
  2587  			{
  2588  				Query: "update a set i = 1",
  2589  				Expected: []sql.Row{
  2590  					{types.OkResult{
  2591  						RowsAffected: 1,
  2592  						Info: plan.UpdateInfo{
  2593  							Matched: 1,
  2594  							Updated: 1,
  2595  						},
  2596  					}},
  2597  				},
  2598  			},
  2599  			{
  2600  				Query: "select x from b",
  2601  				Expected: []sql.Row{
  2602  					{1},
  2603  				},
  2604  			},
  2605  			{
  2606  				Query:          "update a set i = 'not int'",
  2607  				ExpectedErrStr: "error: 'not int' is not a valid value for 'int'",
  2608  			},
  2609  			{
  2610  				Query: "select * from b",
  2611  				Expected: []sql.Row{
  2612  					{1},
  2613  				},
  2614  			},
  2615  		},
  2616  	},
  2617  	{
  2618  		Name: "trigger after update, reverts update when query fails",
  2619  		SetUpScript: []string{
  2620  			"create table a (i int primary key)",
  2621  			"create table b (x int)",
  2622  			"insert into a values (0)",
  2623  			"insert into b values (0)",
  2624  			"create trigger trig after update on a for each row update b set x = x + new.i;",
  2625  		},
  2626  		Assertions: []ScriptTestAssertion{
  2627  			{
  2628  				Query: "update a set i = 1",
  2629  				Expected: []sql.Row{
  2630  					{types.OkResult{
  2631  						RowsAffected: 1,
  2632  						Info: plan.UpdateInfo{
  2633  							Matched: 1,
  2634  							Updated: 1,
  2635  						},
  2636  					}},
  2637  				},
  2638  			},
  2639  			{
  2640  				Query: "select x from b",
  2641  				Expected: []sql.Row{
  2642  					{1},
  2643  				},
  2644  			},
  2645  			{
  2646  				Query:          "update a set i = 'not int'",
  2647  				ExpectedErrStr: "error: 'not int' is not a valid value for 'int'",
  2648  			},
  2649  			{
  2650  				Query: "select * from b",
  2651  				Expected: []sql.Row{
  2652  					{1},
  2653  				},
  2654  			},
  2655  		},
  2656  	},
  2657  	{
  2658  		Name: "trigger before update, reverts delete when query fails",
  2659  		SetUpScript: []string{
  2660  			"create table a (i int primary key)",
  2661  			"create table b (x int)",
  2662  			"insert into a values (0)",
  2663  			"insert into b values (1), (2)",
  2664  			"create trigger trig before update on a for each row delete from b where x = new.i;",
  2665  		},
  2666  		Assertions: []ScriptTestAssertion{
  2667  			{
  2668  				Query: "update a set i = 1",
  2669  				Expected: []sql.Row{
  2670  					{types.OkResult{
  2671  						RowsAffected: 1,
  2672  						Info: plan.UpdateInfo{
  2673  							Matched: 1,
  2674  							Updated: 1,
  2675  						},
  2676  					}},
  2677  				},
  2678  			},
  2679  			{
  2680  				Query: "select x from b",
  2681  				Expected: []sql.Row{
  2682  					{2},
  2683  				},
  2684  			},
  2685  			{
  2686  				Query:          "update a set i = 'not int'",
  2687  				ExpectedErrStr: "error: 'not int' is not a valid value for 'int'",
  2688  			},
  2689  			{
  2690  				Query: "select * from b",
  2691  				Expected: []sql.Row{
  2692  					{2},
  2693  				},
  2694  			},
  2695  		},
  2696  	},
  2697  	{
  2698  		Name: "trigger after update, reverts delete when query fails",
  2699  		SetUpScript: []string{
  2700  			"create table a (i int primary key)",
  2701  			"create table b (x int)",
  2702  			"insert into a values (0)",
  2703  			"insert into b values (1), (2)",
  2704  			"create trigger trig after update on a for each row delete from b where x = new.i;",
  2705  		},
  2706  		Assertions: []ScriptTestAssertion{
  2707  			{
  2708  				Query: "update a set i = 1",
  2709  				Expected: []sql.Row{
  2710  					{types.OkResult{
  2711  						RowsAffected: 1,
  2712  						Info: plan.UpdateInfo{
  2713  							Matched: 1,
  2714  							Updated: 1,
  2715  						},
  2716  					}},
  2717  				},
  2718  			},
  2719  			{
  2720  				Query: "select x from b",
  2721  				Expected: []sql.Row{
  2722  					{2},
  2723  				},
  2724  			},
  2725  			{
  2726  				Query:          "update a set i = 'not int'",
  2727  				ExpectedErrStr: "error: 'not int' is not a valid value for 'int'",
  2728  			},
  2729  			{
  2730  				Query: "select * from b",
  2731  				Expected: []sql.Row{
  2732  					{2},
  2733  				},
  2734  			},
  2735  		},
  2736  	},
  2737  	// Multiple triggers and at least one fails, reverts
  2738  	{
  2739  		Name: "triggers before and after insert fails, rollback",
  2740  		SetUpScript: []string{
  2741  			"create table a (x int primary key)",
  2742  			"create table b (y int primary key)",
  2743  			"create trigger a1 before insert on a for each row insert into b values (NEW.x * 7)",
  2744  			"create trigger a2 after insert on a for each row insert into b values (New.x * 11)",
  2745  		},
  2746  		Assertions: []ScriptTestAssertion{
  2747  			{
  2748  				Query: "insert into a values (2), (3), (5)",
  2749  				Expected: []sql.Row{
  2750  					{types.NewOkResult(3)},
  2751  				},
  2752  			},
  2753  			{
  2754  				Query: "select x from a order by 1",
  2755  				Expected: []sql.Row{
  2756  					{2}, {3}, {5},
  2757  				},
  2758  			},
  2759  			{
  2760  				Query: "select y from b order by 1",
  2761  				Expected: []sql.Row{
  2762  					{14}, {21}, {22}, {33}, {35}, {55},
  2763  				},
  2764  			},
  2765  			{
  2766  				Query:       "insert into a values (2), (3), (5)",
  2767  				ExpectedErr: sql.ErrPrimaryKeyViolation,
  2768  			},
  2769  			{
  2770  				Query: "select x from a order by 1",
  2771  				Expected: []sql.Row{
  2772  					{2}, {3}, {5},
  2773  				},
  2774  			},
  2775  			{
  2776  				Query: "select y from b order by 1",
  2777  				Expected: []sql.Row{
  2778  					{14}, {21}, {22}, {33}, {35}, {55},
  2779  				},
  2780  			},
  2781  		},
  2782  	},
  2783  	// Queries involving auto_commit = off
  2784  	{
  2785  		Name: "autocommit off, trigger before insert, reverts insert when query fails",
  2786  		SetUpScript: []string{
  2787  			"set @@autocommit = off",
  2788  			"create table a (i int primary key)",
  2789  			"create table b (x int)",
  2790  			"create trigger trig before insert on a for each row insert into b values (new.i);",
  2791  		},
  2792  		Assertions: []ScriptTestAssertion{
  2793  			{
  2794  				Query: "insert into a values (1), (2)",
  2795  				Expected: []sql.Row{
  2796  					{types.OkResult{RowsAffected: 2}},
  2797  				},
  2798  			},
  2799  			{
  2800  				Query: "select x from b order by x",
  2801  				Expected: []sql.Row{
  2802  					{1}, {2},
  2803  				},
  2804  			},
  2805  			{
  2806  				Query:       "insert into a values (1)",
  2807  				ExpectedErr: sql.ErrPrimaryKeyViolation,
  2808  			},
  2809  			{
  2810  				Query: "select * from b",
  2811  				Expected: []sql.Row{
  2812  					{1}, {2},
  2813  				},
  2814  			},
  2815  		},
  2816  	},
  2817  	{
  2818  		Name: "trigger before update, reverts insert when query fails",
  2819  		SetUpScript: []string{
  2820  			"set @@autocommit = off",
  2821  			"create table a (i int primary key)",
  2822  			"create table b (x int)",
  2823  			"insert into a values (0)",
  2824  			"create trigger trig before update on a for each row insert into b values (new.i);",
  2825  		},
  2826  		Assertions: []ScriptTestAssertion{
  2827  			{
  2828  				Query: "update a set i = 1",
  2829  				Expected: []sql.Row{
  2830  					{types.OkResult{
  2831  						RowsAffected: 1,
  2832  						Info: plan.UpdateInfo{
  2833  							Matched: 1,
  2834  							Updated: 1,
  2835  						},
  2836  					}},
  2837  				},
  2838  			},
  2839  			{
  2840  				Query: "select x from b",
  2841  				Expected: []sql.Row{
  2842  					{1},
  2843  				},
  2844  			},
  2845  			{
  2846  				Query:          "update a set i = 'not int'",
  2847  				ExpectedErrStr: "error: 'not int' is not a valid value for 'int'",
  2848  			},
  2849  			{
  2850  				Query: "select * from b",
  2851  				Expected: []sql.Row{
  2852  					{1},
  2853  				},
  2854  			},
  2855  		},
  2856  	},
  2857  }
  2858  
  2859  // BrokenTriggerQueries contains trigger queries that should work but do not yet
  2860  var BrokenTriggerQueries = []ScriptTest{
  2861  	{
  2862  		Name: "update common table multiple times in single insert",
  2863  		SetUpScript: []string{
  2864  			"create table mytable (id integer PRIMARY KEY DEFAULT 0, sometext text);",
  2865  			"create table sequence_table (max_id integer PRIMARY KEY);",
  2866  			"create trigger update_position_id before insert on mytable for each row begin set new.id = (select coalesce(max(max_id),1) from sequence_table); update sequence_table set max_id = max_id + 1; end;",
  2867  			"insert into sequence_table values (1);",
  2868  		},
  2869  		Assertions: []ScriptTestAssertion{
  2870  			// Should produce new keys 2, 3, but instead produces a duplicate key error
  2871  			{
  2872  				Query:    "insert into mytable () values (), ();",
  2873  				Expected: []sql.Row{{types.NewOkResult(2)}},
  2874  			},
  2875  			{
  2876  				Query: "select * from mytable order by id",
  2877  				Expected: []sql.Row{
  2878  					{1, nil},
  2879  					{2, nil},
  2880  					{3, nil},
  2881  				},
  2882  			},
  2883  		},
  2884  	},
  2885  	{
  2886  		Name: "insert into table multiple times",
  2887  		SetUpScript: []string{
  2888  			"CREATE TABLE test(pk BIGINT PRIMARY KEY, v1 BIGINT);",
  2889  			"CREATE TABLE test2(pk BIGINT PRIMARY KEY, v1 BIGINT);",
  2890  			"INSERT INTO test VALUES (0,2),(1,3)",
  2891  			`CREATE TRIGGER tt BEFORE INSERT ON test FOR EACH ROW 
  2892  				BEGIN 
  2893  					insert into test2 values (new.pk * 3, new.v1);
  2894  					insert into test2 values (new.pk * 5, new.v1);
  2895  				END;`,
  2896  			// fails at analysis time thinking that test2 is a duplicate table alias
  2897  			"INSERT INTO test VALUES (2,4), (6,8);",
  2898  		},
  2899  		Assertions: []ScriptTestAssertion{
  2900  			{
  2901  				Query: "SELECT * FROM test ORDER BY 1",
  2902  				Expected: []sql.Row{
  2903  					{0, 2}, {1, 3}, {2, -440},
  2904  				},
  2905  			},
  2906  			{
  2907  				Query: "SELECT * FROM test2 ORDER BY 1",
  2908  				Expected: []sql.Row{
  2909  					{2, -440},
  2910  				},
  2911  			},
  2912  		},
  2913  	},
  2914  	// This test is failing due to how trigger logic handles trigger logic with a different database then the one set
  2915  	{
  2916  		Name: "trigger after update, delete from other table",
  2917  		SetUpScript: []string{
  2918  			"create table foo.a (x int primary key)",
  2919  			"create table foo.b (y int primary key)",
  2920  			"insert into foo.a values (0), (2), (4), (6), (8)",
  2921  			"insert into foo.b values (1), (3), (5), (7), (9)",
  2922  			"use foo",
  2923  			"create trigger insert_into_b after update on a for each row insert into b values (old.x + new.x + 1)",
  2924  			"use mydb",
  2925  			"update foo.a set x = x + 1 where x in (2,4)",
  2926  		},
  2927  		Assertions: []ScriptTestAssertion{
  2928  			{
  2929  				Query: "select x from foo.a order by 1",
  2930  				Expected: []sql.Row{
  2931  					{0}, {3}, {5}, {6}, {8},
  2932  				},
  2933  			},
  2934  			{
  2935  				Query: "select y from foo.b order by 1",
  2936  				Expected: []sql.Row{
  2937  					{1}, {3}, {7},
  2938  				},
  2939  			},
  2940  		},
  2941  	},
  2942  	// This test SOMETIMES fails, maybe due to a race condition or something weird happening with references
  2943  	{
  2944  		Name: "trigger before update, begin block with references to other table",
  2945  		SetUpScript: []string{
  2946  			"CREATE TABLE a (i int primary key, j int)",
  2947  			"INSERT INTO a VALUES (0,1),(2,3),(4,5)",
  2948  			"CREATE TABLE b (x int)",
  2949  			"INSERT INTO b VALUES (1)",
  2950  			"CREATE TRIGGER trig BEFORE UPDATE ON a FOR EACH ROW BEGIN SET NEW.i = (SELECT x FROM b); SET NEW.j = OLD.j + NEW.j; UPDATE b SET x = x + 1; END;",
  2951  			"UPDATE a SET j = 10;",
  2952  		},
  2953  		Assertions: []ScriptTestAssertion{
  2954  			{
  2955  				Query: "SELECT * FROM a ORDER BY 1",
  2956  				Expected: []sql.Row{
  2957  					{1, 11}, {2, 13}, {3, 15},
  2958  				},
  2959  			},
  2960  			{
  2961  				Query: "SELECT * FROM b ORDER BY x",
  2962  				Expected: []sql.Row{
  2963  					{4},
  2964  				},
  2965  			},
  2966  		},
  2967  	},
  2968  	{
  2969  		Name: "trigger after inserts, use updated self reference",
  2970  		SetUpScript: []string{
  2971  			"create table a (i int primary key, j int)",
  2972  			"create table b (x int primary key)",
  2973  			"insert into b values (1)",
  2974  			"create trigger trig after insert on a for each row begin update b set x = (select count(*) from a); end;",
  2975  			"insert into a values (1,0), (2,0), (3,0)",
  2976  		},
  2977  		Assertions: []ScriptTestAssertion{
  2978  			{
  2979  				Query: "select * from a order by i",
  2980  				Expected: []sql.Row{
  2981  					{1, 0}, {2, 0}, {3, 0},
  2982  				},
  2983  			},
  2984  			{
  2985  				Query: "select x from b",
  2986  				Expected: []sql.Row{
  2987  					{3},
  2988  				},
  2989  			},
  2990  			{
  2991  				Query: "insert into a values (4,0), (5,0)",
  2992  				Expected: []sql.Row{
  2993  					{types.OkResult{RowsAffected: 2}},
  2994  				},
  2995  			},
  2996  		},
  2997  	},
  2998  }
  2999  
  3000  var TriggerErrorTests = []ScriptTest{
  3001  	{
  3002  		Name: "table doesn't exist",
  3003  		SetUpScript: []string{
  3004  			"create table x (a int primary key, b int, c int)",
  3005  		},
  3006  		Query:       "create trigger not_found before insert on y for each row set new.a = new.a + 1",
  3007  		ExpectedErr: sql.ErrTableNotFound,
  3008  	},
  3009  	{
  3010  		Name: "trigger errors on execution",
  3011  		SetUpScript: []string{
  3012  			"create table x (a int primary key, b int)",
  3013  			"create table y (c int primary key not null)",
  3014  			"create trigger trigger_has_error before insert on x for each row insert into y values (null)",
  3015  		},
  3016  		Query:       "insert into x values (1,2)",
  3017  		ExpectedErr: sql.ErrInsertIntoNonNullableProvidedNull,
  3018  	},
  3019  	{
  3020  		Name: "self update on insert",
  3021  		SetUpScript: []string{
  3022  			"create table a (x int primary key)",
  3023  			"create trigger a1 before insert on a for each row insert into a values (new.x * 2)",
  3024  		},
  3025  		Query:       "insert into a values (1), (2), (3)",
  3026  		ExpectedErr: sql.ErrTriggerTableInUse,
  3027  	},
  3028  	{
  3029  		Name: "self update on delete",
  3030  		SetUpScript: []string{
  3031  			"create table a (x int primary key)",
  3032  			"create trigger a1 before delete on a for each row delete from a",
  3033  		},
  3034  		Query:       "delete from a",
  3035  		ExpectedErr: sql.ErrTriggerTableInUse,
  3036  	},
  3037  	{
  3038  		Name: "self update on update",
  3039  		SetUpScript: []string{
  3040  			"create table a (x int primary key)",
  3041  			"create trigger a1 before update on a for each row update a set x = 1",
  3042  		},
  3043  		Query:       "update a set x = 2",
  3044  		ExpectedErr: sql.ErrTriggerTableInUse,
  3045  	},
  3046  	{
  3047  		Name: "circular dependency",
  3048  		SetUpScript: []string{
  3049  			"create table a (x int primary key)",
  3050  			"create table b (y int primary key)",
  3051  			"create trigger a1 before insert on a for each row insert into b values (new.x * 2)",
  3052  			"create trigger b1 before insert on b for each row insert into a values (new.y * 7)",
  3053  		},
  3054  		Query:       "insert into a values (1), (2), (3)",
  3055  		ExpectedErr: sql.ErrTriggerTableInUse,
  3056  	},
  3057  	{
  3058  		Name: "circular dependency, nested two deep",
  3059  		SetUpScript: []string{
  3060  			"create table a (x int primary key)",
  3061  			"create table b (y int primary key)",
  3062  			"create table c (z int primary key)",
  3063  			"create trigger a1 before insert on a for each row insert into b values (new.x * 2)",
  3064  			"create trigger b1 before insert on b for each row insert into c values (new.y * 5)",
  3065  			"create trigger c1 before insert on c for each row insert into a values (new.z * 7)",
  3066  		},
  3067  		Query:       "insert into a values (1), (2), (3)",
  3068  		ExpectedErr: sql.ErrTriggerTableInUse,
  3069  	},
  3070  	{
  3071  		Name: "reference to old on insert",
  3072  		SetUpScript: []string{
  3073  			"create table x (a int primary key, b int, c int)",
  3074  		},
  3075  		Query:       "create trigger old_on_insert before insert on x for each row set new.c = old.a + 1",
  3076  		ExpectedErr: sql.ErrTableNotFound,
  3077  	},
  3078  	{
  3079  		Name: "reference to new on delete",
  3080  		SetUpScript: []string{
  3081  			"create table x (a int primary key, b int, c int)",
  3082  		},
  3083  		Query:       "create trigger new_on_delete before delete on x for each row set new.c = old.a + 1",
  3084  		ExpectedErr: sql.ErrTableNotFound,
  3085  	},
  3086  	{
  3087  		Name: "set old row on update",
  3088  		SetUpScript: []string{
  3089  			"create table x (a int primary key, b int, c int)",
  3090  		},
  3091  		Query:       "create trigger update_old before update on x for each row set old.c = new.a + 1",
  3092  		ExpectedErr: sql.ErrInvalidUpdateOfOldRow,
  3093  	},
  3094  	{
  3095  		Name: "set old row on update, begin block",
  3096  		SetUpScript: []string{
  3097  			"create table x (a int primary key, b int, c int)",
  3098  		},
  3099  		Query:       "create trigger update_old before update on x for each row BEGIN set old.c = new.a + 1; END",
  3100  		ExpectedErr: sql.ErrInvalidUpdateOfOldRow,
  3101  	},
  3102  	{
  3103  		Name: "set new row after insert",
  3104  		SetUpScript: []string{
  3105  			"create table x (a int primary key, b int, c int)",
  3106  		},
  3107  		Query:       "create trigger update_new after insert on x for each row set new.c = new.a + 1",
  3108  		ExpectedErr: sql.ErrInvalidUpdateInAfterTrigger,
  3109  	},
  3110  	{
  3111  		Name: "set new row after update",
  3112  		SetUpScript: []string{
  3113  			"create table x (a int primary key, b int, c int)",
  3114  		},
  3115  		Query:       "create trigger update_new after update on x for each row set new.c = new.a + 1",
  3116  		ExpectedErr: sql.ErrInvalidUpdateInAfterTrigger,
  3117  	},
  3118  	{
  3119  		Name: "set new row after update, begin block",
  3120  		SetUpScript: []string{
  3121  			"create table x (a int primary key, b int, c int)",
  3122  		},
  3123  		Query:       "create trigger update_new after update on x for each row BEGIN set new.c = new.a + 1; END",
  3124  		ExpectedErr: sql.ErrInvalidUpdateInAfterTrigger,
  3125  	},
  3126  	{
  3127  		Name: "source column doesn't exist",
  3128  		SetUpScript: []string{
  3129  			"create table x (a int primary key, b int, c int)",
  3130  		},
  3131  		Query:       "create trigger not_found before insert on x for each row set new.d = new.d + 1",
  3132  		ExpectedErr: sql.ErrTableNotFound,
  3133  	},
  3134  	{
  3135  		Name: "target column doesn't exist",
  3136  		SetUpScript: []string{
  3137  			"create table x (a int primary key, b int, c int)",
  3138  		},
  3139  		Query:       "create trigger not_found before insert on x for each row set new.d = new.a + 1",
  3140  		ExpectedErr: sql.ErrTableNotFound,
  3141  	},
  3142  	{
  3143  		Name: "prevent creating trigger over views",
  3144  		SetUpScript: []string{
  3145  			"create table x (a int primary key, b int, c int)",
  3146  			"create view v as select * from x",
  3147  		},
  3148  		Query:       "create trigger trig before insert on v for each row set b = 1",
  3149  		ExpectedErr: sql.ErrExpectedTableFoundView,
  3150  	},
  3151  }