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 }