-
Notifications
You must be signed in to change notification settings - Fork 3.8k
/
dep_drop_column.go
99 lines (90 loc) · 3.24 KB
/
dep_drop_column.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
// Copyright 2022 The Cockroach Authors.
//
// Use of this software is governed by the Business Source License
// included in the file licenses/BSL.txt.
//
// As of the Change Date specified in that file, in accordance with
// the Business Source License, use of this software will be governed
// by the Apache License, Version 2.0, included in the file
// licenses/APL.txt.
package rules
import (
"github.com/cockroachdb/cockroach/pkg/sql/schemachanger/rel"
"github.com/cockroachdb/cockroach/pkg/sql/schemachanger/scpb"
"github.com/cockroachdb/cockroach/pkg/sql/schemachanger/scplan/internal/scgraph"
)
// These rules ensure that column-dependent elements, like a column's name, its
// DEFAULT expression, etc. disappear once the column reaches a suitable state.
func init() {
registerDepRuleForDrop(
"column no longer public before dependents",
scgraph.Precedence,
"column", "dependent",
scpb.Status_WRITE_ONLY, scpb.Status_ABSENT,
func(from, to nodeVars) rel.Clauses {
return rel.Clauses{
from.Type((*scpb.Column)(nil)),
to.typeFilter(isColumnDependent),
joinOnColumnID(from, to, "table-id", "col-id"),
}
},
)
registerDepRuleForDrop(
"dependents removed before column",
scgraph.Precedence,
"dependent", "column",
scpb.Status_ABSENT, scpb.Status_ABSENT,
func(from, to nodeVars) rel.Clauses {
return rel.Clauses{
from.typeFilter(isColumnDependent),
to.Type((*scpb.Column)(nil)),
joinOnColumnID(from, to, "table-id", "col-id"),
}
},
)
}
// Special cases of the above.
func init() {
registerDepRule(
"column type dependents removed right before column type",
scgraph.SameStagePrecedence,
"dependent", "column-type",
func(from, to nodeVars) rel.Clauses {
return rel.Clauses{
from.typeFilter(isColumnTypeDependent),
to.Type((*scpb.ColumnType)(nil)),
joinOnColumnID(from, to, "table-id", "col-id"),
statusesToAbsent(from, scpb.Status_ABSENT, to, scpb.Status_ABSENT),
}
},
)
// Special cases for removal of column types, which hold references to other
// descriptors.
//
// When the whole table is dropped, we can (and in fact, should) remove these
// right away in-txn. However, when only the column is dropped but the table
// remains, we need to wait until the column is DELETE_ONLY, which happens
// post-commit because of the need to uphold the 2-version invariant.
//
// We distinguish the two cases using a flag in ColumnType which is set iff
// the parent relation is dropped. This is a dirty hack, ideally we should be
// able to express the _absence_ of a target element as a query clause.
//
// Note that DEFAULT and ON UPDATE expressions are column-dependent elements
// which also hold references to other descriptors. The rule prior to this one
// ensures that they transition to ABSENT before scpb.ColumnType does.
registerDepRule(
"column type removed right before column when not dropping relation",
scgraph.SameStagePrecedence,
"column-type", "column",
func(from, to nodeVars) rel.Clauses {
return rel.Clauses{
from.Type((*scpb.ColumnType)(nil)),
from.descriptorIsNotBeingDropped(),
to.Type((*scpb.Column)(nil)),
joinOnColumnID(from, to, "table-id", "col-id"),
statusesToAbsent(from, scpb.Status_ABSENT, to, scpb.Status_ABSENT),
}
},
)
}