Skip to content

Commit

Permalink
Support check constraint backend (GoogleCloudPlatform#962)
Browse files Browse the repository at this point in the history
* Check constraint backend (#9)

Backend Support for Check Constraint

* update api

* fix PR comment

* remove api call to while validating constraints

* Fixed db collation regex to remove collation name from the results

* renamed function name to formatCheckConstraints and added check if constraint name is empty

* fixed PR comments

* added test case for the empty check constraint name

* fix: added regular exprression to match the exact column

* fix: added regular expression to replace table name

* Added test case for the column rename for check constraint

* 1. Refactored GetConstraint function
2. Fixed inforschema unit tests

* added comment at handling case for check constraints

* reverted white spaces

* reverted white spaces

* nit: doesCheckConstraintNameExist

* added comments for doesCheckConstraintNameExist

* PR and UT fixes

* fix UT

* UT fix

* Removed isCheckConstraintsTablePresent function

* moved regex globally

* Fix UT

* fixed UT

* fixed handling of the constraints

* removed unused function

* added unit tests for incompatable name

* Combined unit tests

* added test case for the renaming column having substring of other column

* added the query changes which return distinct value

---------

Co-authored-by: taherkl <taher.lakdawala@ollion.com>
Co-authored-by: Akash Thawait <aakash@ollion.com>
Co-authored-by: Vivek Yadav <vivek.yadav@ollion.com>
  • Loading branch information
4 people committed Dec 26, 2024
1 parent a4546cc commit b2c193d
Show file tree
Hide file tree
Showing 3 changed files with 0 additions and 114 deletions.
1 change: 0 additions & 1 deletion sources/common/toddl.go
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,6 @@ func (ss *SchemaToSpannerImpl) SchemaToSpannerDDLHelper(conv *internal.Conv, tod
Comment: comment,
Id: srcTable.Id,
}

return nil
}

Expand Down
10 changes: 0 additions & 10 deletions sources/common/toddl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -451,11 +451,6 @@ func Test_cvtCheckContraint(t *testing.T) {
Expr: "age != 0",
ExprId: "expr3",
},
{
Id: "cc3",
Name: "@invalid_name", // incompatabile name
Expr: "age != 0",
},
}
spSchema := []ddl.CheckConstraint{
{
Expand All @@ -476,11 +471,6 @@ func Test_cvtCheckContraint(t *testing.T) {
Expr: "age != 0",
ExprId: "expr3",
},
{
Id: "cc3",
Name: "Ainvalid_name",
Expr: "age != 0",
},
}
result := cvtCheckConstraint(conv, srcSchema)
assert.Equal(t, spSchema, result)
Expand Down
103 changes: 0 additions & 103 deletions webv2/api/schema_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2731,106 +2731,3 @@ func TestVerifyCheckConstraintExpressions(t *testing.T) {
})
}
}

