func (m *Sqlbridge) parseOrderBy(req *SqlSelect) (err error) { if m.Cur().T != lex.TokenOrderBy { return nil } m.Next() // Consume Order By var col *Column for { //u.Debugf("Order By? %v", m.Cur()) switch m.Cur().T { case lex.TokenUdfExpr: // we have a udf/functional expression column //u.Infof("udf: %v", m.Cur().V) col = NewColumnFromToken(m.Cur()) tree := expr.NewTreeFuncs(m.SqlTokenPager, m.funcs) if err := m.parseNode(tree); err != nil { u.Warnf("could not parse: %v", err) return err } col.Expr = tree.Root switch n := col.Expr.(type) { case *expr.FuncNode: col.As = expr.FindIdentityName(0, n, "") if col.As == "" { col.As = n.Name } case *expr.BinaryNode: //u.Debugf("udf? %T ", n) col.As = expr.FindIdentityName(0, n, "") if col.As == "" { u.Errorf("could not find as name: %#v", n) } } //u.Debugf("next? %v", m.Cur()) case lex.TokenIdentity: //u.Warnf("?? %v", m.Cur()) col = NewColumnFromToken(m.Cur()) tree := expr.NewTreeFuncs(m.SqlTokenPager, m.funcs) if err := m.parseNode(tree); err != nil { u.Warnf("could not parse: %v", err) return err } col.Expr = tree.Root } //u.Debugf("OrderBy after colstart?: %v ", m.Cur()) // since we can loop inside switch statement switch m.Cur().T { case lex.TokenAsc, lex.TokenDesc: col.Order = strings.ToUpper(m.Cur().V) case lex.TokenInto, lex.TokenLimit, lex.TokenEOS, lex.TokenEOF: // This indicates we have come to the End of the columns req.OrderBy = append(req.OrderBy, col) //u.Debugf("Ending column ") return nil case lex.TokenCommentSingleLine: m.Next() col.Comment = m.Cur().V case lex.TokenRightParenthesis: // loop on my friend case lex.TokenComma: req.OrderBy = append(req.OrderBy, col) //u.Debugf("comma, added groupby: %v", len(stmt.OrderBy)) default: return fmt.Errorf("expected column but got: %v", m.Cur().String()) } m.Next() } }
func parseColumns(m expr.TokenPager, fr expr.FuncResolver, buildVm bool, stmt ColumnsStatement) error { var col *Column for { //u.Debug(m.Cur()) switch m.Cur().T { case lex.TokenStar, lex.TokenMultiply: col = &Column{Star: true} m.Next() case lex.TokenUdfExpr: // we have a udf/functional expression column col = NewColumnFromToken(m.Cur()) funcName := strings.ToLower(m.Cur().V) tree := expr.NewTreeFuncs(m, fr) if err := tree.BuildTree(buildVm); err != nil { u.Errorf("could not parse: %v", err) return err } col.Expr = tree.Root col.SourceField = expr.FindIdentityField(col.Expr) if strings.Contains(col.SourceField, ".") { if _, right, hasLeft := expr.LeftRight(col.SourceField); hasLeft { col.SourceField = right } } col.Agg = expr.IsAgg(funcName) if m.Cur().T != lex.TokenAs { switch n := col.Expr.(type) { case *expr.FuncNode: // lets lowercase name n.Name = funcName col.As = expr.FindIdentityName(0, n, "") //u.Infof("col %#v", col) if col.As == "" { if strings.ToLower(n.Name) == "count" { //u.Warnf("count*") col.As = "count(*)" } else { col.As = n.Name } } case *expr.BinaryNode: //u.Debugf("udf? %T ", col.Expr) col.As = expr.FindIdentityName(0, n, "") if col.As == "" { u.Errorf("could not find as name: %#v", n) } } } else { switch n := col.Expr.(type) { case *expr.FuncNode: n.Name = funcName } } //u.Debugf("next? %v", m.Cur()) case lex.TokenIdentity: col = NewColumnFromToken(m.Cur()) tree := expr.NewTreeFuncs(m, fr) if err := tree.BuildTree(buildVm); err != nil { u.Errorf("could not parse: %v", err) return err } col.Expr = tree.Root case lex.TokenValue, lex.TokenInteger: // Value Literal col = NewColumnValue(m.Cur()) tree := expr.NewTreeFuncs(m, fr) if err := tree.BuildTree(buildVm); err != nil { u.Errorf("could not parse: %v", err) return err } col.Expr = tree.Root } //u.Debugf("after colstart?: %v ", m.Cur()) // since we can loop inside switch statement switch m.Cur().T { case lex.TokenAs: m.Next() switch m.Cur().T { case lex.TokenIdentity, lex.TokenValue: col.As = m.Cur().V col.originalAs = col.As col.asQuoteByte = m.Cur().Quote m.Next() continue } return fmt.Errorf("expected identity but got: %v", m.Cur().String()) case lex.TokenFrom, lex.TokenInto, lex.TokenLimit, lex.TokenEOS, lex.TokenEOF: // This indicates we have come to the End of the columns stmt.AddColumn(*col) //u.Debugf("Ending column ") return nil case lex.TokenIf: // If guard m.Next() //u.Infof("if guard: %v", m.Cur()) tree := expr.NewTreeFuncs(m, fr) if err := tree.BuildTree(buildVm); err != nil { u.Errorf("could not parse: %v", err) return err } col.Guard = tree.Root // Hm, we need to backup here? Parse Node went to deep? continue //u.Infof("if guard 2: %v", m.Cur()) //u.Debugf("after if guard?: %v ", m.Cur()) case lex.TokenCommentSingleLine: m.Next() col.Comment = m.Cur().V case lex.TokenRightParenthesis: // loop on my friend case lex.TokenComma: //u.Infof("? %#v", stmt) //u.Infof("col?%+v", col) stmt.AddColumn(*col) //u.Debugf("comma, added cols: %v", len(stmt.Columns)) default: return fmt.Errorf("expected column but got: %v", m.Cur().String()) } m.Next() } //u.Debugf("cols: %d", len(stmt.Columns)) return nil }
func (m *Sqlbridge) parseGroupBy(req *SqlSelect) (err error) { if m.Cur().T != lex.TokenGroupBy { return nil } m.Next() var col *Column for { //u.Debugf("Group By? %v", m.Cur()) switch m.Cur().T { case lex.TokenUdfExpr: // we have a udf/functional expression column //u.Infof("udf: %v", m.Cur().V) col = NewColumnFromToken(m.Cur()) tree := expr.NewTreeFuncs(m.SqlTokenPager, m.funcs) if err := m.parseNode(tree); err != nil { return err } col.Expr = tree.Root if m.Cur().T != lex.TokenAs { switch n := col.Expr.(type) { case *expr.FuncNode: col.As = expr.FindIdentityName(0, n, "") if col.As == "" { col.As = n.Name } case *expr.BinaryNode: //u.Debugf("udf? %T ", n) col.As = expr.FindIdentityName(0, n, "") if col.As == "" { u.Errorf("could not find as name: %#v", n) } } } //u.Debugf("next? %v", m.Cur()) case lex.TokenIdentity: //u.Warnf("?? %v", m.Cur()) col = NewColumnFromToken(m.Cur()) tree := expr.NewTreeFuncs(m.SqlTokenPager, m.funcs) if err := m.parseNode(tree); err != nil { return err } col.Expr = tree.Root case lex.TokenValue: // Value Literal col = NewColumnFromToken(m.Cur()) tree := expr.NewTreeFuncs(m.SqlTokenPager, m.funcs) if err := m.parseNode(tree); err != nil { return err } col.Expr = tree.Root } //u.Debugf("GroupBy after colstart?: %v ", m.Cur()) // since we can loop inside switch statement switch m.Cur().T { case lex.TokenAs: m.Next() //u.Debug(m.Cur()) switch m.Cur().T { case lex.TokenIdentity, lex.TokenValue: col.As = m.Cur().V col.originalAs = col.As //u.Infof("set AS=%v", col.As) m.Next() continue } return fmt.Errorf("expected identity but got: %v", m.Cur().String()) case lex.TokenFrom, lex.TokenOrderBy, lex.TokenInto, lex.TokenLimit, lex.TokenHaving, lex.TokenWith, lex.TokenEOS, lex.TokenEOF: // This indicates we have come to the End of the columns req.GroupBy = append(req.GroupBy, col) //u.Debugf("Ending column ") return nil case lex.TokenIf: // If guard m.Next() //u.Infof("if guard: %v", m.Cur()) tree := expr.NewTreeFuncs(m.SqlTokenPager, m.funcs) if err := m.parseNode(tree); err != nil { return err } col.Guard = tree.Root //u.Debugf("after if guard?: %v ", m.Cur()) case lex.TokenCommentSingleLine: m.Next() col.Comment = m.Cur().V case lex.TokenRightParenthesis: // loop on my friend case lex.TokenComma: req.GroupBy = append(req.GroupBy, col) //u.Debugf("comma, added groupby: %v", len(stmt.GroupBy)) default: u.Errorf("expected col? %v", m.Cur()) return fmt.Errorf("expected column but got: %v", m.Cur().String()) } m.Next() } //u.Debugf("groupby: %d", len(req.GroupBy)) return nil }