133 lines
4.5 KiB
Go
133 lines
4.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 contextimpl
|
|
|
|
import (
|
|
"time"
|
|
|
|
"github.com/pingcap/tidb/pkg/errctx"
|
|
exprctx "github.com/pingcap/tidb/pkg/expression/context"
|
|
"github.com/pingcap/tidb/pkg/expression/contextopt"
|
|
"github.com/pingcap/tidb/pkg/parser/auth"
|
|
"github.com/pingcap/tidb/pkg/parser/mysql"
|
|
"github.com/pingcap/tidb/pkg/sessionctx"
|
|
"github.com/pingcap/tidb/pkg/sessionctx/stmtctx"
|
|
"github.com/pingcap/tidb/pkg/sessionctx/variable"
|
|
"github.com/pingcap/tidb/pkg/types"
|
|
"github.com/pingcap/tidb/pkg/util/intest"
|
|
)
|
|
|
|
// sessionctx.Context + *ExprCtxExtendedImpl should implement `expression.BuildContext`
|
|
// Only used to assert `ExprCtxExtendedImpl` should implement all methods not in `sessionctx.Context`
|
|
var _ exprctx.BuildContext = struct {
|
|
sessionctx.Context
|
|
*ExprCtxExtendedImpl
|
|
}{}
|
|
|
|
// ExprCtxExtendedImpl extends the sessionctx.Context to implement `expression.BuildContext`
|
|
type ExprCtxExtendedImpl struct {
|
|
sctx sessionctx.Context
|
|
props contextopt.OptionalEvalPropProviders
|
|
}
|
|
|
|
// NewExprExtendedImpl creates a new ExprCtxExtendedImpl.
|
|
func NewExprExtendedImpl(sctx sessionctx.Context) *ExprCtxExtendedImpl {
|
|
impl := &ExprCtxExtendedImpl{sctx: sctx}
|
|
// set all optional properties
|
|
impl.setOptionalProp(currentUserProp(sctx))
|
|
// When EvalContext is created from a session, it should contain all the optional properties.
|
|
intest.Assert(impl.props.PropKeySet().IsFull())
|
|
return impl
|
|
}
|
|
|
|
func (ctx *ExprCtxExtendedImpl) setOptionalProp(prop exprctx.OptionalEvalPropProvider) {
|
|
intest.AssertFunc(func() bool {
|
|
return !ctx.props.Contains(prop.Desc().Key())
|
|
})
|
|
ctx.props.Add(prop)
|
|
}
|
|
|
|
// CtxID returns the context id.
|
|
func (ctx *ExprCtxExtendedImpl) CtxID() uint64 {
|
|
return ctx.sctx.GetSessionVars().StmtCtx.CtxID()
|
|
}
|
|
|
|
// SQLMode returns the sql mode
|
|
func (ctx *ExprCtxExtendedImpl) SQLMode() mysql.SQLMode {
|
|
return ctx.sctx.GetSessionVars().SQLMode
|
|
}
|
|
|
|
// TypeCtx returns the types.Context
|
|
func (ctx *ExprCtxExtendedImpl) TypeCtx() types.Context {
|
|
return ctx.sctx.GetSessionVars().StmtCtx.TypeCtx()
|
|
}
|
|
|
|
// ErrCtx returns the errctx.Context
|
|
func (ctx *ExprCtxExtendedImpl) ErrCtx() errctx.Context {
|
|
return ctx.sctx.GetSessionVars().StmtCtx.ErrCtx()
|
|
}
|
|
|
|
// Location returns the timezone info
|
|
func (ctx *ExprCtxExtendedImpl) Location() *time.Location {
|
|
tc := ctx.TypeCtx()
|
|
return tc.Location()
|
|
}
|
|
|
|
// AppendWarning append warnings to the context.
|
|
func (ctx *ExprCtxExtendedImpl) AppendWarning(err error) {
|
|
ctx.sctx.GetSessionVars().StmtCtx.AppendWarning(err)
|
|
}
|
|
|
|
// WarningCount gets warning count.
|
|
func (ctx *ExprCtxExtendedImpl) WarningCount() int {
|
|
return int(ctx.sctx.GetSessionVars().StmtCtx.WarningCount())
|
|
}
|
|
|
|
// TruncateWarnings truncates warnings begin from start and returns the truncated warnings.
|
|
func (ctx *ExprCtxExtendedImpl) TruncateWarnings(start int) []stmtctx.SQLWarn {
|
|
return ctx.sctx.GetSessionVars().StmtCtx.TruncateWarnings(start)
|
|
}
|
|
|
|
// CurrentDB return the current database name
|
|
func (ctx *ExprCtxExtendedImpl) CurrentDB() string {
|
|
return ctx.sctx.GetSessionVars().CurrentDB
|
|
}
|
|
|
|
// GetMaxAllowedPacket returns the value of the 'max_allowed_packet' system variable.
|
|
func (ctx *ExprCtxExtendedImpl) GetMaxAllowedPacket() uint64 {
|
|
return ctx.sctx.GetSessionVars().MaxAllowedPacket
|
|
}
|
|
|
|
// GetDefaultWeekFormatMode returns the value of the 'default_week_format' system variable.
|
|
func (ctx *ExprCtxExtendedImpl) GetDefaultWeekFormatMode() string {
|
|
mode, ok := ctx.sctx.GetSessionVars().GetSystemVar(variable.DefaultWeekFormat)
|
|
if !ok || mode == "" {
|
|
return "0"
|
|
}
|
|
return mode
|
|
}
|
|
|
|
// GetOptionalPropProvider gets the optional property provider by key
|
|
func (ctx *ExprCtxExtendedImpl) GetOptionalPropProvider(key exprctx.OptionalEvalPropKey) (exprctx.OptionalEvalPropProvider, bool) {
|
|
return ctx.props.Get(key)
|
|
}
|
|
|
|
func currentUserProp(sctx sessionctx.Context) exprctx.OptionalEvalPropProvider {
|
|
return contextopt.CurrentUserPropProvider(func() (*auth.UserIdentity, []*auth.RoleIdentity) {
|
|
vars := sctx.GetSessionVars()
|
|
return vars.User, vars.ActiveRoles
|
|
})
|
|
}
|