func ParseWith(pg expr.TokenPager) (u.JsonHelper, error) { //u.Debugf("parseWith: %v", pg.Cur()) if pg.Cur().T != lex.TokenWith { // This is an optional statement return nil, nil } pg.Next() // consume WITH jh := make(u.JsonHelper) switch pg.Cur().T { case lex.TokenLeftBrace: // { if err := ParseJsonObject(pg, jh); err != nil { return nil, err } case lex.TokenIdentity: // name=value pairs if err := ParseKeyValue(pg, jh); err != nil { return nil, err } default: u.Warnf("unexpected token? %v", pg.Cur()) return nil, fmt.Errorf("Expected json { , or name=value but got: %v", pg.Cur().T.String()) } return jh, nil }
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 ParseKeyValue(pg expr.TokenPager, jh u.JsonHelper) error { if pg.Cur().T != lex.TokenIdentity { return fmt.Errorf("Expected key/identity for key=value, array but got: %v", pg.Cur().String()) } for { key := pg.Cur().V pg.Next() switch pg.Cur().T { case lex.TokenEOF, lex.TokenEOS: return nil } if pg.Cur().T != lex.TokenEqual { pg.Backup() // whoops, we consumed too much pg.Backup() //u.Debugf("exit keyvalue %v", pg.Cur()) return nil } pg.Next() // consume equal //u.Debugf("%s = %v", key, pg.Cur()) switch pg.Cur().T { case lex.TokenIdentity: bv, err := strconv.ParseBool(pg.Cur().V) if err == nil { jh[key] = bv } else { jh[key] = pg.Cur().V } case lex.TokenValue: jh[key] = pg.Cur().V case lex.TokenBool: bv, err := strconv.ParseBool(pg.Cur().V) if err != nil { return err } jh[key] = bv case lex.TokenInteger: iv, err := strconv.ParseInt(pg.Cur().V, 10, 64) if err != nil { return err } jh[key] = iv case lex.TokenFloat: fv, err := strconv.ParseFloat(pg.Cur().V, 64) if err != nil { return err } jh[key] = fv default: u.Warnf("got unexpected token: %s", pg.Cur()) return fmt.Errorf("Expected value but got: %v for name=value context", pg.Cur().T.String()) } pg.Next() // consume value //u.Debugf("cur: %v", pg.Cur()) if pg.Cur().T != lex.TokenComma { //u.Debugf("finished loop: jh.len=%v token=%v", len(jh), pg.Cur()) return nil } pg.Next() // consume comma } panic("unreachable") }
func ParseJsonArray(pg expr.TokenPager) ([]interface{}, error) { if pg.Cur().T != lex.TokenLeftBracket { return nil, fmt.Errorf("Expected json [ but got: %v", pg.Cur().T.String()) } la := make([]interface{}, 0) pg.Next() // Consume [ for { //u.Debug(pg.Cur()) switch pg.Cur().T { case lex.TokenValue: la = append(la, pg.Cur().V) pg.Next() case lex.TokenBool: bv, err := strconv.ParseBool(pg.Cur().V) if err != nil { return nil, err } la = append(la, bv) pg.Next() case lex.TokenInteger: iv, err := strconv.ParseInt(pg.Cur().V, 10, 64) if err != nil { return nil, err } la = append(la, iv) pg.Next() case lex.TokenFloat: fv, err := strconv.ParseFloat(pg.Cur().V, 64) if err != nil { return nil, err } la = append(la, fv) pg.Next() case lex.TokenLeftBrace: // { obj := make(u.JsonHelper) if err := ParseJsonObject(pg, obj); err != nil { return nil, err } la = append(la, obj) case lex.TokenLeftBracket: // [ list, err := ParseJsonArray(pg) if err != nil { return nil, err } //u.Debugf("list after: %#v", list) la = append(la, list) case lex.TokenRightBracket: return la, nil default: return nil, fmt.Errorf("Expected json key identity but got: %v", pg.Cur().String()) } switch pg.Cur().T { case lex.TokenComma: pg.Next() case lex.TokenRightBracket: pg.Next() // Consume the right ] return la, nil default: return nil, fmt.Errorf("Expected json comma or end of array ] but got: %v", pg.Cur().String()) } } return la, nil }
func parseJsonKeyValue(pg expr.TokenPager, jh u.JsonHelper) error { if pg.Cur().T != lex.TokenIdentity { return fmt.Errorf("Expected json key/identity but got: %v", pg.Cur().String()) } key := pg.Cur().V pg.Next() //u.Debug(key, " ", pg.Cur()) switch pg.Cur().T { case lex.TokenColon: pg.Next() switch pg.Cur().T { case lex.TokenLeftBrace: // { obj := make(u.JsonHelper) if err := ParseJsonObject(pg, obj); err != nil { return err } jh[key] = obj case lex.TokenLeftBracket: // [ list, err := ParseJsonArray(pg) if err != nil { return err } //u.Debugf("list after: %#v", list) jh[key] = list case lex.TokenValue: jh[key] = pg.Cur().V pg.Next() case lex.TokenBool: bv, err := strconv.ParseBool(pg.Cur().V) if err != nil { return err } jh[key] = bv pg.Next() case lex.TokenInteger: iv, err := strconv.ParseInt(pg.Cur().V, 10, 64) if err != nil { return err } jh[key] = iv pg.Next() case lex.TokenFloat: fv, err := strconv.ParseFloat(pg.Cur().V, 64) if err != nil { return err } jh[key] = fv pg.Next() default: u.Warnf("got unexpected token: %s", pg.Cur()) return fmt.Errorf("Expected json { or [ but got: %v", pg.Cur().T.String()) } //u.Debug(key, " ", pg.Cur()) return nil default: return fmt.Errorf("Expected json colon but got: %v", pg.Cur().String()) } return fmt.Errorf("Unreachable json error: %v", pg.Cur().String()) }
func ParseJsonObject(pg expr.TokenPager, jh u.JsonHelper) error { if pg.Cur().T != lex.TokenLeftBrace { return fmt.Errorf("Expected json { but got: %v", pg.Cur().T.String()) } pg.Next() // Consume { for { //u.Debug(pg.Cur()) switch pg.Cur().T { case lex.TokenIdentity: if err := parseJsonKeyValue(pg, jh); err != nil { return err } default: return fmt.Errorf("Expected json key identity but got: %v", pg.Cur().String()) } switch pg.Cur().T { case lex.TokenComma: pg.Next() case lex.TokenRightBrace: pg.Next() // Consume the right } return nil default: return fmt.Errorf("Expected json comma or end of object but got: %v", pg.Cur().String()) } } return nil // panic? error? not reachable }