예제 #1
0
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
}
예제 #2
0
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
}
예제 #3
0
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
}
예제 #4
0
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")
}
예제 #5
0
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
}
예제 #6
0
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())
}