mirror of
https://github.com/neilotoole/sq.git
synced 2024-12-24 08:36:43 +03:00
87 lines
1.8 KiB
Go
87 lines
1.8 KiB
Go
|
package render
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
|
||
|
"github.com/neilotoole/sq/libsq/ast"
|
||
|
"github.com/neilotoole/sq/libsq/core/errz"
|
||
|
)
|
||
|
|
||
|
func doJoin(rc *Context, fnJoin *ast.JoinNode) (string, error) {
|
||
|
enquote := rc.Dialect.Enquote
|
||
|
|
||
|
joinType := "INNER JOIN"
|
||
|
onClause := ""
|
||
|
|
||
|
if len(fnJoin.Children()) == 0 {
|
||
|
joinType = "NATURAL JOIN"
|
||
|
} else {
|
||
|
joinExpr, ok := fnJoin.Children()[0].(*ast.JoinConstraint)
|
||
|
if !ok {
|
||
|
return "", errz.Errorf("expected *FnJoinExpr but got %T", fnJoin.Children()[0])
|
||
|
}
|
||
|
|
||
|
leftOperand := ""
|
||
|
operator := ""
|
||
|
rightOperand := ""
|
||
|
|
||
|
if len(joinExpr.Children()) == 1 {
|
||
|
// It's a single col selector
|
||
|
colSel, ok := joinExpr.Children()[0].(*ast.ColSelectorNode)
|
||
|
if !ok {
|
||
|
return "", errz.Errorf("expected *ColSelectorNode but got %T", joinExpr.Children()[0])
|
||
|
}
|
||
|
|
||
|
colVal, err := colSel.SelValue()
|
||
|
if err != nil {
|
||
|
return "", err
|
||
|
}
|
||
|
|
||
|
leftTblVal := fnJoin.LeftTbl().TblName()
|
||
|
leftOperand = fmt.Sprintf(
|
||
|
"%s.%s",
|
||
|
enquote(leftTblVal),
|
||
|
enquote(colVal),
|
||
|
)
|
||
|
|
||
|
operator = "=="
|
||
|
|
||
|
rightTblVal := fnJoin.RightTbl().TblName()
|
||
|
rightOperand = fmt.Sprintf(
|
||
|
"%s.%s",
|
||
|
enquote(rightTblVal),
|
||
|
enquote(colVal),
|
||
|
)
|
||
|
} else {
|
||
|
var err error
|
||
|
leftOperand, err = renderSelectorNode(rc.Dialect, joinExpr.Children()[0])
|
||
|
if err != nil {
|
||
|
return "", err
|
||
|
}
|
||
|
|
||
|
operator = joinExpr.Children()[1].Text()
|
||
|
|
||
|
rightOperand, err = renderSelectorNode(rc.Dialect, joinExpr.Children()[2])
|
||
|
if err != nil {
|
||
|
return "", err
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if operator == "==" {
|
||
|
operator = "="
|
||
|
}
|
||
|
|
||
|
onClause = fmt.Sprintf("ON %s %s %s", leftOperand, operator, rightOperand)
|
||
|
}
|
||
|
|
||
|
sql := fmt.Sprintf(
|
||
|
"FROM %s %s %s",
|
||
|
enquote(fnJoin.LeftTbl().TblName()),
|
||
|
joinType,
|
||
|
enquote(fnJoin.RightTbl().TblName()),
|
||
|
)
|
||
|
sql = sqlAppend(sql, onClause)
|
||
|
|
||
|
return sql, nil
|
||
|
}
|