github.com/matrixorigin/matrixone@v1.2.0/pkg/sql/util/composite_clusterby_util.go (about)

     1  // Copyright 2021 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 util
    16  
    17  import (
    18  	"github.com/matrixorigin/matrixone/pkg/sql/plan/function"
    19  	"strconv"
    20  
    21  	"github.com/fagongzi/util/format"
    22  	"github.com/matrixorigin/matrixone/pkg/catalog"
    23  	"github.com/matrixorigin/matrixone/pkg/container/batch"
    24  	"github.com/matrixorigin/matrixone/pkg/container/vector"
    25  	"github.com/matrixorigin/matrixone/pkg/vm/process"
    26  )
    27  
    28  func JudgeIsCompositeClusterByColumn(s string) bool {
    29  	if len(s) < len(catalog.PrefixCBColName) {
    30  		return false
    31  	}
    32  	return s[0:len(catalog.PrefixCBColName)] == catalog.PrefixCBColName
    33  }
    34  
    35  func BuildCompositeClusterByColumnName(s []string) string {
    36  	var name string
    37  	name = catalog.PrefixCBColName
    38  	for _, single := range s {
    39  		lenNum := format.Int64ToString(int64(len(single)))
    40  		for num := 0; num < 3-len(lenNum); num++ {
    41  			name += string('0')
    42  		}
    43  		name += lenNum
    44  		name += single
    45  	}
    46  	return name
    47  }
    48  
    49  func SplitCompositeClusterByColumnName(s string) []string {
    50  	var names []string
    51  	for next := len(catalog.PrefixCBColName); next < len(s); {
    52  		strLen, _ := strconv.Atoi(s[next : next+3])
    53  		names = append(names, s[next+3:next+3+strLen])
    54  		next += strLen + 3
    55  	}
    56  
    57  	return names
    58  }
    59  
    60  func GetClusterByFirstColumn(cbName string) string {
    61  	if !JudgeIsCompositeClusterByColumn(cbName) {
    62  		return cbName
    63  	} else {
    64  		return SplitCompositeClusterByColumnName(cbName)[0]
    65  	}
    66  }
    67  
    68  func GetClusterByColumnOrder(cbName, colName string) int {
    69  	if len(cbName) == 0 || len(colName) == 0 {
    70  		return -1
    71  	}
    72  	if cbName == colName {
    73  		return 0
    74  	}
    75  	if !JudgeIsCompositeClusterByColumn(cbName) {
    76  		return -1
    77  	}
    78  	idx := 0
    79  	for next := len(catalog.PrefixCBColName); next < len(cbName); {
    80  		strLen, _ := strconv.Atoi(cbName[next : next+3])
    81  		if cbName[next+3:next+3+strLen] == colName {
    82  			return idx
    83  		}
    84  		next += strLen + 3
    85  		idx++
    86  	}
    87  	return -1
    88  }
    89  
    90  // build the clusterBy key's vector of the cluster table according to the composite column name, and append the result vector to batch
    91  // cbName: column name of composite column
    92  func FillCompositeClusterByBatch(bat *batch.Batch, cbName string, proc *process.Process) error {
    93  	names := SplitCompositeClusterByColumnName(cbName)
    94  	return FillCompositeKeyBatch(bat, cbName, names, proc)
    95  }
    96  
    97  // build the vector of the composite key, and append the result vector to batch
    98  // ckeyName: column name of composite column
    99  // keyParts: parts of the composite column
   100  func FillCompositeKeyBatch(bat *batch.Batch, ckeyName string, keyParts []string, proc *process.Process) error {
   101  	cCBVectorMap := make(map[string]*vector.Vector)
   102  	for num, attrName := range bat.Attrs {
   103  		for _, elem := range keyParts {
   104  			if attrName == elem {
   105  				cCBVectorMap[elem] = bat.Vecs[num]
   106  			}
   107  		}
   108  	}
   109  	vs := make([]*vector.Vector, 0)
   110  	for _, elem := range keyParts {
   111  		v := cCBVectorMap[elem]
   112  		vs = append(vs, v)
   113  	}
   114  	vec, err := function.RunFunctionDirectly(proc, function.SerialFunctionEncodeID, vs, bat.RowCount())
   115  	if err != nil {
   116  		return err
   117  	}
   118  	bat.Attrs = append(bat.Attrs, ckeyName)
   119  	bat.Vecs = append(bat.Vecs, vec)
   120  	return nil
   121  }