Files
upstream-mirror 0f4df23290
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
snapshot of https://github.com/sqlc-dev/sqlc.git (main, 2026-09-16; blobs > 131072B omitted)
2026-09-16 02:17:34 +05:00

135 lines
2.9 KiB
Go

package catalog
import (
"fmt"
"strings"
"github.com/sqlc-dev/sqlc/internal/sql/ast"
"github.com/sqlc-dev/sqlc/internal/sql/sqlerr"
)
// Schema describes how the data in a relational database may relate to other tables or other data models
type Schema struct {
Name string
Tables []*Table
Types []Type
Funcs []*Function
Comment string
}
func (s *Schema) getFunc(rel *ast.FuncName, tns []*ast.TypeName) (*Function, int, error) {
for i := range s.Funcs {
if !strings.EqualFold(s.Funcs[i].Name, rel.Name) {
continue
}
args := s.Funcs[i].InArgs()
if len(args) != len(tns) {
continue
}
found := true
for j := range args {
if !sameType(s.Funcs[i].Args[j].Type, tns[j]) {
found = false
break
}
}
if !found {
continue
}
return s.Funcs[i], i, nil
}
return nil, -1, sqlerr.RelationNotFound(rel.Name)
}
func (s *Schema) getFuncByName(rel *ast.FuncName) (*Function, int, error) {
idx := -1
name := strings.ToLower(rel.Name)
for i := range s.Funcs {
lowered := strings.ToLower(s.Funcs[i].Name)
if lowered == name && idx >= 0 {
return nil, -1, sqlerr.FunctionNotUnique(rel.Name)
}
if lowered == name {
idx = i
}
}
if idx < 0 {
return nil, -1, sqlerr.RelationNotFound(rel.Name)
}
return s.Funcs[idx], idx, nil
}
func (s *Schema) getTable(rel *ast.TableName) (*Table, int, error) {
for i := range s.Tables {
if s.Tables[i].Rel.Name == rel.Name {
return s.Tables[i], i, nil
}
}
return nil, -1, sqlerr.RelationNotFound(rel.Name)
}
func (s *Schema) getType(rel *ast.TypeName) (Type, int, error) {
for i := range s.Types {
switch typ := s.Types[i].(type) {
case *Enum:
if typ.Name == rel.Name {
return s.Types[i], i, nil
}
case *CompositeType:
if typ.Name == rel.Name {
return s.Types[i], i, nil
}
}
}
return nil, -1, sqlerr.TypeNotFound(rel.Name)
}
func (c *Catalog) getSchema(name string) (*Schema, error) {
for i := range c.Schemas {
if c.Schemas[i].Name == name {
return c.Schemas[i], nil
}
}
return nil, sqlerr.SchemaNotFound(name)
}
func (c *Catalog) createSchema(stmt *ast.CreateSchemaStmt) error {
if stmt.Name == nil {
return fmt.Errorf("create schema: empty name")
}
if _, err := c.getSchema(*stmt.Name); err == nil {
// If the default schema already exists, treat additional CREATE SCHEMA
// statements as no-ops.
if *stmt.Name == c.DefaultSchema {
return nil
}
if !stmt.IfNotExists {
return sqlerr.SchemaExists(*stmt.Name)
}
}
c.Schemas = append(c.Schemas, &Schema{Name: *stmt.Name})
return nil
}
func (c *Catalog) dropSchema(stmt *ast.DropSchemaStmt) error {
// TODO: n^2 in the worst-case
for _, name := range stmt.Schemas {
idx := -1
for i := range c.Schemas {
if c.Schemas[i].Name == name.Str {
idx = i
}
}
if idx == -1 {
if stmt.MissingOk {
continue
}
return sqlerr.SchemaNotFound(name.Str)
}
c.Schemas = append(c.Schemas[:idx], c.Schemas[idx+1:]...)
}
return nil
}