|
@@ -42,11 +42,15 @@ type updateClause struct {
|
|
|
}
|
|
|
|
|
|
type selectClause struct {
|
|
|
- selectExpr []string
|
|
|
- from string
|
|
|
- where []string
|
|
|
- limit int
|
|
|
- offset int
|
|
|
+ table string
|
|
|
+ fromSubQuery string
|
|
|
+ selectClause string
|
|
|
+ where string
|
|
|
+ orderBy []string
|
|
|
+ groupBy []string
|
|
|
+ having string
|
|
|
+ pageNo int
|
|
|
+ pageSize int
|
|
|
}
|
|
|
|
|
|
|
|
@@ -252,14 +256,84 @@ func updateWalk(sql string) (*updateClause, error) {
|
|
|
return clause, nil
|
|
|
}
|
|
|
|
|
|
-func selectWalk(sql string) (*insertClause, error) {
|
|
|
- return nil, nil
|
|
|
+func selectWalk(sql string) (*selectClause, error) {
|
|
|
+ clause := new(selectClause)
|
|
|
+
|
|
|
+ stmts, err := parser.Parse(sql)
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+
|
|
|
+ var walkFuncErr error
|
|
|
+
|
|
|
+ w := &walk.AstWalker{
|
|
|
+ Fn: func(ctx interface{}, node interface{}) (stop bool) {
|
|
|
+ realNode := node.(*tree.Select)
|
|
|
+ nodeSelectClause := realNode.Select.(*tree.SelectClause)
|
|
|
+
|
|
|
+
|
|
|
+ clause.selectClause = parseSelect(nodeSelectClause.Exprs)
|
|
|
+
|
|
|
+
|
|
|
+ asFromSubQuery, from := parseFrom(&nodeSelectClause.From)
|
|
|
+ if asFromSubQuery {
|
|
|
+ clause.fromSubQuery = from
|
|
|
+ } else {
|
|
|
+ clause.table = from
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if nodeSelectClause.Where != nil {
|
|
|
+ clause.where = parseWhere(nodeSelectClause.Where)
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if realNode.OrderBy != nil {
|
|
|
+ clause.orderBy = parseOrderBy(realNode.OrderBy)
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if realNode.Limit != nil {
|
|
|
+ pageNo, pageSize, err := parseLimit(realNode.Limit)
|
|
|
+ if err != nil {
|
|
|
+ walkFuncErr = err
|
|
|
+ return true
|
|
|
+ }
|
|
|
+
|
|
|
+ clause.pageNo = pageNo
|
|
|
+ clause.pageSize = pageSize
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if nodeSelectClause.GroupBy != nil {
|
|
|
+ clause.groupBy = parseGroupBy(nodeSelectClause.GroupBy)
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if nodeSelectClause.Having != nil {
|
|
|
+ clause.having = parseWhere(nodeSelectClause.Having)
|
|
|
+ }
|
|
|
+
|
|
|
+ return false
|
|
|
+ },
|
|
|
+ }
|
|
|
+
|
|
|
+ _, err = w.Walk(stmts, nil)
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+
|
|
|
+ if walkFuncErr != nil {
|
|
|
+ return nil, walkFuncErr
|
|
|
+ }
|
|
|
+
|
|
|
+ return clause, nil
|
|
|
}
|
|
|
|
|
|
func parseTableExpr(tableExpr tree.TableExpr) (string, error) {
|
|
|
switch table := tableExpr.(type) {
|
|
|
case *tree.TableName:
|
|
|
- return table.Table(), nil
|
|
|
+ return table.String(), nil
|
|
|
case *tree.AliasedTableExpr:
|
|
|
return table.String(), nil
|
|
|
default:
|
|
@@ -267,10 +341,64 @@ func parseTableExpr(tableExpr tree.TableExpr) (string, error) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+func parseSelect(selectExprs tree.SelectExprs) string {
|
|
|
+ selectFmtCtx := tree.NewFmtCtx(tree.FmtBareStrings)
|
|
|
+ selectExprs.Format(selectFmtCtx)
|
|
|
+ return selectFmtCtx.String()
|
|
|
+}
|
|
|
+
|
|
|
+func parseFrom(from *tree.From) (bool, string) {
|
|
|
+ asFromSubQuery := false
|
|
|
+
|
|
|
+ switch fromTable := from.Tables[0].(type) {
|
|
|
+ case *tree.JoinTableExpr:
|
|
|
+ asFromSubQuery = true
|
|
|
+ case *tree.AliasedTableExpr:
|
|
|
+ _, ok := fromTable.Expr.(*tree.Subquery)
|
|
|
+ asFromSubQuery = ok
|
|
|
+ }
|
|
|
+
|
|
|
+ return asFromSubQuery, fmt.Sprint(from.Tables)
|
|
|
+}
|
|
|
+
|
|
|
func parseWhere(where *tree.Where) string {
|
|
|
return where.Expr.String()
|
|
|
}
|
|
|
|
|
|
+func parseOrderBy(orderBy tree.OrderBy) []string {
|
|
|
+ orderBySlice := make([]string, 0)
|
|
|
+
|
|
|
+ for _, o := range orderBy {
|
|
|
+ orderBySlice = append(orderBySlice, o.Expr.String())
|
|
|
+ }
|
|
|
+
|
|
|
+ return orderBySlice
|
|
|
+}
|
|
|
+
|
|
|
+func parseLimit(limit *tree.Limit) (int, int, error) {
|
|
|
+ pageNo, err := strconv.Atoi(limit.Offset.String())
|
|
|
+ if err != nil {
|
|
|
+ return 0, 0, err
|
|
|
+ }
|
|
|
+
|
|
|
+ pageSize, err := strconv.Atoi(limit.Count.String())
|
|
|
+ if err != nil {
|
|
|
+ return 0, 0, err
|
|
|
+ }
|
|
|
+
|
|
|
+ return pageNo, pageSize, nil
|
|
|
+}
|
|
|
+
|
|
|
+func parseGroupBy(groupBy tree.GroupBy) []string {
|
|
|
+ groupBySlice := make([]string, 0)
|
|
|
+
|
|
|
+ for _, groupExpr := range groupBy {
|
|
|
+ groupBySlice = append(groupBySlice, groupExpr.String())
|
|
|
+ }
|
|
|
+
|
|
|
+ return groupBySlice
|
|
|
+}
|
|
|
+
|
|
|
func parseExpr(valueExpr tree.Expr) (*clauseTableRowValue, error) {
|
|
|
switch realColumn := valueExpr.(type) {
|
|
|
case *tree.FuncExpr:
|