snapshot of https://github.com/sqlc-dev/sqlc.git (main, 2026-09-16; blobs > 131072B omitted)
Some checks failed
kotlin / test (push) Has been skipped
python / test (push) Has been skipped
typescript / test (push) Has been skipped
go / build darwin/amd64 (push) Has been cancelled
go / build linux/amd64 (push) Has been cancelled
go / build windows/amd64 (push) Has been cancelled
go / build darwin/arm64 (push) Has been cancelled
go / build linux/arm64 (push) Has been cancelled
go / build windows/arm64 (push) Has been cancelled
go / test (push) Has been cancelled
go / vuln_check (push) Has been cancelled
Some checks failed
kotlin / test (push) Has been skipped
python / test (push) Has been skipped
typescript / test (push) Has been skipped
go / build darwin/amd64 (push) Has been cancelled
go / build linux/amd64 (push) Has been cancelled
go / build windows/amd64 (push) Has been cancelled
go / build darwin/arm64 (push) Has been cancelled
go / build linux/arm64 (push) Has been cancelled
go / build windows/arm64 (push) Has been cancelled
go / test (push) Has been cancelled
go / vuln_check (push) Has been cancelled
This commit is contained in:
173
internal/core/proc.go
Normal file
173
internal/core/proc.go
Normal file
@@ -0,0 +1,173 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/sqlc-dev/sqlc/internal/core/catalogdb"
|
||||
)
|
||||
|
||||
type ProcSpec struct {
|
||||
Name string
|
||||
NamespaceOID int64
|
||||
DialectOID int64
|
||||
Kind string
|
||||
ReturnTypeOID int64
|
||||
ReturnSet bool
|
||||
ReturnNullable bool
|
||||
// NeverNull marks a function whose result is never NULL even when an
|
||||
// argument is, in a dialect that otherwise propagates nullability.
|
||||
NeverNull bool
|
||||
// ReturnTemplate is the result as an expression over the call's
|
||||
// arguments, when it depends on their values: Decimal(18, $2) for
|
||||
// toDecimal64(x, s).
|
||||
ReturnTemplate string
|
||||
Strict bool
|
||||
VariadicKind string
|
||||
Args []ProcArg
|
||||
}
|
||||
|
||||
// The proc table stores nullability as one integer: 0 leaves it to the
|
||||
// dialect's rule, 1 is always nullable and 2 is never nullable.
|
||||
const (
|
||||
nullableDefault int64 = 0
|
||||
nullableAlways int64 = 1
|
||||
nullableNever int64 = 2
|
||||
)
|
||||
|
||||
type ProcArg struct {
|
||||
Name string
|
||||
TypeOID int64
|
||||
Mode string
|
||||
HasDefault bool
|
||||
}
|
||||
|
||||
func (c *Catalog) CreateProc(p ProcSpec) (int64, error) {
|
||||
if p.Kind == "" {
|
||||
p.Kind = "f"
|
||||
}
|
||||
if p.VariadicKind == "" {
|
||||
p.VariadicKind = "n"
|
||||
}
|
||||
ctx := context.Background()
|
||||
procOID, err := c.q.CreateProc(ctx, catalogdb.CreateProcParams{
|
||||
NamespaceOid: nullInt64(p.NamespaceOID),
|
||||
DialectOid: nullInt64(p.DialectOID),
|
||||
Name: strings.ToLower(p.Name),
|
||||
Kind: p.Kind,
|
||||
ReturnTypeOid: p.ReturnTypeOID,
|
||||
ReturnSet: boolToInt64(p.ReturnSet),
|
||||
ReturnNullable: returnNullable(p),
|
||||
ReturnTemplate: p.ReturnTemplate,
|
||||
Strict: boolToInt64(p.Strict),
|
||||
VariadicKind: p.VariadicKind,
|
||||
})
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("create proc %q: %w", p.Name, err)
|
||||
}
|
||||
for i, a := range p.Args {
|
||||
mode := a.Mode
|
||||
if mode == "" {
|
||||
mode = "i"
|
||||
}
|
||||
err := c.q.CreateProcArg(ctx, catalogdb.CreateProcArgParams{
|
||||
ProcOid: procOID,
|
||||
Ord: int64(i + 1),
|
||||
Name: a.Name,
|
||||
TypeOid: a.TypeOID,
|
||||
Mode: mode,
|
||||
HasDefault: boolToInt64(a.HasDefault),
|
||||
})
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("create proc %q arg %d: %w", p.Name, i+1, err)
|
||||
}
|
||||
}
|
||||
return procOID, nil
|
||||
}
|
||||
|
||||
func returnNullable(p ProcSpec) int64 {
|
||||
switch {
|
||||
case p.NeverNull:
|
||||
return nullableNever
|
||||
case p.ReturnNullable:
|
||||
return nullableAlways
|
||||
}
|
||||
return nullableDefault
|
||||
}
|
||||
|
||||
type ProcOverload struct {
|
||||
OID int64
|
||||
Name string
|
||||
Kind string
|
||||
ReturnTypeOID int64
|
||||
ReturnNullable bool
|
||||
NeverNull bool
|
||||
ReturnTemplate string
|
||||
ArgTypes []int64
|
||||
}
|
||||
|
||||
// FindProcs returns the overloads of name, optionally restricted to the given
|
||||
// namespaces.
|
||||
func (c *Catalog) FindProcs(name string, namespaceOIDs []int64) ([]ProcOverload, error) {
|
||||
ctx := context.Background()
|
||||
lname := strings.ToLower(name)
|
||||
|
||||
var out []ProcOverload
|
||||
if len(namespaceOIDs) == 0 {
|
||||
rows, err := c.q.FindProcsAnyNamespace(ctx, lname)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("find procs %q: %w", name, err)
|
||||
}
|
||||
out = make([]ProcOverload, 0, len(rows))
|
||||
for _, r := range rows {
|
||||
out = append(out, ProcOverload{
|
||||
OID: r.Oid,
|
||||
Name: r.Name,
|
||||
Kind: r.Kind,
|
||||
ReturnTypeOID: r.ReturnTypeOid,
|
||||
ReturnNullable: r.ReturnNullable == nullableAlways,
|
||||
NeverNull: r.ReturnNullable == nullableNever,
|
||||
ReturnTemplate: r.ReturnTemplate,
|
||||
})
|
||||
}
|
||||
} else {
|
||||
nss := make([]sql.NullInt64, len(namespaceOIDs))
|
||||
for i, ns := range namespaceOIDs {
|
||||
nss[i] = sql.NullInt64{Int64: ns, Valid: true}
|
||||
}
|
||||
rows, err := c.q.FindProcsInNamespaces(ctx, catalogdb.FindProcsInNamespacesParams{
|
||||
Name: lname,
|
||||
NamespaceOids: nss,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("find procs %q: %w", name, err)
|
||||
}
|
||||
out = make([]ProcOverload, 0, len(rows))
|
||||
for _, r := range rows {
|
||||
out = append(out, ProcOverload{
|
||||
OID: r.Oid,
|
||||
Name: r.Name,
|
||||
Kind: r.Kind,
|
||||
ReturnTypeOID: r.ReturnTypeOid,
|
||||
ReturnNullable: r.ReturnNullable == nullableAlways,
|
||||
NeverNull: r.ReturnNullable == nullableNever,
|
||||
ReturnTemplate: r.ReturnTemplate,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
for i := range out {
|
||||
argTypes, err := c.procArgTypes(out[i].OID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out[i].ArgTypes = argTypes
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *Catalog) procArgTypes(procOID int64) ([]int64, error) {
|
||||
return c.q.ProcArgTypes(context.Background(), procOID)
|
||||
}
|
||||
Reference in New Issue
Block a user