output_columns.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766
  1. package compiler
  2. import (
  3. "errors"
  4. "fmt"
  5. "github.com/sqlc-dev/sqlc/internal/sql/ast"
  6. "github.com/sqlc-dev/sqlc/internal/sql/astutils"
  7. "github.com/sqlc-dev/sqlc/internal/sql/catalog"
  8. "github.com/sqlc-dev/sqlc/internal/sql/lang"
  9. "github.com/sqlc-dev/sqlc/internal/sql/sqlerr"
  10. )
  11. // OutputColumns determines which columns a statement will output
  12. func (c *Compiler) OutputColumns(stmt ast.Node) ([]*catalog.Column, error) {
  13. qc, err := c.buildQueryCatalog(c.catalog, stmt, nil)
  14. if err != nil {
  15. return nil, err
  16. }
  17. cols, err := c.outputColumns(qc, stmt)
  18. if err != nil {
  19. return nil, err
  20. }
  21. catCols := make([]*catalog.Column, 0, len(cols))
  22. for _, col := range cols {
  23. catCols = append(catCols, &catalog.Column{
  24. Name: col.Name,
  25. Type: ast.TypeName{Name: col.DataType},
  26. IsNotNull: col.NotNull,
  27. IsUnsigned: col.Unsigned,
  28. IsArray: col.IsArray,
  29. ArrayDims: col.ArrayDims,
  30. Comment: col.Comment,
  31. Length: col.Length,
  32. })
  33. }
  34. return catCols, nil
  35. }
  36. func hasStarRef(cf *ast.ColumnRef) bool {
  37. for _, item := range cf.Fields.Items {
  38. if _, ok := item.(*ast.A_Star); ok {
  39. return true
  40. }
  41. }
  42. return false
  43. }
  44. // Compute the output columns for a statement.
  45. //
  46. // Return an error if column references are ambiguous
  47. // Return an error if column references don't exist
  48. func (c *Compiler) outputColumns(qc *QueryCatalog, node ast.Node) ([]*Column, error) {
  49. tables, err := c.sourceTables(qc, node)
  50. if err != nil {
  51. return nil, err
  52. }
  53. targets := &ast.List{}
  54. switch n := node.(type) {
  55. case *ast.DeleteStmt:
  56. targets = n.ReturningList
  57. case *ast.InsertStmt:
  58. targets = n.ReturningList
  59. case *ast.SelectStmt:
  60. targets = n.TargetList
  61. isUnion := len(targets.Items) == 0 && n.Larg != nil
  62. if n.GroupClause != nil {
  63. for _, item := range n.GroupClause.Items {
  64. if err := findColumnForNode(item, tables, targets); err != nil {
  65. return nil, err
  66. }
  67. }
  68. }
  69. validateOrderBy := true
  70. if c.conf.StrictOrderBy != nil {
  71. validateOrderBy = *c.conf.StrictOrderBy
  72. }
  73. if !isUnion && validateOrderBy {
  74. if n.SortClause != nil {
  75. for _, item := range n.SortClause.Items {
  76. sb, ok := item.(*ast.SortBy)
  77. if !ok {
  78. continue
  79. }
  80. if err := findColumnForNode(sb.Node, tables, targets); err != nil {
  81. return nil, fmt.Errorf("%v: if you want to skip this validation, set 'strict_order_by' to false", err)
  82. }
  83. }
  84. }
  85. if n.WindowClause != nil {
  86. for _, item := range n.WindowClause.Items {
  87. sb, ok := item.(*ast.List)
  88. if !ok {
  89. continue
  90. }
  91. for _, single := range sb.Items {
  92. caseExpr, ok := single.(*ast.CaseExpr)
  93. if !ok {
  94. continue
  95. }
  96. if err := findColumnForNode(caseExpr.Xpr, tables, targets); err != nil {
  97. return nil, fmt.Errorf("%v: if you want to skip this validation, set 'strict_order_by' to false", err)
  98. }
  99. }
  100. }
  101. }
  102. }
  103. // For UNION queries, targets is empty and we need to look for the
  104. // columns in Largs.
  105. if isUnion {
  106. return c.outputColumns(qc, n.Larg)
  107. }
  108. case *ast.UpdateStmt:
  109. targets = n.ReturningList
  110. }
  111. var cols []*Column
  112. for _, target := range targets.Items {
  113. res, ok := target.(*ast.ResTarget)
  114. if !ok {
  115. continue
  116. }
  117. switch n := res.Val.(type) {
  118. case *ast.A_Const:
  119. name := ""
  120. if res.Name != nil {
  121. name = *res.Name
  122. }
  123. switch n.Val.(type) {
  124. case *ast.String:
  125. cols = append(cols, &Column{Name: name, DataType: "text", NotNull: true})
  126. case *ast.Integer:
  127. cols = append(cols, &Column{Name: name, DataType: "int", NotNull: true})
  128. case *ast.Float:
  129. cols = append(cols, &Column{Name: name, DataType: "float", NotNull: true})
  130. case *ast.Boolean:
  131. cols = append(cols, &Column{Name: name, DataType: "bool", NotNull: true})
  132. default:
  133. cols = append(cols, &Column{Name: name, DataType: "any", NotNull: false})
  134. }
  135. case *ast.A_Expr:
  136. name := ""
  137. if res.Name != nil {
  138. name = *res.Name
  139. }
  140. switch op := astutils.Join(n.Name, ""); {
  141. case lang.IsComparisonOperator(op):
  142. // TODO: Generate a name for these operations
  143. cols = append(cols, &Column{Name: name, DataType: "bool", NotNull: true})
  144. case lang.IsMathematicalOperator(op):
  145. cols = append(cols, &Column{Name: name, DataType: "int", NotNull: true})
  146. default:
  147. cols = append(cols, &Column{Name: name, DataType: "any", NotNull: false})
  148. }
  149. case *ast.BoolExpr:
  150. name := ""
  151. if res.Name != nil {
  152. name = *res.Name
  153. }
  154. notNull := false
  155. if len(n.Args.Items) == 1 {
  156. switch n.Boolop {
  157. case ast.BoolExprTypeIsNull, ast.BoolExprTypeIsNotNull:
  158. notNull = true
  159. case ast.BoolExprTypeNot:
  160. sublink, ok := n.Args.Items[0].(*ast.SubLink)
  161. if ok && sublink.SubLinkType == ast.EXISTS_SUBLINK {
  162. notNull = true
  163. if name == "" {
  164. name = "not_exists"
  165. }
  166. }
  167. }
  168. }
  169. cols = append(cols, &Column{Name: name, DataType: "bool", NotNull: notNull})
  170. case *ast.CaseExpr:
  171. name := ""
  172. if res.Name != nil {
  173. name = *res.Name
  174. }
  175. // TODO: The TypeCase and A_Const code has been copied from below. Instead, we
  176. // need a recurse function to get the type of a node.
  177. if tc, ok := n.Defresult.(*ast.TypeCast); ok {
  178. if tc.TypeName == nil {
  179. return nil, errors.New("no type name type cast")
  180. }
  181. name := ""
  182. if ref, ok := tc.Arg.(*ast.ColumnRef); ok {
  183. name = astutils.Join(ref.Fields, "_")
  184. }
  185. if res.Name != nil {
  186. name = *res.Name
  187. }
  188. // TODO Validate column names
  189. col := toColumn(tc.TypeName)
  190. col.Name = name
  191. cols = append(cols, col)
  192. } else if aconst, ok := n.Defresult.(*ast.A_Const); ok {
  193. switch aconst.Val.(type) {
  194. case *ast.String:
  195. cols = append(cols, &Column{Name: name, DataType: "text", NotNull: true})
  196. case *ast.Integer:
  197. cols = append(cols, &Column{Name: name, DataType: "int", NotNull: true})
  198. case *ast.Float:
  199. cols = append(cols, &Column{Name: name, DataType: "float", NotNull: true})
  200. case *ast.Boolean:
  201. cols = append(cols, &Column{Name: name, DataType: "bool", NotNull: true})
  202. default:
  203. cols = append(cols, &Column{Name: name, DataType: "any", NotNull: false})
  204. }
  205. } else {
  206. cols = append(cols, &Column{Name: name, DataType: "any", NotNull: false})
  207. }
  208. case *ast.CoalesceExpr:
  209. name := "coalesce"
  210. if res.Name != nil {
  211. name = *res.Name
  212. }
  213. var firstColumn *Column
  214. var shouldNotBeNull bool
  215. for _, arg := range n.Args.Items {
  216. if _, ok := arg.(*ast.A_Const); ok {
  217. shouldNotBeNull = true
  218. continue
  219. }
  220. if ref, ok := arg.(*ast.ColumnRef); ok {
  221. columns, err := outputColumnRefs(res, tables, ref)
  222. if err != nil {
  223. return nil, err
  224. }
  225. for _, c := range columns {
  226. if firstColumn == nil {
  227. firstColumn = c
  228. }
  229. shouldNotBeNull = shouldNotBeNull || c.NotNull
  230. }
  231. }
  232. }
  233. if firstColumn != nil {
  234. firstColumn.NotNull = shouldNotBeNull
  235. firstColumn.skipTableRequiredCheck = true
  236. cols = append(cols, firstColumn)
  237. } else {
  238. cols = append(cols, &Column{Name: name, DataType: "any", NotNull: false})
  239. }
  240. case *ast.ColumnRef:
  241. if hasStarRef(n) {
  242. // add a column with a reference to an embedded table
  243. if embed, ok := qc.embeds.Find(n); ok {
  244. cols = append(cols, &Column{
  245. Name: embed.Table.Name,
  246. EmbedTable: embed.Table,
  247. })
  248. continue
  249. }
  250. // TODO: This code is copied in func expand()
  251. for _, t := range tables {
  252. scope := astutils.Join(n.Fields, ".")
  253. if scope != "" && scope != t.Rel.Name {
  254. continue
  255. }
  256. for _, c := range t.Columns {
  257. cname := c.Name
  258. if res.Name != nil {
  259. cname = *res.Name
  260. }
  261. cols = append(cols, &Column{
  262. Name: cname,
  263. OriginalName: c.Name,
  264. Type: c.Type,
  265. Scope: scope,
  266. Table: c.Table,
  267. TableAlias: t.Rel.Name,
  268. DataType: c.DataType,
  269. NotNull: c.NotNull,
  270. Unsigned: c.Unsigned,
  271. IsArray: c.IsArray,
  272. ArrayDims: c.ArrayDims,
  273. Length: c.Length,
  274. })
  275. }
  276. }
  277. continue
  278. }
  279. columns, err := outputColumnRefs(res, tables, n)
  280. if err != nil {
  281. return nil, err
  282. }
  283. cols = append(cols, columns...)
  284. case *ast.FuncCall:
  285. rel := n.Func
  286. name := rel.Name
  287. if res.Name != nil {
  288. name = *res.Name
  289. }
  290. fun, err := qc.catalog.ResolveFuncCall(n)
  291. if err == nil {
  292. cols = append(cols, &Column{
  293. Name: name,
  294. DataType: dataType(fun.ReturnType),
  295. NotNull: !fun.ReturnTypeNullable,
  296. IsFuncCall: true,
  297. })
  298. } else {
  299. cols = append(cols, &Column{
  300. Name: name,
  301. DataType: "any",
  302. IsFuncCall: true,
  303. })
  304. }
  305. case *ast.SubLink:
  306. name := "exists"
  307. if res.Name != nil {
  308. name = *res.Name
  309. }
  310. switch n.SubLinkType {
  311. case ast.EXISTS_SUBLINK:
  312. cols = append(cols, &Column{Name: name, DataType: "bool", NotNull: true})
  313. case ast.EXPR_SUBLINK:
  314. subcols, err := c.outputColumns(qc, n.Subselect)
  315. if err != nil {
  316. return nil, err
  317. }
  318. first := subcols[0]
  319. if res.Name != nil {
  320. first.Name = *res.Name
  321. }
  322. cols = append(cols, first)
  323. default:
  324. cols = append(cols, &Column{Name: name, DataType: "any", NotNull: false})
  325. }
  326. case *ast.TypeCast:
  327. if n.TypeName == nil {
  328. return nil, errors.New("no type name type cast")
  329. }
  330. name := ""
  331. if ref, ok := n.Arg.(*ast.ColumnRef); ok {
  332. name = astutils.Join(ref.Fields, "_")
  333. }
  334. if res.Name != nil {
  335. name = *res.Name
  336. }
  337. // TODO Validate column names
  338. col := toColumn(n.TypeName)
  339. col.Name = name
  340. // TODO Add correct, real type inference
  341. if constant, ok := n.Arg.(*ast.A_Const); ok {
  342. if _, ok := constant.Val.(*ast.Null); ok {
  343. col.NotNull = false
  344. }
  345. }
  346. cols = append(cols, col)
  347. case *ast.SelectStmt:
  348. subcols, err := c.outputColumns(qc, n)
  349. if err != nil {
  350. return nil, err
  351. }
  352. first := subcols[0]
  353. if res.Name != nil {
  354. first.Name = *res.Name
  355. }
  356. cols = append(cols, first)
  357. default:
  358. name := ""
  359. if res.Name != nil {
  360. name = *res.Name
  361. }
  362. cols = append(cols, &Column{Name: name, DataType: "any", NotNull: false})
  363. }
  364. }
  365. if n, ok := node.(*ast.SelectStmt); ok {
  366. for _, col := range cols {
  367. if !col.NotNull || col.Table == nil || col.skipTableRequiredCheck {
  368. continue
  369. }
  370. for _, f := range n.FromClause.Items {
  371. res := isTableRequired(f, col, tableRequired)
  372. if res != tableNotFound {
  373. col.NotNull = res == tableRequired
  374. break
  375. }
  376. }
  377. }
  378. }
  379. return cols, nil
  380. }
  381. const (
  382. tableNotFound = iota
  383. tableRequired
  384. tableOptional
  385. )
  386. func isTableRequired(n ast.Node, col *Column, prior int) int {
  387. switch n := n.(type) {
  388. case *ast.RangeVar:
  389. tableMatch := *n.Relname == col.Table.Name
  390. aliasMatch := true
  391. if n.Alias != nil && col.TableAlias != "" {
  392. aliasMatch = *n.Alias.Aliasname == col.TableAlias
  393. }
  394. if aliasMatch && tableMatch {
  395. return prior
  396. }
  397. case *ast.JoinExpr:
  398. helper := func(l, r int) int {
  399. if res := isTableRequired(n.Larg, col, l); res != tableNotFound {
  400. return res
  401. }
  402. if res := isTableRequired(n.Rarg, col, r); res != tableNotFound {
  403. return res
  404. }
  405. return tableNotFound
  406. }
  407. switch n.Jointype {
  408. case ast.JoinTypeLeft:
  409. return helper(tableRequired, tableOptional)
  410. case ast.JoinTypeRight:
  411. return helper(tableOptional, tableRequired)
  412. case ast.JoinTypeFull:
  413. return helper(tableOptional, tableOptional)
  414. case ast.JoinTypeInner:
  415. return helper(tableRequired, tableRequired)
  416. }
  417. case *ast.List:
  418. for _, item := range n.Items {
  419. if res := isTableRequired(item, col, prior); res != tableNotFound {
  420. return res
  421. }
  422. }
  423. }
  424. return tableNotFound
  425. }
  426. type tableVisitor struct {
  427. list ast.List
  428. }
  429. func (r *tableVisitor) Visit(n ast.Node) astutils.Visitor {
  430. switch n.(type) {
  431. case *ast.RangeVar, *ast.RangeFunction:
  432. r.list.Items = append(r.list.Items, n)
  433. return r
  434. case *ast.RangeSubselect:
  435. r.list.Items = append(r.list.Items, n)
  436. return nil
  437. default:
  438. return r
  439. }
  440. }
  441. // Compute the output columns for a statement.
  442. //
  443. // Return an error if column references are ambiguous
  444. // Return an error if column references don't exist
  445. // Return an error if a table is referenced twice
  446. // Return an error if an unknown column is referenced
  447. func (c *Compiler) sourceTables(qc *QueryCatalog, node ast.Node) ([]*Table, error) {
  448. list := &ast.List{}
  449. switch n := node.(type) {
  450. case *ast.DeleteStmt:
  451. list = n.Relations
  452. case *ast.InsertStmt:
  453. list = &ast.List{
  454. Items: []ast.Node{n.Relation},
  455. }
  456. case *ast.SelectStmt:
  457. var tv tableVisitor
  458. astutils.Walk(&tv, n.FromClause)
  459. list = &tv.list
  460. case *ast.TruncateStmt:
  461. list = astutils.Search(n.Relations, func(node ast.Node) bool {
  462. _, ok := node.(*ast.RangeVar)
  463. return ok
  464. })
  465. case *ast.RefreshMatViewStmt:
  466. list = astutils.Search(n.Relation, func(node ast.Node) bool {
  467. _, ok := node.(*ast.RangeVar)
  468. return ok
  469. })
  470. case *ast.UpdateStmt:
  471. var tv tableVisitor
  472. astutils.Walk(&tv, n.FromClause)
  473. astutils.Walk(&tv, n.Relations)
  474. list = &tv.list
  475. }
  476. var tables []*Table
  477. for _, item := range list.Items {
  478. item := item
  479. switch n := item.(type) {
  480. case *ast.RangeFunction:
  481. var funcCall *ast.FuncCall
  482. switch f := n.Functions.Items[0].(type) {
  483. case *ast.List:
  484. switch fi := f.Items[0].(type) {
  485. case *ast.FuncCall:
  486. funcCall = fi
  487. case *ast.SQLValueFunction:
  488. continue // TODO handle this correctly
  489. default:
  490. continue
  491. }
  492. case *ast.FuncCall:
  493. funcCall = f
  494. default:
  495. return nil, fmt.Errorf("sourceTables: unsupported function call type %T", n.Functions.Items[0])
  496. }
  497. // If the function or table can't be found, don't error out. There
  498. // are many queries that depend on functions unknown to sqlc.
  499. fn, err := qc.GetFunc(funcCall.Func)
  500. if err != nil {
  501. continue
  502. }
  503. var table *Table
  504. if fn.ReturnType != nil {
  505. table, err = qc.GetTable(&ast.TableName{
  506. Catalog: fn.ReturnType.Catalog,
  507. Schema: fn.ReturnType.Schema,
  508. Name: fn.ReturnType.Name,
  509. })
  510. }
  511. if table == nil || err != nil {
  512. if n.Alias != nil && len(n.Alias.Colnames.Items) > 0 {
  513. table = &Table{}
  514. for _, colName := range n.Alias.Colnames.Items {
  515. table.Columns = append(table.Columns, &Column{
  516. Name: colName.(*ast.String).Str,
  517. DataType: "any",
  518. })
  519. }
  520. } else {
  521. colName := fn.Rel.Name
  522. if n.Alias != nil {
  523. colName = *n.Alias.Aliasname
  524. }
  525. table = &Table{
  526. Rel: &ast.TableName{
  527. Catalog: fn.Rel.Catalog,
  528. Schema: fn.Rel.Schema,
  529. Name: fn.Rel.Name,
  530. },
  531. }
  532. if len(fn.Outs) > 0 {
  533. for _, arg := range fn.Outs {
  534. table.Columns = append(table.Columns, &Column{
  535. Name: arg.Name,
  536. DataType: arg.Type.Name,
  537. })
  538. }
  539. }
  540. if fn.ReturnType != nil {
  541. table.Columns = []*Column{
  542. {
  543. Name: colName,
  544. DataType: fn.ReturnType.Name,
  545. },
  546. }
  547. }
  548. }
  549. }
  550. if n.Alias != nil {
  551. table.Rel = &ast.TableName{
  552. Name: *n.Alias.Aliasname,
  553. }
  554. }
  555. tables = append(tables, table)
  556. case *ast.RangeSubselect:
  557. cols, err := c.outputColumns(qc, n.Subquery)
  558. if err != nil {
  559. return nil, err
  560. }
  561. tables = append(tables, &Table{
  562. Rel: &ast.TableName{
  563. Name: *n.Alias.Aliasname,
  564. },
  565. Columns: cols,
  566. })
  567. case *ast.RangeVar:
  568. fqn, err := ParseTableName(n)
  569. if err != nil {
  570. return nil, err
  571. }
  572. if qc == nil {
  573. return nil, fmt.Errorf("query catalog is empty")
  574. }
  575. table, cerr := qc.GetTable(fqn)
  576. if cerr != nil {
  577. // TODO: Update error location
  578. // cerr.Location = n.Location
  579. // return nil, *cerr
  580. return nil, cerr
  581. }
  582. if n.Alias != nil {
  583. table.Rel = &ast.TableName{
  584. Catalog: table.Rel.Catalog,
  585. Schema: table.Rel.Schema,
  586. Name: *n.Alias.Aliasname,
  587. }
  588. }
  589. tables = append(tables, table)
  590. default:
  591. return nil, fmt.Errorf("sourceTable: unsupported list item type: %T", n)
  592. }
  593. }
  594. return tables, nil
  595. }
  596. func outputColumnRefs(res *ast.ResTarget, tables []*Table, node *ast.ColumnRef) ([]*Column, error) {
  597. parts := stringSlice(node.Fields)
  598. var schema, name, alias string
  599. switch {
  600. case len(parts) == 1:
  601. name = parts[0]
  602. case len(parts) == 2:
  603. alias = parts[0]
  604. name = parts[1]
  605. case len(parts) == 3:
  606. schema = parts[0]
  607. alias = parts[1]
  608. name = parts[2]
  609. default:
  610. return nil, fmt.Errorf("unknown number of fields: %d", len(parts))
  611. }
  612. var cols []*Column
  613. var found int
  614. for _, t := range tables {
  615. if schema != "" && t.Rel.Schema != schema {
  616. continue
  617. }
  618. if alias != "" && t.Rel.Name != alias {
  619. continue
  620. }
  621. for _, c := range t.Columns {
  622. if c.Name == name {
  623. found += 1
  624. cname := c.Name
  625. if res.Name != nil {
  626. cname = *res.Name
  627. }
  628. cols = append(cols, &Column{
  629. Name: cname,
  630. Type: c.Type,
  631. Table: c.Table,
  632. TableAlias: alias,
  633. DataType: c.DataType,
  634. NotNull: c.NotNull,
  635. Unsigned: c.Unsigned,
  636. IsArray: c.IsArray,
  637. ArrayDims: c.ArrayDims,
  638. Length: c.Length,
  639. EmbedTable: c.EmbedTable,
  640. OriginalName: c.Name,
  641. })
  642. }
  643. }
  644. }
  645. if found == 0 {
  646. return nil, &sqlerr.Error{
  647. Code: "42703",
  648. Message: fmt.Sprintf("column %q does not exist", name),
  649. Location: res.Location,
  650. }
  651. }
  652. if found > 1 {
  653. return nil, &sqlerr.Error{
  654. Code: "42703",
  655. Message: fmt.Sprintf("column reference %q is ambiguous", name),
  656. Location: res.Location,
  657. }
  658. }
  659. return cols, nil
  660. }
  661. func findColumnForNode(item ast.Node, tables []*Table, targetList *ast.List) error {
  662. ref, ok := item.(*ast.ColumnRef)
  663. if !ok {
  664. return nil
  665. }
  666. return findColumnForRef(ref, tables, targetList)
  667. }
  668. func findColumnForRef(ref *ast.ColumnRef, tables []*Table, targetList *ast.List) error {
  669. parts := stringSlice(ref.Fields)
  670. var alias, name string
  671. if len(parts) == 1 {
  672. name = parts[0]
  673. } else if len(parts) == 2 {
  674. alias = parts[0]
  675. name = parts[1]
  676. }
  677. var found int
  678. for _, t := range tables {
  679. if alias != "" && t.Rel.Name != alias {
  680. continue
  681. }
  682. // Find matching column
  683. for _, c := range t.Columns {
  684. if c.Name == name {
  685. found++
  686. break
  687. }
  688. }
  689. }
  690. // Find matching alias if necessary
  691. if found == 0 {
  692. for _, c := range targetList.Items {
  693. resTarget, ok := c.(*ast.ResTarget)
  694. if !ok {
  695. continue
  696. }
  697. if resTarget.Name != nil && *resTarget.Name == name {
  698. found++
  699. }
  700. }
  701. }
  702. if found == 0 {
  703. return &sqlerr.Error{
  704. Code: "42703",
  705. Message: fmt.Sprintf("column reference %q not found", name),
  706. Location: ref.Location,
  707. }
  708. }
  709. if found > 1 {
  710. return &sqlerr.Error{
  711. Code: "42703",
  712. Message: fmt.Sprintf("column reference %q is ambiguous", name),
  713. Location: ref.Location,
  714. }
  715. }
  716. return nil
  717. }