206 lines
6.2 KiB
Go
206 lines
6.2 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 metabuild
|
|
|
|
import (
|
|
"github.com/pingcap/tidb/pkg/expression/exprctx"
|
|
"github.com/pingcap/tidb/pkg/expression/exprstatic"
|
|
infoschemactx "github.com/pingcap/tidb/pkg/infoschema/context"
|
|
"github.com/pingcap/tidb/pkg/parser/mysql"
|
|
"github.com/pingcap/tidb/pkg/sessionctx/vardef"
|
|
"github.com/pingcap/tidb/pkg/util/intest"
|
|
)
|
|
|
|
// Option is used to set context options.
|
|
type Option interface {
|
|
applyCtx(*Context)
|
|
}
|
|
|
|
// funcCtxOption implements the Option interface.
|
|
type funcCtxOption struct {
|
|
f func(*Context)
|
|
}
|
|
|
|
func (o funcCtxOption) applyCtx(ctx *Context) {
|
|
o.f(ctx)
|
|
}
|
|
|
|
func funcOpt(f func(ctx *Context)) Option {
|
|
return funcCtxOption{f: f}
|
|
}
|
|
|
|
// WithExprCtx sets the expression context.
|
|
func WithExprCtx(exprCtx exprctx.ExprContext) Option {
|
|
intest.AssertNotNil(exprCtx)
|
|
return funcOpt(func(ctx *Context) {
|
|
ctx.exprCtx = exprCtx
|
|
})
|
|
}
|
|
|
|
// WithEnableAutoIncrementInGenerated sets whether enable auto increment in generated column.
|
|
func WithEnableAutoIncrementInGenerated(enable bool) Option {
|
|
return funcOpt(func(ctx *Context) {
|
|
ctx.enableAutoIncrementInGenerated = enable
|
|
})
|
|
}
|
|
|
|
// WithPrimaryKeyRequired sets whether primary key is required.
|
|
func WithPrimaryKeyRequired(required bool) Option {
|
|
return funcOpt(func(ctx *Context) {
|
|
ctx.primaryKeyRequired = required
|
|
})
|
|
}
|
|
|
|
// WithClusteredIndexDefMode sets the clustered index mode.
|
|
func WithClusteredIndexDefMode(mode vardef.ClusteredIndexDefMode) Option {
|
|
return funcOpt(func(ctx *Context) {
|
|
ctx.clusteredIndexDefMode = mode
|
|
})
|
|
}
|
|
|
|
// WithShardRowIDBits sets the shard row id bits.
|
|
func WithShardRowIDBits(bits uint64) Option {
|
|
return funcOpt(func(ctx *Context) {
|
|
ctx.shardRowIDBits = bits
|
|
})
|
|
}
|
|
|
|
// WithPreSplitRegions sets the pre-split regions.
|
|
func WithPreSplitRegions(regions uint64) Option {
|
|
return funcOpt(func(ctx *Context) {
|
|
ctx.preSplitRegions = regions
|
|
})
|
|
}
|
|
|
|
// WithSuppressTooLongIndexErr sets whether to suppress too long index error.
|
|
func WithSuppressTooLongIndexErr(suppress bool) Option {
|
|
return funcOpt(func(ctx *Context) {
|
|
ctx.suppressTooLongIndexErr = suppress
|
|
})
|
|
}
|
|
|
|
// WithInfoSchema sets the info schema.
|
|
func WithInfoSchema(schema infoschemactx.MetaOnlyInfoSchema) Option {
|
|
return funcOpt(func(ctx *Context) {
|
|
ctx.is = schema
|
|
})
|
|
}
|
|
|
|
// Context is used to build meta like `TableInfo`, `IndexInfo`, etc...
|
|
type Context struct {
|
|
exprCtx exprctx.ExprContext
|
|
enableAutoIncrementInGenerated bool
|
|
primaryKeyRequired bool
|
|
clusteredIndexDefMode vardef.ClusteredIndexDefMode
|
|
shardRowIDBits uint64
|
|
preSplitRegions uint64
|
|
suppressTooLongIndexErr bool
|
|
is infoschemactx.MetaOnlyInfoSchema
|
|
}
|
|
|
|
// NewContext creates a new context for meta-building.
|
|
func NewContext(opts ...Option) *Context {
|
|
ctx := &Context{
|
|
enableAutoIncrementInGenerated: vardef.DefTiDBEnableAutoIncrementInGenerated,
|
|
primaryKeyRequired: false,
|
|
clusteredIndexDefMode: vardef.DefTiDBEnableClusteredIndex,
|
|
shardRowIDBits: vardef.DefShardRowIDBits,
|
|
preSplitRegions: vardef.DefPreSplitRegions,
|
|
suppressTooLongIndexErr: false,
|
|
}
|
|
|
|
for _, opt := range opts {
|
|
opt.applyCtx(ctx)
|
|
}
|
|
|
|
if ctx.exprCtx == nil {
|
|
ctx.exprCtx = exprstatic.NewExprContext()
|
|
}
|
|
|
|
return ctx
|
|
}
|
|
|
|
// NewNonStrictContext creates a new context for meta-building with non-strict mode.
|
|
func NewNonStrictContext() *Context {
|
|
evalCtx := exprstatic.NewEvalContext(
|
|
// use mysql.ModeNone to avoid some special values like datetime `0000-00-00 00:00:00`
|
|
exprstatic.WithSQLMode(mysql.ModeNone),
|
|
)
|
|
return NewContext(WithExprCtx(exprstatic.NewExprContext(
|
|
exprstatic.WithEvalCtx(evalCtx),
|
|
)))
|
|
}
|
|
|
|
// GetExprCtx returns the expression context of the session.
|
|
func (ctx *Context) GetExprCtx() exprctx.ExprContext {
|
|
return ctx.exprCtx
|
|
}
|
|
|
|
// GetDefaultCollationForUTF8MB4 returns the default collation for utf8mb4.
|
|
func (ctx *Context) GetDefaultCollationForUTF8MB4() string {
|
|
return ctx.exprCtx.GetDefaultCollationForUTF8MB4()
|
|
}
|
|
|
|
// GetSQLMode returns the SQL mode.
|
|
func (ctx *Context) GetSQLMode() mysql.SQLMode {
|
|
return ctx.exprCtx.GetEvalCtx().SQLMode()
|
|
}
|
|
|
|
// AppendWarning appends a warning.
|
|
func (ctx *Context) AppendWarning(err error) {
|
|
ctx.GetExprCtx().GetEvalCtx().AppendWarning(err)
|
|
}
|
|
|
|
// AppendNote appends a note.
|
|
func (ctx *Context) AppendNote(note error) {
|
|
ctx.GetExprCtx().GetEvalCtx().AppendNote(note)
|
|
}
|
|
|
|
// EnableAutoIncrementInGenerated returns whether enable auto increment in generated column.
|
|
func (ctx *Context) EnableAutoIncrementInGenerated() bool {
|
|
return ctx.enableAutoIncrementInGenerated
|
|
}
|
|
|
|
// PrimaryKeyRequired returns whether primary key is required.
|
|
func (ctx *Context) PrimaryKeyRequired() bool {
|
|
return ctx.primaryKeyRequired
|
|
}
|
|
|
|
// GetClusteredIndexDefMode returns the clustered index mode.
|
|
func (ctx *Context) GetClusteredIndexDefMode() vardef.ClusteredIndexDefMode {
|
|
return ctx.clusteredIndexDefMode
|
|
}
|
|
|
|
// GetShardRowIDBits returns the shard row id bits.
|
|
func (ctx *Context) GetShardRowIDBits() uint64 {
|
|
return ctx.shardRowIDBits
|
|
}
|
|
|
|
// GetPreSplitRegions returns the pre-split regions.
|
|
func (ctx *Context) GetPreSplitRegions() uint64 {
|
|
return ctx.preSplitRegions
|
|
}
|
|
|
|
// SuppressTooLongIndexErr returns whether suppress too long index error.
|
|
func (ctx *Context) SuppressTooLongIndexErr() bool {
|
|
return ctx.suppressTooLongIndexErr
|
|
}
|
|
|
|
// GetInfoSchema returns the info schema for check some constraints between tables.
|
|
// If the second return value is false, it means that we do not need to check the constraints referred to other tables.
|
|
func (ctx *Context) GetInfoSchema() (infoschemactx.MetaOnlyInfoSchema, bool) {
|
|
return ctx.is, ctx.is != nil
|
|
}
|