github.com/matrixorigin/matrixone@v1.2.0/pkg/sql/plan/partition_hash.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 "context" 19 "github.com/matrixorigin/matrixone/pkg/container/types" 20 "github.com/matrixorigin/matrixone/pkg/pb/plan" 21 "github.com/matrixorigin/matrixone/pkg/sql/parsers/dialect" 22 "github.com/matrixorigin/matrixone/pkg/sql/parsers/tree" 23 ) 24 25 // hashPartitionBuilder processes Hash Partition 26 type hashPartitionBuilder struct { 27 } 28 29 // buildHashPartition handle Hash Partitioning 30 func (hpb *hashPartitionBuilder) build(ctx context.Context, partitionBinder *PartitionBinder, stmt *tree.CreateTable, tableDef *TableDef) error { 31 partitionSyntaxDef := stmt.PartitionOption 32 partitionCount, err := getValidPartitionCount(ctx, false, partitionSyntaxDef) 33 if err != nil { 34 return err 35 } 36 partitionType := partitionSyntaxDef.PartBy.PType.(*tree.HashType) 37 partitionDef := &plan.PartitionByDef{ 38 PartitionNum: partitionCount, 39 IsSubPartition: partitionSyntaxDef.PartBy.IsSubPartition, 40 } 41 42 partitionDef.Type = plan.PartitionType_HASH 43 if partitionType.Linear { 44 partitionDef.Type = plan.PartitionType_LINEAR_HASH 45 } 46 47 // build partition expr 48 err = buildPartitionExpr(ctx, tableDef, partitionBinder, partitionDef, partitionType.Expr) 49 if err != nil { 50 return err 51 } 52 53 err = hpb.buildPartitionDefs(ctx, partitionBinder, partitionDef, partitionSyntaxDef.Partitions) 54 if err != nil { 55 return err 56 } 57 58 err = hpb.checkPartitionIntegrity(ctx, partitionBinder, tableDef, partitionDef) 59 if err != nil { 60 return err 61 } 62 63 err = hpb.buildEvalPartitionExpression(ctx, partitionBinder, stmt.PartitionOption, partitionDef) 64 if err != nil { 65 return err 66 } 67 68 partitionDef.PartitionMsg = tree.String(partitionSyntaxDef, dialect.MYSQL) 69 tableDef.Partition = partitionDef 70 return nil 71 } 72 73 // buildPartitionDefs decides the partition defs 74 func (hpb *hashPartitionBuilder) buildPartitionDefs(ctx context.Context, _ *PartitionBinder, 75 partitionDef *plan.PartitionByDef, syntaxDefs []*tree.Partition) error { 76 return buildPartitionDefs(ctx, partitionDef, syntaxDefs) 77 } 78 79 /* 80 checkTableDefPartition 81 check partition keys 82 check partition expr type 83 check partition defs constraints 84 */ 85 func (hpb *hashPartitionBuilder) checkPartitionIntegrity(ctx context.Context, partitionBinder *PartitionBinder, tableDef *TableDef, partitionDef *plan.PartitionByDef) error { 86 return checkPartitionIntegrity(ctx, partitionBinder, tableDef, partitionDef) 87 } 88 89 func (hpb *hashPartitionBuilder) buildEvalPartitionExpression(ctx context.Context, partitionBinder *PartitionBinder, 90 stmt *tree.PartitionOption, partitionDef *plan.PartitionByDef) error { 91 partitionType := stmt.PartBy.PType.(*tree.HashType) 92 // For the Hash partition, convert the partition information into the expression,such as: abs (hash_value (expr)) % partitionNum 93 hashExpr := partitionType.Expr 94 partitionAst := genPartitionAst(tree.Exprs{hashExpr}, int64(partitionDef.PartitionNum)) 95 96 tempExpr, err := partitionBinder.baseBindExpr(partitionAst, 0, true) 97 if err != nil { 98 return err 99 } 100 partitionExpression, err := appendCastBeforeExpr(ctx, tempExpr, plan.Type{ 101 Id: int32(types.T_int32), 102 NotNullable: true, 103 }) 104 if err != nil { 105 return err 106 } 107 partitionDef.PartitionExpression = partitionExpression 108 return nil 109 }