forked from dolthub/go-mysql-server
-
Notifications
You must be signed in to change notification settings - Fork 0
/
constraints.go
129 lines (113 loc) · 4.29 KB
/
constraints.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// Copyright 2021 Dolthub, 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 sql
import (
"fmt"
"strings"
)
// ForeignKeyConstraint declares a constraint between the columns of two tables.
type ForeignKeyConstraint struct {
Name string
Database string
Table string
Columns []string
ParentDatabase string
ParentTable string
ParentColumns []string
OnUpdate ForeignKeyReferentialAction
OnDelete ForeignKeyReferentialAction
IsResolved bool
}
// ForeignKeyReferentialAction is the behavior for this foreign key with the relevant action is performed on the foreign
// table.
type ForeignKeyReferentialAction string
const (
ForeignKeyReferentialAction_DefaultAction ForeignKeyReferentialAction = "DEFAULT" // No explicit action was specified
ForeignKeyReferentialAction_Restrict ForeignKeyReferentialAction = "RESTRICT"
ForeignKeyReferentialAction_Cascade ForeignKeyReferentialAction = "CASCADE"
ForeignKeyReferentialAction_NoAction ForeignKeyReferentialAction = "NO ACTION"
ForeignKeyReferentialAction_SetNull ForeignKeyReferentialAction = "SET NULL"
ForeignKeyReferentialAction_SetDefault ForeignKeyReferentialAction = "SET DEFAULT"
)
// IsSelfReferential returns whether this foreign key represents a self-referential foreign key.
func (f ForeignKeyConstraint) IsSelfReferential() bool {
return strings.ToLower(f.Database) == strings.ToLower(f.ParentDatabase) &&
strings.ToLower(f.Table) == strings.ToLower(f.ParentTable)
}
func (f *ForeignKeyConstraint) DebugString() string {
return fmt.Sprintf(
"FOREIGN KEY %s (%s) REFERENCES %s (%s)",
f.Name,
strings.Join(f.Columns, ","),
f.ParentTable,
strings.Join(f.ParentColumns, ","),
)
}
// IsEquivalentToRestrict returns whether the referential action is equivalent to RESTRICT. In MySQL, although there are
// a number of referential actions, the majority of them are functionally ignored and default to RESTRICT.
func (f ForeignKeyReferentialAction) IsEquivalentToRestrict() bool {
switch f {
case ForeignKeyReferentialAction_Cascade, ForeignKeyReferentialAction_SetNull:
return false
default:
return true
}
}
// CheckDefinition defines a trigger. Integrators are not expected to parse or understand the trigger definitions,
// but must store and return them when asked.
type CheckDefinition struct {
Name string // The name of this check. Check names in a database are unique.
CheckExpression string // String serialization of the check expression
Enforced bool // Whether this constraint is enforced
}
// CheckConstraint declares a boolean-eval constraint.
type CheckConstraint struct {
Name string
Expr Expression
Enforced bool
}
type CheckConstraints []*CheckConstraint
// ToExpressions returns the check expressions in these constraints as a slice of sql.Expression
func (checks CheckConstraints) ToExpressions() []Expression {
exprs := make([]Expression, len(checks))
for i := range checks {
exprs[i] = checks[i].Expr
}
return exprs
}
// FromExpressions takes a slice of sql.Expression in the same order as these constraints, and returns a new slice of
// constraints with the expressions given, holding names and other properties constant.
func (checks CheckConstraints) FromExpressions(exprs []Expression) (CheckConstraints, error) {
if len(checks) != len(exprs) {
return nil, ErrInvalidChildrenNumber.New(checks, len(exprs), len(checks))
}
newChecks := make(CheckConstraints, len(checks))
for i := range exprs {
nc := *checks[i]
newChecks[i] = &nc
newChecks[i].Expr = exprs[i]
}
return newChecks, nil
}
func (c CheckConstraint) DebugString() string {
name := c.Name
if len(name) > 0 {
name += " "
}
not := ""
if !c.Enforced {
not = "not "
}
return fmt.Sprintf("%sCHECK %s %sENFORCED", name, DebugString(c.Expr), not)
}