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

     1  // Copyright 2021 - 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  	"context"
    19  	"encoding/json"
    20  	"strings"
    21  
    22  	"github.com/matrixorigin/matrixone/pkg/sql/util"
    23  
    24  	"github.com/matrixorigin/matrixone/pkg/testutil"
    25  	"github.com/matrixorigin/matrixone/pkg/vm/process"
    26  
    27  	"github.com/matrixorigin/matrixone/pkg/catalog"
    28  	"github.com/matrixorigin/matrixone/pkg/common/moerr"
    29  	"github.com/matrixorigin/matrixone/pkg/container/types"
    30  	"github.com/matrixorigin/matrixone/pkg/pb/plan"
    31  	"github.com/matrixorigin/matrixone/pkg/sql/parsers/tree"
    32  )
    33  
    34  type MockCompilerContext struct {
    35  	objects         map[string]*ObjectRef
    36  	tables          map[string]*TableDef
    37  	stats           map[string]*Stats
    38  	pks             map[string][]int
    39  	id2name         map[uint64]string
    40  	isDml           bool
    41  	mysqlCompatible bool
    42  
    43  	// ctx default: nil
    44  	ctx context.Context
    45  }
    46  
    47  func (m *MockCompilerContext) ResolveAccountIds(accountNames []string) ([]uint32, error) {
    48  	return []uint32{catalog.System_Account}, nil
    49  }
    50  
    51  func (m *MockCompilerContext) ResolveVariable(varName string, isSystemVar, isGlobalVar bool) (interface{}, error) {
    52  	vars := make(map[string]interface{})
    53  	vars["str_var"] = "str"
    54  	vars["int_var"] = 20
    55  	vars["bool_var"] = false
    56  	vars["float_var"] = 20.20
    57  	dec, _ := types.ParseStringToDecimal128("200.001", 2, 2, false)
    58  	vars["decimal_var"] = dec
    59  	vars["null_var"] = nil
    60  
    61  	if m.mysqlCompatible {
    62  		vars["sql_mode"] = ""
    63  	} else {
    64  		vars["sql_mode"] = "ONLY_FULL_GROUP_BY"
    65  	}
    66  
    67  	if result, ok := vars[varName]; ok {
    68  		return result, nil
    69  	}
    70  
    71  	return nil, moerr.NewInternalError(m.ctx, "var not found")
    72  }
    73  
    74  type col struct {
    75  	Name      string
    76  	Id        types.T
    77  	Nullable  bool
    78  	Precision int32
    79  	Scale     int32
    80  }
    81  
    82  type index struct {
    83  	indexName  string
    84  	tableName  string
    85  	parts      []string
    86  	cols       []col
    87  	tableExist bool
    88  }
    89  
    90  // NewEmptyCompilerContext for test create/drop statement
    91  func NewEmptyCompilerContext() *MockCompilerContext {
    92  	return &MockCompilerContext{
    93  		objects: make(map[string]*ObjectRef),
    94  		tables:  make(map[string]*TableDef),
    95  		ctx:     context.Background(),
    96  	}
    97  }
    98  
    99  type Schema struct {
   100  	cols      []col
   101  	pks       []int
   102  	idxs      []index
   103  	fks       []*ForeignKeyDef
   104  	clusterby *ClusterByDef
   105  	outcnt    float64
   106  }
   107  
   108  const SF float64 = 1
   109  
   110  func NewMockCompilerContext(isDml bool) *MockCompilerContext {
   111  	tpchSchema := make(map[string]*Schema)
   112  	moSchema := make(map[string]*Schema)
   113  	constraintTestSchema := make(map[string]*Schema)
   114  
   115  	schemas := map[string]map[string]*Schema{
   116  		"tpch":            tpchSchema,
   117  		"mo_catalog":      moSchema,
   118  		"constraint_test": constraintTestSchema,
   119  	}
   120  
   121  	tpchSchema["nation"] = &Schema{
   122  		cols: []col{
   123  			{"n_nationkey", types.T_int32, false, 0, 0},
   124  			{"n_name", types.T_varchar, false, 25, 0},
   125  			{"n_regionkey", types.T_int32, false, 0, 0},
   126  			{"n_comment", types.T_varchar, true, 152, 0},
   127  			{catalog.Row_ID, types.T_Rowid, false, 16, 0},
   128  		},
   129  		pks:    []int{0},
   130  		outcnt: 25,
   131  	}
   132  	tpchSchema["nation2"] = &Schema{
   133  		cols: []col{ //not exist in tpch, create for test NaturalJoin And UsingJoin
   134  			{"n_nationkey", types.T_int32, false, 0, 0},
   135  			{"n_name", types.T_varchar, false, 25, 0},
   136  			{"r_regionkey", types.T_int32, false, 0, 0}, //change N_REGIONKEY to R_REGIONKEY for test NaturalJoin And UsingJoin
   137  			{"n_comment", types.T_varchar, true, 152, 0},
   138  			{catalog.Row_ID, types.T_Rowid, false, 16, 0},
   139  		},
   140  		pks:    []int{0},
   141  		outcnt: 25,
   142  	}
   143  	tpchSchema["test_idx"] = &Schema{
   144  		cols: []col{
   145  			{"n_nationkey", types.T_int32, false, 0, 0},
   146  			{"n_name", types.T_varchar, false, 25, 0},
   147  			{catalog.Row_ID, types.T_Rowid, false, 16, 0},
   148  		},
   149  		pks:    []int{0},
   150  		outcnt: 25,
   151  	}
   152  	tpchSchema["region"] = &Schema{
   153  		cols: []col{
   154  			{"r_regionkey", types.T_int32, false, 0, 0},
   155  			{"r_name", types.T_varchar, false, 25, 0},
   156  			{"r_comment", types.T_varchar, true, 152, 0},
   157  			{catalog.Row_ID, types.T_Rowid, false, 16, 0},
   158  		},
   159  		pks:    []int{0},
   160  		outcnt: 5,
   161  	}
   162  	tpchSchema["part"] = &Schema{
   163  		cols: []col{
   164  			{"p_partkey", types.T_int32, false, 0, 0},
   165  			{"p_name", types.T_varchar, false, 55, 0},
   166  			{"p_mfgr", types.T_varchar, false, 25, 0},
   167  			{"p_brand", types.T_varchar, false, 10, 0},
   168  			{"p_type", types.T_varchar, false, 25, 0},
   169  			{"p_size", types.T_int32, false, 0, 0},
   170  			{"p_container", types.T_varchar, false, 10, 0},
   171  			{"p_retailprice", types.T_decimal64, false, 15, 2},
   172  			{"p_comment", types.T_varchar, false, 23, 0},
   173  			{catalog.Row_ID, types.T_Rowid, false, 16, 0},
   174  		},
   175  		pks:    []int{0},
   176  		outcnt: SF * 2e5,
   177  	}
   178  	tpchSchema["supplier"] = &Schema{
   179  		cols: []col{
   180  			{"s_suppkey", types.T_int32, false, 0, 0},
   181  			{"s_name", types.T_varchar, false, 25, 0},
   182  			{"s_address", types.T_varchar, false, 40, 0},
   183  			{"s_nationkey", types.T_int32, false, 0, 0},
   184  			{"s_phone", types.T_varchar, false, 15, 0},
   185  			{"s_acctbal", types.T_decimal64, false, 15, 2},
   186  			{"s_comment", types.T_varchar, false, 101, 0},
   187  			{catalog.Row_ID, types.T_Rowid, false, 16, 0},
   188  		},
   189  		pks:    []int{0},
   190  		outcnt: SF * 1e4,
   191  	}
   192  	tpchSchema["partsupp"] = &Schema{
   193  		cols: []col{
   194  			{"ps_partkey", types.T_int32, false, 0, 0},
   195  			{"ps_suppkey", types.T_int32, false, 0, 0},
   196  			{"ps_availqty", types.T_int32, false, 0, 0},
   197  			{"ps_supplycost", types.T_decimal64, false, 15, 2},
   198  			{"ps_comment", types.T_varchar, false, 199, 0},
   199  			{catalog.Row_ID, types.T_Rowid, false, 16, 0},
   200  		},
   201  		pks:    []int{0, 1},
   202  		outcnt: SF * 8e5,
   203  	}
   204  	tpchSchema["customer"] = &Schema{
   205  		cols: []col{
   206  			{"c_custkey", types.T_int32, false, 0, 0},
   207  			{"c_name", types.T_varchar, false, 25, 0},
   208  			{"c_address", types.T_varchar, false, 40, 0},
   209  			{"c_nationkey", types.T_int32, false, 0, 0},
   210  			{"c_phone", types.T_varchar, false, 15, 0},
   211  			{"c_acctbal", types.T_decimal64, false, 15, 2},
   212  			{"c_mktsegment", types.T_varchar, false, 10, 0},
   213  			{"c_comment", types.T_varchar, false, 117, 0},
   214  			{catalog.Row_ID, types.T_Rowid, false, 16, 0},
   215  		},
   216  		pks:    []int{0},
   217  		outcnt: SF * 15e4,
   218  	}
   219  	tpchSchema["orders"] = &Schema{
   220  		cols: []col{
   221  			{"o_orderkey", types.T_int64, false, 0, 0},
   222  			{"o_custkey", types.T_int32, false, 0, 0},
   223  			{"o_orderstatus", types.T_varchar, false, 1, 0},
   224  			{"o_totalprice", types.T_decimal64, false, 15, 2},
   225  			{"o_orderdate", types.T_date, false, 0, 0},
   226  			{"o_orderpriority", types.T_varchar, false, 15, 0},
   227  			{"o_clerk", types.T_varchar, false, 15, 0},
   228  			{"o_shippriority", types.T_int32, false, 0, 0},
   229  			{"o_comment", types.T_varchar, false, 79, 0},
   230  			{catalog.Row_ID, types.T_Rowid, false, 16, 0},
   231  		},
   232  		pks:    []int{0},
   233  		outcnt: SF * 15e5,
   234  	}
   235  	tpchSchema["lineitem"] = &Schema{
   236  		cols: []col{
   237  			{"l_orderkey", types.T_int64, false, 0, 0},
   238  			{"l_partkey", types.T_int32, false, 0, 0},
   239  			{"l_suppkey", types.T_int32, false, 0, 0},
   240  			{"l_linenumber", types.T_int32, false, 0, 0},
   241  			{"l_quantity", types.T_int32, false, 0, 0},
   242  			{"l_extendedprice", types.T_decimal64, false, 15, 2},
   243  			{"l_discount", types.T_decimal64, false, 15, 2},
   244  			{"l_tax", types.T_decimal64, false, 15, 2},
   245  			{"l_returnflag", types.T_varchar, false, 1, 0},
   246  			{"l_linestatus", types.T_varchar, false, 1, 0},
   247  			{"l_shipdate", types.T_date, false, 0, 0},
   248  			{"l_commitdate", types.T_date, false, 0, 0},
   249  			{"l_receiptdate", types.T_date, false, 0, 0},
   250  			{"l_shipinstruct", types.T_varchar, false, 25, 0},
   251  			{"l_shipmode", types.T_varchar, false, 10, 0},
   252  			{"l_comment", types.T_varchar, false, 44, 0},
   253  			{catalog.Row_ID, types.T_Rowid, false, 16, 0},
   254  		},
   255  		pks:    []int{0, 3},
   256  		outcnt: SF * 6e6,
   257  	}
   258  	// it's a view
   259  	tpchSchema["v1"] = &Schema{
   260  		cols: []col{
   261  			{"n_name", types.T_varchar, false, 50, 0},
   262  		},
   263  	}
   264  
   265  	moSchema["mo_database"] = &Schema{
   266  		cols: []col{
   267  			{"datname", types.T_varchar, false, 50, 0},
   268  			{"account_id", types.T_uint32, false, 0, 0},
   269  			{catalog.Row_ID, types.T_Rowid, false, 16, 0},
   270  		},
   271  	}
   272  	moSchema["mo_tables"] = &Schema{
   273  		cols: []col{
   274  			{"reldatabase", types.T_varchar, false, 50, 0},
   275  			{"relname", types.T_varchar, false, 50, 0},
   276  			{"relkind", types.T_varchar, false, 50, 0},
   277  			{"account_id", types.T_uint32, false, 0, 0},
   278  			{catalog.Row_ID, types.T_Rowid, false, 16, 0},
   279  		},
   280  	}
   281  	moSchema["mo_columns"] = &Schema{
   282  		cols: []col{
   283  			{"att_database", types.T_varchar, false, 50, 0},
   284  			{"att_relname", types.T_varchar, false, 50, 0},
   285  			{"attname", types.T_varchar, false, 50, 0},
   286  			{"atttyp", types.T_int32, false, 0, 0},
   287  			{"attnum", types.T_int32, false, 0, 0},
   288  			{"att_length", types.T_int32, false, 0, 0},
   289  			{"attnotnull", types.T_int8, false, 0, 0},
   290  			{"att_constraint_type", types.T_char, false, 1, 0},
   291  			{"att_default", types.T_varchar, false, 1024, 0},
   292  			{"att_comment", types.T_varchar, false, 1024, 0},
   293  			{"account_id", types.T_uint32, false, 0, 0},
   294  			{"att_is_hidden", types.T_bool, false, 0, 0},
   295  			{catalog.Row_ID, types.T_Rowid, false, 16, 0},
   296  		},
   297  	}
   298  	moSchema["mo_user"] = &Schema{
   299  		cols: []col{
   300  			{"user_id", types.T_int32, false, 50, 0},
   301  			{"user_host", types.T_varchar, false, 100, 0},
   302  			{"user_name", types.T_varchar, false, 300, 0},
   303  			{"authentication_string", types.T_varchar, false, 100, 0},
   304  			{"status", types.T_varchar, false, 100, 0},
   305  			{"created_time", types.T_timestamp, false, 0, 0},
   306  			{"expired_time", types.T_timestamp, false, 0, 0},
   307  			{"login_type", types.T_varchar, false, 100, 0},
   308  			{"creator", types.T_int32, false, 50, 0},
   309  			{"owner", types.T_int32, false, 50, 0},
   310  			{"default_role", types.T_int32, false, 50, 0},
   311  			{catalog.Row_ID, types.T_Rowid, false, 16, 0},
   312  		},
   313  	}
   314  
   315  	moSchema["mo_role_privs"] = &Schema{
   316  		cols: []col{
   317  			{"privilege_level", types.T_varchar, false, 100, 0},
   318  			{"obj_id", types.T_uint64, false, 100, 0},
   319  			{"obj_type", types.T_varchar, false, 16, 0},
   320  			{"role_id", types.T_int32, false, 50, 0},
   321  			{"role_name", types.T_varchar, false, 100, 0},
   322  			{"granted_time", types.T_timestamp, false, 0, 0},
   323  			{"operation_user_id", types.T_uint32, false, 50, 0},
   324  			{"privilege_name", types.T_varchar, false, 100, 0},
   325  			{"with_grant_option", types.T_bool, false, 0, 0},
   326  			{"privilege_id", types.T_int32, false, 50, 0},
   327  			{catalog.Row_ID, types.T_Rowid, false, 16, 0},
   328  		},
   329  	}
   330  
   331  	moSchema["mo_user_defined_function"] = &Schema{
   332  		cols: []col{
   333  			{"function_id", types.T_int32, false, 50, 0},
   334  			{"name", types.T_varchar, false, 100, 0},
   335  			{"args", types.T_text, false, 1000, 0},
   336  			{"retType", types.T_varchar, false, 20, 0},
   337  			{"body", types.T_text, false, 1000, 0},
   338  			{"language", types.T_varchar, false, 20, 0},
   339  			{"db", types.T_varchar, false, 100, 0},
   340  			{"definer", types.T_varchar, false, 50, 0},
   341  			{"modified_time", types.T_timestamp, false, 0, 0},
   342  			{"created_time", types.T_timestamp, false, 0, 0},
   343  			{"type", types.T_varchar, false, 10, 0},
   344  			{"security_type", types.T_varchar, false, 10, 0},
   345  			{"comment", types.T_varchar, false, 5000, 0},
   346  			{"character_set_client", types.T_varchar, false, 64, 0},
   347  			{"collation_connection", types.T_varchar, false, 64, 0},
   348  			{"database_collation", types.T_varchar, false, 64, 0},
   349  			{catalog.Row_ID, types.T_Rowid, false, 16, 0},
   350  		},
   351  	}
   352  
   353  	//---------------------------------------------constraint test schema---------------------------------------------------------
   354  	/*
   355  		create table emp(
   356  			empno int unsigned primary key,
   357  			ename varchar(15),
   358  			job varchar(10),
   359  			mgr int unsigned,
   360  			hiredate date,
   361  			sal decimal(7,2),
   362  			comm decimal(7,2),
   363  			deptno int unsigned,
   364  			unique key(ename, job),
   365  			foreign key (deptno) references dept(deptno)
   366  		);
   367  	*/
   368  	constraintTestSchema["emp"] = &Schema{
   369  		cols: []col{
   370  			{"empno", types.T_uint32, true, 32, 0},
   371  			{"ename", types.T_varchar, true, 15, 0},
   372  			{"job", types.T_varchar, true, 10, 0},
   373  			{"mgr", types.T_uint32, true, 32, 0},
   374  			{"hiredate", types.T_date, true, 0, 0},
   375  			{"sal", types.T_decimal64, true, 7, 0},
   376  			{"comm", types.T_decimal64, true, 7, 0},
   377  			{"deptno", types.T_uint32, true, 32, 0},
   378  			{"__mo_rowid", types.T_Rowid, true, 0, 0},
   379  		},
   380  		pks: []int{0}, // primary key "empno"
   381  		fks: []*plan.ForeignKeyDef{
   382  			{
   383  				Name:        "",                          // string
   384  				Cols:        []uint64{7},                 // []uint64
   385  				ForeignTbl:  272450,                      // uint64
   386  				ForeignCols: []uint64{1},                 // []uint64
   387  				OnDelete:    plan.ForeignKeyDef_RESTRICT, // ForeignKeyDef_RefAction
   388  				OnUpdate:    plan.ForeignKeyDef_RESTRICT, // ForeignKeyDef_RefAction
   389  			},
   390  		},
   391  		idxs: []index{
   392  			{
   393  				indexName: "",
   394  				tableName: "__mo_index_unique__412f4fad-77ba-11ed-b347-000c29847904",
   395  				parts:     []string{"ename", "job"},
   396  				cols: []col{
   397  					{"__mo_index_idx_col", types.T_varchar, true, 65535, 0},
   398  				},
   399  				tableExist: true,
   400  			},
   401  		},
   402  		outcnt: 14,
   403  	}
   404  
   405  	// index table
   406  	constraintTestSchema["__mo_index_unique__412f4fad-77ba-11ed-b347-000c29847904"] = &Schema{
   407  		cols: []col{
   408  			{"__mo_index_idx_col", types.T_varchar, true, 65535, 0},
   409  			{"__mo_index_pri_col", types.T_uint32, true, 32, 0},
   410  			{"__mo_rowid", types.T_Rowid, true, 0, 0},
   411  		},
   412  		pks:    []int{0},
   413  		outcnt: 13,
   414  	}
   415  
   416  	/*
   417  		create table dept(
   418  			deptno int unsigned auto_increment,
   419  			dname varchar(15),
   420  			loc varchar(50),
   421  			primary key(deptno),
   422  			unique index(dname)
   423  		);
   424  	*/
   425  	constraintTestSchema["dept"] = &Schema{
   426  		cols: []col{
   427  			{"deptno", types.T_uint32, true, 32, 0},
   428  			{"dname", types.T_varchar, true, 15, 0},
   429  			{"loc", types.T_varchar, true, 50, 0},
   430  			{"__mo_rowid", types.T_Rowid, true, 0, 0},
   431  		},
   432  		pks: []int{0}, // primary key "deptno"
   433  		idxs: []index{
   434  			{
   435  				indexName: "",
   436  				tableName: "__mo_index_unique__8e3246dd-7a19-11ed-ba7d-000c29847904",
   437  				parts:     []string{"dname"},
   438  				cols: []col{
   439  					{"__mo_index_idx_col", types.T_varchar, true, 15, 0},
   440  				},
   441  				tableExist: true,
   442  			},
   443  		},
   444  		outcnt: 4,
   445  	}
   446  
   447  	// index table
   448  	constraintTestSchema["__mo_index_unique__8e3246dd-7a19-11ed-ba7d-000c29847904"] = &Schema{
   449  		cols: []col{
   450  			{"__mo_index_idx_col", types.T_varchar, true, 15, 0},
   451  			{"__mo_index_pri_col", types.T_uint32, true, 32, 0},
   452  			{"__mo_rowid", types.T_Rowid, true, 0, 0},
   453  		},
   454  		pks:    []int{0},
   455  		outcnt: 4,
   456  	}
   457  	/*
   458  		create table products (
   459  			pid int not null,
   460  			pname varchar(50) not null,
   461  			description varchar(20) not null,
   462  			price decimal(9,2) not null
   463  		) cluster by(pid,pname);
   464  	*/
   465  	constraintTestSchema["products"] = &Schema{
   466  		cols: []col{
   467  			{"pid", types.T_int32, true, 32, 0},
   468  			{"pname", types.T_varchar, true, 50, 0},
   469  			{"description", types.T_varchar, true, 20, 0},
   470  			{"price", types.T_uint32, true, 9, 0},
   471  			{"__mo_cbkey_003pid005pname", types.T_varchar, true, 65535, 0},
   472  			{catalog.Row_ID, types.T_Rowid, false, 16, 0},
   473  		},
   474  		clusterby: &ClusterByDef{
   475  			Name: "__mo_cbkey_003pid005pname",
   476  		},
   477  		outcnt: 14,
   478  	}
   479  
   480  	//+----------+--------------+------+-----+---------+-------+
   481  	//| Field    | Type         | Null | Key | Default | Extra |
   482  	//+----------+--------------+------+-----+---------+-------+
   483  	//| empno    | int unsigned | YES  | MUL | NULL    |       |
   484  	//| ename    | varchar(15)  | YES  |     | NULL    |       |
   485  	//| job      | varchar(10)  | YES  |     | NULL    |       |
   486  	//| mgr      | int unsigned | YES  |     | NULL    |       |
   487  	//| hiredate | date         | YES  |     | NULL    |       |
   488  	//| sal      | decimal(7,2) | YES  |     | NULL    |       |
   489  	//| comm     | decimal(7,2) | YES  |     | NULL    |       |
   490  	//| deptno   | int unsigned | YES  |     | NULL    |       |
   491  	//+----------+--------------+------+-----+---------+-------+
   492  	constraintTestSchema["employees"] = &Schema{
   493  		cols: []col{
   494  			{"empno", types.T_uint32, true, 32, 0},
   495  			{"ename", types.T_varchar, true, 15, 0},
   496  			{"job", types.T_varchar, true, 10, 0},
   497  			{"mgr", types.T_uint32, true, 32, 0},
   498  			{"hiredate", types.T_date, true, 0, 0},
   499  			{"sal", types.T_decimal64, true, 7, 0},
   500  			{"comm", types.T_decimal64, true, 7, 0},
   501  			{"deptno", types.T_uint32, true, 32, 0},
   502  			{catalog.Row_ID, types.T_Rowid, false, 16, 0},
   503  		},
   504  		idxs: []index{
   505  			{
   506  				indexName: "",
   507  				tableName: "__mo_index_unique__6380d30e-79f8-11ed-9c02-000c29847904",
   508  				parts:     []string{"empno", "ename"},
   509  				cols: []col{
   510  					{"__mo_index_idx_col", types.T_varchar, true, 65535, 0},
   511  				},
   512  				tableExist: true,
   513  			},
   514  		},
   515  		outcnt: 14,
   516  	}
   517  
   518  	constraintTestSchema["__mo_index_unique__6380d30e-79f8-11ed-9c02-000c29847904"] = &Schema{
   519  		cols: []col{
   520  			{"__mo_index_idx_col", types.T_varchar, true, 65535, 0},
   521  			{catalog.Row_ID, types.T_Rowid, false, 16, 0},
   522  		},
   523  		pks:    []int{0},
   524  		outcnt: 12,
   525  	}
   526  
   527  	objects := make(map[string]*ObjectRef)
   528  	tables := make(map[string]*TableDef)
   529  	stats := make(map[string]*Stats)
   530  	pks := make(map[string][]int)
   531  	id2name := make(map[uint64]string)
   532  	// build tpch/mo context data(schema)
   533  	for db, schema := range schemas {
   534  		tableIdx := 0
   535  		for tableName, table := range schema {
   536  			colDefs := make([]*ColDef, 0, len(table.cols))
   537  
   538  			for idx, col := range table.cols {
   539  				colDefs = append(colDefs, &ColDef{
   540  					ColId: uint64(idx),
   541  					Typ: &plan.Type{
   542  						Id:          int32(col.Id),
   543  						NotNullable: !col.Nullable,
   544  						Precision:   col.Precision,
   545  						Scale:       col.Scale,
   546  					},
   547  					Name:  col.Name,
   548  					Pkidx: 1,
   549  					Default: &plan.Default{
   550  						NullAbility: col.Nullable,
   551  					},
   552  				})
   553  			}
   554  
   555  			objects[tableName] = &ObjectRef{
   556  				Server:     0,
   557  				Db:         0,
   558  				Schema:     0,
   559  				Obj:        int64(tableIdx),
   560  				ServerName: "",
   561  				DbName:     "",
   562  				SchemaName: db,
   563  				ObjName:    tableName,
   564  			}
   565  
   566  			tableDef := &TableDef{
   567  				TableType: catalog.SystemOrdinaryRel,
   568  				TblId:     uint64(tableIdx),
   569  				Name:      tableName,
   570  				Cols:      colDefs,
   571  				Indexes:   make([]*IndexDef, len(table.idxs)),
   572  			}
   573  
   574  			if table.idxs != nil {
   575  
   576  				for i, idx := range table.idxs {
   577  					indexdef := &plan.IndexDef{
   578  						IndexName:      idx.indexName,
   579  						Parts:          idx.parts,
   580  						Unique:         true,
   581  						IndexTableName: idx.tableName,
   582  						TableExist:     true,
   583  					}
   584  					tableDef.Indexes[i] = indexdef
   585  				}
   586  			}
   587  
   588  			if table.fks != nil {
   589  				tableDef.Fkeys = table.fks
   590  			}
   591  
   592  			if table.clusterby != nil {
   593  				tableDef.ClusterBy = &plan.ClusterByDef{
   594  					Name: "__mo_cbkey_003pid005pname",
   595  				}
   596  			}
   597  
   598  			if tableName != "v1" {
   599  				properties := []*plan.Property{
   600  					{
   601  						Key:   catalog.SystemRelAttr_Kind,
   602  						Value: catalog.SystemOrdinaryRel,
   603  					},
   604  					{
   605  						Key:   catalog.SystemRelAttr_Comment,
   606  						Value: tableName,
   607  					},
   608  				}
   609  				tableDef.Defs = append(tableDef.Defs, &plan.TableDef_DefType{
   610  					Def: &plan.TableDef_DefType_Properties{
   611  						Properties: &plan.PropertiesDef{
   612  							Properties: properties,
   613  						},
   614  					},
   615  				})
   616  			}
   617  
   618  			if tableName == "test_idx" {
   619  				indexParts := []string{"n_nationkey"}
   620  
   621  				p := &plan.IndexDef{
   622  					IndexName:      "idx1",
   623  					Parts:          indexParts,
   624  					Unique:         true,
   625  					IndexTableName: "nation",
   626  					TableExist:     true,
   627  				}
   628  				tableDef.Indexes = []*plan.IndexDef{p}
   629  			}
   630  
   631  			if tableName == "v1" {
   632  				tableDef.TableType = catalog.SystemViewRel
   633  				viewData, _ := json.Marshal(ViewData{
   634  					Stmt:            "select n_name from nation where n_nationkey > ?",
   635  					DefaultDatabase: "tpch",
   636  				})
   637  				tableDef.ViewSql = &plan.ViewDef{
   638  					View: string(viewData),
   639  				}
   640  				properties := []*plan.Property{
   641  					{
   642  						Key:   catalog.SystemRelAttr_Kind,
   643  						Value: catalog.SystemViewRel,
   644  					},
   645  				}
   646  				tableDef.Defs = append(tableDef.Defs, &plan.TableDef_DefType{
   647  					Def: &plan.TableDef_DefType_Properties{
   648  						Properties: &plan.PropertiesDef{
   649  							Properties: properties,
   650  						},
   651  					},
   652  				})
   653  			}
   654  
   655  			tables[tableName] = tableDef
   656  			id2name[tableDef.TblId] = tableName
   657  			tableIdx++
   658  
   659  			if table.outcnt == 0 {
   660  				table.outcnt = 1
   661  			}
   662  			stats[tableName] = &plan.Stats{
   663  				Outcnt: table.outcnt,
   664  			}
   665  
   666  			pks[tableName] = table.pks
   667  		}
   668  	}
   669  
   670  	return &MockCompilerContext{
   671  		isDml:   isDml,
   672  		objects: objects,
   673  		tables:  tables,
   674  		id2name: id2name,
   675  		stats:   stats,
   676  		pks:     pks,
   677  		ctx:     context.TODO(),
   678  	}
   679  }
   680  
   681  func (m *MockCompilerContext) DatabaseExists(name string) bool {
   682  	return strings.ToLower(name) == "tpch" || strings.ToLower(name) == "mo"
   683  }
   684  
   685  func (m *MockCompilerContext) DefaultDatabase() string {
   686  	return "tpch"
   687  }
   688  
   689  func (m *MockCompilerContext) GetRootSql() string {
   690  	return ""
   691  }
   692  
   693  func (m *MockCompilerContext) GetUserName() string {
   694  	return "root"
   695  }
   696  
   697  func (m *MockCompilerContext) Resolve(dbName string, tableName string) (*ObjectRef, *TableDef) {
   698  	name := strings.ToLower(tableName)
   699  	tableDef := DeepCopyTableDef(m.tables[name])
   700  	if tableDef != nil && !m.isDml {
   701  
   702  		for i, col := range tableDef.Cols {
   703  			if col.Typ.Id == int32(types.T_Rowid) {
   704  				tableDef.Cols = append(tableDef.Cols[:i], tableDef.Cols[i+1:]...)
   705  				break
   706  			}
   707  		}
   708  
   709  		for i, col := range tableDef.Cols {
   710  			isCPkey := util.JudgeIsCompositePrimaryKeyColumn(col.Name)
   711  			if isCPkey {
   712  				tableDef.Cols = append(tableDef.Cols[:i], tableDef.Cols[i+1:]...)
   713  				break
   714  			}
   715  		}
   716  	}
   717  	return m.objects[name], tableDef
   718  }
   719  
   720  func (m *MockCompilerContext) ResolveById(tableId uint64) (*ObjectRef, *TableDef) {
   721  	name := m.id2name[tableId]
   722  	tableDef := DeepCopyTableDef(m.tables[name])
   723  	if tableDef != nil && !m.isDml {
   724  		for i, col := range tableDef.Cols {
   725  			if col.Typ.Id == int32(types.T_Rowid) {
   726  				tableDef.Cols = append(tableDef.Cols[:i], tableDef.Cols[i+1:]...)
   727  				break
   728  			}
   729  		}
   730  	}
   731  	return m.objects[name], tableDef
   732  }
   733  
   734  func (m *MockCompilerContext) GetPrimaryKeyDef(dbName string, tableName string) []*ColDef {
   735  	defs := make([]*ColDef, 0, 2)
   736  	for _, pk := range m.pks[tableName] {
   737  		defs = append(defs, m.tables[tableName].Cols[pk])
   738  	}
   739  	return defs
   740  }
   741  
   742  func (m *MockCompilerContext) GetHideKeyDef(dbName string, tableName string) *ColDef {
   743  	return m.tables[tableName].Cols[len(m.tables[tableName].Cols)-1]
   744  }
   745  
   746  func (m *MockCompilerContext) Stats(obj *ObjectRef, e *Expr) *Stats {
   747  	return m.stats[obj.ObjName]
   748  }
   749  
   750  func (m *MockCompilerContext) GetAccountId() uint32 {
   751  	return 0
   752  }
   753  
   754  func (m *MockCompilerContext) GetContext() context.Context {
   755  	return m.ctx
   756  }
   757  
   758  func (m *MockCompilerContext) GetProcess() *process.Process {
   759  	return testutil.NewProc()
   760  }
   761  
   762  func (m *MockCompilerContext) GetQueryResultMeta(uuid string) ([]*ColDef, string, error) {
   763  	return nil, "", nil
   764  }
   765  
   766  func (m *MockCompilerContext) SetBuildingAlterView(yesOrNo bool, dbName, viewName string) {
   767  }
   768  
   769  func (m *MockCompilerContext) GetBuildingAlterView() (bool, string, string) {
   770  	return false, "", ""
   771  }
   772  
   773  type MockOptimizer struct {
   774  	ctxt MockCompilerContext
   775  }
   776  
   777  func NewEmptyMockOptimizer() *MockOptimizer {
   778  	return &MockOptimizer{
   779  		ctxt: *NewEmptyCompilerContext(),
   780  	}
   781  }
   782  
   783  func NewMockOptimizer(isDml bool) *MockOptimizer {
   784  	return &MockOptimizer{
   785  		ctxt: *NewMockCompilerContext(isDml),
   786  	}
   787  }
   788  
   789  func (moc *MockOptimizer) Optimize(stmt tree.Statement) (*Query, error) {
   790  	ctx := moc.CurrentContext()
   791  	query, err := BuildPlan(ctx, stmt)
   792  	if err != nil {
   793  		// logutil.Infof("Optimize statement error: '%v'", tree.String(stmt, dialect.MYSQL))
   794  		return nil, err
   795  	}
   796  	return query.GetQuery(), nil
   797  }
   798  
   799  func (moc *MockOptimizer) CurrentContext() CompilerContext {
   800  	return &moc.ctxt
   801  }