Files
tidb/pkg/expression/exprctx/optional.go

198 lines
5.5 KiB
Go

// Copyright 2024 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package exprctx
import (
"fmt"
"log"
"unsafe"
"github.com/pingcap/tidb/pkg/util/intest"
)
func init() {
// Ensure the count of optional properties is less than the bits of OptionalEvalProps.
if maxCnt := int64(unsafe.Sizeof(*new(OptionalEvalPropKeySet))) * 8; int64(OptPropsCnt) > maxCnt {
log.Fatalf(
"The count optional properties should less than the bits of OptionalEvalProps, but %d > %d",
OptPropsCnt, maxCnt,
)
}
// check optionalPropertyDescList are valid
if len(optionalPropertyDescList) != OptPropsCnt {
log.Fatalf(
"The lenghth of OptionalPropertieDescs should be %d, but got %d",
OptPropsCnt, len(optionalPropertyDescList),
)
}
for i := 0; i < OptPropsCnt; i++ {
if key := optionalPropertyDescList[i].Key(); key != OptionalEvalPropKey(i) {
log.Fatalf(
"Invalid optionalPropertyDescList[%d].Key, unexpected index: %d",
i, key,
)
}
}
}
// OptionalEvalPropKey is the key for optional evaluation properties in EvalContext.
type OptionalEvalPropKey int
// AsPropKeySet returns the set only contains the property key.
func (k OptionalEvalPropKey) AsPropKeySet() OptionalEvalPropKeySet {
return 1 << k
}
// Desc returns the description for the property key.
func (k OptionalEvalPropKey) Desc() *OptionalEvalPropDesc {
return &optionalPropertyDescList[k]
}
// String implements fmt.Stringer interface.
func (k OptionalEvalPropKey) String() string {
if k < optPropsCnt {
return k.Desc().str
}
return fmt.Sprintf("UnknownOptionalEvalPropKey(%d)", k)
}
const (
// OptPropCurrentUser indicates to provide the current user property.
OptPropCurrentUser OptionalEvalPropKey = iota
// OptPropSessionVars indicates to provide `variable.SessionVariable`.
OptPropSessionVars
// OptPropInfoSchema indicates to provide the information schema.
OptPropInfoSchema
// OptPropKVStore indicates to provide the kv store.
OptPropKVStore
// OptPropSQLExecutor indicates to provide executors to execute sql.
OptPropSQLExecutor
// OptPropSequenceOperator indicates to provide sequence operators for sequences.
OptPropSequenceOperator
// OptPropAdvisoryLock indicates to provide advisory lock operations.
OptPropAdvisoryLock
// OptPropDDLOwnerInfo indicates to provide DDL owner information.
OptPropDDLOwnerInfo
// OptPropPrivilegeChecker indicates to provide the privilege checker.
OptPropPrivilegeChecker
// optPropsCnt is the count of optional properties. DO NOT use it as a property key.
optPropsCnt
)
const allOptPropsMask = (1 << optPropsCnt) - 1
// OptPropsCnt is the count of optional properties.
const OptPropsCnt = int(optPropsCnt)
// OptionalEvalPropDesc is the description for optional evaluation properties in EvalContext.
type OptionalEvalPropDesc struct {
key OptionalEvalPropKey
str string
// TODO: add more fields if needed
}
// Key returns the property key.
func (desc *OptionalEvalPropDesc) Key() OptionalEvalPropKey {
return desc.key
}
// OptionalEvalPropProvider is the interface to provide optional properties in EvalContext.
type OptionalEvalPropProvider interface {
Desc() *OptionalEvalPropDesc
}
// optionalPropertyDescList contains all optional property descriptions in EvalContext.
var optionalPropertyDescList = []OptionalEvalPropDesc{
{
key: OptPropCurrentUser,
str: "OptPropCurrentUser",
},
{
key: OptPropSessionVars,
str: "OptPropSessionVars",
},
{
key: OptPropInfoSchema,
str: "OptPropInfoSchema",
},
{
key: OptPropKVStore,
str: "OptPropKVStore",
},
{
key: OptPropSQLExecutor,
str: "OptPropSQLExecutor",
},
{
key: OptPropSequenceOperator,
str: "OptPropDDLOwnerInfo",
},
{
key: OptPropAdvisoryLock,
str: "OptPropAdvisoryLock",
},
{
key: OptPropDDLOwnerInfo,
str: "OptPropDDLOwnerInfo",
},
{
key: OptPropPrivilegeChecker,
str: "OptPropPrivilegeChecker",
},
}
// OptionalEvalPropKeySet is a bit map for optional evaluation properties in EvalContext
// to indicate whether some properties are set.
type OptionalEvalPropKeySet uint64
// Add adds the property key to the set
func (b OptionalEvalPropKeySet) Add(key OptionalEvalPropKey) OptionalEvalPropKeySet {
intest.Assert(key < optPropsCnt)
if key >= optPropsCnt {
return b
}
return b | key.AsPropKeySet()
}
// Remove removes the property key from the set
func (b OptionalEvalPropKeySet) Remove(key OptionalEvalPropKey) OptionalEvalPropKeySet {
intest.Assert(key < optPropsCnt)
if key >= optPropsCnt {
return b
}
return b &^ key.AsPropKeySet()
}
// Contains checks whether the set contains the property
func (b OptionalEvalPropKeySet) Contains(key OptionalEvalPropKey) bool {
intest.Assert(key < optPropsCnt)
if key >= optPropsCnt {
return false
}
return b&key.AsPropKeySet() != 0
}
// IsEmpty checks whether the bit map is empty.
func (b OptionalEvalPropKeySet) IsEmpty() bool {
return b&allOptPropsMask == 0
}
// IsFull checks whether all optional properties are contained in the bit map.
func (b OptionalEvalPropKeySet) IsFull() bool {
return b&allOptPropsMask == allOptPropsMask
}