github.com/matrixorigin/matrixone@v1.2.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/catalog" 23 "github.com/matrixorigin/matrixone/pkg/common/moerr" 24 "github.com/matrixorigin/matrixone/pkg/container/types" 25 "github.com/matrixorigin/matrixone/pkg/pb/plan" 26 pb "github.com/matrixorigin/matrixone/pkg/pb/statsinfo" 27 "github.com/matrixorigin/matrixone/pkg/sql/parsers/tree" 28 "github.com/matrixorigin/matrixone/pkg/sql/plan/function" 29 "github.com/matrixorigin/matrixone/pkg/testutil" 30 "github.com/matrixorigin/matrixone/pkg/vm/process" 31 ) 32 33 type MockCompilerContext struct { 34 objects map[string]*ObjectRef 35 tables map[string]*TableDef 36 pks map[string][]int 37 id2name map[uint64]string 38 isDml bool 39 mysqlCompatible bool 40 41 // ctx default: nil 42 ctx context.Context 43 } 44 45 func (m *MockCompilerContext) GetViews() []string { 46 return nil 47 } 48 49 func (m *MockCompilerContext) SetViews(views []string) { 50 } 51 52 func (m *MockCompilerContext) GetSnapshot() *Snapshot { 53 return nil 54 } 55 56 func (m *MockCompilerContext) SetSnapshot(snapshot *Snapshot) {} 57 58 func (m *MockCompilerContext) ReplacePlan(execPlan *plan.Execute) (*plan.Plan, tree.Statement, error) { 59 //TODO implement me 60 panic("implement me") 61 } 62 63 func (m *MockCompilerContext) CheckSubscriptionValid(subName, accName string, pubName string) error { 64 //TODO implement me 65 panic("implement me") 66 } 67 68 func (m *MockCompilerContext) ResolveSubscriptionTableById(tableId uint64, pubmeta *SubscriptionMeta) (*ObjectRef, *TableDef) { 69 return nil, nil 70 } 71 72 func (m *MockCompilerContext) ResolveUdf(name string, ast []*plan.Expr) (*function.Udf, error) { 73 return nil, nil 74 } 75 76 func (m *MockCompilerContext) ResolveAccountIds(accountNames []string) ([]uint32, error) { 77 return []uint32{catalog.System_Account}, nil 78 } 79 80 func (m *MockCompilerContext) ResolveVariable(varName string, isSystemVar, isGlobalVar bool) (interface{}, error) { 81 vars := make(map[string]interface{}) 82 vars["str_var"] = "str" 83 vars["int_var"] = 20 84 vars["bool_var"] = false 85 vars["float_var"] = 20.20 86 dec, _ := types.ParseDecimal128("200.001", 38, 3) 87 vars["decimal_var"] = dec 88 vars["null_var"] = nil 89 90 if m.mysqlCompatible { 91 vars["sql_mode"] = "" 92 } else { 93 vars["sql_mode"] = "ONLY_FULL_GROUP_BY" 94 } 95 96 vars["foreign_key_checks"] = int64(1) 97 98 if result, ok := vars[varName]; ok { 99 return result, nil 100 } 101 102 return nil, moerr.NewInternalError(m.ctx, "var not found") 103 } 104 105 type col struct { 106 Name string 107 Id types.T 108 Nullable bool 109 Width int32 110 Scale int32 111 } 112 113 type index struct { 114 indexName string 115 tableName string 116 unique bool 117 parts []string 118 cols []col 119 tableExist bool 120 } 121 122 // NewEmptyCompilerContext for test create/drop statement 123 func NewEmptyCompilerContext() *MockCompilerContext { 124 return &MockCompilerContext{ 125 objects: make(map[string]*ObjectRef), 126 tables: make(map[string]*TableDef), 127 ctx: context.Background(), 128 } 129 } 130 131 type Schema struct { 132 cols []col 133 pks []int 134 idxs []index 135 fks []*ForeignKeyDef 136 clusterby *ClusterByDef 137 outcnt float64 138 tblId int64 139 } 140 141 const SF float64 = 1 142 143 func NewMockCompilerContext(isDml bool) *MockCompilerContext { 144 tpchSchema := make(map[string]*Schema) 145 moSchema := make(map[string]*Schema) 146 constraintTestSchema := make(map[string]*Schema) 147 148 schemas := map[string]map[string]*Schema{ 149 "tpch": tpchSchema, 150 "mo_catalog": moSchema, 151 "constraint_test": constraintTestSchema, 152 } 153 154 tpchSchema["nation"] = &Schema{ 155 cols: []col{ 156 {"n_nationkey", types.T_int32, false, 0, 0}, 157 {"n_name", types.T_varchar, false, 25, 0}, 158 {"n_regionkey", types.T_int32, false, 0, 0}, 159 {"n_comment", types.T_varchar, true, 152, 0}, 160 {catalog.Row_ID, types.T_Rowid, false, 16, 0}, 161 }, 162 pks: []int{0}, 163 outcnt: 25, 164 } 165 tpchSchema["nation2"] = &Schema{ 166 cols: []col{ //not exist in tpch, create for test NaturalJoin And UsingJoin 167 {"n_nationkey", types.T_int32, false, 0, 0}, 168 {"n_name", types.T_varchar, false, 25, 0}, 169 {"r_regionkey", types.T_int32, false, 0, 0}, //change N_REGIONKEY to R_REGIONKEY for test NaturalJoin And UsingJoin 170 {"n_comment", types.T_varchar, true, 152, 0}, 171 {catalog.Row_ID, types.T_Rowid, false, 16, 0}, 172 }, 173 pks: []int{0}, 174 outcnt: 25, 175 } 176 tpchSchema["test_idx"] = &Schema{ 177 cols: []col{ 178 {"n_nationkey", types.T_int32, false, 0, 0}, 179 {"n_name", types.T_varchar, false, 25, 0}, 180 {catalog.Row_ID, types.T_Rowid, false, 16, 0}, 181 }, 182 pks: []int{0}, 183 outcnt: 25, 184 } 185 tpchSchema["region"] = &Schema{ 186 cols: []col{ 187 {"r_regionkey", types.T_int32, false, 0, 0}, 188 {"r_name", types.T_varchar, false, 25, 0}, 189 {"r_comment", types.T_varchar, true, 152, 0}, 190 {catalog.Row_ID, types.T_Rowid, false, 16, 0}, 191 }, 192 pks: []int{0}, 193 outcnt: 5, 194 } 195 tpchSchema["part"] = &Schema{ 196 cols: []col{ 197 {"p_partkey", types.T_int32, false, 0, 0}, 198 {"p_name", types.T_varchar, false, 55, 0}, 199 {"p_mfgr", types.T_varchar, false, 25, 0}, 200 {"p_brand", types.T_varchar, false, 10, 0}, 201 {"p_type", types.T_varchar, false, 25, 0}, 202 {"p_size", types.T_int32, false, 0, 0}, 203 {"p_container", types.T_varchar, false, 10, 0}, 204 {"p_retailprice", types.T_decimal64, false, 15, 2}, 205 {"p_comment", types.T_varchar, false, 23, 0}, 206 {catalog.Row_ID, types.T_Rowid, false, 16, 0}, 207 }, 208 pks: []int{0}, 209 outcnt: SF * 2e5, 210 } 211 tpchSchema["supplier"] = &Schema{ 212 cols: []col{ 213 {"s_suppkey", types.T_int32, false, 0, 0}, 214 {"s_name", types.T_varchar, false, 25, 0}, 215 {"s_address", types.T_varchar, false, 40, 0}, 216 {"s_nationkey", types.T_int32, false, 0, 0}, 217 {"s_phone", types.T_varchar, false, 15, 0}, 218 {"s_acctbal", types.T_decimal64, false, 15, 2}, 219 {"s_comment", types.T_varchar, false, 101, 0}, 220 {catalog.Row_ID, types.T_Rowid, false, 16, 0}, 221 }, 222 pks: []int{0}, 223 outcnt: SF * 1e4, 224 } 225 tpchSchema["partsupp"] = &Schema{ 226 cols: []col{ 227 {"ps_partkey", types.T_int32, false, 0, 0}, 228 {"ps_suppkey", types.T_int32, false, 0, 0}, 229 {"ps_availqty", types.T_int32, false, 0, 0}, 230 {"ps_supplycost", types.T_decimal64, false, 15, 2}, 231 {"ps_comment", types.T_varchar, false, 199, 0}, 232 {catalog.Row_ID, types.T_Rowid, false, 16, 0}, 233 }, 234 pks: []int{0, 1}, 235 outcnt: SF * 8e5, 236 } 237 tpchSchema["customer"] = &Schema{ 238 cols: []col{ 239 {"c_custkey", types.T_int32, false, 0, 0}, 240 {"c_name", types.T_varchar, false, 25, 0}, 241 {"c_address", types.T_varchar, false, 40, 0}, 242 {"c_nationkey", types.T_int32, false, 0, 0}, 243 {"c_phone", types.T_varchar, false, 15, 0}, 244 {"c_acctbal", types.T_decimal64, false, 15, 2}, 245 {"c_mktsegment", types.T_varchar, false, 10, 0}, 246 {"c_comment", types.T_varchar, false, 117, 0}, 247 {catalog.Row_ID, types.T_Rowid, false, 16, 0}, 248 }, 249 pks: []int{0}, 250 outcnt: SF * 15e4, 251 } 252 tpchSchema["orders"] = &Schema{ 253 cols: []col{ 254 {"o_orderkey", types.T_int64, false, 0, 0}, 255 {"o_custkey", types.T_int32, false, 0, 0}, 256 {"o_orderstatus", types.T_varchar, false, 1, 0}, 257 {"o_totalprice", types.T_decimal64, false, 15, 2}, 258 {"o_orderdate", types.T_date, false, 0, 0}, 259 {"o_orderpriority", types.T_varchar, false, 15, 0}, 260 {"o_clerk", types.T_varchar, false, 15, 0}, 261 {"o_shippriority", types.T_int32, false, 0, 0}, 262 {"o_comment", types.T_varchar, false, 79, 0}, 263 {catalog.Row_ID, types.T_Rowid, false, 16, 0}, 264 }, 265 pks: []int{0}, 266 outcnt: SF * 15e5, 267 } 268 tpchSchema["lineitem"] = &Schema{ 269 cols: []col{ 270 {"l_orderkey", types.T_int64, false, 0, 0}, 271 {"l_partkey", types.T_int32, false, 0, 0}, 272 {"l_suppkey", types.T_int32, false, 0, 0}, 273 {"l_linenumber", types.T_int32, false, 0, 0}, 274 {"l_quantity", types.T_decimal64, false, 15, 2}, 275 {"l_extendedprice", types.T_decimal64, false, 15, 2}, 276 {"l_discount", types.T_decimal64, false, 15, 2}, 277 {"l_tax", types.T_decimal64, false, 15, 2}, 278 {"l_returnflag", types.T_varchar, false, 1, 0}, 279 {"l_linestatus", types.T_varchar, false, 1, 0}, 280 {"l_shipdate", types.T_date, false, 0, 0}, 281 {"l_commitdate", types.T_date, false, 0, 0}, 282 {"l_receiptdate", types.T_date, false, 0, 0}, 283 {"l_shipinstruct", types.T_varchar, false, 25, 0}, 284 {"l_shipmode", types.T_varchar, false, 10, 0}, 285 {"l_comment", types.T_varchar, false, 44, 0}, 286 {catalog.Row_ID, types.T_Rowid, false, 16, 0}, 287 }, 288 pks: []int{0, 3}, 289 outcnt: SF * 6e6, 290 } 291 // it's a view 292 tpchSchema["v1"] = &Schema{ 293 cols: []col{ 294 {"n_name", types.T_varchar, false, 50, 0}, 295 }, 296 } 297 298 moSchema["mo_database"] = &Schema{ 299 cols: []col{ 300 {"datname", types.T_varchar, false, 50, 0}, 301 {"account_id", types.T_uint32, false, 0, 0}, 302 {"dat_createsql", types.T_varchar, false, 1024, 0}, 303 {catalog.Row_ID, types.T_Rowid, false, 16, 0}, 304 }, 305 pks: []int{0}, 306 } 307 moSchema["mo_tables"] = &Schema{ 308 cols: []col{ 309 {"reldatabase", types.T_varchar, false, 50, 0}, 310 {"relname", types.T_varchar, false, 50, 0}, 311 {"relkind", types.T_varchar, false, 50, 0}, 312 {"account_id", types.T_uint32, false, 0, 0}, 313 {catalog.Row_ID, types.T_Rowid, false, 16, 0}, 314 }, 315 pks: []int{0, 1}, 316 } 317 moSchema["mo_columns"] = &Schema{ 318 cols: []col{ 319 {"att_uniq_name", types.T_varchar, false, 256, 0}, 320 {"account_id", types.T_uint32, false, 0, 0}, 321 {"att_database_id", types.T_uint32, false, 0, 0}, 322 {"att_database", types.T_varchar, false, 50, 0}, 323 {"att_relname_id", types.T_uint32, false, 0, 0}, 324 {"att_relname", types.T_varchar, false, 50, 0}, 325 {"attname", types.T_varchar, false, 50, 0}, 326 {"atttyp", types.T_int32, false, 0, 0}, 327 {"attnum", types.T_int32, false, 0, 0}, 328 {"att_length", types.T_int32, false, 0, 0}, 329 {"attnotnull", types.T_int8, false, 0, 0}, 330 {"atthasdef", types.T_int8, false, 0, 0}, 331 {"att_default", types.T_varchar, false, 2048, 0}, 332 {"attisdropped", types.T_int8, false, 0, 0}, 333 {"att_constraint_type", types.T_varchar, false, 1, 0}, 334 {"att_is_unsigned", types.T_int8, false, 0, 0}, 335 {"att_is_auto_increment", types.T_int8, false, 0, 0}, 336 {"att_comment", types.T_varchar, false, 1024, 0}, 337 {"att_is_hidden", types.T_bool, false, 0, 0}, 338 {"attr_has_update", types.T_int8, false, 0, 0}, 339 {"attr_update", types.T_varchar, false, 2048, 0}, 340 {"att_attr_is_clusterby", types.T_int8, false, 0, 0}, 341 {"attr_seqnum", types.T_int8, false, 0, 0}, 342 {"attr_enum", types.T_varchar, false, 2048, 0}, 343 {catalog.Row_ID, types.T_Rowid, false, 16, 0}, 344 }, 345 pks: []int{0}, 346 } 347 moSchema["mo_user"] = &Schema{ 348 cols: []col{ 349 {"user_id", types.T_int32, false, 50, 0}, 350 {"user_host", types.T_varchar, false, 100, 0}, 351 {"user_name", types.T_varchar, false, 300, 0}, 352 {"authentication_string", types.T_varchar, false, 100, 0}, 353 {"status", types.T_varchar, false, 100, 0}, 354 {"created_time", types.T_timestamp, false, 0, 0}, 355 {"expired_time", types.T_timestamp, false, 0, 0}, 356 {"login_type", types.T_varchar, false, 100, 0}, 357 {"creator", types.T_int32, false, 50, 0}, 358 {"owner", types.T_int32, false, 50, 0}, 359 {"default_role", types.T_int32, false, 50, 0}, 360 {catalog.Row_ID, types.T_Rowid, false, 16, 0}, 361 }, 362 pks: []int{0}, 363 } 364 365 moSchema["mo_role_privs"] = &Schema{ 366 cols: []col{ 367 {"privilege_level", types.T_varchar, false, 100, 0}, 368 {"obj_id", types.T_uint64, false, 100, 0}, 369 {"obj_type", types.T_varchar, false, 16, 0}, 370 {"role_id", types.T_int32, false, 50, 0}, 371 {"role_name", types.T_varchar, false, 100, 0}, 372 {"granted_time", types.T_timestamp, false, 0, 0}, 373 {"operation_user_id", types.T_uint32, false, 50, 0}, 374 {"privilege_name", types.T_varchar, false, 100, 0}, 375 {"with_grant_option", types.T_bool, false, 0, 0}, 376 {"privilege_id", types.T_int32, false, 50, 0}, 377 {catalog.Row_ID, types.T_Rowid, false, 16, 0}, 378 }, 379 } 380 381 moSchema["mo_user_defined_function"] = &Schema{ 382 cols: []col{ 383 {"function_id", types.T_int32, false, 50, 0}, 384 {"name", types.T_varchar, false, 100, 0}, 385 {"creator", types.T_uint64, false, 50, 0}, 386 {"args", types.T_text, false, 1000, 0}, 387 {"retType", types.T_varchar, false, 20, 0}, 388 {"body", types.T_text, false, 1000, 0}, 389 {"language", types.T_varchar, false, 20, 0}, 390 {"db", types.T_varchar, false, 100, 0}, 391 {"definer", types.T_varchar, false, 50, 0}, 392 {"modified_time", types.T_timestamp, false, 0, 0}, 393 {"created_time", types.T_timestamp, false, 0, 0}, 394 {"type", types.T_varchar, false, 10, 0}, 395 {"security_type", types.T_varchar, false, 10, 0}, 396 {"comment", types.T_varchar, false, 5000, 0}, 397 {"character_set_client", types.T_varchar, false, 64, 0}, 398 {"collation_connection", types.T_varchar, false, 64, 0}, 399 {"database_collation", types.T_varchar, false, 64, 0}, 400 {catalog.Row_ID, types.T_Rowid, false, 16, 0}, 401 }, 402 pks: []int{0}, 403 } 404 405 moSchema["mo_indexes"] = &Schema{ 406 cols: []col{ 407 {"id", types.T_uint64, false, 100, 0}, 408 {"table_id", types.T_uint64, false, 100, 0}, 409 {"database_id", types.T_uint64, false, 100, 0}, 410 {"name", types.T_varchar, false, 64, 0}, 411 {"type", types.T_varchar, false, 11, 0}, 412 {"algo", types.T_varchar, false, 11, 0}, 413 {"algo_table_type", types.T_varchar, false, 11, 0}, 414 {"algo_params", types.T_varchar, false, 2048, 0}, 415 {"is_visible", types.T_int8, false, 50, 0}, 416 {"hidden", types.T_int8, false, 50, 0}, 417 {"comment", types.T_varchar, false, 2048, 0}, 418 {"column_name", types.T_varchar, false, 256, 0}, 419 {"ordinal_position", types.T_uint32, false, 50, 0}, 420 {"options", types.T_text, true, 50, 0}, 421 {"index_table_name", types.T_varchar, true, 50, 0}, 422 {catalog.Row_ID, types.T_Rowid, false, 16, 0}, 423 }, 424 pks: []int{0}, 425 } 426 427 moSchema["mo_role"] = &Schema{ 428 cols: []col{ 429 {"role_id", types.T_uint64, false, 100, 0}, 430 {"role_name", types.T_varchar, false, 64, 0}, 431 {"creator", types.T_int64, false, 50, 0}, 432 {"owner", types.T_int64, false, 50, 0}, 433 {"created_time", types.T_timestamp, false, 0, 0}, 434 {"comments", types.T_varchar, false, 2048, 0}, 435 }, 436 pks: []int{0}, 437 } 438 439 moSchema["mo_stages"] = &Schema{ 440 cols: []col{ 441 {"stage_id", types.T_uint64, false, 100, 0}, 442 {"stage_name", types.T_varchar, false, 64, 0}, 443 {"url", types.T_varchar, false, 50, 0}, 444 {"stage_credentials", types.T_varchar, false, 50, 0}, 445 {"stage_status", types.T_varchar, false, 50, 0}, 446 {"created_time", types.T_timestamp, false, 0, 0}, 447 {"comment", types.T_varchar, false, 2048, 0}, 448 }, 449 } 450 451 moSchema["mo_snapshots"] = &Schema{ 452 cols: []col{ 453 {"snapshot_id", types.T_uuid, false, 100, 0}, 454 {"sname", types.T_varchar, false, 64, 0}, 455 {"ts", types.T_int64, false, 50, 0}, 456 {"level", types.T_enum, false, 50, 0}, 457 {"account_name", types.T_varchar, false, 50, 0}, 458 {"database_name", types.T_varchar, false, 50, 0}, 459 {"table_name", types.T_varchar, false, 50, 0}, 460 {"obj_id", types.T_uint64, false, 100, 0}, 461 }, 462 pks: []int{0}, 463 } 464 465 //---------------------------------------------constraint test schema--------------------------------------------------------- 466 /* 467 create table emp( 468 empno int unsigned primary key, 469 ename varchar(15), 470 job varchar(10), 471 mgr int unsigned, 472 hiredate date, 473 sal decimal(7,2), 474 comm decimal(7,2), 475 deptno int unsigned, 476 unique key(ename, job), 477 key (ename, job), 478 foreign key (deptno) references dept(deptno) 479 ); 480 */ 481 constraintTestSchema["emp"] = &Schema{ 482 cols: []col{ 483 {"empno", types.T_uint32, true, 32, 0}, 484 {"ename", types.T_varchar, true, 15, 0}, 485 {"job", types.T_varchar, true, 10, 0}, 486 {"mgr", types.T_uint32, true, 32, 0}, 487 {"hiredate", types.T_date, true, 0, 0}, 488 {"sal", types.T_decimal64, true, 7, 0}, 489 {"comm", types.T_decimal64, true, 7, 0}, 490 {"deptno", types.T_uint32, true, 32, 0}, 491 {catalog.Row_ID, types.T_Rowid, true, 0, 0}, 492 }, 493 pks: []int{0}, // primary key "empno" 494 fks: []*plan.ForeignKeyDef{ 495 { 496 Name: "fk1", // string 497 Cols: []uint64{7}, // []uint64 498 ForeignTbl: 88888, // uint64 499 ForeignCols: []uint64{1}, // []uint64 500 OnDelete: plan.ForeignKeyDef_RESTRICT, // ForeignKeyDef_RefAction 501 OnUpdate: plan.ForeignKeyDef_RESTRICT, // ForeignKeyDef_RefAction 502 }, 503 }, 504 idxs: []index{ 505 { 506 indexName: "", 507 tableName: catalog.UniqueIndexTableNamePrefix + "412f4fad-77ba-11ed-b347-000c29847904", 508 parts: []string{"ename", "job"}, 509 cols: []col{ 510 {catalog.IndexTableIndexColName, types.T_varchar, true, 65535, 0}, 511 }, 512 tableExist: true, 513 unique: true, 514 }, 515 { 516 indexName: "", 517 tableName: catalog.SecondaryIndexTableNamePrefix + "512f4fad-77ba-11ed-b347-000c29847904", 518 parts: []string{"ename", "job"}, 519 cols: []col{ 520 {catalog.IndexTableIndexColName, types.T_varchar, true, 65535, 0}, 521 }, 522 tableExist: true, 523 unique: false, 524 }, 525 }, 526 outcnt: 14, 527 } 528 529 // index table 530 constraintTestSchema[catalog.UniqueIndexTableNamePrefix+"412f4fad-77ba-11ed-b347-000c29847904"] = &Schema{ 531 cols: []col{ 532 {catalog.IndexTableIndexColName, types.T_varchar, true, 65535, 0}, 533 {catalog.IndexTablePrimaryColName, types.T_uint32, true, 32, 0}, 534 {catalog.Row_ID, types.T_Rowid, true, 0, 0}, 535 }, 536 pks: []int{0}, 537 outcnt: 13, 538 } 539 constraintTestSchema[catalog.SecondaryIndexTableNamePrefix+"512f4fad-77ba-11ed-b347-000c29847904"] = &Schema{ 540 cols: []col{ 541 {catalog.IndexTableIndexColName, types.T_varchar, true, 65535, 0}, 542 {catalog.IndexTablePrimaryColName, types.T_uint32, true, 32, 0}, 543 {catalog.Row_ID, types.T_Rowid, true, 0, 0}, 544 }, 545 pks: []int{0}, 546 outcnt: 13, 547 } 548 549 /* 550 create table dept( 551 deptno int unsigned auto_increment, 552 dname varchar(15), 553 loc varchar(50), 554 primary key(deptno), 555 unique index(dname) 556 ); 557 */ 558 constraintTestSchema["dept"] = &Schema{ 559 tblId: 88888, 560 cols: []col{ 561 {"deptno", types.T_uint32, true, 32, 0}, 562 {"dname", types.T_varchar, true, 15, 0}, 563 {"loc", types.T_varchar, true, 50, 0}, 564 {catalog.Row_ID, types.T_Rowid, true, 0, 0}, 565 }, 566 pks: []int{0}, // primary key "deptno" 567 idxs: []index{ 568 { 569 indexName: "", 570 tableName: catalog.UniqueIndexTableNamePrefix + "8e3246dd-7a19-11ed-ba7d-000c29847904", 571 parts: []string{"dname"}, 572 cols: []col{ 573 {catalog.IndexTableIndexColName, types.T_varchar, true, 15, 0}, 574 }, 575 tableExist: true, 576 unique: true, 577 }, 578 }, 579 outcnt: 4, 580 } 581 582 // index table 583 constraintTestSchema[catalog.UniqueIndexTableNamePrefix+"8e3246dd-7a19-11ed-ba7d-000c29847904"] = &Schema{ 584 cols: []col{ 585 {catalog.IndexTableIndexColName, types.T_varchar, true, 15, 0}, 586 {catalog.IndexTablePrimaryColName, types.T_uint32, true, 32, 0}, 587 {catalog.Row_ID, types.T_Rowid, true, 0, 0}, 588 }, 589 pks: []int{0}, 590 outcnt: 4, 591 } 592 /* 593 create table products ( 594 pid int not null, 595 pname varchar(50) not null, 596 description varchar(20) not null, 597 price decimal(9,2) not null 598 ) cluster by(pid,pname); 599 */ 600 constraintTestSchema["products"] = &Schema{ 601 cols: []col{ 602 {"pid", types.T_int32, true, 32, 0}, 603 {"pname", types.T_varchar, true, 50, 0}, 604 {"description", types.T_varchar, true, 20, 0}, 605 {"price", types.T_uint32, true, 9, 0}, 606 {"__mo_cbkey_003pid005pname", types.T_varchar, true, 65535, 0}, 607 {catalog.Row_ID, types.T_Rowid, false, 16, 0}, 608 }, 609 clusterby: &ClusterByDef{ 610 Name: "__mo_cbkey_003pid005pname", 611 }, 612 outcnt: 14, 613 } 614 615 //+----------+--------------+------+-----+---------+-------+ 616 //| Field | Type | Null | Key | Default | Extra | 617 //+----------+--------------+------+-----+---------+-------+ 618 //| empno | int unsigned | YES | MUL | NULL | | 619 //| ename | varchar(15) | YES | | NULL | | 620 //| job | varchar(10) | YES | | NULL | | 621 //| mgr | int unsigned | YES | | NULL | | 622 //| hiredate | date | YES | | NULL | | 623 //| sal | decimal(7,2) | YES | | NULL | | 624 //| comm | decimal(7,2) | YES | | NULL | | 625 //| deptno | int unsigned | YES | | NULL | | 626 //+----------+--------------+------+-----+---------+-------+ 627 constraintTestSchema["employees"] = &Schema{ 628 cols: []col{ 629 {"empno", types.T_uint32, true, 32, 0}, 630 {"ename", types.T_varchar, true, 15, 0}, 631 {"job", types.T_varchar, true, 10, 0}, 632 {"mgr", types.T_uint32, true, 32, 0}, 633 {"hiredate", types.T_date, true, 0, 0}, 634 {"sal", types.T_decimal64, true, 7, 0}, 635 {"comm", types.T_decimal64, true, 7, 0}, 636 {"deptno", types.T_uint32, true, 32, 0}, 637 {catalog.Row_ID, types.T_Rowid, false, 16, 0}, 638 }, 639 pks: []int{0}, // primary key "deptno" 640 idxs: []index{ 641 { 642 indexName: "", 643 tableName: catalog.UniqueIndexTableNamePrefix + "6380d30e-79f8-11ed-9c02-000c29847904", 644 parts: []string{"empno", "ename"}, 645 cols: []col{ 646 {catalog.IndexTableIndexColName, types.T_varchar, true, 65535, 0}, 647 }, 648 tableExist: true, 649 unique: true, 650 }, 651 }, 652 outcnt: 14, 653 } 654 655 constraintTestSchema[catalog.UniqueIndexTableNamePrefix+"6380d30e-79f8-11ed-9c02-000c29847904"] = &Schema{ 656 cols: []col{ 657 {catalog.IndexTableIndexColName, types.T_varchar, true, 65535, 0}, 658 {catalog.Row_ID, types.T_Rowid, false, 16, 0}, 659 }, 660 pks: []int{0}, 661 outcnt: 12, 662 } 663 664 constraintTestSchema["t1"] = &Schema{ 665 cols: []col{ 666 {"a", types.T_int64, false, 0, 0}, 667 {"b", types.T_varchar, false, 1, 0}, 668 {catalog.Row_ID, types.T_Rowid, false, 16, 0}, 669 }, 670 pks: []int{0}, 671 outcnt: 4, 672 } 673 674 objects := make(map[string]*ObjectRef) 675 tables := make(map[string]*TableDef) 676 stats := make(map[string]*Stats) 677 pks := make(map[string][]int) 678 id2name := make(map[uint64]string) 679 // build tpch/mo context data(schema) 680 for db, schema := range schemas { 681 tableIdx := 0 682 for tableName, table := range schema { 683 tblId := table.tblId 684 if tblId == 0 { 685 tblId = int64(tableIdx) 686 } 687 colDefs := make([]*ColDef, 0, len(table.cols)) 688 689 for idx, col := range table.cols { 690 colDefs = append(colDefs, &ColDef{ 691 ColId: uint64(idx), 692 Typ: plan.Type{ 693 Id: int32(col.Id), 694 NotNullable: !col.Nullable, 695 Width: col.Width, 696 Scale: col.Scale, 697 }, 698 Name: col.Name, 699 Primary: idx == 0, 700 Hidden: col.Name == catalog.Row_ID || col.Name == catalog.CPrimaryKeyColName, 701 Pkidx: 1, 702 Default: &plan.Default{ 703 NullAbility: col.Nullable, 704 }, 705 }) 706 } 707 708 objects[tableName] = &ObjectRef{ 709 Server: 0, 710 Db: 0, 711 Schema: 0, 712 Obj: int64(tableIdx), 713 ServerName: "", 714 DbName: "", 715 SchemaName: db, 716 ObjName: tableName, 717 } 718 719 tableDef := &TableDef{ 720 TableType: catalog.SystemOrdinaryRel, 721 TblId: uint64(tblId), 722 Name: tableName, 723 Cols: colDefs, 724 Indexes: make([]*IndexDef, len(table.idxs)), 725 } 726 if len(table.pks) == 1 { 727 tableDef.Pkey = &plan.PrimaryKeyDef{ 728 PkeyColName: colDefs[table.pks[0]].Name, 729 Cols: []uint64{uint64(table.pks[0])}, 730 Names: []string{colDefs[table.pks[0]].Name}, 731 CompPkeyCol: colDefs[table.pks[0]], 732 } 733 } else if len(table.pks) > 1 { 734 names := make([]string, len(table.pks)) 735 cols := make([]uint64, len(table.pks)) 736 for pkidx := range table.pks { 737 names = append(names, colDefs[table.pks[pkidx]].Name) 738 cols = append(cols, uint64(pkidx)) 739 } 740 pkName := catalog.PrefixCBColName + "_" + tableName 741 tableDef.Pkey = &plan.PrimaryKeyDef{ 742 PkeyColName: pkName, 743 Names: names, 744 Cols: cols, 745 CompPkeyCol: MakeHiddenColDefByName(pkName), 746 } 747 } 748 749 if table.idxs != nil { 750 for i, idx := range table.idxs { 751 indexdef := &plan.IndexDef{ 752 IndexName: idx.indexName, 753 Parts: idx.parts, 754 Unique: idx.unique, 755 IndexTableName: idx.tableName, 756 TableExist: true, 757 } 758 tableDef.Indexes[i] = indexdef 759 } 760 } 761 762 if table.fks != nil { 763 tableDef.Fkeys = table.fks 764 } 765 766 if table.clusterby != nil { 767 tableDef.ClusterBy = &plan.ClusterByDef{ 768 Name: "__mo_cbkey_003pid005pname", 769 } 770 } 771 772 if tableName != "v1" { 773 properties := []*plan.Property{ 774 { 775 Key: catalog.SystemRelAttr_Kind, 776 Value: catalog.SystemOrdinaryRel, 777 }, 778 { 779 Key: catalog.SystemRelAttr_Comment, 780 Value: tableName, 781 }, 782 } 783 tableDef.Defs = append(tableDef.Defs, &plan.TableDef_DefType{ 784 Def: &plan.TableDef_DefType_Properties{ 785 Properties: &plan.PropertiesDef{ 786 Properties: properties, 787 }, 788 }, 789 }) 790 } 791 792 if tableName == "test_idx" { 793 indexParts := []string{"n_nationkey"} 794 795 p := &plan.IndexDef{ 796 IndexName: "idx1", 797 Parts: indexParts, 798 Unique: true, 799 IndexTableName: "nation", 800 TableExist: true, 801 } 802 tableDef.Indexes = []*plan.IndexDef{p} 803 } 804 805 if tableName == "v1" { 806 tableDef.TableType = catalog.SystemViewRel 807 viewData, _ := json.Marshal(ViewData{ 808 Stmt: "select n_name from nation where n_nationkey > ?", 809 DefaultDatabase: "tpch", 810 }) 811 tableDef.ViewSql = &plan.ViewDef{ 812 View: string(viewData), 813 } 814 properties := []*plan.Property{ 815 { 816 Key: catalog.SystemRelAttr_Kind, 817 Value: catalog.SystemViewRel, 818 }, 819 } 820 tableDef.Defs = append(tableDef.Defs, &plan.TableDef_DefType{ 821 Def: &plan.TableDef_DefType_Properties{ 822 Properties: &plan.PropertiesDef{ 823 Properties: properties, 824 }, 825 }, 826 }) 827 } 828 829 tables[tableName] = tableDef 830 id2name[tableDef.TblId] = tableName 831 tableIdx++ 832 833 if table.outcnt == 0 { 834 table.outcnt = 1 835 } 836 stats[tableName] = &plan.Stats{ 837 Outcnt: table.outcnt, 838 } 839 840 pks[tableName] = table.pks 841 } 842 } 843 844 return &MockCompilerContext{ 845 isDml: isDml, 846 objects: objects, 847 tables: tables, 848 id2name: id2name, 849 pks: pks, 850 ctx: context.TODO(), 851 } 852 } 853 854 func (m *MockCompilerContext) DatabaseExists(name string, snapshot Snapshot) bool { 855 return strings.ToLower(name) == "tpch" || strings.ToLower(name) == "mo" || strings.ToLower(name) == "mo_catalog" 856 } 857 858 func (m *MockCompilerContext) GetDatabaseId(dbName string, snapshot Snapshot) (uint64, error) { 859 return 0, nil 860 } 861 862 func (m *MockCompilerContext) DefaultDatabase() string { 863 return "tpch" 864 } 865 866 func (m *MockCompilerContext) GetRootSql() string { 867 return "" 868 } 869 870 func (m *MockCompilerContext) GetUserName() string { 871 return "root" 872 } 873 874 func (m *MockCompilerContext) Resolve(dbName string, tableName string, snapshot Snapshot) (*ObjectRef, *TableDef) { 875 name := strings.ToLower(tableName) 876 tableDef := DeepCopyTableDef(m.tables[name], true) 877 if tableDef != nil && !m.isDml { 878 for i, col := range tableDef.Cols { 879 if col.Typ.Id == int32(types.T_Rowid) { 880 tableDef.Cols = append(tableDef.Cols[:i], tableDef.Cols[i+1:]...) 881 break 882 } 883 } 884 885 for i, col := range tableDef.Cols { 886 // judege whether it is a composite primary key 887 if col.Name == catalog.CPrimaryKeyColName { 888 tableDef.Cols = append(tableDef.Cols[:i], tableDef.Cols[i+1:]...) 889 break 890 } 891 } 892 } 893 return m.objects[name], tableDef 894 } 895 896 func (m *MockCompilerContext) ResolveById(tableId uint64, snapshot Snapshot) (*ObjectRef, *TableDef) { 897 name := m.id2name[tableId] 898 tableDef := DeepCopyTableDef(m.tables[name], true) 899 if tableDef != nil && !m.isDml { 900 for i, col := range tableDef.Cols { 901 if col.Typ.Id == int32(types.T_Rowid) { 902 tableDef.Cols = append(tableDef.Cols[:i], tableDef.Cols[i+1:]...) 903 break 904 } 905 } 906 } 907 return m.objects[name], tableDef 908 } 909 910 func (m *MockCompilerContext) GetPrimaryKeyDef(dbName string, tableName string, snapshot Snapshot) []*ColDef { 911 defs := make([]*ColDef, 0, 2) 912 for _, pk := range m.pks[tableName] { 913 defs = append(defs, m.tables[tableName].Cols[pk]) 914 } 915 return defs 916 } 917 918 func (m *MockCompilerContext) Stats(obj *ObjectRef, snapshot Snapshot) (*pb.StatsInfo, error) { 919 return nil, nil 920 } 921 922 func (m *MockCompilerContext) GetStatsCache() *StatsCache { 923 return nil 924 } 925 926 func (m *MockCompilerContext) GetAccountId() (uint32, error) { 927 return 0, nil 928 } 929 930 func (m *MockCompilerContext) GetContext() context.Context { 931 return m.ctx 932 } 933 934 func (m *MockCompilerContext) GetProcess() *process.Process { 935 return testutil.NewProc() 936 } 937 938 func (m *MockCompilerContext) GetQueryResultMeta(uuid string) ([]*ColDef, string, error) { 939 return nil, "", nil 940 } 941 942 func (m *MockCompilerContext) SetBuildingAlterView(yesOrNo bool, dbName, viewName string) { 943 } 944 945 func (m *MockCompilerContext) GetBuildingAlterView() (bool, string, string) { 946 return false, "", "" 947 } 948 949 func (m *MockCompilerContext) GetSubscriptionMeta(dbName string, snapshot Snapshot) (*SubscriptionMeta, error) { 950 return nil, nil 951 } 952 func (m *MockCompilerContext) SetQueryingSubscription(*SubscriptionMeta) { 953 954 } 955 func (m *MockCompilerContext) GetQueryingSubscription() *SubscriptionMeta { 956 return nil 957 } 958 func (m *MockCompilerContext) IsPublishing(dbName string) (bool, error) { 959 return false, nil 960 } 961 962 func (m *MockCompilerContext) ResolveSnapshotWithSnapshotName(snapshotName string) (*Snapshot, error) { 963 return nil, nil 964 } 965 966 func (m *MockCompilerContext) CheckTimeStampValid(ts int64) (bool, error) { 967 return false, nil 968 } 969 970 type MockOptimizer struct { 971 ctxt MockCompilerContext 972 } 973 974 func NewEmptyMockOptimizer() *MockOptimizer { 975 return &MockOptimizer{ 976 ctxt: *NewEmptyCompilerContext(), 977 } 978 } 979 980 func NewMockOptimizer(_ bool) *MockOptimizer { 981 return &MockOptimizer{ 982 ctxt: *NewMockCompilerContext(true), 983 } 984 } 985 986 func (moc *MockOptimizer) Optimize(stmt tree.Statement) (*Query, error) { 987 ctx := moc.CurrentContext() 988 query, err := BuildPlan(ctx, stmt, false) 989 if err != nil { 990 // logutil.Infof("Optimize statement error: '%v'", tree.String(stmt, dialect.MYSQL)) 991 return nil, err 992 } 993 return query.GetQuery(), nil 994 } 995 996 func (moc *MockOptimizer) CurrentContext() CompilerContext { 997 return &moc.ctxt 998 }