compat.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. package compiler
  2. import (
  3. "fmt"
  4. "strings"
  5. "github.com/sqlc-dev/sqlc/internal/sql/ast"
  6. "github.com/sqlc-dev/sqlc/internal/sql/astutils"
  7. )
  8. // This is mainly copy-pasted from internal/postgresql/parse.go
  9. func stringSlice(list *ast.List) []string {
  10. items := []string{}
  11. for _, item := range list.Items {
  12. if n, ok := item.(*ast.String); ok {
  13. items = append(items, n.Str)
  14. }
  15. }
  16. return items
  17. }
  18. type Relation struct {
  19. Catalog string
  20. Schema string
  21. Name string
  22. }
  23. func parseRelation(node ast.Node) (*Relation, error) {
  24. switch n := node.(type) {
  25. case *ast.Boolean:
  26. if n == nil {
  27. return nil, fmt.Errorf("unexpected nil in %T node", n)
  28. }
  29. return &Relation{Name: "bool"}, nil
  30. case *ast.List:
  31. if n == nil {
  32. return nil, fmt.Errorf("unexpected nil in %T node", n)
  33. }
  34. parts := stringSlice(n)
  35. switch len(parts) {
  36. case 1:
  37. return &Relation{
  38. Name: parts[0],
  39. }, nil
  40. case 2:
  41. return &Relation{
  42. Schema: parts[0],
  43. Name: parts[1],
  44. }, nil
  45. case 3:
  46. return &Relation{
  47. Catalog: parts[0],
  48. Schema: parts[1],
  49. Name: parts[2],
  50. }, nil
  51. default:
  52. return nil, fmt.Errorf("invalid name: %s", astutils.Join(n, "."))
  53. }
  54. case *ast.RangeVar:
  55. if n == nil {
  56. return nil, fmt.Errorf("unexpected nil in %T node", n)
  57. }
  58. name := Relation{}
  59. if n.Catalogname != nil {
  60. name.Catalog = *n.Catalogname
  61. }
  62. if n.Schemaname != nil {
  63. name.Schema = *n.Schemaname
  64. }
  65. if n.Relname != nil {
  66. name.Name = *n.Relname
  67. }
  68. return &name, nil
  69. case *ast.TypeName:
  70. if n == nil {
  71. return nil, fmt.Errorf("unexpected nil in %T node", n)
  72. }
  73. if n.Names != nil {
  74. return parseRelation(n.Names)
  75. } else {
  76. return &Relation{Name: n.Name}, nil
  77. }
  78. default:
  79. return nil, fmt.Errorf("unexpected node type: %T", node)
  80. }
  81. }
  82. func ParseTableName(node ast.Node) (*ast.TableName, error) {
  83. rel, err := parseRelation(node)
  84. if err != nil {
  85. return nil, fmt.Errorf("parse table name: %w", err)
  86. }
  87. return &ast.TableName{
  88. Catalog: rel.Catalog,
  89. Schema: rel.Schema,
  90. Name: rel.Name,
  91. }, nil
  92. }
  93. func ParseTypeName(node ast.Node) (*ast.TypeName, error) {
  94. rel, err := parseRelation(node)
  95. if err != nil {
  96. return nil, fmt.Errorf("parse type name: %w", err)
  97. }
  98. return &ast.TypeName{
  99. Catalog: rel.Catalog,
  100. Schema: rel.Schema,
  101. Name: rel.Name,
  102. }, nil
  103. }
  104. func ParseRelationString(name string) (*Relation, error) {
  105. parts := strings.Split(name, ".")
  106. switch len(parts) {
  107. case 1:
  108. return &Relation{
  109. Name: parts[0],
  110. }, nil
  111. case 2:
  112. return &Relation{
  113. Schema: parts[0],
  114. Name: parts[1],
  115. }, nil
  116. case 3:
  117. return &Relation{
  118. Catalog: parts[0],
  119. Schema: parts[1],
  120. Name: parts[2],
  121. }, nil
  122. default:
  123. return nil, fmt.Errorf("invalid name: %s", name)
  124. }
  125. }