Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

table: add WritableConstraint to interface table.Table to avoid implicit interface implementation #54825

Merged
merged 1 commit into from
Jul 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 3 additions & 10 deletions pkg/executor/write.go
Original file line number Diff line number Diff line change
Expand Up @@ -329,8 +329,9 @@ func checkRowForExchangePartition(sctx table.MutateContext, row []types.Datum, t
if !ok {
return errors.Errorf("exchange partition process assert table partition failed")
}
evalCtx := sctx.GetExprCtx().GetEvalCtx()
err := p.CheckForExchangePartition(
sctx.GetExprCtx().GetEvalCtx(),
evalCtx,
pt.Meta().Partition,
row,
tbl.ExchangePartitionInfo.ExchangePartitionDefID,
Expand All @@ -340,15 +341,7 @@ func checkRowForExchangePartition(sctx table.MutateContext, row []types.Datum, t
return err
}
if variable.EnableCheckConstraint.Load() {
type CheckConstraintTable interface {
CheckRowConstraint(ctx table.MutateContext, rowToCheck []types.Datum) error
}
cc, ok := pt.(CheckConstraintTable)
if !ok {
return errors.Errorf("exchange partition process assert check constraint failed")
}
err := cc.CheckRowConstraint(sctx, row)
if err != nil {
if err = table.CheckRowConstraintWithDatum(evalCtx, pt.WritableConstraint(), row); err != nil {
// TODO: make error include ExchangePartition info.
return err
}
Expand Down
10 changes: 10 additions & 0 deletions pkg/infoschema/tables.go
Original file line number Diff line number Diff line change
Expand Up @@ -2410,6 +2410,11 @@ func (it *infoschemaTable) Indices() []table.Index {
return nil
}

// WritableConstraint implements table.Table WritableConstraint interface.
func (it *infoschemaTable) WritableConstraint() []*table.Constraint {
return nil
}

// RecordPrefix implements table.Table RecordPrefix interface.
func (it *infoschemaTable) RecordPrefix() kv.Key {
return nil
Expand Down Expand Up @@ -2498,6 +2503,11 @@ func (vt *VirtualTable) Indices() []table.Index {
return nil
}

// WritableConstraint implements table.Table WritableConstraint interface.
func (vt *VirtualTable) WritableConstraint() []*table.Constraint {
return nil
}

// RecordPrefix implements table.Table RecordPrefix interface.
func (vt *VirtualTable) RecordPrefix() kv.Key {
return nil
Expand Down
28 changes: 28 additions & 0 deletions pkg/table/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@ import (

mysql "github.com/pingcap/tidb/pkg/errno"
"github.com/pingcap/tidb/pkg/expression"
exprctx "github.com/pingcap/tidb/pkg/expression/context"
"github.com/pingcap/tidb/pkg/kv"
"github.com/pingcap/tidb/pkg/meta/autoid"
"github.com/pingcap/tidb/pkg/parser/model"
"github.com/pingcap/tidb/pkg/sessionctx"
"github.com/pingcap/tidb/pkg/sessionctx/variable"
tbctx "github.com/pingcap/tidb/pkg/table/context"
"github.com/pingcap/tidb/pkg/types"
"github.com/pingcap/tidb/pkg/util/chunk"
"github.com/pingcap/tidb/pkg/util/dbterror"
"github.com/pingcap/tidb/pkg/util/sqlexec"
"github.com/pingcap/tidb/pkg/util/tracing"
Expand Down Expand Up @@ -188,6 +190,9 @@ type Table interface {
// The caller must be aware of that not all the returned indices are public.
Indices() []Index

// WritableConstraint returns constraints of the table in writable states.
WritableConstraint() []*Constraint

// RecordPrefix returns the record key prefix.
RecordPrefix() kv.Key
// IndexPrefix returns the index key prefix.
Expand Down Expand Up @@ -303,3 +308,26 @@ type CachedTable interface {
// The result is sent to the 'wg' channel.
WriteLockAndKeepAlive(ctx context.Context, exit chan struct{}, leasePtr *uint64, wg chan error)
}

// CheckRowConstraint verify row check constraints.
func CheckRowConstraint(ctx exprctx.EvalContext, constraints []*Constraint, rowToCheck chunk.Row) error {
for _, constraint := range constraints {
ok, isNull, err := constraint.ConstraintExpr.EvalInt(ctx, rowToCheck)
if err != nil {
return err
}
if ok == 0 && !isNull {
return ErrCheckConstraintViolated.FastGenByArgs(constraint.Name.O)
}
}
return nil
}

// CheckRowConstraintWithDatum verify row check constraints.
// It is the same with `CheckRowConstraint` but receives a slice of `types.Datum` instead of `chunk.Row`.
func CheckRowConstraintWithDatum(ctx exprctx.EvalContext, constraints []*Constraint, row []types.Datum) error {
if len(constraints) == 0 {
return nil
}
Comment on lines +329 to +331
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this? CheckRowConstraint also return nil when len(constraints) == 0.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, to avoid unnecessary perf cost of chunk.MutRowFromDatums(row).ToRow()

return CheckRowConstraint(ctx, constraints, chunk.MutRowFromDatums(row).ToRow())
}
12 changes: 3 additions & 9 deletions pkg/table/tables/partition.go
Original file line number Diff line number Diff line change
Expand Up @@ -1579,15 +1579,9 @@ func checkConstraintForExchangePartition(sctx table.MutateContext, row []types.D
return errors.Errorf("exchange partition process table by id failed")
}
}
type CheckConstraintTable interface {
CheckRowConstraint(ctx table.MutateContext, rowToCheck []types.Datum) error
}
cc, ok := nt.(CheckConstraintTable)
if !ok {
return errors.Errorf("exchange partition process assert check constraint failed")
}
err := cc.CheckRowConstraint(sctx, row)
if err != nil {

evalCtx := sctx.GetExprCtx().GetEvalCtx()
if err := table.CheckRowConstraintWithDatum(evalCtx, nt.WritableConstraint(), row); err != nil {
// TODO: make error include ExchangePartition info.
return err
}
Expand Down
30 changes: 2 additions & 28 deletions pkg/table/tables/tables.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ import (
"github.com/pingcap/tidb/pkg/tablecodec"
"github.com/pingcap/tidb/pkg/types"
"github.com/pingcap/tidb/pkg/util"
"github.com/pingcap/tidb/pkg/util/chunk"
"github.com/pingcap/tidb/pkg/util/codec"
"github.com/pingcap/tidb/pkg/util/collate"
"github.com/pingcap/tidb/pkg/util/generatedexpr"
Expand Down Expand Up @@ -378,30 +377,6 @@ func (t *TableCommon) WritableConstraint() []*table.Constraint {
return t.writableConstraints
}

// CheckRowConstraint verify row check constraints.
func (t *TableCommon) CheckRowConstraint(ctx table.MutateContext, rowToCheck []types.Datum) error {
if constraints := t.WritableConstraint(); len(constraints) > 0 {
ectx := ctx.GetExprCtx().GetEvalCtx()
row := chunk.MutRowFromDatums(rowToCheck).ToRow()
return checkRowConstraint(ectx, constraints, row)
}
return nil
}

// checkRowConstraint verify row check constraints.
func checkRowConstraint(ctx exprctx.EvalContext, constraints []*table.Constraint, rowToCheck chunk.Row) error {
for _, constraint := range constraints {
ok, isNull, err := constraint.ConstraintExpr.EvalInt(ctx, rowToCheck)
if err != nil {
return err
}
if ok == 0 && !isNull {
return table.ErrCheckConstraintViolated.FastGenByArgs(constraint.Name.O)
}
}
return nil
}

// FullHiddenColsAndVisibleCols implements table FullHiddenColsAndVisibleCols interface.
func (t *TableCommon) FullHiddenColsAndVisibleCols() []*table.Column {
return t.fullHiddenColsAndVisibleColumns
Expand Down Expand Up @@ -531,7 +506,7 @@ func (t *TableCommon) UpdateRecord(ctx context.Context, sctx table.MutateContext
// check data constraint
evalCtx := sctx.GetExprCtx().GetEvalCtx()
if constraints := t.WritableConstraint(); len(constraints) > 0 {
if err = checkRowConstraint(evalCtx, constraints, checkRowBuffer.GetRowToCheck()); err != nil {
if err = table.CheckRowConstraint(evalCtx, constraints, checkRowBuffer.GetRowToCheck()); err != nil {
return err
}
}
Expand Down Expand Up @@ -914,8 +889,7 @@ func (t *TableCommon) AddRecord(sctx table.MutateContext, r []types.Datum, opts
}
}
// check data constraint
err = t.CheckRowConstraint(sctx, r)
if err != nil {
if err = table.CheckRowConstraintWithDatum(evalCtx, t.WritableConstraint(), r); err != nil {
return nil, err
}
key := t.RecordKey(recordID)
Expand Down