-
Notifications
You must be signed in to change notification settings - Fork 3.8k
/
set_schema.go
86 lines (75 loc) · 2.79 KB
/
set_schema.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
// Copyright 2020 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 sql
import (
"context"
"github.com/cockroachdb/cockroach/pkg/sql/catalog"
"github.com/cockroachdb/cockroach/pkg/sql/catalog/descpb"
"github.com/cockroachdb/cockroach/pkg/sql/catalog/descs"
"github.com/cockroachdb/cockroach/pkg/sql/catalog/tabledesc"
"github.com/cockroachdb/cockroach/pkg/sql/catalog/typedesc"
"github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgcode"
"github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror"
"github.com/cockroachdb/cockroach/pkg/sql/privilege"
"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
)
// prepareSetSchema verifies that a table/type can be set to the desired
// schema and returns the schema id of the desired schema.
func (p *planner) prepareSetSchema(
ctx context.Context, db catalog.DatabaseDescriptor, desc catalog.MutableDescriptor, schema string,
) (descpb.ID, error) {
var objectName tree.ObjectName
switch t := desc.(type) {
case *tabledesc.Mutable:
objectName = tree.NewUnqualifiedTableName(tree.Name(desc.GetName()))
case *typedesc.Mutable:
objectName = tree.NewUnqualifiedTypeName(desc.GetName())
default:
return 0, pgerror.Newf(
pgcode.InvalidParameterValue,
"no table or type was found for SET SCHEMA command, found %T", t)
}
// Lookup the schema we want to set to.
res, err := p.Descriptors().ByName(p.txn).Get().Schema(ctx, db, schema)
if err != nil {
return 0, err
}
switch res.SchemaKind() {
case catalog.SchemaTemporary:
return 0, pgerror.Newf(pgcode.FeatureNotSupported,
"cannot move objects into or out of temporary schemas")
case catalog.SchemaVirtual:
return 0, pgerror.Newf(pgcode.FeatureNotSupported,
"cannot move objects into or out of virtual schemas")
case catalog.SchemaPublic:
// We do not need to check for privileges on the public schema.
default:
// The user needs CREATE privilege on the target schema to move an object
// to the schema.
err = p.CheckPrivilege(ctx, res, privilege.CREATE)
if err != nil {
return 0, err
}
}
desiredSchemaID := res.GetID()
// If the schema being changed to is the same as the current schema a no-op
// will happen so we don't have to check if there is an object in the schema
// with the same name.
if desiredSchemaID == desc.GetParentSchemaID() {
return desiredSchemaID, nil
}
err = descs.CheckObjectNameCollision(
ctx, p.Descriptors(), p.txn, db.GetID(), desiredSchemaID, objectName,
)
if err != nil {
return descpb.InvalidID, err
}
return desiredSchemaID, nil
}