query_catalog.go 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. package compiler
  2. import (
  3. "github.com/kyleconroy/sqlc/internal/sql/ast"
  4. "github.com/kyleconroy/sqlc/internal/sql/ast/pg"
  5. "github.com/kyleconroy/sqlc/internal/sql/catalog"
  6. )
  7. type QueryCatalog struct {
  8. catalog *catalog.Catalog
  9. ctes map[string]*Table
  10. }
  11. func buildQueryCatalog(c *catalog.Catalog, node ast.Node) (*QueryCatalog, error) {
  12. var with *pg.WithClause
  13. switch n := node.(type) {
  14. case *pg.InsertStmt:
  15. with = n.WithClause
  16. case *pg.UpdateStmt:
  17. with = n.WithClause
  18. case *pg.SelectStmt:
  19. with = n.WithClause
  20. default:
  21. with = nil
  22. }
  23. qc := &QueryCatalog{catalog: c, ctes: map[string]*Table{}}
  24. if with != nil {
  25. for _, item := range with.Ctes.Items {
  26. if cte, ok := item.(*pg.CommonTableExpr); ok {
  27. cols, err := outputColumns(qc, cte.Ctequery)
  28. if err != nil {
  29. return nil, err
  30. }
  31. rel := &ast.TableName{Name: *cte.Ctename}
  32. for i := range cols {
  33. cols[i].Table = rel
  34. }
  35. qc.ctes[*cte.Ctename] = &Table{
  36. Rel: rel,
  37. Columns: cols,
  38. }
  39. }
  40. }
  41. }
  42. return qc, nil
  43. }
  44. func ConvertColumn(rel *ast.TableName, c *catalog.Column) *Column {
  45. return &Column{
  46. Table: rel,
  47. Name: c.Name,
  48. DataType: dataType(&c.Type),
  49. NotNull: c.IsNotNull,
  50. IsArray: c.IsArray,
  51. Type: &c.Type,
  52. }
  53. }
  54. func (qc QueryCatalog) GetTable(rel *ast.TableName) (*Table, error) {
  55. cte, exists := qc.ctes[rel.Name]
  56. if exists {
  57. return cte, nil
  58. }
  59. src, err := qc.catalog.GetTable(rel)
  60. if err != nil {
  61. return nil, err
  62. }
  63. var cols []*Column
  64. for _, c := range src.Columns {
  65. cols = append(cols, ConvertColumn(rel, c))
  66. }
  67. return &Table{Rel: rel, Columns: cols}, nil
  68. }