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

     1  // Copyright 2022 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  	"github.com/dolthub/go-mysql-server/sql"
    19  	"github.com/dolthub/go-mysql-server/sql/plan"
    20  	"github.com/dolthub/go-mysql-server/sql/types"
    21  )
    22  
    23  var CreateCheckConstraintsScripts = []ScriptTest{
    24  	{
    25  		Name:        "simple check constraint check on ChecksSetup data",
    26  		SetUpScript: []string{},
    27  		Assertions: []ScriptTestAssertion{
    28  			{
    29  				Query: `SELECT TC.CONSTRAINT_NAME, CC.CHECK_CLAUSE, TC.ENFORCED 
    30  FROM information_schema.TABLE_CONSTRAINTS TC, information_schema.CHECK_CONSTRAINTS CC 
    31  WHERE TABLE_SCHEMA = 'mydb' AND TABLE_NAME = 'checks' AND TC.TABLE_SCHEMA = CC.CONSTRAINT_SCHEMA AND TC.CONSTRAINT_NAME = CC.CONSTRAINT_NAME AND TC.CONSTRAINT_TYPE = 'CHECK';`,
    32  				Expected: []sql.Row{{"chk1", "(B > 0)", "YES"}, {"chk2", "(b > 0)", "NO"}, {"chk3", "(B > 1)", "YES"}, {"chk4", "(upper(C) = c)", "YES"}},
    33  			},
    34  		},
    35  	},
    36  	{
    37  		Name: "unnamed constraint",
    38  		SetUpScript: []string{
    39  			"ALTER TABLE checks ADD CONSTRAINT CHECK (b > 100)",
    40  		},
    41  		Assertions: []ScriptTestAssertion{
    42  			{
    43  				Query: `SELECT LENGTH(TC.CONSTRAINT_NAME) > 0
    44  FROM information_schema.TABLE_CONSTRAINTS TC, information_schema.CHECK_CONSTRAINTS CC 
    45  WHERE TABLE_SCHEMA = 'mydb' AND TABLE_NAME = 'checks' AND TC.TABLE_SCHEMA = CC.CONSTRAINT_SCHEMA AND TC.CONSTRAINT_NAME = CC.CONSTRAINT_NAME AND TC.CONSTRAINT_TYPE = 'CHECK' AND  CC.CHECK_CLAUSE = '(b > 100)';`,
    46  				Expected: []sql.Row{{true}},
    47  			},
    48  		},
    49  	},
    50  	{
    51  		Name: "check statements in CREATE TABLE statements",
    52  		SetUpScript: []string{
    53  			`
    54  CREATE TABLE T2
    55  (
    56    CHECK (c1 = c2),
    57    c1 INT CHECK (c1 > 10),
    58    c2 INT CONSTRAINT c2_positive CHECK (c2 > 0),
    59    c3 INT CHECK (c3 < 100),
    60    CONSTRAINT c1_nonzero CHECK (c1 = 0),
    61    CHECK (C1 > C3)
    62  );`,
    63  		},
    64  		Assertions: []ScriptTestAssertion{
    65  			{
    66  				Query: `SELECT CC.CHECK_CLAUSE
    67  FROM information_schema.TABLE_CONSTRAINTS TC, information_schema.CHECK_CONSTRAINTS CC 
    68  WHERE TABLE_SCHEMA = 'mydb' AND TABLE_NAME = 't2' AND TC.TABLE_SCHEMA = CC.CONSTRAINT_SCHEMA AND TC.CONSTRAINT_NAME = CC.CONSTRAINT_NAME AND TC.CONSTRAINT_TYPE = 'CHECK';`,
    69  				Expected: []sql.Row{{"(c1 = c2)"}, {"(c1 > 10)"}, {"(c2 > 0)"}, {"(c3 < 100)"}, {"(c1 = 0)"}, {"(C1 > C3)"}},
    70  			},
    71  		},
    72  	},
    73  	{
    74  		Name:        "error cases",
    75  		SetUpScript: []string{},
    76  		Assertions: []ScriptTestAssertion{
    77  			{
    78  				Query:       "ALTER TABLE t3 ADD CONSTRAINT chk2 CHECK (c > 0)",
    79  				ExpectedErr: sql.ErrTableNotFound,
    80  			},
    81  			{
    82  				Query:       "ALTER TABLE checks ADD CONSTRAINT chk3 CHECK (d > 0)",
    83  				ExpectedErr: sql.ErrColumnNotFound,
    84  			},
    85  			{
    86  				Query: `
    87  CREATE TABLE t4
    88  (
    89    CHECK (c1 = c2),
    90    c1 INT CHECK (c1 > 10),
    91    c2 INT CONSTRAINT c2_positive CHECK (c2 > 0),
    92    CHECK (c1 > c3)
    93  );`,
    94  				ExpectedErr: sql.ErrColumnNotFound,
    95  			},
    96  		},
    97  	},
    98  	{
    99  		Name: "Run SHOW CREATE TABLE with different types of check constraints",
   100  		SetUpScript: []string{
   101  			"CREATE TABLE mytable1(pk int PRIMARY KEY, CONSTRAINT check1 CHECK (pk = 5))",
   102  			"ALTER TABLE mytable1 ADD CONSTRAINT check11 CHECK (pk < 6)",
   103  			"CREATE TABLE mytable2(pk int PRIMARY KEY, v int, CONSTRAINT check2 CHECK (v < 5))",
   104  			"ALTER TABLE mytable2 ADD CONSTRAINT check12 CHECK (pk  + v = 6)",
   105  			"CREATE TABLE mytable3(pk int PRIMARY KEY, v int, CONSTRAINT check3 CHECK (pk > 2 AND v < 5))",
   106  			"ALTER TABLE mytable3 ADD CONSTRAINT check13 CHECK (pk BETWEEN 2 AND 100)",
   107  			"CREATE TABLE mytable4(pk int PRIMARY KEY, v int, CONSTRAINT check4 CHECK (pk > 2 AND v < 5 AND pk < 9))",
   108  			"CREATE TABLE mytable5(pk int PRIMARY KEY, v int, CONSTRAINT check5 CHECK (pk > 2 OR (v < 5 AND pk < 9)))",
   109  			"CREATE TABLE mytable6(pk int PRIMARY KEY, v int, CONSTRAINT check6 CHECK (NOT pk))",
   110  			"CREATE TABLE mytable7(pk int PRIMARY KEY, v int, CONSTRAINT check7 CHECK (pk != v))",
   111  			"CREATE TABLE mytable8(pk int PRIMARY KEY, v int, CONSTRAINT check8 CHECK (pk > 2 OR v < 5 OR pk < 10))",
   112  			"CREATE TABLE mytable9(pk int PRIMARY KEY, v int, CONSTRAINT check9 CHECK ((pk + v) / 2 >= 1))",
   113  			"CREATE TABLE mytable10(pk int PRIMARY KEY, v int, CONSTRAINT check10 CHECK (v < 5) NOT ENFORCED)",
   114  		},
   115  		Assertions: []ScriptTestAssertion{
   116  			{
   117  				Query: "SHOW CREATE TABLE mytable1",
   118  				Expected: []sql.Row{
   119  					{
   120  						"mytable1",
   121  						"CREATE TABLE `mytable1` (\n  `pk` int NOT NULL,\n" +
   122  							"  PRIMARY KEY (`pk`),\n" +
   123  							"  CONSTRAINT `check1` CHECK ((`pk` = 5)),\n" +
   124  							"  CONSTRAINT `check11` CHECK ((`pk` < 6))\n" +
   125  							") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin",
   126  					},
   127  				},
   128  			},
   129  			{
   130  				Query: "SHOW CREATE TABLE mytable2",
   131  				Expected: []sql.Row{
   132  					{
   133  						"mytable2",
   134  						"CREATE TABLE `mytable2` (\n  `pk` int NOT NULL,\n" +
   135  							"  `v` int,\n" +
   136  							"  PRIMARY KEY (`pk`),\n" +
   137  							"  CONSTRAINT `check2` CHECK ((`v` < 5)),\n" +
   138  							"  CONSTRAINT `check12` CHECK (((`pk` + `v`) = 6))\n" +
   139  							") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin",
   140  					},
   141  				},
   142  			},
   143  			{
   144  				Query: "SHOW CREATE TABLE mytable3",
   145  				Expected: []sql.Row{
   146  					{
   147  						"mytable3",
   148  						"CREATE TABLE `mytable3` (\n  `pk` int NOT NULL,\n" +
   149  							"  `v` int,\n" +
   150  							"  PRIMARY KEY (`pk`),\n" +
   151  							"  CONSTRAINT `check3` CHECK (((`pk` > 2) AND (`v` < 5))),\n" +
   152  							"  CONSTRAINT `check13` CHECK ((`pk` BETWEEN 2 AND 100))\n" +
   153  							") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin",
   154  					},
   155  				},
   156  			},
   157  			{
   158  				Query: "SHOW CREATE TABLE mytable4",
   159  				Expected: []sql.Row{
   160  					{
   161  						"mytable4",
   162  						"CREATE TABLE `mytable4` (\n  `pk` int NOT NULL,\n" +
   163  							"  `v` int,\n" +
   164  							"  PRIMARY KEY (`pk`),\n" +
   165  							"  CONSTRAINT `check4` CHECK ((((`pk` > 2) AND (`v` < 5)) AND (`pk` < 9)))\n" +
   166  							") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin",
   167  					},
   168  				},
   169  			},
   170  			{
   171  				Query: "SHOW CREATE TABLE mytable5",
   172  				Expected: []sql.Row{
   173  					{
   174  						"mytable5",
   175  						"CREATE TABLE `mytable5` (\n  `pk` int NOT NULL,\n" +
   176  							"  `v` int,\n" +
   177  							"  PRIMARY KEY (`pk`),\n" +
   178  							"  CONSTRAINT `check5` CHECK (((`pk` > 2) OR ((`v` < 5) AND (`pk` < 9))))\n" +
   179  							") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin",
   180  					},
   181  				},
   182  			},
   183  			{
   184  				Query: "SHOW CREATE TABLE mytable6",
   185  				Expected: []sql.Row{
   186  					{
   187  						"mytable6",
   188  						"CREATE TABLE `mytable6` (\n  `pk` int NOT NULL,\n" +
   189  							"  `v` int,\n" +
   190  							"  PRIMARY KEY (`pk`),\n" +
   191  							"  CONSTRAINT `check6` CHECK ((NOT(`pk`)))\n" +
   192  							") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin",
   193  					},
   194  				},
   195  			},
   196  			{
   197  				Query: "SHOW CREATE TABLE mytable7",
   198  				Expected: []sql.Row{
   199  					{
   200  						"mytable7",
   201  						"CREATE TABLE `mytable7` (\n  `pk` int NOT NULL,\n" +
   202  							"  `v` int,\n" +
   203  							"  PRIMARY KEY (`pk`),\n" +
   204  							"  CONSTRAINT `check7` CHECK ((NOT((`pk` = `v`))))\n" +
   205  							") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin",
   206  					},
   207  				},
   208  			},
   209  			{
   210  				Query: "SHOW CREATE TABLE mytable8",
   211  				Expected: []sql.Row{
   212  					{
   213  						"mytable8",
   214  						"CREATE TABLE `mytable8` (\n  `pk` int NOT NULL,\n" +
   215  							"  `v` int,\n" +
   216  							"  PRIMARY KEY (`pk`),\n" +
   217  							"  CONSTRAINT `check8` CHECK ((((`pk` > 2) OR (`v` < 5)) OR (`pk` < 10)))\n" +
   218  							") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin",
   219  					},
   220  				},
   221  			},
   222  			{
   223  				Query: "SHOW CREATE TABLE mytable9",
   224  				Expected: []sql.Row{
   225  					{
   226  						"mytable9",
   227  						"CREATE TABLE `mytable9` (\n  `pk` int NOT NULL,\n" +
   228  							"  `v` int,\n" +
   229  							"  PRIMARY KEY (`pk`),\n" +
   230  							"  CONSTRAINT `check9` CHECK ((((`pk` + `v`) / 2) >= 1))\n" +
   231  							") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin",
   232  					},
   233  				},
   234  			},
   235  			{
   236  				Query: "SHOW CREATE TABLE mytable10",
   237  				Expected: []sql.Row{
   238  					{
   239  						"mytable10",
   240  						"CREATE TABLE `mytable10` (\n  `pk` int NOT NULL,\n" +
   241  							"  `v` int,\n" +
   242  							"  PRIMARY KEY (`pk`),\n" +
   243  							"  CONSTRAINT `check10` CHECK ((`v` < 5)) /*!80016 NOT ENFORCED */\n" +
   244  							") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin",
   245  					},
   246  				},
   247  			},
   248  		},
   249  	},
   250  	{
   251  		Name: "Create a table with a check and validate that it appears in check_constraints and table_constraints",
   252  		SetUpScript: []string{
   253  			"CREATE TABLE mytable (pk int primary key, test_score int, height int, CONSTRAINT mycheck CHECK (test_score >= 50), CONSTRAINT hcheck CHECK (height < 10), CONSTRAINT vcheck CHECK (height > 0))",
   254  		},
   255  		Assertions: []ScriptTestAssertion{
   256  			{
   257  				Query: "SELECT * from information_schema.check_constraints where constraint_name IN ('mycheck', 'hcheck') ORDER BY constraint_name",
   258  				Expected: []sql.Row{
   259  					{"def", "mydb", "hcheck", "(height < 10)"},
   260  					{"def", "mydb", "mycheck", "(test_score >= 50)"},
   261  				},
   262  			},
   263  			{
   264  				Query: "SELECT * FROM information_schema.table_constraints where table_name='mytable' ORDER BY constraint_type,constraint_name",
   265  				Expected: []sql.Row{
   266  					{"def", "mydb", "hcheck", "mydb", "mytable", "CHECK", "YES"},
   267  					{"def", "mydb", "mycheck", "mydb", "mytable", "CHECK", "YES"},
   268  					{"def", "mydb", "vcheck", "mydb", "mytable", "CHECK", "YES"},
   269  					{"def", "mydb", "PRIMARY", "mydb", "mytable", "PRIMARY KEY", "YES"},
   270  				},
   271  			},
   272  		},
   273  	},
   274  	{
   275  		Name: "multi column index, lower()",
   276  		SetUpScript: []string{
   277  			"CREATE TABLE test (pk BIGINT PRIMARY KEY, v1 varchar(100), v2 varchar(100), INDEX (v1,v2));",
   278  			"INSERT INTO test VALUES (1,'happy','birthday'), (2,'HAPPY','BIRTHDAY'), (3,'hello','sailor');",
   279  		},
   280  		Assertions: []ScriptTestAssertion{
   281  			{
   282  				Query:    "SELECT pk FROM test where lower(v1) = 'happy' and lower(v2) = 'birthday' order by 1",
   283  				Expected: []sql.Row{{1}, {2}},
   284  			},
   285  		},
   286  	},
   287  	{
   288  		Name: "adding check constraint to a table that violates said constraint correctly throws an error",
   289  		SetUpScript: []string{
   290  			"CREATE TABLE test (pk int)",
   291  			"INSERT INTO test VALUES (1),(2),(300)",
   292  		},
   293  		Assertions: []ScriptTestAssertion{
   294  			{
   295  				Query:       "ALTER TABLE test ADD CONSTRAINT bad_check CHECK (pk < 5)",
   296  				ExpectedErr: plan.ErrCheckViolated,
   297  			},
   298  		},
   299  	},
   300  	{
   301  		Name: "duplicate indexes still returns correct results",
   302  		SetUpScript: []string{
   303  			"CREATE TABLE test (i int)",
   304  			"CREATE INDEX test_idx1 on test (i)",
   305  			"CREATE INDEX test_idx2 on test (i)",
   306  			"INSERT INTO test values (1), (2), (3)",
   307  		},
   308  		Assertions: []ScriptTestAssertion{
   309  			{
   310  				Query:    "SELECT * FROM test ORDER BY i",
   311  				Expected: []sql.Row{{1}, {2}, {3}},
   312  			},
   313  			{
   314  				Query: "SELECT * FROM test where i = 2",
   315  				Expected: []sql.Row{
   316  					{2},
   317  				},
   318  			},
   319  		},
   320  	},
   321  }
   322  
   323  var DropCheckConstraintsScripts = []ScriptTest{
   324  	{
   325  		Name: "basic drop check constraints",
   326  		SetUpScript: []string{
   327  			"CREATE TABLE t1 (a INTEGER PRIMARY KEY, b INTEGER, c integer)",
   328  			"ALTER TABLE t1 ADD CONSTRAINT chk1 CHECK (a > 0)",
   329  			"ALTER TABLE t1 ADD CONSTRAINT chk2 CHECK (b > 0) NOT ENFORCED",
   330  			"ALTER TABLE t1 ADD CONSTRAINT chk3 CHECK (c > 0)",
   331  			"ALTER TABLE t1 DROP CONSTRAINT chk2",
   332  			"ALTER TABLE t1 DROP CHECK chk1",
   333  		},
   334  		Assertions: []ScriptTestAssertion{
   335  			{
   336  				Query: `SELECT TC.CONSTRAINT_NAME, CC.CHECK_CLAUSE, TC.ENFORCED 
   337  FROM information_schema.TABLE_CONSTRAINTS TC, information_schema.CHECK_CONSTRAINTS CC 
   338  WHERE TABLE_SCHEMA = 'mydb' AND TABLE_NAME = 't1' AND TC.TABLE_SCHEMA = CC.CONSTRAINT_SCHEMA AND TC.CONSTRAINT_NAME = CC.CONSTRAINT_NAME AND TC.CONSTRAINT_TYPE = 'CHECK';`,
   339  				Expected: []sql.Row{{"chk3", "(c > 0)", "YES"}},
   340  			},
   341  		},
   342  	},
   343  	{
   344  		Name: "error cases",
   345  		SetUpScript: []string{
   346  			"ALTER TABLE t1 DROP CHECK chk3",
   347  		},
   348  		Assertions: []ScriptTestAssertion{
   349  			{
   350  				Query:       "ALTER TABLE t2 DROP CONSTRAINT chk2",
   351  				ExpectedErr: sql.ErrTableNotFound,
   352  			},
   353  			{
   354  				Query:       "ALTER TABLE t1 DROP CONSTRAINT dne",
   355  				ExpectedErr: sql.ErrUnknownConstraint,
   356  			},
   357  		},
   358  	},
   359  }
   360  
   361  var ChecksOnInsertScripts = []ScriptTest{
   362  	{
   363  		Name: "basic checks constraints violations on insert",
   364  		SetUpScript: []string{
   365  			"CREATE TABLE t1 (a INTEGER PRIMARY KEY, b INTEGER, c varchar(20))",
   366  			"ALTER TABLE t1 ADD CONSTRAINT chk1 CHECK (b > 10) NOT ENFORCED",
   367  			"ALTER TABLE t1 ADD CONSTRAINT chk2 CHECK (b > 0)",
   368  			"ALTER TABLE t1 ADD CONSTRAINT chk3 CHECK ((a + b) / 2 >= 1) ENFORCED",
   369  			// TODO(Zach on 1/6/22): checks get serialized as strings, which means that the String() method of functions is load-bearing.
   370  			//  We do not have tests for all of them. Write some.
   371  			"ALTER TABLE t1 ADD CONSTRAINT chk4 CHECK (upper(c) = c) ENFORCED",
   372  			"ALTER TABLE t1 ADD CONSTRAINT chk5 CHECK (trim(c) = c) ENFORCED",
   373  			"ALTER TABLE t1 ADD CONSTRAINT chk6 CHECK (trim(leading ' ' from c) = c) ENFORCED",
   374  
   375  			"INSERT INTO t1 VALUES (1,1,'ABC')",
   376  		},
   377  		Assertions: []ScriptTestAssertion{
   378  			{
   379  				Query:    "SELECT * FROM t1;",
   380  				Expected: []sql.Row{{1, 1, "ABC"}},
   381  			},
   382  			{
   383  				Query:       "INSERT INTO t1 (a,b) VALUES (0,0)",
   384  				ExpectedErr: sql.ErrCheckConstraintViolated,
   385  			},
   386  			{
   387  				Query:       "INSERT INTO t1 (a,b) VALUES (0,1)",
   388  				ExpectedErr: sql.ErrCheckConstraintViolated,
   389  			},
   390  			{
   391  				Query:       "INSERT INTO t1 (a,b,c) VALUES (2,2,'abc')",
   392  				ExpectedErr: sql.ErrCheckConstraintViolated,
   393  			},
   394  			{
   395  				Query:       "INSERT INTO t1 (a,b,c) VALUES (2,2,'ABC ')",
   396  				ExpectedErr: sql.ErrCheckConstraintViolated,
   397  			},
   398  			{
   399  				Query:       "INSERT INTO t1 (a,b,c) VALUES (2,2,' ABC')",
   400  				ExpectedErr: sql.ErrCheckConstraintViolated,
   401  			},
   402  		},
   403  	},
   404  	{
   405  		Name: "simple insert with check constraint",
   406  		SetUpScript: []string{
   407  			"INSERT INTO t1 VALUES (2,2,'ABC')",
   408  			"INSERT INTO t1 (a,b) VALUES (4,NULL)",
   409  		},
   410  		Assertions: []ScriptTestAssertion{
   411  			{
   412  				Query: "SELECT * FROM t1;",
   413  				Expected: []sql.Row{
   414  					{1, 1, "ABC"},
   415  					{2, 2, "ABC"},
   416  					{4, nil, nil},
   417  				},
   418  			},
   419  		},
   420  	},
   421  	{
   422  		Name: "insert into table from table",
   423  		SetUpScript: []string{
   424  			"CREATE TABLE t2 (a INTEGER PRIMARY KEY, b INTEGER)",
   425  			"INSERT INTO t2 VALUES (2,2),(3,3)",
   426  			"DELETE FROM t1",
   427  		},
   428  		Assertions: []ScriptTestAssertion{
   429  			{
   430  				Query:       "INSERT INTO t1 (a,b) select a - 2, b - 1 from t2",
   431  				ExpectedErr: sql.ErrCheckConstraintViolated,
   432  			},
   433  			{
   434  				Query:    "INSERT INTO t1 (a,b) select a, b from t2",
   435  				Expected: []sql.Row{{types.OkResult{RowsAffected: 2}}},
   436  			},
   437  			{
   438  				// Check that INSERT IGNORE correctly drops errors with check constraints and does not update the actual table.
   439  				Query:    "INSERT IGNORE INTO t1 VALUES (5,2, 'abc')",
   440  				Expected: []sql.Row{{types.OkResult{RowsAffected: 0}}},
   441  			},
   442  			{
   443  				Query:    "SELECT count(*) FROM t1 where a = 5",
   444  				Expected: []sql.Row{{0}},
   445  			},
   446  			{
   447  				// One value is correctly accepted and the other value is not accepted due to a check constraint violation.
   448  				// The accepted value is correctly added to the table.
   449  				Query:    "INSERT IGNORE INTO t1 VALUES (4,4, null), (5,2, 'abc')",
   450  				Expected: []sql.Row{{types.OkResult{RowsAffected: 1}}},
   451  			},
   452  			{
   453  				Query:    "SELECT count(*) FROM t1 where a = 5",
   454  				Expected: []sql.Row{{0}},
   455  			},
   456  			{
   457  				Query:    "SELECT count(*) FROM t1 where a = 4",
   458  				Expected: []sql.Row{{1}},
   459  			},
   460  		},
   461  	},
   462  }
   463  
   464  var ChecksOnUpdateScriptTests = []ScriptTest{
   465  	{
   466  		Name: "Single table updates",
   467  		SetUpScript: []string{
   468  			"CREATE TABLE t1 (a INTEGER PRIMARY KEY, b INTEGER)",
   469  			"ALTER TABLE t1 ADD CONSTRAINT chk1 CHECK (b > 10) NOT ENFORCED",
   470  			"ALTER TABLE t1 ADD CONSTRAINT chk2 CHECK (b > 0)",
   471  			"ALTER TABLE t1 ADD CONSTRAINT chk3 CHECK ((a + b) / 2 >= 1) ENFORCED",
   472  			"INSERT INTO t1 VALUES (1,1)",
   473  		},
   474  		Assertions: []ScriptTestAssertion{
   475  			{
   476  				Query:    "SELECT * FROM t1;",
   477  				Expected: []sql.Row{{1, 1}},
   478  			},
   479  			{
   480  				Query:       "UPDATE t1 set b = 0;",
   481  				ExpectedErr: sql.ErrCheckConstraintViolated,
   482  			},
   483  			{
   484  				Query:       "UPDATE t1 set a = 0, b = 1;",
   485  				ExpectedErr: sql.ErrCheckConstraintViolated,
   486  			},
   487  			{
   488  				Query:       "UPDATE t1 set b = 0 WHERE b = 1;",
   489  				ExpectedErr: sql.ErrCheckConstraintViolated,
   490  			},
   491  			{
   492  				Query:       "UPDATE t1 set a = 0, b = 1 WHERE b = 1;",
   493  				ExpectedErr: sql.ErrCheckConstraintViolated,
   494  			},
   495  		},
   496  	},
   497  	{
   498  		Name: "Update join updates",
   499  		SetUpScript: []string{
   500  			"CREATE TABLE sales (year_built int primary key, CONSTRAINT `valid_year_built` CHECK (year_built <= 2022));",
   501  			"INSERT INTO sales VALUES (1981);",
   502  		},
   503  		Assertions: []ScriptTestAssertion{
   504  			{
   505  				Query:    "UPDATE sales JOIN (SELECT year_built FROM sales) AS t ON sales.year_built = t.year_built SET sales.year_built = 1901;",
   506  				Expected: []sql.Row{{types.OkResult{1, 0, plan.UpdateInfo{1, 1, 0}}}},
   507  			},
   508  			{
   509  				Query:    "select * from sales;",
   510  				Expected: []sql.Row{{1901}},
   511  			},
   512  			{
   513  				Query:    "UPDATE sales as s1 JOIN (SELECT year_built FROM sales) AS t SET S1.year_built = 1902;",
   514  				Expected: []sql.Row{{types.OkResult{1, 0, plan.UpdateInfo{1, 1, 0}}}},
   515  			},
   516  			{
   517  				Query:    "select * from sales;",
   518  				Expected: []sql.Row{{1902}},
   519  			},
   520  			{
   521  				Query:       "UPDATE sales as s1 JOIN (SELECT year_built FROM sales) AS t SET t.year_built = 1903;",
   522  				ExpectedErr: plan.ErrUpdateForTableNotSupported,
   523  			},
   524  			{
   525  				Query:       "UPDATE sales JOIN (SELECT year_built FROM sales) AS t SET sales.year_built = 2030;",
   526  				ExpectedErr: sql.ErrCheckConstraintViolated,
   527  			},
   528  			{
   529  				Query:       "UPDATE sales as s1 JOIN (SELECT year_built FROM sales) AS t SET s1.year_built = 2030;",
   530  				ExpectedErr: sql.ErrCheckConstraintViolated,
   531  			},
   532  			{
   533  				Query:       "UPDATE sales as s1 JOIN (SELECT year_built FROM sales) AS t SET t.year_built = 2030;",
   534  				ExpectedErr: plan.ErrUpdateForTableNotSupported,
   535  			},
   536  		},
   537  	},
   538  }
   539  
   540  var DisallowedCheckConstraintsScripts = []ScriptTest{
   541  	{
   542  		Name: "error cases",
   543  		SetUpScript: []string{
   544  			"CREATE TABLE t1 (a INTEGER PRIMARY KEY, b INTEGER)",
   545  		},
   546  		Assertions: []ScriptTestAssertion{
   547  			// non-deterministic functions
   548  			{
   549  				Query:       "ALTER TABLE t1 ADD CONSTRAINT chk2 CHECK (current_user = \"root@\")",
   550  				ExpectedErr: sql.ErrInvalidConstraintFunctionNotSupported,
   551  			},
   552  			{
   553  				Query:       "ALTER TABLE t1 ADD CONSTRAINT chk2 CHECK (user() = \"root@\")",
   554  				ExpectedErr: sql.ErrInvalidConstraintFunctionNotSupported,
   555  			},
   556  			{
   557  				Query:       "ALTER TABLE t1 ADD CONSTRAINT chk2 CHECK (now() > '2021')",
   558  				ExpectedErr: sql.ErrInvalidConstraintFunctionNotSupported,
   559  			},
   560  			{
   561  				Query:       "ALTER TABLE t1 ADD CONSTRAINT chk2 CHECK (current_date() > '2021')",
   562  				ExpectedErr: sql.ErrInvalidConstraintFunctionNotSupported,
   563  			},
   564  			{
   565  				Query:       "ALTER TABLE t1 ADD CONSTRAINT chk2 CHECK (uuid() > 'a')",
   566  				ExpectedErr: sql.ErrInvalidConstraintFunctionNotSupported,
   567  			},
   568  			{
   569  				Query:       "ALTER TABLE t1 ADD CONSTRAINT chk2 CHECK (database() = 'foo')",
   570  				ExpectedErr: sql.ErrInvalidConstraintFunctionNotSupported,
   571  			},
   572  			{
   573  				Query:       "ALTER TABLE t1 ADD CONSTRAINT chk2 CHECK (schema() = 'foo')",
   574  				ExpectedErr: sql.ErrInvalidConstraintFunctionNotSupported,
   575  			},
   576  			{
   577  				Query:       "ALTER TABLE t1 ADD CONSTRAINT chk2 CHECK (version() = 'foo')",
   578  				ExpectedErr: sql.ErrInvalidConstraintFunctionNotSupported,
   579  			},
   580  			{
   581  				Query:       "ALTER TABLE t1 ADD CONSTRAINT chk2 CHECK (last_insert_id() = 0)",
   582  				ExpectedErr: sql.ErrInvalidConstraintFunctionNotSupported,
   583  			},
   584  			{
   585  				Query:       "ALTER TABLE t1 ADD CONSTRAINT chk2 CHECK (rand() < .8)",
   586  				ExpectedErr: sql.ErrInvalidConstraintFunctionNotSupported,
   587  			},
   588  			{
   589  				Query:       "ALTER TABLE t1 ADD CONSTRAINT chk2 CHECK (row_count() = 0)",
   590  				ExpectedErr: sql.ErrInvalidConstraintFunctionNotSupported,
   591  			},
   592  			{
   593  				Query:       "ALTER TABLE t1 ADD CONSTRAINT chk2 CHECK (found_rows() = 0)",
   594  				ExpectedErr: sql.ErrInvalidConstraintFunctionNotSupported,
   595  			},
   596  			{
   597  				Query:       "ALTER TABLE t1 ADD CONSTRAINT chk2 CHECK (curdate() > '2021')",
   598  				ExpectedErr: sql.ErrInvalidConstraintFunctionNotSupported,
   599  			},
   600  			{
   601  				Query:       "ALTER TABLE t1 ADD CONSTRAINT chk2 CHECK (curtime() > '2021')",
   602  				ExpectedErr: sql.ErrInvalidConstraintFunctionNotSupported,
   603  			},
   604  			{
   605  				Query:       "ALTER TABLE t1 ADD CONSTRAINT chk2 CHECK (current_timestamp() > '2021')",
   606  				ExpectedErr: sql.ErrInvalidConstraintFunctionNotSupported,
   607  			},
   608  			{
   609  				Query:       "ALTER TABLE t1 ADD CONSTRAINT chk2 CHECK (connection_id() = 2)",
   610  				ExpectedErr: sql.ErrInvalidConstraintFunctionNotSupported,
   611  			},
   612  			// locks
   613  			{
   614  				Query:       "ALTER TABLE t1 ADD CONSTRAINT chk2 CHECK (get_lock('abc', 0) is null)",
   615  				ExpectedErr: sql.ErrInvalidConstraintFunctionNotSupported,
   616  			},
   617  			{
   618  				Query:       "ALTER TABLE t1 ADD CONSTRAINT chk2 CHECK (release_all_locks() is null)",
   619  				ExpectedErr: sql.ErrInvalidConstraintFunctionNotSupported,
   620  			},
   621  			{
   622  				Query:       "ALTER TABLE t1 ADD CONSTRAINT chk2 CHECK (release_lock('abc') is null)",
   623  				ExpectedErr: sql.ErrInvalidConstraintFunctionNotSupported,
   624  			},
   625  			{
   626  				Query:       "ALTER TABLE t1 ADD CONSTRAINT chk2 CHECK (is_free_lock('abc') is null)",
   627  				ExpectedErr: sql.ErrInvalidConstraintFunctionNotSupported,
   628  			},
   629  			{
   630  				Query:       "ALTER TABLE t1 ADD CONSTRAINT chk2 CHECK (is_used_lock('abc') is null)",
   631  				ExpectedErr: sql.ErrInvalidConstraintFunctionNotSupported,
   632  			},
   633  			// subqueries
   634  			{
   635  				Query:       "ALTER TABLE t1 ADD CONSTRAINT chk2 CHECK ((select count(*) from t1) = 0)",
   636  				ExpectedErr: sql.ErrInvalidConstraintSubqueryNotSupported,
   637  			},
   638  			// Some spot checks on create table forms of the above
   639  			{
   640  				Query: `
   641  CREATE TABLE t3 (
   642  	a int primary key CONSTRAINT chk2 CHECK (current_user = "root@")
   643  )
   644  `,
   645  				ExpectedErr: sql.ErrInvalidConstraintFunctionNotSupported,
   646  			},
   647  			{
   648  				Query: `
   649  CREATE TABLE t3 (
   650  	a int primary key,
   651  	CHECK (current_user = "root@")
   652  )
   653  `,
   654  				ExpectedErr: sql.ErrInvalidConstraintFunctionNotSupported,
   655  			},
   656  			{
   657  				Query: `
   658  CREATE TABLE t3 (
   659  	a int primary key CONSTRAINT chk2 CHECK (a = (select count(*) from t1))
   660  )
   661  `,
   662  				ExpectedErr: sql.ErrInvalidConstraintSubqueryNotSupported,
   663  			},
   664  			{
   665  				Query: `
   666  CREATE TABLE t3 (
   667  	a int primary key,
   668  	CHECK (a = (select count(*) from t1))
   669  )
   670  `,
   671  				ExpectedErr: sql.ErrInvalidConstraintSubqueryNotSupported,
   672  			},
   673  		},
   674  	},
   675  }