198 lines
5.5 KiB
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
|
|
}
|