func TestVerifyCheckConstraintExpressions(t *testing.T) {
tests := []struct {
name string
expressions []ddl.CheckConstraint
expectedResults []internal.ExpressionVerificationOutput
expectedResponse bool
}{
{
name: "AllValidExpressions",
expressions: []ddl.CheckConstraint{
{Expr: "(col1 > 0)", ExprId: "expr1", Name: "check1"},
},
expectedResults: []internal.ExpressionVerificationOutput{
{Result: true, Err: nil, ExpressionDetail: internal.ExpressionDetail{Expression: "(col1 > 0)", Type: "CHECK", Metadata: map[string]string{"tableId": "t1", "colId": "c1", "checkConstraintName": "check1"}, ExpressionId: "expr1"}},
},
expectedResponse: false,
},
{
name: "InvalidSyntaxError",
expressions: []ddl.CheckConstraint{
{Expr: "(col1 > 0)", ExprId: "expr1", Name: "check1"},
{Expr: "(col1 > 18", ExprId: "expr2", Name: "check2"},
},
expectedResults: []internal.ExpressionVerificationOutput{
{Result: true, Err: nil, ExpressionDetail: internal.ExpressionDetail{Expression: "(col1 > 0)", Type: "CHECK", Metadata: map[string]string{"tableId": "t1", "colId": "c1", "checkConstraintName": "check1"}, ExpressionId: "expr1"}},
{Result: false, Err: errors.New("Syntax error ..."), ExpressionDetail: internal.ExpressionDetail{Expression: "(col1 > 18", Type: "CHECK", Metadata: map[string]string{"tableId": "t1", "colId": "c1", "checkConstraintName": "check2"}, ExpressionId: "expr2"}},
},
expectedResponse: true,
},
{
name: "NameError",
expressions: []ddl.CheckConstraint{
{Expr: "(col1 > 0)", ExprId: "expr1", Name: "check1"},
{Expr: "(col1 > 18)", ExprId: "expr2", Name: "check2"},
},
expectedResults: []internal.ExpressionVerificationOutput{
{Result: true, Err: nil, ExpressionDetail: internal.ExpressionDetail{Expression: "(col1 > 0)", Type: "CHECK", Metadata: map[string]string{"tableId": "t1", "colId": "c1", "checkConstraintName": "check1"}, ExpressionId: "expr1"}},
{Result: false, Err: errors.New("Unrecognized name ..."), ExpressionDetail: internal.ExpressionDetail{Expression: "(col1 > 18)", Type: "CHECK", Metadata: map[string]string{"tableId": "t1", "colId": "c1", "checkConstraintName": "check2"}, ExpressionId: "expr2"}},
},
expectedResponse: true,
},
{
name: "TypeError",
expressions: []ddl.CheckConstraint{
{Expr: "(col1 > 0)", ExprId: "expr1", Name: "check1"},
{Expr: "(col1 > 18)", ExprId: "expr2", Name: "check2"},
},
expectedResults: []internal.ExpressionVerificationOutput{
{Result: true, Err: nil, ExpressionDetail: internal.ExpressionDetail{Expression: "(col1 > 0)", Type: "CHECK", Metadata: map[string]string{"tableId": "t1", "colId": "c1", "checkConstraintName": "check1"}, ExpressionId: "expr1"}},
{Result: false, Err: errors.New("No matching signature for operator"), ExpressionDetail: internal.ExpressionDetail{Expression: "(col1 > 18)", Type: "CHECK", Metadata: map[string]string{"tableId": "t1", "colId": "c1", "checkConstraintName": "check2"}, ExpressionId: "expr2"}},
},
expectedResponse: true,
},
}

for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
mockAccessor := new(mocks.MockExpressionVerificationAccessor)
handler := &api.ExpressionsVerificationHandler{ExpressionVerificationAccessor: mockAccessor}

req, err := http.NewRequest("POST", "/verifyCheckConstraintExpression", nil)
if err != nil {
t.Fatal(err)
}

ctx := req.Context()
sessionState := session.GetSessionState()
sessionState.Driver = constants.MYSQL
sessionState.SpannerInstanceID = "foo"
sessionState.SpannerProjectId = "daring-12"
sessionState.Conv = internal.MakeConv()
sessionState.Conv.SpSchema = map[string]ddl.CreateTable{
"t1": {
Name: "table1",
Id: "t1",
PrimaryKeys: []ddl.IndexKey{{ColId: "c1"}},
ColIds: []string{"c1"},
ColDefs: map[string]ddl.ColumnDef{
"c1": {Name: "col1", Id: "c1", T: ddl.Type{Name: ddl.Int64}},
},
CheckConstraints: tc.expressions,
},
}

mockAccessor.On("VerifyExpressions", ctx, mock.Anything).Return(internal.VerifyExpressionsOutput{
ExpressionVerificationOutputList: tc.expectedResults,
})

rr := httptest.NewRecorder()
handler.VerifyCheckConstraintExpression(rr, req)

assert.Equal(t, http.StatusOK, rr.Code)

var response bool
err = json.NewDecoder(rr.Body).Decode(&response)
if err != nil {
t.Fatal(err)
}
assert.Equal(t, tc.expectedResponse, response)
})
}
}

0 comments on commit b2c193d

Please sign in to comment.