github.com/matrixorigin/matrixone@v0.7.0/pkg/sql/plan/build_partition_test.go (about)

     1  // Copyright 2022 Matrix Origin
     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 plan
    16  
    17  import (
    18  	"testing"
    19  
    20  	"github.com/matrixorigin/matrixone/pkg/sql/parsers/dialect/mysql"
    21  )
    22  
    23  func TestSingleDDLPartition(t *testing.T) {
    24  	//sql := `CREATE TABLE k1 (
    25  	//			id INT NOT NULL PRIMARY KEY,
    26  	//			name VARCHAR(20)
    27  	//		)
    28  	//		PARTITION BY KEY()
    29  	//		PARTITIONS 2;`
    30  
    31  	//sql := `CREATE TABLE k1 (
    32  	//			id INT NOT NULL,
    33  	//			name VARCHAR(20),
    34  	//			sal DOUBLE,
    35  	//			PRIMARY KEY (id, name)
    36  	//		)
    37  	//		PARTITION BY KEY()
    38  	//		PARTITIONS 2;`
    39  
    40  	sql := `CREATE TABLE k1 (
    41  				id INT NOT NULL,
    42  				name VARCHAR(20),
    43  				UNIQUE KEY (id)
    44  			)
    45  			PARTITION BY KEY()
    46  			PARTITIONS 2;`
    47  
    48  	//sql := `CREATE TABLE quarterly_report_status (
    49  	//		report_id INT NOT NULL,
    50  	//		report_status VARCHAR(20) NOT NULL,
    51  	//		report_updated TIMESTAMP NOT NULL
    52  	//	)
    53  	//		PARTITION BY RANGE ( UNIX_TIMESTAMP(report_updated) ) (
    54  	//		PARTITION p0 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-01-01 00:00:00') ),
    55  	//		PARTITION p1 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-04-01 00:00:00') ),
    56  	//		PARTITION p2 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-07-01 00:00:00') ),
    57  	//		PARTITION p3 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-10-01 00:00:00') ),
    58  	//		PARTITION p4 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-01-01 00:00:00') ),
    59  	//		PARTITION p5 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-04-01 00:00:00') ),
    60  	//		PARTITION p6 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-07-01 00:00:00') ),
    61  	//		PARTITION p7 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-10-01 00:00:00') ),
    62  	//		PARTITION p8 VALUES LESS THAN ( UNIX_TIMESTAMP('2010-01-01 00:00:00') ),
    63  	//		PARTITION p9 VALUES LESS THAN (MAXVALUE)
    64  	//	);`
    65  
    66  	mock := NewMockOptimizer(false)
    67  	logicPlan, err := buildSingleStmt(mock, t, sql)
    68  	if err != nil {
    69  		t.Fatalf("%+v", err)
    70  	}
    71  	outPutPlan(logicPlan, true, t)
    72  }
    73  
    74  // ---------------------------------- Key Partition ----------------------------------
    75  func TestKeyPartition(t *testing.T) {
    76  	// KEY(column_list) Partition
    77  	sqls := []string{
    78  		"CREATE TABLE tk (col1 INT, col2 CHAR(5), col3 DATE) PARTITION BY KEY(col3) PARTITIONS 4;",
    79  		"CREATE TABLE tk (col1 INT, col2 CHAR(5), col3 DATE) PARTITION BY KEY(col3);",
    80  		"CREATE TABLE tk (col1 INT, col2 CHAR(5), col3 DATE) PARTITION BY LINEAR KEY(col3) PARTITIONS 5;",
    81  		"CREATE TABLE tk (col1 INT, col2 CHAR(5), col3 DATE) PARTITION BY KEY ALGORITHM = 1 (col3);",
    82  		"CREATE TABLE tk (col1 INT, col2 CHAR(5), col3 DATE) PARTITION BY LINEAR KEY ALGORITHM = 1 (col3) PARTITIONS 5;",
    83  		"CREATE TABLE tk (col1 INT, col2 CHAR(5), col3 DATE) PARTITION BY KEY(col1, col2) PARTITIONS 4;",
    84  		`CREATE TABLE t1 (
    85  			col1 INT NOT NULL,
    86  			col2 DATE NOT NULL,
    87  			col3 INT NOT NULL,
    88  			col4 INT NOT NULL,
    89  			PRIMARY KEY (col1, col2)
    90  		)
    91  		PARTITION BY KEY(col1)
    92  		PARTITIONS 4;`,
    93  		`CREATE TABLE k1 (
    94  					id INT NOT NULL PRIMARY KEY,
    95  					name VARCHAR(20)
    96  				)
    97  				PARTITION BY KEY()
    98  				PARTITIONS 2;`,
    99  		`CREATE TABLE k1 (
   100  				id INT NOT NULL,
   101  				name VARCHAR(20),
   102  				sal DOUBLE,
   103  				PRIMARY KEY (id, name)
   104  			)
   105  			PARTITION BY KEY()
   106  			PARTITIONS 2;`,
   107  		`CREATE TABLE k1 (
   108  				id INT NOT NULL,
   109  				name VARCHAR(20),
   110  				UNIQUE KEY (id)
   111  			)
   112  			PARTITION BY KEY()
   113  			PARTITIONS 2;`,
   114  		`CREATE TABLE t1 (
   115  				col1 INT NOT NULL,
   116  				col2 DATE NOT NULL,
   117  				col3 INT NOT NULL,
   118  				col4 INT NOT NULL,
   119  				PRIMARY KEY (col1, col2)
   120  			)
   121  			PARTITION BY KEY()
   122  			PARTITIONS 4;`,
   123  		`CREATE TABLE t2 (
   124  			col1 INT NOT NULL,
   125  			col2 DATE NOT NULL,
   126  			col3 INT NOT NULL,
   127  			col4 INT NOT NULL,
   128  			PRIMARY KEY (col1),
   129  			unique key (col1, col4)
   130  		)
   131  			PARTITION BY KEY()
   132  			PARTITIONS 4;`,
   133  	}
   134  
   135  	mock := NewMockOptimizer(false)
   136  	for _, sql := range sqls {
   137  		t.Log(sql)
   138  		logicPlan, err := buildSingleStmt(mock, t, sql)
   139  		if err != nil {
   140  			t.Fatalf("%+v", err)
   141  		}
   142  		outPutPlan(logicPlan, true, t)
   143  	}
   144  }
   145  
   146  func TestKeyPartitionError(t *testing.T) {
   147  	sqls := []string{
   148  		"CREATE TABLE ts (id INT, purchased DATE) PARTITION BY KEY( id ) PARTITIONS 4 SUBPARTITION BY HASH( TO_DAYS(purchased) ) SUBPARTITIONS 2;",
   149  		"CREATE TABLE tk (col1 INT, col2 CHAR(5), col3 DATE) PARTITION BY KEY(col4) PARTITIONS 4;",
   150  		"CREATE TABLE tk (col1 INT, col2 CHAR(5), col3 DATE) PARTITION BY KEY ALGORITHM = 3 (col3);",
   151  		`CREATE TABLE t1 (
   152  			col1 INT NOT NULL,
   153  			col2 DATE NOT NULL,
   154  			col3 INT NOT NULL,
   155  			col4 INT NOT NULL,
   156  			PRIMARY KEY (col1, col2)
   157  		)
   158  		PARTITION BY KEY(col3)
   159  		PARTITIONS 4;`,
   160  		`CREATE TABLE k1 (
   161  					id INT NOT NULL,
   162  					name VARCHAR(20)
   163  				)
   164  				PARTITION BY KEY()
   165  				PARTITIONS 2;`,
   166  		`CREATE TABLE t4 (
   167  			col1 INT NOT NULL,
   168  			col2 INT NOT NULL,
   169  			col3 INT NOT NULL,
   170  			col4 INT NOT NULL,
   171  			UNIQUE KEY (col1, col3),
   172  			UNIQUE KEY (col2, col4)
   173  		)
   174  		PARTITION BY KEY()
   175  		PARTITIONS 2;`,
   176  
   177  		`CREATE TABLE t2 (
   178  			col1 INT NOT NULL,
   179  			col2 DATE NOT NULL,
   180  			col3 INT NOT NULL,
   181  			col4 INT NOT NULL,
   182  			PRIMARY KEY (col1),
   183  			unique key (col3, col4)
   184  		)
   185  			PARTITION BY KEY()
   186  			PARTITIONS 4;`,
   187  
   188  		`CREATE TABLE t3 (
   189  			col1 INT NOT NULL,
   190  			col2 DATE NOT NULL,
   191  			col3 INT NOT NULL,
   192  			col4 INT NOT NULL,
   193  			PRIMARY KEY (col1, col4),
   194  			unique key (col1)
   195  		)
   196  			PARTITION BY KEY()
   197  			PARTITIONS 4;`,
   198  		`CREATE TABLE t1 (
   199  		col1 INT NOT NULL,
   200  		col2 DATE NOT NULL,
   201  		col3 INT NOT NULL,
   202  		col4 INT NOT NULL,
   203  		PRIMARY KEY (col1, col2)
   204  		)
   205  		PARTITION BY KEY(col3)
   206  		PARTITIONS 4;`,
   207  	}
   208  	mock := NewMockOptimizer(false)
   209  	for _, sql := range sqls {
   210  		_, err := buildSingleStmt(mock, t, sql)
   211  		t.Log(sql)
   212  		t.Log(err)
   213  		if err == nil {
   214  			t.Fatalf("%+v", err)
   215  		}
   216  	}
   217  }
   218  
   219  // -----------------------Hash Partition-------------------------------------
   220  func TestHashPartition(t *testing.T) {
   221  	// HASH(expr) Partition
   222  	sqls := []string{
   223  		"CREATE TABLE t1 (col1 INT, col2 CHAR(5)) PARTITION BY HASH(col1);",
   224  		"CREATE TABLE t1 (col1 INT, col2 CHAR(5)) PARTITION BY HASH(col1) PARTITIONS 4;",
   225  		"CREATE TABLE t1 (col1 INT, col2 CHAR(5), col3 DATETIME) PARTITION BY HASH (YEAR(col3));",
   226  		"CREATE TABLE t1 (col1 INT, col2 CHAR(5), col3 DATE) PARTITION BY LINEAR HASH( YEAR(col3)) PARTITIONS 6;",
   227  		`CREATE TABLE employees (
   228  				id INT NOT NULL,
   229  				fname VARCHAR(30),
   230  				lname VARCHAR(30),
   231  				hired DATE NOT NULL DEFAULT '1970-01-01',
   232  				separated DATE NOT NULL DEFAULT '9999-12-31',
   233  				job_code INT,
   234  				store_id INT
   235  			)
   236  			PARTITION BY HASH(store_id)
   237  			PARTITIONS 4;`,
   238  
   239  		`CREATE TABLE t1 (
   240  			col1 INT NOT NULL,
   241  			col2 DATE NOT NULL,
   242  			col3 INT NOT NULL,
   243  			col4 INT NOT NULL,
   244  			PRIMARY KEY (col1, col2)
   245  		)
   246  		PARTITION BY HASH(col1)
   247  		PARTITIONS 4;`,
   248  
   249  		`CREATE TABLE t1 (
   250  			col1 INT NOT NULL,
   251  			col2 DATE NOT NULL,
   252  			col3 INT NOT NULL,
   253  			col4 INT NOT NULL,
   254  			PRIMARY KEY (col1, col3)
   255  		)
   256  		PARTITION BY HASH(col1 + col3)
   257  		PARTITIONS 4;`,
   258  
   259  		`CREATE TABLE t2 (
   260  			col1 INT NOT NULL,
   261  			col2 DATE NOT NULL,
   262  			col3 INT NOT NULL,
   263  			col4 INT NOT NULL,
   264  			PRIMARY KEY (col1)
   265  		)
   266  		PARTITION BY HASH(col1+10)
   267  		PARTITIONS 4;`,
   268  		`CREATE TABLE employees (
   269  				id INT NOT NULL,
   270  				fname VARCHAR(30),
   271  				lname VARCHAR(30),
   272  				hired DATE NOT NULL DEFAULT '1970-01-01',
   273  				separated DATE NOT NULL DEFAULT '9999-12-31',
   274  				job_code INT,
   275  				store_id INT
   276  			)
   277  			PARTITION BY LINEAR HASH( YEAR(hired) )
   278  			PARTITIONS 4;`,
   279  	}
   280  
   281  	mock := NewMockOptimizer(false)
   282  	for _, sql := range sqls {
   283  		t.Log(sql)
   284  		logicPlan, err := buildSingleStmt(mock, t, sql)
   285  		if err != nil {
   286  			t.Fatalf("%+v", err)
   287  		}
   288  		outPutPlan(logicPlan, true, t)
   289  	}
   290  }
   291  
   292  func TestHashPartitionError(t *testing.T) {
   293  	// HASH(expr) Partition
   294  	sqls := []string{
   295  		"CREATE TABLE t1 (col1 INT, col2 CHAR(5)) PARTITION BY HASH(col2);",
   296  		"CREATE TABLE t1 (col1 INT, col2 DECIMAL) PARTITION BY HASH(col2);",
   297  		"CREATE TABLE t1 (col1 INT, col2 DECIMAL) PARTITION BY HASH(col1+0.5);",
   298  		"CREATE TABLE t1 (col1 INT, col2 DECIMAL) PARTITION BY HASH(12);",
   299  		"CREATE TABLE t1 (col1 INT, col2 CHAR(5), col3 DATETIME) PARTITION BY HASH (YEAR(col3)) PARTITIONS 4 SUBPARTITION BY KEY(col1);",
   300  		"CREATE TABLE t1 (col1 INT, col2 CHAR(5), col3 DATE) PARTITION BY HASH( YEAR(col3) ) PARTITIONS;",
   301  		`CREATE TABLE employees (
   302  					id INT NOT NULL,
   303  					fname VARCHAR(30),
   304  					lname VARCHAR(30),
   305  					hired DATE NOT NULL DEFAULT '1970-01-01',
   306  					separated DATE NOT NULL DEFAULT '9999-12-31',
   307  					job_code INT,
   308  					store_id INT
   309  				)
   310  				PARTITION BY HASH(4)
   311  				PARTITIONS 4;`,
   312  
   313  		`CREATE TABLE t1 (
   314  			col1 INT NOT NULL,
   315  			col2 DATE NOT NULL,
   316  			col3 INT NOT NULL,
   317  			col4 INT NOT NULL,
   318  			PRIMARY KEY (col1, col2)
   319  		)
   320  			PARTITION BY HASH(col3)
   321  			PARTITIONS 4;`,
   322  
   323  		`CREATE TABLE t2 (
   324  			col1 INT NOT NULL,
   325  			col2 DATE NOT NULL,
   326  			col3 INT NOT NULL,
   327  			col4 INT NOT NULL,
   328  			PRIMARY KEY (col1)
   329  		)
   330  			PARTITION BY HASH(col1 + col3)
   331  			PARTITIONS 4;`,
   332  
   333  		`CREATE TABLE t2 (
   334  			col1 INT NOT NULL,
   335  			col2 DATE NOT NULL,
   336  			col3 INT NOT NULL,
   337  			col4 INT NOT NULL,
   338  			UNIQUE KEY (col1),
   339  			UNIQUE KEY (col3)
   340  		)
   341  		PARTITION BY HASH(col1,col3)
   342  		PARTITIONS 4;`,
   343  	}
   344  
   345  	mock := NewMockOptimizer(false)
   346  	for _, sql := range sqls {
   347  		_, err := buildSingleStmt(mock, t, sql)
   348  		t.Log(sql)
   349  		t.Log(err)
   350  		if err == nil {
   351  			t.Fatalf("%+v", err)
   352  		}
   353  	}
   354  
   355  }
   356  
   357  // -----------------------Range Partition-------------------------------------
   358  func TestRangePartition(t *testing.T) {
   359  	sqls := []string{
   360  		`CREATE TABLE employees (
   361  				id INT NOT NULL,
   362  				fname VARCHAR(30),
   363  				lname VARCHAR(30),
   364  				hired DATE NOT NULL DEFAULT '1970-01-01',
   365  				separated DATE NOT NULL DEFAULT '9999-12-31',
   366  				job_code INT NOT NULL,
   367  				store_id INT NOT NULL
   368  			)
   369  			PARTITION BY RANGE (store_id) (
   370  				PARTITION p0 VALUES LESS THAN (6),
   371  				PARTITION p1 VALUES LESS THAN (11),
   372  				PARTITION p2 VALUES LESS THAN (16),
   373  				PARTITION p3 VALUES LESS THAN (21)
   374  			);`,
   375  
   376  		`CREATE TABLE t1 (
   377  				year_col  INT,
   378  				some_data INT
   379  			)
   380  			PARTITION BY RANGE (year_col) (
   381  				PARTITION p0 VALUES LESS THAN (1991),
   382  				PARTITION p1 VALUES LESS THAN (1995),
   383  				PARTITION p2 VALUES LESS THAN (1999),
   384  				PARTITION p3 VALUES LESS THAN (2002),
   385  				PARTITION p4 VALUES LESS THAN (2006),
   386  				PARTITION p5 VALUES LESS THAN (2012)
   387  			);`,
   388  
   389  		`CREATE TABLE t1 (
   390  				year_col  INT,
   391  				some_data INT
   392  			)
   393  			PARTITION BY RANGE (year_col) (
   394  				PARTITION p0 VALUES LESS THAN (1991) COMMENT = 'Data for the years previous to 1991',
   395  				PARTITION p1 VALUES LESS THAN (1995) COMMENT = 'Data for the years previous to 1995',
   396  				PARTITION p2 VALUES LESS THAN (1999) COMMENT = 'Data for the years previous to 1999',
   397  				PARTITION p3 VALUES LESS THAN (2002) COMMENT = 'Data for the years previous to 2002',
   398  				PARTITION p4 VALUES LESS THAN (2006) COMMENT = 'Data for the years previous to 2006',
   399  				PARTITION p5 VALUES LESS THAN (2012) COMMENT = 'Data for the years previous to 2012'
   400  			);`,
   401  
   402  		`CREATE TABLE employees (
   403  				id INT NOT NULL,
   404  				fname VARCHAR(30),
   405  				lname VARCHAR(30),
   406  				hired DATE NOT NULL DEFAULT '1970-01-01',
   407  				separated DATE NOT NULL DEFAULT '9999-12-31',
   408  				job_code INT NOT NULL,
   409  				store_id INT NOT NULL
   410  			)
   411  			PARTITION BY RANGE (store_id) (
   412  				PARTITION p0 VALUES LESS THAN (6),
   413  				PARTITION p1 VALUES LESS THAN (11),
   414  				PARTITION p2 VALUES LESS THAN (16),
   415  				PARTITION p3 VALUES LESS THAN MAXVALUE
   416  			);`,
   417  
   418  		`CREATE TABLE employees (
   419  				id INT NOT NULL,
   420  				fname VARCHAR(30),
   421  				lname VARCHAR(30),
   422  				hired DATE NOT NULL DEFAULT '1970-01-01',
   423  				separated DATE NOT NULL DEFAULT '9999-12-31',
   424  				job_code INT NOT NULL,
   425  				store_id INT NOT NULL
   426  			)
   427  			PARTITION BY RANGE (job_code) (
   428  				PARTITION p0 VALUES LESS THAN (100),
   429  				PARTITION p1 VALUES LESS THAN (1000),
   430  				PARTITION p2 VALUES LESS THAN (10000)
   431  			);`,
   432  
   433  		`CREATE TABLE employees (
   434  				id INT NOT NULL,
   435  				fname VARCHAR(30),
   436  				lname VARCHAR(30),
   437  				hired DATE NOT NULL DEFAULT '1970-01-01',
   438  				separated DATE NOT NULL DEFAULT '9999-12-31',
   439  				job_code INT,
   440  				store_id INT
   441  			)
   442  			PARTITION BY RANGE ( YEAR(separated) ) (
   443  				PARTITION p0 VALUES LESS THAN (1991),
   444  				PARTITION p1 VALUES LESS THAN (1996),
   445  				PARTITION p2 VALUES LESS THAN (2001),
   446  				PARTITION p3 VALUES LESS THAN MAXVALUE
   447  			);`,
   448  
   449  		`CREATE TABLE employees (
   450  			id INT NOT NULL,
   451  			fname VARCHAR(30),
   452  			lname VARCHAR(30),
   453  			hired DATE NOT NULL DEFAULT '1970-01-01',
   454  			separated DATE NOT NULL DEFAULT '9999-12-31',
   455  			job_code INT NOT NULL,
   456  			store_id INT NOT NULL,
   457  			PRIMARY KEY(id, store_id)
   458  		)
   459  			PARTITION BY RANGE (store_id) (
   460  			PARTITION p0 VALUES LESS THAN (6),
   461  			PARTITION p1 VALUES LESS THAN (11),
   462  			PARTITION p2 VALUES LESS THAN (16),
   463  			PARTITION p3 VALUES LESS THAN (21)
   464  		);`,
   465  
   466  		`CREATE TABLE employees (
   467  			id INT NOT NULL,
   468  			fname VARCHAR(30),
   469  			lname VARCHAR(30),
   470  			hired DATE NOT NULL DEFAULT '1970-01-01',
   471  			separated DATE NOT NULL DEFAULT '9999-12-31',
   472  			job_code INT NOT NULL,
   473  			store_id INT NOT NULL,
   474  			PRIMARY KEY(id, store_id)
   475  		)
   476  			PARTITION BY RANGE (store_id + 5) (
   477  			PARTITION p0 VALUES LESS THAN (6),
   478  			PARTITION p1 VALUES LESS THAN (11),
   479  			PARTITION p2 VALUES LESS THAN (16),
   480  			PARTITION p3 VALUES LESS THAN (21)
   481  		);`,
   482  
   483  		`CREATE TABLE employees (
   484  			id INT NOT NULL,
   485  			fname VARCHAR(30),
   486  			lname VARCHAR(30),
   487  			hired DATE NOT NULL DEFAULT '1970-01-01',
   488  			separated DATE NOT NULL DEFAULT '9999-12-31',
   489  			job_code INT NOT NULL,
   490  			store_id INT NOT NULL,
   491  			PRIMARY KEY(id, hired)
   492  		)
   493  			PARTITION BY RANGE (year(hired)) (
   494  			PARTITION p0 VALUES LESS THAN (6),
   495  			PARTITION p1 VALUES LESS THAN (11),
   496  			PARTITION p2 VALUES LESS THAN (16),
   497  			PARTITION p3 VALUES LESS THAN (21)
   498  		);`,
   499  
   500  		`CREATE TABLE members (
   501  			firstname VARCHAR(25) NOT NULL,
   502  			lastname VARCHAR(25) NOT NULL,
   503  			username VARCHAR(16) NOT NULL,
   504  			email VARCHAR(35),
   505  			joined DATE NOT NULL
   506  		)
   507  		PARTITION BY RANGE( YEAR(joined) ) PARTITIONS 5 (
   508  			PARTITION p0 VALUES LESS THAN (1960),
   509  			PARTITION p1 VALUES LESS THAN (1970),
   510  			PARTITION p2 VALUES LESS THAN (1980),
   511  			PARTITION p3 VALUES LESS THAN (1990),
   512  			PARTITION p4 VALUES LESS THAN MAXVALUE
   513  		);`,
   514  
   515  		//`CREATE TABLE quarterly_report_status (
   516  		//	report_id INT NOT NULL,
   517  		//	report_status VARCHAR(20) NOT NULL,
   518  		//	report_updated TIMESTAMP NOT NULL
   519  		//)
   520  		//	PARTITION BY RANGE ( UNIX_TIMESTAMP(report_updated) ) (
   521  		//	PARTITION p0 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-01-01 00:00:00') ),
   522  		//	PARTITION p1 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-04-01 00:00:00') ),
   523  		//	PARTITION p2 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-07-01 00:00:00') ),
   524  		//	PARTITION p3 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-10-01 00:00:00') ),
   525  		//	PARTITION p4 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-01-01 00:00:00') ),
   526  		//	PARTITION p5 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-04-01 00:00:00') ),
   527  		//	PARTITION p6 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-07-01 00:00:00') ),
   528  		//	PARTITION p7 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-10-01 00:00:00') ),
   529  		//	PARTITION p8 VALUES LESS THAN ( UNIX_TIMESTAMP('2010-01-01 00:00:00') ),
   530  		//	PARTITION p9 VALUES LESS THAN (MAXVALUE)
   531  		//);`,
   532  	}
   533  
   534  	mock := NewMockOptimizer(false)
   535  	for _, sql := range sqls {
   536  		t.Log(sql)
   537  		logicPlan, err := buildSingleStmt(mock, t, sql)
   538  		if err != nil {
   539  			t.Fatalf("%+v", err)
   540  		}
   541  		outPutPlan(logicPlan, true, t)
   542  	}
   543  }
   544  
   545  func TestRangePartitionError(t *testing.T) {
   546  	sqls := []string{
   547  		`CREATE TABLE employees (
   548  			id INT NOT NULL,
   549  			fname VARCHAR(30),
   550  			lname VARCHAR(30),
   551  			hired DATE NOT NULL DEFAULT '1970-01-01',
   552  			separated DATE NOT NULL DEFAULT '9999-12-31',
   553  			job_code INT NOT NULL,
   554  			store_id INT NOT NULL,
   555  			PRIMARY KEY(id, store_id)
   556  		)
   557  		PARTITION BY RANGE (job_code) (
   558  			PARTITION p0 VALUES LESS THAN (6),
   559  			PARTITION p1 VALUES LESS THAN (11),
   560  			PARTITION p2 VALUES LESS THAN (16),
   561  			PARTITION p3 VALUES LESS THAN (21)
   562  		);`,
   563  
   564  		`CREATE TABLE employees (
   565  			id INT NOT NULL,
   566  			fname VARCHAR(30),
   567  			lname VARCHAR(30),
   568  			hired DATE NOT NULL DEFAULT '1970-01-01',
   569  			separated DATE NOT NULL DEFAULT '9999-12-31',
   570  			job_code INT NOT NULL,
   571  			store_id INT NOT NULL,
   572  			PRIMARY KEY(id, store_id)
   573  		)
   574  		PARTITION BY RANGE (job_code + 5) (
   575  			PARTITION p0 VALUES LESS THAN (6),
   576  			PARTITION p1 VALUES LESS THAN (11),
   577  			PARTITION p2 VALUES LESS THAN (16),
   578  			PARTITION p3 VALUES LESS THAN (21)
   579  		);`,
   580  
   581  		`CREATE TABLE employees (
   582  			id INT NOT NULL,
   583  			fname VARCHAR(30),
   584  			lname VARCHAR(30),
   585  			hired DATE NOT NULL DEFAULT '1970-01-01',
   586  			separated DATE NOT NULL DEFAULT '9999-12-31',
   587  			job_code INT NOT NULL,
   588  			store_id INT NOT NULL,
   589  			PRIMARY KEY(id, hired)
   590  		)
   591  		PARTITION BY RANGE (year(separated)) (
   592  			PARTITION p0 VALUES LESS THAN (6),
   593  			PARTITION p1 VALUES LESS THAN (11),
   594  			PARTITION p2 VALUES LESS THAN (16),
   595  			PARTITION p3 VALUES LESS THAN (21)
   596  		);`,
   597  
   598  		`CREATE TABLE employees (
   599  			id INT NOT NULL,
   600  			fname VARCHAR(30),
   601  			lname VARCHAR(30),
   602  			hired DATE NOT NULL DEFAULT '1970-01-01',
   603  			separated DATE NOT NULL DEFAULT '9999-12-31',
   604  			job_code INT NOT NULL,
   605  			store_id INT NOT NULL,
   606  			PRIMARY KEY(id, store_id)
   607  		)
   608  		PARTITION BY RANGE (job_code + store_id) (
   609  			PARTITION p0 VALUES LESS THAN (6),
   610  			PARTITION p1 VALUES LESS THAN (11),
   611  			PARTITION p2 VALUES LESS THAN (16),
   612  			PARTITION p3 VALUES LESS THAN (21)
   613  		);`,
   614  
   615  		`CREATE TABLE members (
   616  			firstname VARCHAR(25) NOT NULL,
   617  			lastname VARCHAR(25) NOT NULL,
   618  			username VARCHAR(16) NOT NULL,
   619  			email VARCHAR(35),
   620  			joined DATE NOT NULL
   621  		)
   622  		PARTITION BY RANGE( YEAR(joined) ) PARTITIONS 4 (
   623  			PARTITION p0 VALUES LESS THAN (1960),
   624  			PARTITION p1 VALUES LESS THAN (1970),
   625  			PARTITION p2 VALUES LESS THAN (1980),
   626  			PARTITION p3 VALUES LESS THAN (1990),
   627  			PARTITION p4 VALUES LESS THAN MAXVALUE
   628  		);`,
   629  	}
   630  
   631  	mock := NewMockOptimizer(false)
   632  	for _, sql := range sqls {
   633  		_, err := buildSingleStmt(mock, t, sql)
   634  		t.Log(sql)
   635  		t.Log(err)
   636  		if err == nil {
   637  			t.Fatalf("%+v", err)
   638  		}
   639  	}
   640  }
   641  
   642  // ---------------------Range Columns Partition--------------------------------
   643  func TestRangeColumnsPartition(t *testing.T) {
   644  	sqls := []string{
   645  		`CREATE TABLE rc (
   646  				a INT NOT NULL,
   647  				b INT NOT NULL
   648  			)
   649  			PARTITION BY RANGE COLUMNS(a,b) (
   650  				PARTITION p0 VALUES LESS THAN (10,5),
   651  				PARTITION p1 VALUES LESS THAN (20,10),
   652  				PARTITION p2 VALUES LESS THAN (50,20),
   653  				PARTITION p3 VALUES LESS THAN (65,30)
   654  			);`,
   655  
   656  		`CREATE TABLE rc (
   657  				a INT NOT NULL,
   658  				b INT NOT NULL
   659  			)
   660  			PARTITION BY RANGE COLUMNS(a,b) (
   661  				PARTITION p0 VALUES LESS THAN (10,5),
   662  				PARTITION p1 VALUES LESS THAN (20,10),
   663  				PARTITION p2 VALUES LESS THAN (50,MAXVALUE),
   664  				PARTITION p3 VALUES LESS THAN (65,MAXVALUE),
   665  				PARTITION p4 VALUES LESS THAN (MAXVALUE,MAXVALUE)
   666  			);`,
   667  
   668  		`CREATE TABLE rc (
   669  				a INT NOT NULL,
   670  				b INT NOT NULL
   671  			)
   672  			PARTITION BY RANGE COLUMNS(a,b) (
   673  				PARTITION p0 VALUES LESS THAN (10,5) COMMENT = 'Data for LESS THAN (10,5)',
   674  				PARTITION p1 VALUES LESS THAN (20,10) COMMENT = 'Data for LESS THAN (20,10)',
   675  				PARTITION p2 VALUES LESS THAN (50,MAXVALUE) COMMENT = 'Data for LESS THAN (50,MAXVALUE)',
   676  				PARTITION p3 VALUES LESS THAN (65,MAXVALUE) COMMENT = 'Data for LESS THAN (65,MAXVALUE)',
   677  				PARTITION p4 VALUES LESS THAN (MAXVALUE,MAXVALUE) COMMENT = 'Data for LESS THAN (MAXVALUE,MAXVALUE)'
   678  			);`,
   679  
   680  		`CREATE TABLE rcx (
   681  				a INT,
   682  				b INT,
   683  				c CHAR(3),
   684  				d INT
   685  			)
   686  			PARTITION BY RANGE COLUMNS(a,d,c) (
   687  				PARTITION p0 VALUES LESS THAN (5,10,'ggg'),
   688  				PARTITION p1 VALUES LESS THAN (10,20,'mmm'),
   689  				PARTITION p2 VALUES LESS THAN (15,30,'sss'),
   690  				PARTITION p3 VALUES LESS THAN (MAXVALUE,MAXVALUE,MAXVALUE)
   691  			);`,
   692  
   693  		`CREATE TABLE t1 (
   694  			col1 INT NOT NULL,
   695  			col2 INT NOT NULL,
   696  			col3 INT NOT NULL,
   697  			col4 INT NOT NULL,
   698  			PRIMARY KEY(col1, col3)
   699  		)
   700  			PARTITION BY RANGE COLUMNS(col1,col3) (
   701  			PARTITION p0 VALUES LESS THAN (10,5),
   702  			PARTITION p1 VALUES LESS THAN (20,10),
   703  			PARTITION p2 VALUES LESS THAN (50,20),
   704  			PARTITION p3 VALUES LESS THAN (65,30)
   705  		);`,
   706  
   707  		`CREATE TABLE rc (
   708  				a INT NOT NULL,
   709  				b INT NOT NULL
   710  			)
   711  			PARTITION BY RANGE COLUMNS(a,b) PARTITIONS 4 (
   712  				PARTITION p0 VALUES LESS THAN (10,5),
   713  				PARTITION p1 VALUES LESS THAN (20,10),
   714  				PARTITION p2 VALUES LESS THAN (50,20),
   715  				PARTITION p3 VALUES LESS THAN (65,30)
   716           );`,
   717  	}
   718  	mock := NewMockOptimizer(false)
   719  	for _, sql := range sqls {
   720  		t.Log(sql)
   721  		logicPlan, err := buildSingleStmt(mock, t, sql)
   722  		if err != nil {
   723  			t.Fatalf("%+v", err)
   724  		}
   725  		outPutPlan(logicPlan, true, t)
   726  	}
   727  }
   728  
   729  func TestRangeColumnsPartitionError(t *testing.T) {
   730  	sqls := []string{
   731  		`CREATE TABLE rc3 (
   732  			a INT NOT NULL,
   733  			b INT NOT NULL
   734  		)
   735  		PARTITION BY RANGE COLUMNS(a,b) (
   736  			PARTITION p0 VALUES LESS THAN (a,5),
   737  			PARTITION p1 VALUES LESS THAN (20,10),
   738  			PARTITION p2 VALUES LESS THAN (50,20),
   739  			PARTITION p3 VALUES LESS THAN (65,30)
   740  		);`,
   741  
   742  		`CREATE TABLE rc3 (
   743  			a INT NOT NULL,
   744  			b INT NOT NULL
   745  		)
   746  		PARTITION BY RANGE COLUMNS(a,b) (
   747  			PARTITION p0 VALUES LESS THAN (a+7,5),
   748  			PARTITION p1 VALUES LESS THAN (20,10),
   749  			PARTITION p2 VALUES LESS THAN (50,20),
   750  			PARTITION p3 VALUES LESS THAN (65,30)
   751  		);`,
   752  
   753  		`CREATE TABLE t1 (
   754  			col1 INT NOT NULL,
   755  			col2 INT NOT NULL,
   756  			col3 INT NOT NULL,
   757  			col4 INT NOT NULL,
   758  			PRIMARY KEY(col1, col3)
   759  		)
   760  		PARTITION BY RANGE COLUMNS(col1,col2) (
   761  			PARTITION p0 VALUES LESS THAN (10,5),
   762  			PARTITION p1 VALUES LESS THAN (20,10),
   763  			PARTITION p2 VALUES LESS THAN (50,20),
   764  			PARTITION p3 VALUES LESS THAN (65,30)
   765  		);`,
   766  
   767  		`CREATE TABLE rc (
   768  				a INT NOT NULL,
   769  				b INT NOT NULL
   770  			)
   771  			PARTITION BY RANGE COLUMNS(a,b) PARTITIONS 5 (
   772  				PARTITION p0 VALUES LESS THAN (10,5),
   773  				PARTITION p1 VALUES LESS THAN (20,10),
   774  				PARTITION p2 VALUES LESS THAN (50,20),
   775  				PARTITION p3 VALUES LESS THAN (65,30)
   776           );`,
   777  
   778  		`CREATE TABLE rc (
   779  			a INT NOT NULL,
   780  			b INT NOT NULL
   781  		)
   782  		PARTITION BY RANGE COLUMNS(a,b) (
   783  			PARTITION p0 VALUES LESS THAN (10,5),
   784  			PARTITION p1 VALUES IN( 1,2 ),
   785  			PARTITION p2 VALUES LESS THAN (50,20),
   786  			PARTITION p3 VALUES LESS THAN (65,30)
   787  		);`,
   788  	}
   789  
   790  	mock := NewMockOptimizer(false)
   791  	for _, sql := range sqls {
   792  		_, err := buildSingleStmt(mock, t, sql)
   793  		t.Log(sql)
   794  		t.Log(err)
   795  		if err == nil {
   796  			t.Fatalf("%+v", err)
   797  		}
   798  	}
   799  }
   800  
   801  // -----------------------List Partition--------------------------------------
   802  func TestListPartition(t *testing.T) {
   803  	sqls := []string{
   804  		`CREATE TABLE client_firms (
   805  			id   INT,
   806  			name VARCHAR(35)
   807  		)
   808  		PARTITION BY LIST (id) (
   809  			PARTITION r0 VALUES IN (1, 5, 9, 13, 17, 21),
   810  			PARTITION r1 VALUES IN (2, 6, 10, 14, 18, 22),
   811  			PARTITION r2 VALUES IN (3, 7, 11, 15, 19, 23),
   812  			PARTITION r3 VALUES IN (4, 8, 12, 16, 20, 24)
   813  		);`,
   814  
   815  		`CREATE TABLE employees (
   816  			id INT NOT NULL,
   817  			fname VARCHAR(30),
   818  			lname VARCHAR(30),
   819  			hired DATE NOT NULL DEFAULT '1970-01-01',
   820  			separated DATE NOT NULL DEFAULT '9999-12-31',
   821  			job_code INT,
   822  			store_id INT
   823  		)
   824  		PARTITION BY LIST(store_id) (
   825  			PARTITION pNorth VALUES IN (3,5,6,9,17),
   826  			PARTITION pEast VALUES IN (1,2,10,11,19,20),
   827  			PARTITION pWest VALUES IN (4,12,13,14,18),
   828  			PARTITION pCentral VALUES IN (7,8,15,16)
   829  		);`,
   830  
   831  		`CREATE TABLE t1 (
   832  			id   INT PRIMARY KEY,
   833  			name VARCHAR(35)
   834  		)
   835  		PARTITION BY LIST (id) (
   836  			PARTITION r0 VALUES IN (1, 5, 9, 13, 17, 21),
   837  			PARTITION r1 VALUES IN (2, 6, 10, 14, 18, 22),
   838  			PARTITION r2 VALUES IN (3, 7, 11, 15, 19, 23),
   839  			PARTITION r3 VALUES IN (4, 8, 12, 16, 20, 24)
   840  		);`,
   841  
   842  		`CREATE TABLE lc (
   843  			a INT NULL,
   844  			b INT NULL
   845  		)
   846  		PARTITION BY LIST (a) (
   847  			PARTITION p0 VALUES IN(0,NULL),
   848  			PARTITION p1 VALUES IN( 1,2 ),
   849  			PARTITION p2 VALUES IN( 3,4 ),
   850  			PARTITION p3 VALUES IN( 5,6 )
   851  		);`,
   852  	}
   853  
   854  	mock := NewMockOptimizer(false)
   855  	for _, sql := range sqls {
   856  		t.Log(sql)
   857  		logicPlan, err := buildSingleStmt(mock, t, sql)
   858  		if err != nil {
   859  			t.Fatalf("%+v", err)
   860  		}
   861  		outPutPlan(logicPlan, true, t)
   862  	}
   863  }
   864  
   865  func TestListPartitionError(t *testing.T) {
   866  	sqls := []string{
   867  		`CREATE TABLE t1 (
   868  			id   INT,
   869  			name VARCHAR(35)
   870  		)
   871  		PARTITION BY LIST (id);`,
   872  
   873  		`CREATE TABLE t2 (
   874  			id   INT,
   875  			name VARCHAR(35)
   876  		)
   877           PARTITION BY LIST (id) (
   878  			PARTITION r0 VALUES IN (1, 5, 9, 13, 17, 21),
   879  			PARTITION r1 VALUES IN (2, 6, 10, 14, 18, 22),
   880  			PARTITION r2 VALUES IN (3, 7, 11, 15, 19, 23),
   881  			PARTITION r2 VALUES IN (4, 8, 12, 16, 20, 24)
   882  		);`,
   883  
   884  		`CREATE TABLE t1 (
   885  			id   INT PRIMARY KEY,
   886  			name VARCHAR(35),
   887  			age INT unsigned
   888  		)
   889  		PARTITION BY LIST (age) (
   890  			PARTITION r0 VALUES IN (1, 5, 9, 13, 17, 21),
   891  			PARTITION r1 VALUES IN (2, 6, 10, 14, 18, 22),
   892  			PARTITION r2 VALUES IN (3, 7, 11, 15, 19, 23),
   893  			PARTITION r3 VALUES IN (4, 8, 12, 16, 20, 24)
   894  		);`,
   895  
   896  		`CREATE TABLE lc (
   897  			a INT NULL,
   898  			b INT NULL
   899  		)
   900  		PARTITION BY LIST (a) (
   901  			PARTITION p0 VALUES IN(NULL,NULL),
   902  			PARTITION p1 VALUES IN( 1,2 ),
   903  			PARTITION p2 VALUES IN( 3,4 ),
   904  			PARTITION p3 VALUES IN( 5,6 )
   905  		);`,
   906  
   907  		`CREATE TABLE lc (
   908  			a INT NULL,
   909  			b INT NULL
   910  		)
   911  		PARTITION BY LIST (a) (
   912  			PARTITION p0 VALUES IN(NULL,NULL),
   913  			PARTITION p1 VALUES IN( 1,2 ),
   914  			PARTITION p2 VALUES IN( 3,1 ),
   915  			PARTITION p3 VALUES IN( 3,3 )
   916  		);`,
   917  
   918  		`CREATE TABLE lc (
   919  			a INT NULL,
   920  			b INT NULL
   921  		)
   922  		PARTITION BY LIST (a) (
   923  			PARTITION p0 VALUES IN(0,NULL),
   924  			PARTITION p1 VALUES IN( 1,2 ),
   925  			PARTITION p2 VALUES IN( 3,4 ),
   926  			PARTITION p3 VALUES LESS THAN (50,20)
   927  		);`,
   928  
   929  		`create table pt_table_50(
   930  			col1 tinyint,
   931  			col2 smallint,
   932  			col3 int,
   933  			col4 bigint,
   934  			col5 tinyint unsigned,
   935  			col6 smallint unsigned,
   936  			col7 int unsigned,
   937  			col8 bigint unsigned,
   938  			col9 float,
   939  			col10 double,
   940  			col11 varchar(255),
   941  			col12 Date,
   942  			col13 DateTime,
   943  			col14 timestamp,
   944  			col15 bool,
   945  			col16 decimal(5,2),
   946  			col17 text,
   947  			col18 varchar(255),
   948  			col19 varchar(255),
   949  			col20 text,
   950  			primary key(col4,col3,col11)
   951  			) partition by list(col3) (
   952  			PARTITION r0 VALUES IN (1, 5*2, 9, 13, 17-20, 21),
   953  			PARTITION r1 VALUES IN (2, 6, 10, 7, 18, 22),
   954  			PARTITION r2 VALUES IN (3, 7, 11+6, 15, 19, 23),
   955  			PARTITION r3 VALUES IN (4, 8, 12, 16, 20, 24)
   956  			);`,
   957  
   958  		`create table pt_table_50(
   959  			col1 tinyint,
   960  			col2 smallint,
   961  			col3 int,
   962  			col4 bigint,
   963  			col5 tinyint unsigned,
   964  			col6 smallint unsigned,
   965  			col7 int unsigned,
   966  			col8 bigint unsigned,
   967  			col9 float,
   968  			col10 double,
   969  			col11 varchar(255),
   970  			col12 Date,
   971  			col13 DateTime,
   972  			col14 timestamp,
   973  			col15 bool,
   974  			col16 decimal(5,2),
   975  			col17 text,
   976  			col18 varchar(255),
   977  			col19 varchar(255),
   978  			col20 text,
   979  			primary key(col4,col3,col11)
   980  			) partition by list(col3) (
   981  			PARTITION r0 VALUES IN (1, 5*2, 9, 13, 17-20, 21),
   982  			PARTITION r1 VALUES IN (2, 6, 10, 14/2, 18, 22),
   983  			PARTITION r2 VALUES IN (3, 7, 11+6, 15, 19, 23),
   984  			PARTITION r3 VALUES IN (4, 8, 12, 16, 20, 24)
   985  			);`,
   986  	}
   987  
   988  	mock := NewMockOptimizer(false)
   989  	for _, sql := range sqls {
   990  		_, err := buildSingleStmt(mock, t, sql)
   991  		t.Log(sql)
   992  		t.Log(err)
   993  		if err == nil {
   994  			t.Fatalf("%+v", err)
   995  		}
   996  	}
   997  }
   998  
   999  // -----------------------List Columns Partition--------------------------------------
  1000  func TestListColumnsPartition(t *testing.T) {
  1001  	sqls := []string{
  1002  		`CREATE TABLE lc (
  1003  				a INT NULL,
  1004  				b INT NULL
  1005  			)
  1006  			PARTITION BY LIST COLUMNS(a,b) (
  1007  				PARTITION p0 VALUES IN( (0,0), (NULL,NULL) ),
  1008  				PARTITION p1 VALUES IN( (0,1), (0,2), (0,3), (1,1), (1,2) ),
  1009  				PARTITION p2 VALUES IN( (1,0), (2,0), (2,1), (3,0), (3,1) ),
  1010  				PARTITION p3 VALUES IN( (1,3), (2,2), (2,3), (3,2), (3,3) )
  1011  			);`,
  1012  
  1013  		`CREATE TABLE customers_1 (
  1014  			first_name VARCHAR(25),
  1015  			last_name VARCHAR(25),
  1016  			street_1 VARCHAR(30),
  1017  			street_2 VARCHAR(30),
  1018  			city VARCHAR(15),
  1019  			renewal DATE
  1020  		)
  1021  			PARTITION BY LIST COLUMNS(city) (
  1022  			PARTITION pRegion_1 VALUES IN('Oskarshamn', 'Högsby', 'Mönsterås'),
  1023  			PARTITION pRegion_2 VALUES IN('Vimmerby', 'Hultsfred', 'Västervik'),
  1024  			PARTITION pRegion_3 VALUES IN('Nässjö', 'Eksjö', 'Vetlanda'),
  1025  			PARTITION pRegion_4 VALUES IN('Uppvidinge', 'Alvesta', 'Växjo')
  1026  		);`,
  1027  
  1028  		`CREATE TABLE customers_2 (
  1029  			first_name VARCHAR(25),
  1030  			last_name VARCHAR(25),
  1031  			street_1 VARCHAR(30),
  1032  			street_2 VARCHAR(30),
  1033  			city VARCHAR(15),
  1034  			renewal DATE
  1035  		)
  1036  		PARTITION BY LIST COLUMNS(renewal) (
  1037  			PARTITION pWeek_1 VALUES IN('2010-02-01', '2010-02-02', '2010-02-03',
  1038  				'2010-02-04', '2010-02-05', '2010-02-06', '2010-02-07'),
  1039  			PARTITION pWeek_2 VALUES IN('2010-02-08', '2010-02-09', '2010-02-10',
  1040  				'2010-02-11', '2010-02-12', '2010-02-13', '2010-02-14'),
  1041  			PARTITION pWeek_3 VALUES IN('2010-02-15', '2010-02-16', '2010-02-17',
  1042  				'2010-02-18', '2010-02-19', '2010-02-20', '2010-02-21'),
  1043  			PARTITION pWeek_4 VALUES IN('2010-02-22', '2010-02-23', '2010-02-24',
  1044  				'2010-02-25', '2010-02-26', '2010-02-27', '2010-02-28')
  1045  		);`,
  1046  
  1047  		`CREATE TABLE lc (
  1048  			a INT NULL,
  1049  			b INT NULL
  1050  		)
  1051  		PARTITION BY LIST COLUMNS(a,b) PARTITIONS 4 (
  1052  			PARTITION p0 VALUES IN( (0,0), (NULL,NULL) ),
  1053  			PARTITION p1 VALUES IN( (0,1), (0,2), (0,3), (1,1), (1,2) ),
  1054  			PARTITION p2 VALUES IN( (1,0), (2,0), (2,1), (3,0), (3,1) ),
  1055  			PARTITION p3 VALUES IN( (1,3), (2,2), (2,3), (3,2), (3,3) )
  1056  		);`,
  1057  
  1058  		`CREATE TABLE lc (
  1059  				a INT NULL,
  1060  				b INT NULL
  1061  			)
  1062  			PARTITION BY LIST COLUMNS(a,b) (
  1063  				PARTITION p0 VALUES IN( (0,0), (NULL,NULL) ),
  1064  				PARTITION p1 VALUES IN( (0,1), (0,2) ),
  1065  				PARTITION p2 VALUES IN( (1,0), (2,0) )
  1066  			);`,
  1067  	}
  1068  
  1069  	mock := NewMockOptimizer(false)
  1070  	for _, sql := range sqls {
  1071  		t.Log(sql)
  1072  		logicPlan, err := buildSingleStmt(mock, t, sql)
  1073  		if err != nil {
  1074  			t.Fatalf("%+v", err)
  1075  		}
  1076  		outPutPlan(logicPlan, true, t)
  1077  	}
  1078  }
  1079  
  1080  func TestListColumnsPartitionError(t *testing.T) {
  1081  	sqls := []string{
  1082  		`CREATE TABLE t1 (
  1083  			a INT NULL,
  1084  			b INT NULL
  1085  		)
  1086  		PARTITION BY LIST COLUMNS(a,b);`,
  1087  
  1088  		`CREATE TABLE t2 (
  1089  			a INT NULL,
  1090  			b INT NULL
  1091  		)
  1092  		PARTITION BY LIST COLUMNS(a,b) (
  1093  			PARTITION p0 VALUES IN( (0,0), (NULL,NULL) ),
  1094  			PARTITION p1 VALUES IN( (0,1), (0,2), (0,3), (1,1), (1,2) ),
  1095  			PARTITION p2 VALUES IN( (1,0), (2,0), (2,1), (3,0), (3,1) ),
  1096  			PARTITION p2 VALUES IN( (1,3), (2,2), (2,3), (3,2), (3,3) )
  1097  		);`,
  1098  
  1099  		`CREATE TABLE lc (
  1100  			a INT NULL,
  1101  			b INT NULL
  1102  		)
  1103  		PARTITION BY LIST COLUMNS(a,b) PARTITIONS 5 (
  1104  			PARTITION p0 VALUES IN( (0,0), (NULL,NULL) ),
  1105  			PARTITION p1 VALUES IN( (0,1), (0,2), (0,3), (1,1), (1,2) ),
  1106  			PARTITION p2 VALUES IN( (1,0), (2,0), (2,1), (3,0), (3,1) ),
  1107  			PARTITION p3 VALUES IN( (1,3), (2,2), (2,3), (3,2), (3,3) )
  1108  		);`,
  1109  	}
  1110  
  1111  	mock := NewMockOptimizer(false)
  1112  	for _, sql := range sqls {
  1113  		_, err := buildSingleStmt(mock, t, sql)
  1114  		t.Log(sql)
  1115  		t.Log(err)
  1116  		if err == nil {
  1117  			t.Fatalf("%+v", err)
  1118  		}
  1119  	}
  1120  }
  1121  
  1122  func TestPartitioningKeysUniqueKeys(t *testing.T) {
  1123  	sqls := []string{
  1124  		`CREATE TABLE t1 (
  1125  			col1 INT  NOT NULL,
  1126  			col2 DATE NOT NULL,
  1127  			col3 INT NOT NULL,
  1128  			col4 INT NOT NULL,
  1129  			UNIQUE KEY (col1, col2)
  1130  		)
  1131  		PARTITION BY KEY()
  1132  		PARTITIONS 4;`,
  1133  
  1134  		`CREATE TABLE t1 (
  1135  				col1 INT NOT NULL,
  1136  				col2 DATE NOT NULL,
  1137  				col3 INT NOT NULL,
  1138  				col4 INT NOT NULL,
  1139  				UNIQUE KEY (col1, col2, col3)
  1140  			)
  1141  			PARTITION BY HASH(col3)
  1142  			PARTITIONS 4;`,
  1143  
  1144  		`CREATE TABLE t2 (
  1145  				col1 INT NOT NULL,
  1146  				col2 DATE NOT NULL,
  1147  				col3 INT NOT NULL,
  1148  				col4 INT NOT NULL,
  1149  				UNIQUE KEY (col1, col3)
  1150  			)
  1151  			PARTITION BY HASH(col1 + col3)
  1152  			PARTITIONS 4;`,
  1153  
  1154  		`CREATE TABLE t1 (
  1155  			col1 INT NOT NULL,
  1156  			col2 DATE NOT NULL,
  1157  			col3 INT NOT NULL,
  1158  			col4 INT NOT NULL,
  1159  			UNIQUE KEY (col1, col2, col3)
  1160  		)
  1161  			PARTITION BY KEY(col3)
  1162  			PARTITIONS 4;`,
  1163  
  1164  		`CREATE TABLE t2 (
  1165  			col1 INT NOT NULL,
  1166  			col2 DATE NOT NULL,
  1167  			col3 INT NOT NULL,
  1168  			col4 INT NOT NULL,
  1169  			UNIQUE KEY (col1, col3)
  1170  		)
  1171  			PARTITION BY KEY(col1,col3)
  1172  			PARTITIONS 4;`,
  1173  
  1174  		`CREATE TABLE t3 (
  1175  			col1 INT NOT NULL,
  1176  			col2 DATE NOT NULL,
  1177  			col3 INT NOT NULL,
  1178  			col4 INT NOT NULL,
  1179  			UNIQUE KEY (col1, col2, col3),
  1180  			UNIQUE KEY (col3)
  1181  		)
  1182  			PARTITION BY HASH(col3)
  1183  			PARTITIONS 4;`,
  1184  
  1185  		`CREATE TABLE t3 (
  1186  			col1 INT NOT NULL,
  1187  			col2 DATE NOT NULL,
  1188  			col3 INT NOT NULL,
  1189  			col4 INT NOT NULL,
  1190  			UNIQUE KEY (col1, col2, col3),
  1191  			UNIQUE KEY (col3)
  1192  		)
  1193  			PARTITION BY KEY(col3)
  1194  			PARTITIONS 4;`,
  1195  
  1196  		`CREATE TABLE t4 (
  1197  			col1 INT NOT NULL,
  1198  			col2 DATE NOT NULL,
  1199  			col3 INT NOT NULL UNIQUE,
  1200  			col4 INT NOT NULL
  1201  		)
  1202  			PARTITION BY KEY(col3)
  1203  			PARTITIONS 4;`,
  1204  	}
  1205  
  1206  	mock := NewMockOptimizer(false)
  1207  	for _, sql := range sqls {
  1208  		t.Log(sql)
  1209  		logicPlan, err := buildSingleStmt(mock, t, sql)
  1210  		if err != nil {
  1211  			t.Fatalf("%+v", err)
  1212  		}
  1213  		outPutPlan(logicPlan, true, t)
  1214  	}
  1215  }
  1216  
  1217  func TestPartitioningKeysUniqueKeysError(t *testing.T) {
  1218  	sqls := []string{
  1219  		`CREATE TABLE t1 (
  1220  			col1 INT NOT NULL,
  1221  			col2 DATE NOT NULL,
  1222  			col3 INT NOT NULL,
  1223  			col4 INT NOT NULL,
  1224  			UNIQUE KEY (col1, col2)
  1225  		)
  1226  		PARTITION BY HASH(col3)
  1227  		PARTITIONS 4;`,
  1228  
  1229  		`CREATE TABLE t2 (
  1230  			col1 INT NOT NULL,
  1231  			col2 DATE NOT NULL,
  1232  			col3 INT NOT NULL,
  1233  			col4 INT NOT NULL,
  1234  			UNIQUE KEY (col1),
  1235  			UNIQUE KEY (col3)
  1236  		)
  1237  		PARTITION BY HASH(col1 + col3)
  1238  		PARTITIONS 4;`,
  1239  
  1240  		`CREATE TABLE t1 (
  1241  			col1 INT UNIQUE NOT NULL,
  1242  			col2 DATE NOT NULL,
  1243  			col3 INT NOT NULL,
  1244  			col4 INT NOT NULL
  1245  		)
  1246  		PARTITION BY HASH(col3)
  1247  		PARTITIONS 4;`,
  1248  
  1249  		`CREATE TABLE t2 (
  1250  			col1 INT NOT NULL,
  1251  			col2 DATE NOT NULL,
  1252  			col3 INT NOT NULL,
  1253  			col4 INT NOT NULL,
  1254  			UNIQUE KEY (col1),
  1255  			UNIQUE KEY (col3)
  1256  		)
  1257  		PARTITION BY KEY(col1,col3)
  1258  		PARTITIONS 4;`,
  1259  
  1260  		`CREATE TABLE t3 (
  1261  			col1 INT NOT NULL,
  1262  			col2 DATE NOT NULL,
  1263  			col3 INT NOT NULL,
  1264  			col4 INT NOT NULL,
  1265  			UNIQUE KEY (col1, col2),
  1266  			UNIQUE KEY (col3)
  1267  		)
  1268  			PARTITION BY HASH(col1 + col3)
  1269  			PARTITIONS 4;`,
  1270  
  1271  		`CREATE TABLE t3 (
  1272  			col1 INT NOT NULL,
  1273  			col2 DATE NOT NULL,
  1274  			col3 INT NOT NULL,
  1275  			col4 INT NOT NULL,
  1276  			UNIQUE KEY (col1, col2),
  1277  			UNIQUE KEY (col3)
  1278  		)
  1279  			PARTITION BY KEY(col1, col3)
  1280  			PARTITIONS 4;`,
  1281  		// should show error:Field in list of fields for partition function not found in table
  1282  		`CREATE TABLE k1 (
  1283  			id INT NOT NULL,
  1284  			name VARCHAR(20),
  1285  			sal DOUBLE
  1286  		)
  1287  		PARTITION BY KEY()
  1288  		PARTITIONS 2;`,
  1289  
  1290  		`CREATE TABLE t6 (
  1291  		col1 INT NOT NULL,
  1292  		col2 DATE NOT NULL,
  1293  		col3 INT NOT NULL UNIQUE,
  1294  		col4 INT NOT NULL
  1295  	   )
  1296  		PARTITION BY KEY(col1)
  1297  		PARTITIONS 4;`,
  1298  
  1299  		`CREATE TABLE t7 (
  1300  		col1 INT NOT NULL,
  1301  		col2 DATE NOT NULL,
  1302  		col3 INT NOT NULL UNIQUE,
  1303  		col4 INT NOT NULL
  1304  	   )
  1305  		PARTITION BY HASH(col4)
  1306  		PARTITIONS 4;`,
  1307  	}
  1308  
  1309  	mock := NewMockOptimizer(false)
  1310  	for _, sql := range sqls {
  1311  		_, err := buildSingleStmt(mock, t, sql)
  1312  		t.Log(sql)
  1313  		t.Log(err)
  1314  		if err == nil {
  1315  			t.Fatalf("%+v", err)
  1316  		}
  1317  	}
  1318  }
  1319  
  1320  func TestPartitioningKeysPrimaryKeys(t *testing.T) {
  1321  	sqls := []string{
  1322  		`CREATE TABLE t7 (
  1323  			col1 INT NOT NULL,
  1324  			col2 DATE NOT NULL,
  1325  			col3 INT NOT NULL,
  1326  			col4 INT NOT NULL,
  1327  			PRIMARY KEY(col1, col2)
  1328  		)
  1329  		PARTITION BY HASH(col1 + YEAR(col2))
  1330  		PARTITIONS 4;`,
  1331  
  1332  		`CREATE TABLE t8 (
  1333  			col1 INT NOT NULL,
  1334  			col2 DATE NOT NULL,
  1335  			col3 INT NOT NULL,
  1336  			col4 INT NOT NULL,
  1337  			PRIMARY KEY(col1, col2, col4),
  1338  			UNIQUE KEY(col2, col1)
  1339  		)
  1340  		PARTITION BY HASH(col1 + YEAR(col2))
  1341  		PARTITIONS 4;`,
  1342  
  1343  		`CREATE TABLE t7 (
  1344  			col1 INT NOT NULL,
  1345  			col2 DATE NOT NULL,
  1346  			col3 INT NOT NULL,
  1347  			col4 INT NOT NULL,
  1348  			PRIMARY KEY(col1, col2)
  1349  		)
  1350  		PARTITION BY KEY(col1,col2)
  1351  		PARTITIONS 4;`,
  1352  
  1353  		`CREATE TABLE t8 (
  1354  			col1 INT NOT NULL,
  1355  			col2 DATE NOT NULL,
  1356  			col3 INT NOT NULL,
  1357  			col4 INT NOT NULL,
  1358  			PRIMARY KEY(col1, col2, col4),
  1359  			UNIQUE KEY(col2, col1)
  1360  		)
  1361  		PARTITION BY KEY(col1,col2)
  1362  		PARTITIONS 4;`,
  1363  
  1364  		`CREATE TABLE k1 (
  1365  			id INT NOT NULL,
  1366  			name VARCHAR(20),
  1367  			sal DOUBLE,
  1368  			PRIMARY KEY (id, name),
  1369  			unique key (id)
  1370  		)
  1371  		PARTITION BY KEY(id)
  1372  		PARTITIONS 2;`,
  1373  	}
  1374  
  1375  	mock := NewMockOptimizer(false)
  1376  	for _, sql := range sqls {
  1377  		t.Log(sql)
  1378  		logicPlan, err := buildSingleStmt(mock, t, sql)
  1379  		if err != nil {
  1380  			t.Fatalf("%+v", err)
  1381  		}
  1382  		outPutPlan(logicPlan, true, t)
  1383  	}
  1384  }
  1385  
  1386  func TestPartitioningKeysPrimaryKeysError(t *testing.T) {
  1387  	sqls := []string{
  1388  		`CREATE TABLE t5 (
  1389  			col1 INT NOT NULL,
  1390  			col2 DATE NOT NULL,
  1391  			col3 INT NOT NULL,
  1392  			col4 INT NOT NULL,
  1393  			PRIMARY KEY(col1, col2)
  1394  		)
  1395  		PARTITION BY HASH(col3)
  1396  		PARTITIONS 4;`,
  1397  
  1398  		`CREATE TABLE t6 (
  1399  			col1 INT NOT NULL,
  1400  			col2 DATE NOT NULL,
  1401  			col3 INT NOT NULL,
  1402  			col4 INT NOT NULL,
  1403  			PRIMARY KEY(col1, col3),
  1404  			UNIQUE KEY(col2)
  1405  		)
  1406  		PARTITION BY HASH( YEAR(col2) )
  1407  		PARTITIONS 4;`,
  1408  
  1409  		`CREATE TABLE t5 (
  1410  			col1 INT NOT NULL,
  1411  			col2 DATE NOT NULL,
  1412  			col3 INT NOT NULL,
  1413  			col4 INT NOT NULL,
  1414  			PRIMARY KEY(col1, col2)
  1415  		)
  1416  		PARTITION BY KEY(col3)
  1417  		PARTITIONS 4;`,
  1418  
  1419  		`CREATE TABLE t6 (
  1420  			col1 INT NOT NULL,
  1421  			col2 DATE NOT NULL,
  1422  			col3 INT NOT NULL,
  1423  			col4 INT NOT NULL,
  1424  			PRIMARY KEY(col1, col3),
  1425  			UNIQUE KEY(col2)
  1426  		)
  1427  		PARTITION BY KEY(col2)
  1428  		PARTITIONS 4;`,
  1429  	}
  1430  
  1431  	mock := NewMockOptimizer(false)
  1432  	for _, sql := range sqls {
  1433  		_, err := buildSingleStmt(mock, t, sql)
  1434  		t.Log(sql)
  1435  		t.Log(err)
  1436  		if err == nil {
  1437  			t.Fatalf("%+v", err)
  1438  		}
  1439  	}
  1440  }
  1441  
  1442  // A UNIQUE INDEX must include all columns in the table's partitioning function
  1443  func TestPartitionKeysShouldShowError(t *testing.T) {
  1444  	sqls := []string{
  1445  		`CREATE TABLE t4 (
  1446  				col1 INT NOT NULL,
  1447  				col2 INT NOT NULL,
  1448  				col3 INT NOT NULL,
  1449  				col4 INT NOT NULL,
  1450  				UNIQUE KEY (col1, col3),
  1451  				UNIQUE KEY (col2, col4)
  1452  			)
  1453  			PARTITION BY KEY(col1, col3)
  1454  			PARTITIONS 2;`,
  1455  
  1456  		`CREATE TABLE t4 (
  1457  				col1 INT NOT NULL,
  1458  				col2 INT NOT NULL,
  1459  				col3 INT NOT NULL,
  1460  				col4 INT NOT NULL,
  1461  				UNIQUE KEY (col1, col3),
  1462  				UNIQUE KEY (col2, col4)
  1463  			)
  1464  			PARTITION BY HASH(col1 + col3)
  1465  			PARTITIONS 2;`,
  1466  
  1467  		`CREATE TABLE t4 (
  1468  				col1 INT NOT NULL,
  1469  				col2 INT NOT NULL,
  1470  				col3 INT NOT NULL,
  1471  				col4 INT NOT NULL,
  1472  				UNIQUE KEY (col1, col3),
  1473  				UNIQUE KEY (col2, col4)
  1474  			)
  1475  			PARTITION BY RANGE (col1 + col3) (
  1476  			PARTITION p0 VALUES LESS THAN (6),
  1477  			PARTITION p1 VALUES LESS THAN (11),
  1478  			PARTITION p2 VALUES LESS THAN (16),
  1479  			PARTITION p3 VALUES LESS THAN (21)
  1480  			);`,
  1481  
  1482  		`CREATE TABLE t4 (
  1483  				col1 INT NOT NULL,
  1484  				col2 INT NOT NULL,
  1485  				col3 INT NOT NULL,
  1486  				col4 INT NOT NULL,
  1487  				UNIQUE KEY (col1, col3),
  1488  				UNIQUE KEY (col2, col4)
  1489  			)
  1490  			PARTITION BY RANGE COLUMNS(col1, col3) PARTITIONS 4 (
  1491  			PARTITION p0 VALUES LESS THAN (10,5),
  1492  			PARTITION p1 VALUES LESS THAN (20,10),
  1493  			PARTITION p2 VALUES LESS THAN (50,20),
  1494  			PARTITION p3 VALUES LESS THAN (65,30)
  1495  			);`,
  1496  
  1497  		`CREATE TABLE t4 (
  1498  				col1 INT NOT NULL,
  1499  				col2 INT NOT NULL,
  1500  				col3 INT NOT NULL,
  1501  				col4 INT NOT NULL,
  1502  				UNIQUE KEY (col1),
  1503  				UNIQUE KEY (col2, col4)
  1504  			)
  1505  			PARTITION BY LIST (col1) (
  1506  			PARTITION r0 VALUES IN (1, 5, 9, 13, 17, 21),
  1507  			PARTITION r1 VALUES IN (2, 6, 10, 14, 18, 22),
  1508  			PARTITION r2 VALUES IN (3, 7, 11, 15, 19, 23),
  1509  			PARTITION r3 VALUES IN (4, 8, 12, 16, 20, 24)
  1510  			);`,
  1511  
  1512  		`CREATE TABLE t4 (
  1513  				col1 INT NOT NULL,
  1514  				col2 INT NOT NULL,
  1515  				col3 INT NOT NULL,
  1516  				col4 INT NOT NULL,
  1517  				UNIQUE KEY (col1, col3),
  1518  				UNIQUE KEY (col2, col4)
  1519  			)
  1520  			PARTITION BY LIST COLUMNS(col1, col3) (
  1521  			PARTITION p0 VALUES IN( (0,0), (NULL,NULL) ),
  1522  			PARTITION p1 VALUES IN( (0,1), (0,2), (0,3), (1,1), (1,2) ),
  1523  			PARTITION p2 VALUES IN( (1,0), (2,0), (2,1), (3,0), (3,1) ),
  1524  			PARTITION p3 VALUES IN( (1,3), (2,2), (2,3), (3,2), (3,3) )
  1525  			);`,
  1526  	}
  1527  	mock := NewMockOptimizer(false)
  1528  	for _, sql := range sqls {
  1529  		_, err := buildSingleStmt(mock, t, sql)
  1530  		t.Log(sql)
  1531  		t.Log(err)
  1532  		if err == nil {
  1533  			t.Fatalf("%+v", err)
  1534  		}
  1535  	}
  1536  }
  1537  
  1538  func TestListPartitionFunction(t *testing.T) {
  1539  	sqls := []string{
  1540  		`CREATE TABLE lc (
  1541  			a INT NULL,
  1542  			b INT NULL
  1543  		)
  1544  		PARTITION BY LIST COLUMNS(a,b) (
  1545  			PARTITION p0 VALUES IN( (0,0), (NULL,NULL) ),
  1546  			PARTITION p1 VALUES IN( (0,1), (0,4+2) ),
  1547  			PARTITION p2 VALUES IN( (1,0), (2,0) )
  1548  		);`,
  1549  
  1550  		`CREATE TABLE lc (
  1551  			a INT NULL,
  1552  			b INT NULL
  1553  		)
  1554  		PARTITION BY LIST(a) (
  1555  			PARTITION p0 VALUES IN(0, NULL ),
  1556  			PARTITION p1 VALUES IN(1, 2),
  1557  			PARTITION p2 VALUES IN(3, 4)
  1558  		);`,
  1559  
  1560  		`CREATE TABLE lc (
  1561  			a INT NULL,
  1562  			b INT NULL
  1563  		)
  1564  		PARTITION BY LIST COLUMNS(b) (
  1565  			PARTITION p0 VALUES IN( 0,NULL ),
  1566  			PARTITION p1 VALUES IN( 1,2 ),
  1567  			PARTITION p2 VALUES IN( 3,4 )
  1568  		);`,
  1569  
  1570  		`CREATE TABLE lc (
  1571  			a INT NULL,
  1572  			b INT NULL
  1573  		)
  1574  		PARTITION BY LIST COLUMNS(b) (
  1575  			PARTITION p0 VALUES IN( 0,NULL ),
  1576  			PARTITION p1 VALUES IN( 1,1+1 ),
  1577  			PARTITION p2 VALUES IN( 3,4 )
  1578  		);`,
  1579  	}
  1580  
  1581  	mock := NewMockOptimizer(false)
  1582  	for _, sql := range sqls {
  1583  		t.Log(sql)
  1584  		logicPlan, err := buildSingleStmt(mock, t, sql)
  1585  		if err != nil {
  1586  			t.Fatalf("%+v", err)
  1587  		}
  1588  		outPutPlan(logicPlan, true, t)
  1589  	}
  1590  }
  1591  
  1592  func TestListPartitionFunctionError(t *testing.T) {
  1593  	sqls := []string{
  1594  		`create table pt_table_45(
  1595  			col1 tinyint,
  1596  			col2 smallint,
  1597  			col3 int,
  1598  			col4 bigint,
  1599  			col5 tinyint unsigned,
  1600  			col6 smallint unsigned,
  1601  			col7 int unsigned,
  1602  			col8 bigint unsigned,
  1603  			col9 float,
  1604  			col10 double,
  1605  			col11 varchar(255),
  1606  			col12 Date,
  1607  			col13 DateTime,
  1608  			col14 timestamp,
  1609  			col15 bool,
  1610  			col16 decimal(5,2),
  1611  			col17 text,
  1612  			col18 varchar(255),
  1613  			col19 varchar(255),
  1614  			col20 text,
  1615  			primary key(col4,col3,col11))
  1616  		partition by list(col3) (
  1617  			PARTITION r0 VALUES IN (1, 5*2, 9, 13, 17-20, 21),
  1618  			PARTITION r1 VALUES IN (2, 6, 10, 14/2, 18, 22),
  1619  			PARTITION r2 VALUES IN (3, 7, 11+6, 15, 19, 23),
  1620  			PARTITION r3 VALUES IN (4, 8, 12, 16, 20, 24)
  1621  		);`,
  1622  
  1623  		`CREATE TABLE lc (
  1624  			a INT NULL,
  1625  			b INT NULL
  1626  		)
  1627  		PARTITION BY LIST COLUMNS(a,b) (
  1628  			PARTITION p0 VALUES IN( (0,0), (NULL,NULL) ),
  1629  			PARTITION p1 VALUES IN( (0,1), (0,4/2) ),
  1630  			PARTITION p2 VALUES IN( (1,0), (2,0) )
  1631  		);`,
  1632  
  1633  		`CREATE TABLE lc (
  1634  			a INT NULL,
  1635  			b INT NULL
  1636  		)
  1637  		PARTITION BY LIST COLUMNS(a,b) (
  1638  			PARTITION p0 VALUES IN( (0,0), (NULL,NULL) ),
  1639  			PARTITION p1 VALUES IN( (0,1), (0,4.2) ),
  1640  			PARTITION p2 VALUES IN( (1,0), (2,0) )
  1641  		);`,
  1642  
  1643  		`CREATE TABLE lc (
  1644  			a INT NULL,
  1645  			b INT NULL
  1646  		)
  1647  		PARTITION BY LIST COLUMNS(a,b) (
  1648  			PARTITION p0 VALUES IN( 0,NULL ),
  1649  			PARTITION p1 VALUES IN( 0,1 ),
  1650  			PARTITION p2 VALUES IN( 1,0 )
  1651  		);`,
  1652  
  1653  		`CREATE TABLE lc (
  1654  			a INT NULL,
  1655  			b INT NULL
  1656  		)
  1657  		PARTITION BY LIST(a) (
  1658  			PARTITION p0 VALUES IN(0, NULL ),
  1659  			PARTITION p1 VALUES IN(1, 4/2),
  1660  			PARTITION p2 VALUES IN(3, 4)
  1661  		);`,
  1662  
  1663  		`CREATE TABLE lc (
  1664  			a INT NULL,
  1665  			b INT NULL
  1666  		)
  1667  		PARTITION BY LIST COLUMNS(b) (
  1668  			PARTITION p0 VALUES IN( 0,NULL ),
  1669  			PARTITION p1 VALUES IN( 1,4/2 ),
  1670  			PARTITION p2 VALUES IN( 3,4 )
  1671  		);`,
  1672  
  1673  		`CREATE TABLE lc (
  1674  			a INT NULL,
  1675  			b INT NULL
  1676  		)
  1677  		PARTITION BY LIST COLUMNS(a,b) (
  1678  			PARTITION p0 VALUES IN( (0,0), (NULL,NULL) ),
  1679  			PARTITION p1 VALUES IN( (0,1,3), (0,4,5) ),
  1680  			PARTITION p2 VALUES IN( (1,0), (2,0) )
  1681  		);`,
  1682  	}
  1683  
  1684  	mock := NewMockOptimizer(false)
  1685  	for _, sql := range sqls {
  1686  		_, err := buildSingleStmt(mock, t, sql)
  1687  		t.Log(sql)
  1688  		t.Log(err)
  1689  		if err == nil {
  1690  			t.Fatalf("%+v", err)
  1691  		}
  1692  	}
  1693  }
  1694  
  1695  func TestRangePartitionFunctionError(t *testing.T) {
  1696  	sqls := []string{
  1697  		`CREATE TABLE r1 (
  1698  			a INT,
  1699  			b INT
  1700  		)
  1701  		PARTITION BY RANGE (a) (
  1702  			PARTITION p0 VALUES LESS THAN (5/2),
  1703  			PARTITION p1 VALUES LESS THAN (MAXVALUE)
  1704  		);`,
  1705  
  1706  		`CREATE TABLE r1 (
  1707  			a INT,
  1708  			b INT
  1709  		)
  1710  		PARTITION BY RANGE (a) (
  1711  			PARTITION p0 VALUES LESS THAN (5.2),
  1712  			PARTITION p1 VALUES LESS THAN (12)
  1713  		);`,
  1714  
  1715  		`CREATE TABLE r1 (
  1716  			a INT,
  1717  			b FLOAT
  1718  		)
  1719  		PARTITION BY RANGE (b) (
  1720  			PARTITION p0 VALUES LESS THAN (12),
  1721  			PARTITION p1 VALUES LESS THAN (MAXVALUE)
  1722  		);`,
  1723  		//`create TABLE t1 (
  1724  		//	col1 int,
  1725  		//	col2 float
  1726  		//)
  1727  		//partition by range( case when col1 > 0 then 10 else 20 end ) (
  1728  		//	partition p0 values less than (2),
  1729  		//	partition p1 values less than (6)
  1730  		//);`,
  1731  	}
  1732  	mock := NewMockOptimizer(false)
  1733  	for _, sql := range sqls {
  1734  		_, err := buildSingleStmt(mock, t, sql)
  1735  		t.Log(sql)
  1736  		t.Log(err)
  1737  		if err == nil {
  1738  			t.Fatalf("%+v", err)
  1739  		}
  1740  	}
  1741  }
  1742  
  1743  func buildSingleStmt(opt Optimizer, t *testing.T, sql string) (*Plan, error) {
  1744  	statements, err := mysql.Parse(opt.CurrentContext().GetContext(), sql)
  1745  	if err != nil {
  1746  		return nil, err
  1747  	}
  1748  	// this sql always return single statement
  1749  	context := opt.CurrentContext()
  1750  	plan, err := BuildPlan(context, statements[0])
  1751  	if plan != nil {
  1752  		testDeepCopy(plan)
  1753  	}
  1754  	return plan, err
  1755  }