| 414 | ) |
| 415 | |
| 416 | func isTableRequired(n ast.Node, col *Column, prior int) int { |
| 417 | switch n := n.(type) { |
| 418 | case *ast.RangeVar: |
| 419 | tableMatch := *n.Relname == col.Table.Name |
| 420 | aliasMatch := true |
| 421 | if n.Alias != nil && col.TableAlias != "" { |
| 422 | aliasMatch = *n.Alias.Aliasname == col.TableAlias |
| 423 | } |
| 424 | if aliasMatch && tableMatch { |
| 425 | return prior |
| 426 | } |
| 427 | case *ast.JoinExpr: |
| 428 | helper := func(l, r int) int { |
| 429 | if res := isTableRequired(n.Larg, col, l); res != tableNotFound { |
| 430 | return res |
| 431 | } |
| 432 | if res := isTableRequired(n.Rarg, col, r); res != tableNotFound { |
| 433 | return res |
| 434 | } |
| 435 | return tableNotFound |
| 436 | } |
| 437 | switch n.Jointype { |
| 438 | case ast.JoinTypeLeft: |
| 439 | return helper(tableRequired, tableOptional) |
| 440 | case ast.JoinTypeRight: |
| 441 | return helper(tableOptional, tableRequired) |
| 442 | case ast.JoinTypeFull: |
| 443 | return helper(tableOptional, tableOptional) |
| 444 | case ast.JoinTypeInner: |
| 445 | return helper(tableRequired, tableRequired) |
| 446 | } |
| 447 | case *ast.List: |
| 448 | for _, item := range n.Items { |
| 449 | if res := isTableRequired(item, col, prior); res != tableNotFound { |
| 450 | return res |
| 451 | } |
| 452 | } |
| 453 | } |
| 454 | |
| 455 | return tableNotFound |
| 456 | } |
| 457 | |
| 458 | type tableVisitor struct { |
| 459 | list ast.List |