github.com/matrixorigin/matrixone@v1.2.0/pkg/sql/plan/partition_list_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  	"github.com/matrixorigin/matrixone/pkg/common/moerr"
    19  	"github.com/stretchr/testify/require"
    20  	"testing"
    21  )
    22  
    23  func TestCreateListPartitionTable(t *testing.T) {
    24  	//sql := `CREATE TABLE w_videos_partition (
    25  	//		  id bigint(20) NOT NULL AUTO_INCREMENT,
    26  	//		  create_time char(12) NOT NULL DEFAULT '' COMMENT '创建时间戳',
    27  	//		  created_at datetime NOT NULL COMMENT '创建时间',
    28  	//		  updated_at datetime DEFAULT NULL COMMENT '更新时间',
    29  	//		  content text,
    30  	//		  event_start char(12) NOT NULL DEFAULT '' COMMENT '事件开始时间戳',
    31  	//		  event_end char(12) NOT NULL DEFAULT '' COMMENT '事件结束时间戳',
    32  	//		  msg_id varchar(32) NOT NULL DEFAULT '',
    33  	//		  event_id varchar(32) NOT NULL DEFAULT '',
    34  	//		  accept tinyint(4) NOT NULL DEFAULT '0',
    35  	//		  PRIMARY KEY (id,created_at)
    36  	//		)
    37  	//		PARTITION BY LIST ((TO_DAYS(created_at)*24 + HOUR(created_at)) % (7*24))(
    38  	//		 PARTITION hour0 VALUES IN (0),
    39  	//		 PARTITION hour1 VALUES IN (1),
    40  	//		 PARTITION hour2 VALUES IN (2),
    41  	//		 PARTITION hour3 VALUES IN (3),
    42  	//		 PARTITION hour4 VALUES IN (4)
    43  	//		);`
    44  
    45  	//sql := `CREATE TABLE t2 (
    46  	//		id   INT,
    47  	//		name VARCHAR(35)
    48  	//	)
    49  	//    PARTITION BY LIST (id) (
    50  	//		PARTITION r0 VALUES IN (1, 5, 9, 13, 17, 21),
    51  	//		PARTITION r1 VALUES IN (2, 6, 10, 14, 18, 22),
    52  	//		PARTITION r2 VALUES IN (3, 7, 11, 15, 19, 23),
    53  	//		PARTITION r3 VALUES IN (4, 8, 12, 16, 20, 24)
    54  	//	);`
    55  	//sql := `CREATE TABLE lc (
    56  	//			a INT NULL,
    57  	//			b INT NULL
    58  	//		)
    59  	//		PARTITION BY LIST COLUMNS(a,b) (
    60  	//			PARTITION p0 VALUES IN( (0,0), (NULL,NULL) ),
    61  	//			PARTITION p1 VALUES IN( (0,1), (0,2), (0,3), (1,1), (1,2) ),
    62  	//			PARTITION p2 VALUES IN( (1,0), (2,0), (2,1), (3,0), (3,1) ),
    63  	//			PARTITION p3 VALUES IN( (1,3), (2,2), (2,3), (3,2), (3,3) )
    64  	//		);`
    65  
    66  	sql := `CREATE TABLE lc (
    67  				a INT NULL,
    68  				b INT NULL
    69  			)
    70  			PARTITION BY LIST COLUMNS(a) (
    71  				PARTITION p0 VALUES IN( -1, NULL),
    72  				PARTITION p1 VALUES IN( 0, 1),
    73  				PARTITION p2 VALUES IN( 2, 3),
    74  				PARTITION p3 VALUES IN( 4, 5)
    75  			);`
    76  
    77  	mock := NewMockOptimizer(false)
    78  	logicPlan, err := buildSingleStmt(mock, t, sql)
    79  	if err != nil {
    80  		t.Fatalf("%+v", err)
    81  	}
    82  	outPutPlan(logicPlan, true, t)
    83  }
    84  
    85  // -----------------------List Partition--------------------------------------
    86  func TestListPartition(t *testing.T) {
    87  	sqls := []string{
    88  		`CREATE TABLE client_firms (
    89  			id   INT,
    90  			name VARCHAR(35)
    91  		)
    92  		PARTITION BY LIST (id) (
    93  			PARTITION r0 VALUES IN (1, 5, 9, 13, 17, 21),
    94  			PARTITION r1 VALUES IN (2, 6, 10, 14, 18, 22),
    95  			PARTITION r2 VALUES IN (3, 7, 11, 15, 19, 23),
    96  			PARTITION r3 VALUES IN (4, 8, 12, 16, 20, 24)
    97  		);`,
    98  
    99  		`CREATE TABLE employees (
   100  			id INT NOT NULL,
   101  			fname VARCHAR(30),
   102  			lname VARCHAR(30),
   103  			hired DATE NOT NULL DEFAULT '1970-01-01',
   104  			separated DATE NOT NULL DEFAULT '9999-12-31',
   105  			job_code INT,
   106  			store_id INT
   107  		)
   108  		PARTITION BY LIST(store_id) (
   109  			PARTITION pNorth VALUES IN (3,5,6,9,17),
   110  			PARTITION pEast VALUES IN (1,2,10,11,19,20),
   111  			PARTITION pWest VALUES IN (4,12,13,14,18),
   112  			PARTITION pCentral VALUES IN (7,8,15,16)
   113  		);`,
   114  
   115  		`CREATE TABLE t1 (
   116  			id   INT PRIMARY KEY,
   117  			name VARCHAR(35)
   118  		)
   119  		PARTITION BY LIST (id) (
   120  			PARTITION r0 VALUES IN (1, 5, 9, 13, 17, 21),
   121  			PARTITION r1 VALUES IN (2, 6, 10, 14, 18, 22),
   122  			PARTITION r2 VALUES IN (3, 7, 11, 15, 19, 23),
   123  			PARTITION r3 VALUES IN (4, 8, 12, 16, 20, 24)
   124  		);`,
   125  
   126  		`CREATE TABLE lc (
   127  			a INT NULL,
   128  			b INT NULL
   129  		)
   130  		PARTITION BY LIST (a) (
   131  			PARTITION p0 VALUES IN(0,NULL),
   132  			PARTITION p1 VALUES IN( 1,2 ),
   133  			PARTITION p2 VALUES IN( 3,4 ),
   134  			PARTITION p3 VALUES IN( 5,6 )
   135  		);`,
   136  
   137  		`CREATE TABLE w_videos_partition (
   138  			  id bigint(20) NOT NULL AUTO_INCREMENT,
   139  			  create_time char(12) NOT NULL DEFAULT '' COMMENT '创建时间戳',
   140  			  created_at datetime NOT NULL COMMENT '创建时间',
   141  			  updated_at datetime DEFAULT NULL COMMENT '更新时间',
   142  			  content text,
   143  			  event_start char(12) NOT NULL DEFAULT '' COMMENT '事件开始时间戳',
   144  			  event_end char(12) NOT NULL DEFAULT '' COMMENT '事件结束时间戳',
   145  			  msg_id varchar(32) NOT NULL DEFAULT '',
   146  			  event_id varchar(32) NOT NULL DEFAULT '',
   147  			  accept tinyint(4) NOT NULL DEFAULT '0',
   148  			  PRIMARY KEY (id,created_at)
   149  			)
   150  			PARTITION BY LIST ((TO_DAYS(created_at)*24 + HOUR(created_at)) % (7*24))( 
   151  			 PARTITION hour0 VALUES IN (0),
   152  			 PARTITION hour1 VALUES IN (1),
   153  			 PARTITION hour2 VALUES IN (2),
   154  			 PARTITION hour3 VALUES IN (3),
   155  			 PARTITION hour4 VALUES IN (4)
   156  			);`,
   157  	}
   158  
   159  	mock := NewMockOptimizer(false)
   160  	for _, sql := range sqls {
   161  		t.Log(sql)
   162  		logicPlan, err := buildSingleStmt(mock, t, sql)
   163  		if err != nil {
   164  			t.Fatalf("%+v", err)
   165  		}
   166  		outPutPlan(logicPlan, true, t)
   167  	}
   168  }
   169  
   170  func TestListPartitionError(t *testing.T) {
   171  	sqls := []string{
   172  		`CREATE TABLE t1 (
   173  			id   INT,
   174  			name VARCHAR(35)
   175  		)
   176  		PARTITION BY LIST (id);`,
   177  
   178  		`CREATE TABLE t2 (
   179  			id   INT,
   180  			name VARCHAR(35)
   181  		)
   182           PARTITION BY LIST (id) (
   183  			PARTITION r0 VALUES IN (1, 5, 9, 13, 17, 21),
   184  			PARTITION r1 VALUES IN (2, 6, 10, 14, 18, 22),
   185  			PARTITION r2 VALUES IN (3, 7, 11, 15, 19, 23),
   186  			PARTITION r2 VALUES IN (4, 8, 12, 16, 20, 24)
   187  		);`,
   188  
   189  		`CREATE TABLE t1 (
   190  			id   INT PRIMARY KEY,
   191  			name VARCHAR(35),
   192  			age INT unsigned
   193  		)
   194  		PARTITION BY LIST (age) (
   195  			PARTITION r0 VALUES IN (1, 5, 9, 13, 17, 21),
   196  			PARTITION r1 VALUES IN (2, 6, 10, 14, 18, 22),
   197  			PARTITION r2 VALUES IN (3, 7, 11, 15, 19, 23),
   198  			PARTITION r3 VALUES IN (4, 8, 12, 16, 20, 24)
   199  		);`,
   200  
   201  		`CREATE TABLE lc (
   202  			a INT NULL,
   203  			b INT NULL
   204  		)
   205  		PARTITION BY LIST (a) (
   206  			PARTITION p0 VALUES IN(NULL,NULL),
   207  			PARTITION p1 VALUES IN( 1,2 ),
   208  			PARTITION p2 VALUES IN( 3,4 ),
   209  			PARTITION p3 VALUES IN( 5,6 )
   210  		);`,
   211  
   212  		`CREATE TABLE lc (
   213  			a INT NULL,
   214  			b INT NULL
   215  		)
   216  		PARTITION BY LIST (a) (
   217  			PARTITION p0 VALUES IN(NULL,NULL),
   218  			PARTITION p1 VALUES IN( 1,2 ),
   219  			PARTITION p2 VALUES IN( 3,1 ),
   220  			PARTITION p3 VALUES IN( 3,3 )
   221  		);`,
   222  
   223  		`CREATE TABLE lc (
   224  			a INT NULL,
   225  			b INT NULL
   226  		)
   227  		PARTITION BY LIST (a) (
   228  			PARTITION p0 VALUES IN(0,NULL),
   229  			PARTITION p1 VALUES IN( 1,2 ),
   230  			PARTITION p2 VALUES IN( 3,4 ),
   231  			PARTITION p3 VALUES LESS THAN (50,20)
   232  		);`,
   233  
   234  		`create table pt_table_50(
   235  			col1 tinyint,
   236  			col2 smallint,
   237  			col3 int,
   238  			col4 bigint,
   239  			col5 tinyint unsigned,
   240  			col6 smallint unsigned,
   241  			col7 int unsigned,
   242  			col8 bigint unsigned,
   243  			col9 float,
   244  			col10 double,
   245  			col11 varchar(255),
   246  			col12 Date,
   247  			col13 DateTime,
   248  			col14 timestamp,
   249  			col15 bool,
   250  			col16 decimal(5,2),
   251  			col17 text,
   252  			col18 varchar(255),
   253  			col19 varchar(255),
   254  			col20 text,
   255  			primary key(col4,col3,col11)
   256  			) partition by list(col3) (
   257  			PARTITION r0 VALUES IN (1, 5*2, 9, 13, 17-20, 21),
   258  			PARTITION r1 VALUES IN (2, 6, 10, 7, 18, 22),
   259  			PARTITION r2 VALUES IN (3, 7, 11+6, 15, 19, 23),
   260  			PARTITION r3 VALUES IN (4, 8, 12, 16, 20, 24)
   261  			);`,
   262  
   263  		`create table pt_table_50(
   264  			col1 tinyint,
   265  			col2 smallint,
   266  			col3 int,
   267  			col4 bigint,
   268  			col5 tinyint unsigned,
   269  			col6 smallint unsigned,
   270  			col7 int unsigned,
   271  			col8 bigint unsigned,
   272  			col9 float,
   273  			col10 double,
   274  			col11 varchar(255),
   275  			col12 Date,
   276  			col13 DateTime,
   277  			col14 timestamp,
   278  			col15 bool,
   279  			col16 decimal(5,2),
   280  			col17 text,
   281  			col18 varchar(255),
   282  			col19 varchar(255),
   283  			col20 text,
   284  			primary key(col4,col3,col11)
   285  			) partition by list(col3) (
   286  			PARTITION r0 VALUES IN (1, 5*2, 9, 13, 17-20, 21),
   287  			PARTITION r1 VALUES IN (2, 6, 10, 14/2, 18, 22),
   288  			PARTITION r2 VALUES IN (3, 7, 11+6, 15, 19, 23),
   289  			PARTITION r3 VALUES IN (4, 8, 12, 16, 20, 24)
   290  			);`,
   291  	}
   292  
   293  	mock := NewMockOptimizer(false)
   294  	for _, sql := range sqls {
   295  		_, err := buildSingleStmt(mock, t, sql)
   296  		t.Log(sql)
   297  		t.Log(err)
   298  		if err == nil {
   299  			t.Fatalf("%+v", err)
   300  		}
   301  	}
   302  }
   303  
   304  // -----------------------List Columns Partition--------------------------------------
   305  func TestListColumnsPartition(t *testing.T) {
   306  	sqls := []string{
   307  		`CREATE TABLE lc (
   308  				a INT NULL,
   309  				b INT NULL
   310  			)
   311  			PARTITION BY LIST COLUMNS(a,b) (
   312  				PARTITION p0 VALUES IN( (0,0), (NULL,NULL) ),
   313  				PARTITION p1 VALUES IN( (0,1), (0,2), (0,3), (1,1), (1,2) ),
   314  				PARTITION p2 VALUES IN( (1,0), (2,0), (2,1), (3,0), (3,1) ),
   315  				PARTITION p3 VALUES IN( (1,3), (2,2), (2,3), (3,2), (3,3) )
   316  			);`,
   317  
   318  		`CREATE TABLE customers_1 (
   319  			first_name VARCHAR(25),
   320  			last_name VARCHAR(25),
   321  			street_1 VARCHAR(30),
   322  			street_2 VARCHAR(30),
   323  			city VARCHAR(15),
   324  			renewal DATE
   325  		)
   326  			PARTITION BY LIST COLUMNS(city) (
   327  			PARTITION pRegion_1 VALUES IN('Oskarshamn', 'Högsby', 'Mönsterås'),
   328  			PARTITION pRegion_2 VALUES IN('Vimmerby', 'Hultsfred', 'Västervik'),
   329  			PARTITION pRegion_3 VALUES IN('Nässjö', 'Eksjö', 'Vetlanda'),
   330  			PARTITION pRegion_4 VALUES IN('Uppvidinge', 'Alvesta', 'Växjo')
   331  		);`,
   332  
   333  		`CREATE TABLE customers_2 (
   334  			first_name VARCHAR(25),
   335  			last_name VARCHAR(25),
   336  			street_1 VARCHAR(30),
   337  			street_2 VARCHAR(30),
   338  			city VARCHAR(15),
   339  			renewal DATE
   340  		)
   341  		PARTITION BY LIST COLUMNS(renewal) (
   342  			PARTITION pWeek_1 VALUES IN('2010-02-01', '2010-02-02', '2010-02-03',
   343  				'2010-02-04', '2010-02-05', '2010-02-06', '2010-02-07'),
   344  			PARTITION pWeek_2 VALUES IN('2010-02-08', '2010-02-09', '2010-02-10',
   345  				'2010-02-11', '2010-02-12', '2010-02-13', '2010-02-14'),
   346  			PARTITION pWeek_3 VALUES IN('2010-02-15', '2010-02-16', '2010-02-17',
   347  				'2010-02-18', '2010-02-19', '2010-02-20', '2010-02-21'),
   348  			PARTITION pWeek_4 VALUES IN('2010-02-22', '2010-02-23', '2010-02-24',
   349  				'2010-02-25', '2010-02-26', '2010-02-27', '2010-02-28')
   350  		);`,
   351  
   352  		`CREATE TABLE lc (
   353  			a INT NULL,
   354  			b INT NULL
   355  		)
   356  		PARTITION BY LIST COLUMNS(a,b) PARTITIONS 4 (
   357  			PARTITION p0 VALUES IN( (0,0), (NULL,NULL) ),
   358  			PARTITION p1 VALUES IN( (0,1), (0,2), (0,3), (1,1), (1,2) ),
   359  			PARTITION p2 VALUES IN( (1,0), (2,0), (2,1), (3,0), (3,1) ),
   360  			PARTITION p3 VALUES IN( (1,3), (2,2), (2,3), (3,2), (3,3) )
   361  		);`,
   362  
   363  		`CREATE TABLE lc (
   364  				a INT NULL,
   365  				b INT NULL
   366  			)
   367  			PARTITION BY LIST COLUMNS(a,b) (
   368  				PARTITION p0 VALUES IN( (0,0), (NULL,NULL) ),
   369  				PARTITION p1 VALUES IN( (0,1), (0,2) ),
   370  				PARTITION p2 VALUES IN( (1,0), (2,0) )
   371  			);`,
   372  	}
   373  
   374  	mock := NewMockOptimizer(false)
   375  	for _, sql := range sqls {
   376  		t.Log(sql)
   377  		logicPlan, err := buildSingleStmt(mock, t, sql)
   378  		if err != nil {
   379  			t.Fatalf("%+v", err)
   380  		}
   381  		outPutPlan(logicPlan, true, t)
   382  	}
   383  }
   384  
   385  func TestListColumnsPartitionError(t *testing.T) {
   386  	sqls := []string{
   387  		`CREATE TABLE t1 (
   388  			a INT NULL,
   389  			b INT NULL
   390  		)
   391  		PARTITION BY LIST COLUMNS(a,b);`,
   392  
   393  		`CREATE TABLE t2 (
   394  			a INT NULL,
   395  			b INT NULL
   396  		)
   397  		PARTITION BY LIST COLUMNS(a,b) (
   398  			PARTITION p0 VALUES IN( (0,0), (NULL,NULL) ),
   399  			PARTITION p1 VALUES IN( (0,1), (0,2), (0,3), (1,1), (1,2) ),
   400  			PARTITION p2 VALUES IN( (1,0), (2,0), (2,1), (3,0), (3,1) ),
   401  			PARTITION p2 VALUES IN( (1,3), (2,2), (2,3), (3,2), (3,3) )
   402  		);`,
   403  
   404  		`CREATE TABLE lc (
   405  			a INT NULL,
   406  			b INT NULL
   407  		)
   408  		PARTITION BY LIST COLUMNS(a,b) PARTITIONS 5 (
   409  			PARTITION p0 VALUES IN( (0,0), (NULL,NULL) ),
   410  			PARTITION p1 VALUES IN( (0,1), (0,2), (0,3), (1,1), (1,2) ),
   411  			PARTITION p2 VALUES IN( (1,0), (2,0), (2,1), (3,0), (3,1) ),
   412  			PARTITION p3 VALUES IN( (1,3), (2,2), (2,3), (3,2), (3,3) )
   413  		);`,
   414  
   415  		`CREATE TABLE lc (
   416  				a INT NULL,
   417  				b INT NULL
   418  			)
   419  			PARTITION BY LIST COLUMNS(a,a) (
   420  				PARTITION p0 VALUES IN( (0,0), (NULL,NULL) ),
   421  				PARTITION p1 VALUES IN( (0,1), (0,2), (0,3), (1,1), (1,2) ),
   422  				PARTITION p2 VALUES IN( (1,0), (2,0), (2,1), (3,0), (3,1) ),
   423  				PARTITION p3 VALUES IN( (1,3), (2,2), (2,3), (3,2), (3,3) )
   424  			);`,
   425  
   426  		`CREATE TABLE lc (
   427  				a INT NULL,
   428  				b INT NULL
   429  			)
   430  			PARTITION BY LIST COLUMNS(a) (
   431  				PARTITION p0 VALUES IN( -1, NULL),
   432  				PARTITION p1 VALUES IN( 1, 1),
   433  				PARTITION p2 VALUES IN( 2, 3),    
   434  				PARTITION p3 VALUES IN( 4, 5)
   435  			);`,
   436  		`CREATE TABLE lc (
   437  				a INT NULL,
   438  				b INT NULL
   439  			)
   440  			PARTITION BY LIST COLUMNS(a,b) (
   441  				PARTITION p0 VALUES IN( 0, 1, NULL),
   442  				PARTITION p1 VALUES IN( 2, 3, 4 ),
   443  				PARTITION p2 VALUES IN( 5, 6, 7 ),    
   444  				PARTITION p3 VALUES IN( 8, 9, 10)
   445  			);`,
   446  	}
   447  
   448  	mock := NewMockOptimizer(false)
   449  	for _, sql := range sqls {
   450  		_, err := buildSingleStmt(mock, t, sql)
   451  		t.Log(sql)
   452  		t.Log(err)
   453  		if err == nil {
   454  			t.Fatalf("%+v", err)
   455  		}
   456  	}
   457  }
   458  
   459  func TestListPartitionFunction(t *testing.T) {
   460  	sqls := []string{
   461  		`CREATE TABLE lc (
   462  			a INT NULL,
   463  			b INT NULL
   464  		)
   465  		PARTITION BY LIST COLUMNS(a,b) (
   466  			PARTITION p0 VALUES IN( (0,0), (NULL,NULL) ),
   467  			PARTITION p1 VALUES IN( (0,1), (0,4+2) ),
   468  			PARTITION p2 VALUES IN( (1,0), (2,0) )
   469  		);`,
   470  
   471  		`CREATE TABLE lc (
   472  			a INT NULL,
   473  			b INT NULL
   474  		)
   475  		PARTITION BY LIST(a) (
   476  			PARTITION p0 VALUES IN(0, NULL ),
   477  			PARTITION p1 VALUES IN(1, 2),
   478  			PARTITION p2 VALUES IN(3, 4)
   479  		);`,
   480  
   481  		`CREATE TABLE lc (
   482  			a INT NULL,
   483  			b INT NULL
   484  		)
   485  		PARTITION BY LIST COLUMNS(b) (
   486  			PARTITION p0 VALUES IN( 0,NULL ),
   487  			PARTITION p1 VALUES IN( 1,2 ),
   488  			PARTITION p2 VALUES IN( 3,4 )
   489  		);`,
   490  
   491  		`CREATE TABLE lc (
   492  			a INT NULL,
   493  			b INT NULL
   494  		)
   495  		PARTITION BY LIST COLUMNS(b) (
   496  			PARTITION p0 VALUES IN( 0,NULL ),
   497  			PARTITION p1 VALUES IN( 1,1+1 ),
   498  			PARTITION p2 VALUES IN( 3,4 )
   499  		);`,
   500  	}
   501  
   502  	mock := NewMockOptimizer(false)
   503  	for _, sql := range sqls {
   504  		t.Log(sql)
   505  		logicPlan, err := buildSingleStmt(mock, t, sql)
   506  		if err != nil {
   507  			t.Fatalf("%+v", err)
   508  		}
   509  		outPutPlan(logicPlan, true, t)
   510  	}
   511  }
   512  
   513  func TestListPartitionFunctionError(t *testing.T) {
   514  	sqls := []string{
   515  		`create table pt_table_45(
   516  			col1 tinyint,
   517  			col2 smallint,
   518  			col3 int,
   519  			col4 bigint,
   520  			col5 tinyint unsigned,
   521  			col6 smallint unsigned,
   522  			col7 int unsigned,
   523  			col8 bigint unsigned,
   524  			col9 float,
   525  			col10 double,
   526  			col11 varchar(255),
   527  			col12 Date,
   528  			col13 DateTime,
   529  			col14 timestamp,
   530  			col15 bool,
   531  			col16 decimal(5,2),
   532  			col17 text,
   533  			col18 varchar(255),
   534  			col19 varchar(255),
   535  			col20 text,
   536  			primary key(col4,col3,col11))
   537  		partition by list(col3) (
   538  			PARTITION r0 VALUES IN (1, 5*2, 9, 13, 17-20, 21),
   539  			PARTITION r1 VALUES IN (2, 6, 10, 14/2, 18, 22),
   540  			PARTITION r2 VALUES IN (3, 7, 11+6, 15, 19, 23),
   541  			PARTITION r3 VALUES IN (4, 8, 12, 16, 20, 24)
   542  		);`,
   543  
   544  		`CREATE TABLE lc (
   545  			a INT NULL,
   546  			b INT NULL
   547  		)
   548  		PARTITION BY LIST COLUMNS(a,b) (
   549  			PARTITION p0 VALUES IN( (0,0), (NULL,NULL) ),
   550  			PARTITION p1 VALUES IN( (0,1), (0,4/2) ),
   551  			PARTITION p2 VALUES IN( (1,0), (2,0) )
   552  		);`,
   553  
   554  		`CREATE TABLE lc (
   555  			a INT NULL,
   556  			b INT NULL
   557  		)
   558  		PARTITION BY LIST COLUMNS(a,b) (
   559  			PARTITION p0 VALUES IN( (0,0), (NULL,NULL) ),
   560  			PARTITION p1 VALUES IN( (0,1), (0,4.2) ),
   561  			PARTITION p2 VALUES IN( (1,0), (2,0) )
   562  		);`,
   563  
   564  		`CREATE TABLE lc (
   565  			a INT NULL,
   566  			b INT NULL
   567  		)
   568  		PARTITION BY LIST COLUMNS(a,b) (
   569  			PARTITION p0 VALUES IN( 0,NULL ),
   570  			PARTITION p1 VALUES IN( 0,1 ),
   571  			PARTITION p2 VALUES IN( 1,0 )
   572  		);`,
   573  
   574  		`CREATE TABLE lc (
   575  			a INT NULL,
   576  			b INT NULL
   577  		)
   578  		PARTITION BY LIST(a) (
   579  			PARTITION p0 VALUES IN(0, NULL ),
   580  			PARTITION p1 VALUES IN(1, 4/2),
   581  			PARTITION p2 VALUES IN(3, 4)
   582  		);`,
   583  
   584  		`CREATE TABLE lc (
   585  			a INT NULL,
   586  			b INT NULL
   587  		)
   588  		PARTITION BY LIST COLUMNS(b) (
   589  			PARTITION p0 VALUES IN( 0,NULL ),
   590  			PARTITION p1 VALUES IN( 1,4/2 ),
   591  			PARTITION p2 VALUES IN( 3,4 )
   592  		);`,
   593  
   594  		`CREATE TABLE lc (
   595  			a INT NULL,
   596  			b INT NULL
   597  		)
   598  		PARTITION BY LIST COLUMNS(a,b) (
   599  			PARTITION p0 VALUES IN( (0,0), (NULL,NULL) ),
   600  			PARTITION p1 VALUES IN( (0,1,3), (0,4,5) ),
   601  			PARTITION p2 VALUES IN( (1,0), (2,0) )
   602  		);`,
   603  	}
   604  
   605  	mock := NewMockOptimizer(false)
   606  	for _, sql := range sqls {
   607  		_, err := buildSingleStmt(mock, t, sql)
   608  		t.Log(sql)
   609  		t.Log(err)
   610  		if err == nil {
   611  			t.Fatalf("%+v", err)
   612  		}
   613  	}
   614  }
   615  
   616  func TestCreateTableWithListPartition(t *testing.T) {
   617  	type errorCase struct {
   618  		sql       string
   619  		errorCode uint16
   620  	}
   621  
   622  	cases := []errorCase{
   623  		{
   624  			"create table t (id timestamp) partition by list (id) (partition p0 values in ('2019-01-09 11:23:34'));",
   625  			moerr.ErrValuesIsNotIntType,
   626  		},
   627  		{
   628  			"create table t (id int) partition by list (id);",
   629  			moerr.ErrPartitionsMustBeDefined,
   630  		},
   631  		{
   632  			"create table t (a int) partition by list (b) (partition p0 values in (1));",
   633  			moerr.ErrBadFieldError,
   634  		},
   635  		{
   636  			"create table t (id decimal) partition by list (id) (partition p0 values in ('2019-01-09 11:23:34'));",
   637  			moerr.ErrValuesIsNotIntType,
   638  		},
   639  		{
   640  			"create table t (id float) partition by list (id) (partition p0 values in (1));",
   641  			moerr.ErrFieldTypeNotAllowedAsPartitionField,
   642  		},
   643  		{
   644  			"create table t (id double) partition by list (id) (partition p0 values in (1));",
   645  			moerr.ErrFieldTypeNotAllowedAsPartitionField,
   646  		},
   647  		{
   648  			"create table t (id text) partition by list (id) (partition p0 values in ('abc'));",
   649  			moerr.ErrValuesIsNotIntType,
   650  		},
   651  		{
   652  			"create table t (id blob) partition by list (id) (partition p0 values in ('abc'));",
   653  			moerr.ErrValuesIsNotIntType,
   654  		},
   655  		{
   656  			"create table t (id enum('a','b')) partition by list (id) (partition p0 values in ('a'));",
   657  			moerr.ErrValuesIsNotIntType,
   658  		},
   659  		{
   660  			"create table t (a int) partition by list (a) (partition p0 values in (1), partition P0 values in (2));",
   661  			moerr.ErrSameNamePartition,
   662  		},
   663  		{
   664  			"create table t (id bigint) partition by list (cast(id as unsigned)) (partition p0 values in (1))",
   665  			moerr.ErrPartitionFunctionIsNotAllowed,
   666  		},
   667  		{
   668  			"create table t (a int) partition by list (a) (partition p0 values in (1), partition p0 values in (2));",
   669  			moerr.ErrSameNamePartition,
   670  		},
   671  		{
   672  			"create table t (id float) partition by list (ceiling(id)) (partition p0 values in (1))",
   673  			moerr.ErrPartitionFuncNotAllowed,
   674  		},
   675  		{
   676  			"create table t (a date) partition by list (to_days(to_days(a))) (partition p0 values in (1), partition P1 values in (2));",
   677  			moerr.ErrWrongExprInPartitionFunc,
   678  		},
   679  		{
   680  			"create table t (a int) partition by list (a) (partition p0 values in (1), partition p1 values in (1));",
   681  			moerr.ErrMultipleDefConstInListPart,
   682  		},
   683  		{
   684  			"create table t (a int) partition by list (a) (partition p0 values in (1), partition p1 values in (+1));",
   685  			moerr.ErrMultipleDefConstInListPart,
   686  		},
   687  		{
   688  			"create table t (a int) partition by list (a) (partition p0 values in (null), partition p1 values in (NULL));",
   689  			moerr.ErrMultipleDefConstInListPart,
   690  		},
   691  		{
   692  			`create table t1 (id int key, name varchar(10), unique index idx(name)) partition by list  (id) (
   693  				    partition p0 values in (3,5,6,9,17),
   694  				    partition p1 values in (1,2,10,11,19,20),
   695  				    partition p2 values in (4,12,13,14,18),
   696  				    partition p3 values in (7,8,15,16)
   697  				);`,
   698  			moerr.ErrUniqueKeyNeedAllFieldsInPf,
   699  		},
   700  		{
   701  			`CREATE TABLE t2 (id INT, name VARCHAR(35))
   702  			PARTITION BY LIST (id) (
   703  			PARTITION r0 VALUES IN (1, 5, MAXVALUE),
   704  			PARTITION r1 VALUES IN (2, 6, 10)
   705  			);`,
   706  			moerr.ErrMaxvalueInValuesIn,
   707  		},
   708  		{
   709  			`CREATE TABLE t2 (id INT, name VARCHAR(35))  PARTITION BY LIST (id) ( PARTITION r0 VALUES IN ((1, 4), (5, 6)),  PARTITION r1 VALUES IN ((2, 3), (4, 7)) );`,
   710  			moerr.ErrRowSinglePartitionField,
   711  		},
   712  	}
   713  
   714  	mock := NewMockOptimizer(false)
   715  	for i, tt := range cases {
   716  		_, err := buildSingleStmt(mock, t, tt.sql)
   717  		require.Truef(t, moerr.IsMoErrCode(err, tt.errorCode),
   718  			"case %d failed, sql = `%s`\nexpected error = `%v`\n  actual error = `%v`",
   719  			i, tt.sql, tt.errorCode, err,
   720  		)
   721  	}
   722  
   723  	validCases := []string{
   724  		"create table t (a int) partition by list (a) (partition p0 values in (1));",
   725  		"create table t (a bigint unsigned) partition by list (a) (partition p0 values in (18446744073709551615));",
   726  		//"create table t (a bigint unsigned) partition by list (a) (partition p0 values in (18446744073709551615 - 1));",
   727  		"create table t (a int) partition by list (a) (partition p0 values in (1,null));",
   728  		"create table t (a int) partition by list (a) (partition p0 values in (1), partition p1 values in (2));",
   729  		`create table t (id int, name varchar(10), age int) partition by list (id) (
   730  			partition p0 values in (3,5,6,9,17),
   731  			partition p1 values in (1,2,10,11,19,21),
   732  			partition p2 values in (4,12,13,-14,18),
   733  			partition p3 values in (7,8,15,+16,20)
   734  		);`,
   735  		"create table t (a tinyint) partition by list (a) (partition p0 values in (65536));",
   736  		"create table t (a tinyint) partition by list (a*100) (partition p0 values in (65536));",
   737  		"create table t(a binary) partition by list columns (a) (partition p0 values in (X'0C'));",
   738  		"create table t (a bigint) partition by list (a) (partition p0 values in (to_seconds('2020-09-28 17:03:38'),to_seconds('2020-09-28 17:03:39')));",
   739  		"create table t (a datetime) partition by list (to_seconds(a)) (partition p0 values in (to_seconds('2020-09-28 17:03:38'),to_seconds('2020-09-28 17:03:39')));",
   740  	}
   741  
   742  	//mock := NewMockOptimizer(false)
   743  	for i, sql := range validCases {
   744  		_, err := buildSingleStmt(mock, t, sql)
   745  		require.Truef(t, err == nil,
   746  			"case %d failed, sql = `%s`\n  actual error = `%v`",
   747  			i, sql, err,
   748  		)
   749  	}
   750  
   751  }
   752  
   753  func TestCreateTableWithListColumnsPartition(t *testing.T) {
   754  	type errorCase struct {
   755  		sql       string
   756  		errorCode uint16
   757  	}
   758  	cases := []errorCase{
   759  		{
   760  			"create table t (id int) partition by list columns (id);",
   761  			moerr.ErrPartitionsMustBeDefined,
   762  		},
   763  		{
   764  			"create table t (a int) partition by list columns (b) (partition p0 values in (1));",
   765  			moerr.ErrFieldNotFoundPart,
   766  		},
   767  		{
   768  			"create table t (id timestamp) partition by list columns (id) (partition p0 values in ('2019-01-09 11:23:34'));",
   769  			moerr.ErrFieldTypeNotAllowedAsPartitionField,
   770  		},
   771  		{
   772  			"create table t (id decimal) partition by list columns (id) (partition p0 values in ('2019-01-09 11:23:34'));",
   773  			moerr.ErrFieldTypeNotAllowedAsPartitionField,
   774  		},
   775  		{
   776  			"create table t (id float) partition by list columns (id) (partition p0 values in (1));",
   777  			moerr.ErrFieldTypeNotAllowedAsPartitionField,
   778  		},
   779  		{
   780  			"create table t (id double) partition by list columns (id) (partition p0 values in (1));",
   781  			moerr.ErrFieldTypeNotAllowedAsPartitionField,
   782  		},
   783  		{
   784  			"create table t (id text) partition by list columns (id) (partition p0 values in ('abc'));",
   785  			moerr.ErrFieldTypeNotAllowedAsPartitionField,
   786  		},
   787  		{
   788  			"create table t (id blob) partition by list columns (id) (partition p0 values in ('abc'));",
   789  			moerr.ErrFieldTypeNotAllowedAsPartitionField,
   790  		},
   791  		{
   792  			"create table t (id enum('a','b')) partition by list columns (id) (partition p0 values in ('a'));",
   793  			moerr.ErrFieldTypeNotAllowedAsPartitionField,
   794  		},
   795  		{
   796  			"create table t (a varchar(2)) partition by list columns (a) (partition p0 values in ('abc'));",
   797  			moerr.ErrWrongTypeColumnValue,
   798  		},
   799  		{
   800  			"create table t (a tinyint) partition by list columns (a) (partition p0 values in (65536));",
   801  			moerr.ErrWrongTypeColumnValue,
   802  		},
   803  		{
   804  			"create table t (a bigint) partition by list columns (a) (partition p0 values in (18446744073709551615));",
   805  			moerr.ErrWrongTypeColumnValue,
   806  		},
   807  		{
   808  			"create table t (a bigint unsigned) partition by list columns (a) (partition p0 values in (-1));",
   809  			moerr.ErrWrongTypeColumnValue,
   810  		},
   811  		{
   812  			"create table t (a char) partition by list columns (a) (partition p0 values in ('abc'));",
   813  			moerr.ErrWrongTypeColumnValue,
   814  		},
   815  		{
   816  			"create table t (a datetime) partition by list columns (a) (partition p0 values in ('2020-11-31 12:00:00'));",
   817  			moerr.ErrWrongTypeColumnValue,
   818  		},
   819  		{
   820  			"create table t (a int) partition by list columns (a) (partition p0 values in (1), partition p0 values in (2));",
   821  			moerr.ErrSameNamePartition,
   822  		},
   823  		{
   824  			"create table t (a int) partition by list columns (a) (partition p0 values in (1), partition P0 values in (2));",
   825  			moerr.ErrSameNamePartition,
   826  		},
   827  		{
   828  			"create table t (a int) partition by list columns (a) (partition p0 values in (1), partition p1 values in (1));",
   829  			moerr.ErrMultipleDefConstInListPart,
   830  		},
   831  		{
   832  			"create table t (a int) partition by list columns (a) (partition p0 values in (1), partition p1 values in (+1));",
   833  			moerr.ErrMultipleDefConstInListPart,
   834  		},
   835  		{
   836  			"create table t (a tinyint) partition by list columns (a) (partition p0 values in (1), partition p1 values in (+1));",
   837  			moerr.ErrMultipleDefConstInListPart,
   838  		},
   839  		{
   840  			"create table t (a mediumint) partition by list columns (a) (partition p0 values in (1), partition p1 values in (+1));",
   841  			moerr.ErrMultipleDefConstInListPart,
   842  		},
   843  		{
   844  			"create table t (a bigint) partition by list columns (a) (partition p0 values in (1), partition p1 values in (+1));",
   845  			moerr.ErrMultipleDefConstInListPart,
   846  		},
   847  		{
   848  			"create table t (a bigint) partition by list columns (a) (partition p0 values in (1,+1))",
   849  			moerr.ErrMultipleDefConstInListPart,
   850  		},
   851  		{
   852  			"create table t (a int) partition by list columns (a) (partition p0 values in (null), partition p1 values in (NULL));",
   853  			moerr.ErrMultipleDefConstInListPart,
   854  		},
   855  		{
   856  			"create table t (a bigint, b int) partition by list columns (a,b) (partition p0 values in ((1,2),(1,2)))",
   857  			moerr.ErrMultipleDefConstInListPart,
   858  		},
   859  		{
   860  			"create table t (a bigint, b int) partition by list columns (a,b) (partition p0 values in ((1,1),(2,2)), partition p1 values in ((+1,1)));",
   861  			moerr.ErrMultipleDefConstInListPart,
   862  		},
   863  		{
   864  			"create table t1 (a int, b int) partition by list columns(a,a) ( partition p values in ((1,1)));",
   865  			moerr.ErrSameNamePartitionField,
   866  		},
   867  		{
   868  			"create table t1 (a int, b int) partition by list columns(a,b,b) ( partition p values in ((1,1,1)));",
   869  			moerr.ErrSameNamePartitionField,
   870  		},
   871  		{
   872  			`create table t1 (id int key, name varchar(10), unique index idx(name)) partition by list columns (id) (
   873  				    partition p0 values in (3,5,6,9,17),
   874  				    partition p1 values in (1,2,10,11,19,20),
   875  				    partition p2 values in (4,12,13,14,18),
   876  				    partition p3 values in (7,8,15,16)
   877  				);`,
   878  			moerr.ErrUniqueKeyNeedAllFieldsInPf,
   879  		},
   880  		{
   881  			"create table t (a date) partition by list columns (a) (partition p0 values in ('2020-02-02'), partition p1 values in ('20200202'));",
   882  			moerr.ErrMultipleDefConstInListPart,
   883  		},
   884  		{
   885  			"create table t (a int, b varchar(10)) partition by list columns (a,b) (partition p0 values in (1));",
   886  			moerr.ErrPartitionColumnList,
   887  		},
   888  		{
   889  			"create table t (a int, b varchar(10)) partition by list columns (a,b) (partition p0 values in (('ab','ab')));",
   890  			moerr.ErrWrongTypeColumnValue,
   891  		},
   892  		{
   893  			"create table t (a int, b datetime) partition by list columns (a,b) (partition p0 values in ((1)));",
   894  			moerr.ErrPartitionColumnList,
   895  		},
   896  		{
   897  			"create table t(b int) partition by hash ( b ) partitions 3 (partition p1, partition p2, partition p2);",
   898  			moerr.ErrSameNamePartition,
   899  		},
   900  		{
   901  			`CREATE TABLE t( a INT NULL, b INT NULL ) PARTITION BY LIST COLUMNS(a) ( PARTITION p1 VALUES IN( 0, maxvalue), PARTITION p2 VALUES IN( 2, 3), PARTITION p3 VALUES IN( 4, 5));`,
   902  			moerr.ErrMaxvalueInValuesIn,
   903  		},
   904  		{
   905  			`create table pt_table_21(
   906  			col1 int,
   907  			col2 int,
   908  			col3 int,
   909  			col4 int,
   910  			col5 int,
   911  			col6 int,
   912  			col7 int,
   913  			col8 int,
   914  			col9 int,
   915  			col10 int,
   916  			col11 int,
   917  			col12 int,
   918  			col13 int,
   919  			col14 int,
   920  			col15 int,
   921  			col16 int,
   922  			col17 int,
   923  			col18 int,
   924  			col19 int,
   925  			col20 int,
   926  			col21 int
   927  			) PARTITION BY LIST COLUMNS(col1,col2,col3, col4,col5 ,col6 ,col7 ,col8 ,col9 ,col10,col11,col12,col13,col14,col15,col16,col17) (
   928  				PARTITION p1 VALUES IN( (1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1), (2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2)),
   929  				PARTITION p2 VALUES IN( (3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3), (4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4))
   930  			);`,
   931  			moerr.ErrTooManyPartitionFuncFields,
   932  		},
   933  	}
   934  
   935  	mock := NewMockOptimizer(false)
   936  	for i, tt := range cases {
   937  		_, err := buildSingleStmt(mock, t, tt.sql)
   938  		require.Truef(t, moerr.IsMoErrCode(err, tt.errorCode),
   939  			"error test case %d failed, sql = `%s`\nexpected error = `%v`\n  actual error = `%v`",
   940  			i, tt.sql, tt.errorCode, err,
   941  		)
   942  	}
   943  
   944  	validCases := []string{
   945  		"create table t (a int) partition by list columns (a) (partition p0 values in (1));",
   946  		"create table t (a bigint unsigned) partition by list columns (a) (partition p0 values in (18446744073709551615));",
   947  		//"create table t (a bigint unsigned) partition by list columns (a) (partition p0 values in (18446744073709551615 - 1));",
   948  		"create table t (a int) partition by list columns (a) (partition p0 values in (1,null));",
   949  		"create table t (a int) partition by list columns (a) (partition p0 values in (1), partition p1 values in (2));",
   950  		`create table t (id int, name varchar(10), age int) partition by list columns (id) (
   951  			partition p0 values in (3,5,6,9,17),
   952  			partition p1 values in (1,2,10,11,19,20),
   953  			partition p2 values in (4,12,13,-14,18),
   954  			partition p3 values in (7,8,15,+16)
   955  		);`,
   956  		"create table t (a datetime) partition by list columns (a) (partition p0 values in ('2020-09-28 17:03:38','2020-09-28 17:03:39'));",
   957  		"create table t (a date) partition by list columns (a) (partition p0 values in ('2020-09-28','2020-09-29'));",
   958  		"create table t (a bigint, b date) partition by list columns (a,b) (partition p0 values in ((1,'2020-09-28'),(1,'2020-09-29')));",
   959  		"create table t (a bigint)   partition by list columns (a) (partition p0 values in (to_seconds('2020-09-28 17:03:38'),to_seconds('2020-09-28 17:03:39')));",
   960  		"create table t (a varchar(10)) partition by list columns (a) (partition p0 values in ('abc'));",
   961  		"create table t (a char) partition by list columns (a) (partition p0 values in ('a'));",
   962  		"create table t (a bool) partition by list columns (a) (partition p0 values in (1));",
   963  		"create table t (c1 bool, c2 tinyint, c3 int, c4 bigint, c5 datetime, c6 date,c7 varchar(10), c8 char) " +
   964  			"partition by list columns (c1,c2,c3,c4,c5,c6,c7,c8) (" +
   965  			"partition p0 values in ((1,2,3,4,'2020-11-30 00:00:01', '2020-11-30','abc','a')));",
   966  		"create table t(a int,b char(10)) partition by list columns (a, b) (partition p1 values in ((2, 'a'), (1, 'b')), partition p2 values in ((2, 'b')));",
   967  	}
   968  
   969  	//mock := NewMockOptimizer(false)
   970  	for i, sql := range validCases {
   971  		_, err := buildSingleStmt(mock, t, sql)
   972  		require.Truef(t, err == nil,
   973  			"valid test case %d failed, sql = `%s`\n  actual error = `%v`", i, sql, err,
   974  		)
   975  	}
   976  }