Skip to content

Commit

Permalink
feat: ignore foreign keys planning if fk checks are turned off
Browse files Browse the repository at this point in the history
Signed-off-by: Manan Gupta <[email protected]>
  • Loading branch information
GuptaManan100 committed Nov 7, 2023
1 parent d8a6a04 commit 48e875c
Show file tree
Hide file tree
Showing 8 changed files with 37 additions and 14 deletions.
21 changes: 13 additions & 8 deletions go/test/vschemawrapper/vschema_wrapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,15 @@ import (
var _ plancontext.VSchema = (*VSchemaWrapper)(nil)

type VSchemaWrapper struct {
V *vindexes.VSchema
Keyspace *vindexes.Keyspace
TabletType_ topodatapb.TabletType
Dest key.Destination
SysVarEnabled bool
Version plancontext.PlannerVersion
EnableViews bool
TestBuilder func(query string, vschema plancontext.VSchema, keyspace string) (*engine.Plan, error)
V *vindexes.VSchema
Keyspace *vindexes.Keyspace
TabletType_ topodatapb.TabletType
Dest key.Destination
SysVarEnabled bool
ForeignKeyChecksState sqlparser.FkChecksState
Version plancontext.PlannerVersion
EnableViews bool
TestBuilder func(query string, vschema plancontext.VSchema, keyspace string) (*engine.Plan, error)
}

func (vw *VSchemaWrapper) GetPrepareData(stmtName string) *vtgatepb.PrepareData {
Expand Down Expand Up @@ -140,6 +141,10 @@ func (vw *VSchemaWrapper) KeyspaceError(keyspace string) error {
return nil
}

func (vw *VSchemaWrapper) GetForeignKeyChecksState() sqlparser.FkChecksState {
return vw.ForeignKeyChecksState
}

func (vw *VSchemaWrapper) AllKeyspace() ([]*vindexes.Keyspace, error) {
if vw.Keyspace == nil {
return nil, vterrors.VT13001("keyspace not available")
Expand Down
4 changes: 4 additions & 0 deletions go/vt/schemadiff/semantics.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ func (si *declarativeSchemaInformation) KeyspaceError(keyspace string) error {
return nil
}

func (si *declarativeSchemaInformation) GetForeignKeyChecksState() sqlparser.FkChecksState {
return sqlparser.FkChecksUnspecified
}

// addTable adds a fake table with an empty column list
func (si *declarativeSchemaInformation) addTable(tableName string) {
tbl := &vindexes.Table{
Expand Down
2 changes: 2 additions & 0 deletions go/vt/vtgate/planbuilder/plancontext/vschema.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ type VSchema interface {
// KeyspaceError returns any error in the keyspace vschema.
KeyspaceError(keyspace string) error

GetForeignKeyChecksState() sqlparser.FkChecksState

// GetVSchema returns the latest cached vindexes.VSchema
GetVSchema() *vindexes.VSchema

Expand Down
4 changes: 4 additions & 0 deletions go/vt/vtgate/semantics/FakeSI.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ func (s *FakeSI) ForeignKeyMode(keyspace string) (vschemapb.Keyspace_ForeignKeyM
return vschemapb.Keyspace_unmanaged, nil
}

func (s *FakeSI) GetForeignKeyChecksState() sqlparser.FkChecksState {
return sqlparser.FkChecksUnspecified
}

func (s *FakeSI) KeyspaceError(keyspace string) error {
if s.KsError != nil {
fkErr, isPresent := s.KsError[keyspace]
Expand Down
11 changes: 7 additions & 4 deletions go/vt/vtgate/semantics/analyzer.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ func Analyze(statement sqlparser.Statement, currentDb string, si SchemaInformati
}

// Creation of the semantic table
return analyzer.newSemTable(statement, si.ConnCollation())
return analyzer.newSemTable(statement, si.ConnCollation(), si.GetForeignKeyChecksState())
}

// AnalyzeStrict analyzes the parsed query, and fails the analysis for any possible errors
Expand All @@ -97,7 +97,7 @@ func AnalyzeStrict(statement sqlparser.Statement, currentDb string, si SchemaInf
return st, nil
}

func (a *analyzer) newSemTable(statement sqlparser.Statement, coll collations.ID) (*SemTable, error) {
func (a *analyzer) newSemTable(statement sqlparser.Statement, coll collations.ID, fkChecksState sqlparser.FkChecksState) (*SemTable, error) {
var comments *sqlparser.ParsedComments
commentedStmt, isCommented := statement.(sqlparser.Commented)
if isCommented {
Expand All @@ -108,7 +108,7 @@ func (a *analyzer) newSemTable(statement sqlparser.Statement, coll collations.ID
columns[union] = info.exprs
}

childFks, parentFks, err := a.getInvolvedForeignKeys(statement)
childFks, parentFks, err := a.getInvolvedForeignKeys(statement, fkChecksState)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -317,7 +317,10 @@ func (a *analyzer) noteQuerySignature(node sqlparser.SQLNode) {
}

// getInvolvedForeignKeys gets the foreign keys that might require taking care off when executing the given statement.
func (a *analyzer) getInvolvedForeignKeys(statement sqlparser.Statement) (map[TableSet][]vindexes.ChildFKInfo, map[TableSet][]vindexes.ParentFKInfo, error) {
func (a *analyzer) getInvolvedForeignKeys(statement sqlparser.Statement, fkChecksState sqlparser.FkChecksState) (map[TableSet][]vindexes.ChildFKInfo, map[TableSet][]vindexes.ParentFKInfo, error) {
if fkChecksState == sqlparser.FkChecksOff {
return nil, nil, nil
}
// There are only the DML statements that require any foreign keys handling.
switch stmt := statement.(type) {
case *sqlparser.Delete:
Expand Down
2 changes: 1 addition & 1 deletion go/vt/vtgate/semantics/analyzer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2152,7 +2152,7 @@ func TestGetInvolvedForeignKeys(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
childFks, parentFks, err := tt.analyzer.getInvolvedForeignKeys(tt.stmt)
childFks, parentFks, err := tt.analyzer.getInvolvedForeignKeys(tt.stmt, sqlparser.FkChecksOn)
if tt.expectedErr != "" {
require.EqualError(t, err, tt.expectedErr)
return
Expand Down
4 changes: 4 additions & 0 deletions go/vt/vtgate/semantics/info_schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -1718,6 +1718,10 @@ func (i *infoSchemaWithColumns) ForeignKeyMode(keyspace string) (vschemapb.Keysp
return i.inner.ForeignKeyMode(keyspace)
}

func (i *infoSchemaWithColumns) GetForeignKeyChecksState() sqlparser.FkChecksState {
return sqlparser.FkChecksUnspecified
}

func (i *infoSchemaWithColumns) KeyspaceError(keyspace string) error {
return i.inner.KeyspaceError(keyspace)
}
3 changes: 2 additions & 1 deletion go/vt/vtgate/semantics/semantic_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,12 +144,13 @@ type (
ColumnName string
}

// SchemaInformation is used tp provide table information from Vschema.
// SchemaInformation is used to provide table information from Vschema.
SchemaInformation interface {
FindTableOrVindex(tablename sqlparser.TableName) (*vindexes.Table, vindexes.Vindex, string, topodatapb.TabletType, key.Destination, error)
ConnCollation() collations.ID
// ForeignKeyMode returns the foreign_key flag value
ForeignKeyMode(keyspace string) (vschemapb.Keyspace_ForeignKeyMode, error)
GetForeignKeyChecksState() sqlparser.FkChecksState
KeyspaceError(keyspace string) error
}

Expand Down

0 comments on commit 48e875c

Please sign in to comment.