-
Notifications
You must be signed in to change notification settings - Fork 3.9k
/
Copy pathexecute.go
71 lines (63 loc) · 2.19 KB
/
execute.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
// Copyright 2017 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/schemaexpr"
"github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgcode"
"github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror"
"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
"github.com/cockroachdb/errors"
)
// fillInPlaceholder helps with the EXECUTE foo(args) SQL statement: it takes in
// a prepared statement returning
// the referenced prepared statement and correctly updated placeholder info.
// See https://www.postgresql.org/docs/current/static/sql-execute.html for details.
func (p *planner) fillInPlaceholders(
ctx context.Context, ps *PreparedStatement, name string, params tree.Exprs,
) (*tree.PlaceholderInfo, error) {
if len(ps.Types) != len(params) {
return nil, pgerror.Newf(pgcode.Syntax,
"wrong number of parameters for prepared statement %q: expected %d, got %d",
name, len(ps.Types), len(params))
}
qArgs := make(tree.QueryArguments, len(params))
var semaCtx tree.SemaContext
for i, e := range params {
idx := tree.PlaceholderIdx(i)
typ, ok := ps.ValueType(idx)
if !ok {
return nil, errors.AssertionFailedf("no type for placeholder %s", idx)
}
// For user-defined types, we need to resolve the type to make sure we get
// the latest changes to the type.
if typ.UserDefined() {
var err error
typ, err = p.ResolveTypeByOID(ctx, typ.Oid())
if err != nil {
return nil, err
}
}
typedExpr, err := schemaexpr.SanitizeVarFreeExpr(
ctx, e, typ, "EXECUTE parameter" /* context */, &semaCtx, tree.VolatilityVolatile,
)
if err != nil {
return nil, pgerror.WithCandidateCode(err, pgcode.WrongObjectType)
}
qArgs[idx] = typedExpr
}
return &tree.PlaceholderInfo{
Values: qArgs,
PlaceholderTypesInfo: tree.PlaceholderTypesInfo{
TypeHints: ps.TypeHints,
Types: ps.Types,
},
}, nil
}