// errorf formats the error and terminates processing. func (t *Tree) errorf(format string, args ...interface{}) { t.Root = nil format = fmt.Sprintf("expr: %s", format) msg := fmt.Errorf(format, args...) u.LogTracef(u.WARN, "about to panic: %v", msg) panic(msg) }
// Create a new Value type with native go value func NewValue(goVal interface{}) Value { switch val := goVal.(type) { case nil: return NilValueVal case Value: return val case float64: return NewNumberValue(val) case float32: return NewNumberValue(float64(val)) case int: return NewIntValue(int64(val)) case int32: return NewIntValue(int64(val)) case int64: return NewIntValue(val) case string: return NewStringValue(val) case []string: return NewStringsValue(val) // case []uint8: // return NewByteSliceValue([]byte(val)) case []byte: return NewByteSliceValue(val) case bool: return NewBoolValue(val) case time.Time: return NewTimeValue(val) case *time.Time: return NewTimeValue(*val) case map[string]interface{}: return NewMapValue(val) case map[string]string: return NewMapStringValue(val) case map[string]float64: return NewMapNumberValue(val) case map[string]int64: return NewMapIntValue(val) case map[string]bool: return NewMapBoolValue(val) case map[string]int: nm := make(map[string]int64, len(val)) for k, v := range val { nm[k] = int64(v) } return NewMapIntValue(nm) default: if valValue, ok := goVal.(Value); ok { return valValue } u.LogTracef(u.WARN, "hello") u.Errorf("invalud value type %T.", val) } return NilValueVal }
func (m *DataSources) Get(sourceType string) *DataSourceFeatures { if source, ok := m.sources[strings.ToLower(sourceType)]; ok { u.Infof("found source: %v", sourceType) return NewFeaturedSource(source) } if len(m.sources) == 1 { for _, src := range m.sources { u.Warnf("only one source?") return NewFeaturedSource(src) } } if sourceType == "" { u.LogTracef(u.WARN, "No Source Type?") } else { u.Debugf("datasource.Get('%v')", sourceType) } if len(m.tableSources) == 0 { for _, src := range m.sources { tbls := src.Tables() for _, tbl := range tbls { if _, ok := m.tableSources[tbl]; ok { u.Warnf("table names must be unique across sources %v", tbl) } else { u.Debugf("creating tbl/source: %v %T", tbl, src) m.tableSources[tbl] = src } } } } if src, ok := m.tableSources[sourceType]; ok { u.Debugf("found src with %v", sourceType) return NewFeaturedSource(src) } else { for src, _ := range m.sources { u.Debugf("source: %v", src) } u.LogTracef(u.WARN, "No table? len(sources)=%d len(tables)=%v", len(m.sources), len(m.tableSources)) u.Warnf("could not find table: %v tables:%v", sourceType, m.tableSources) } return nil }
// We need to find all columns used in the given Node (where/join expression) // to ensure we have those columns in projection for sub-queries func columnsFromNode(from *SqlSource, isLeft bool, node Node, cols Columns) Columns { switch nt := node.(type) { case *IdentityNode: if left, right, ok := nt.LeftRight(); ok { //u.Debugf("from.Name:%v AS %v Joinnode l:%v r:%v %#v", from.Name, from.alias, left, right, nt) //u.Warnf("check cols against join expr arg: %#v", nt) if left == from.alias { found := false for _, col := range cols { colLeft, colRight, _ := col.LeftRight() //u.Debugf("left='%s' colLeft='%s' right='%s' %#v", left, colLeft, colRight, col) //u.Debugf("col: From %s AS '%s' '%s'.'%s' JoinExpr: '%v'.'%v' col:%#v", from.Name, from.alias, colLeft, colRight, left, right, col) if left == colLeft || colRight == right { found = true //u.Infof("columnsFromNode isLeft?%v from.Name:%v l:%v r:%v", isLeft, from.alias, left, right) } else { //u.Warnf("not? isLeft?%v from.Name:%v l:%v r:%v col: P:%p %#v", isLeft, from.alias, left, right, col, col) } } if !found { //u.Debugf("columnsFromNode isLeft?%v from.Name:%v l:%v r:%v", isLeft, from.alias, left, right) newCol := &Column{As: right, SourceField: right, Expr: &IdentityNode{Text: right}} newCol.Index = len(cols) cols = append(cols, newCol) //u.Warnf("sure we want to add?, found it! %s len(cols) = %v", right, len(cols)) } } } case *BinaryNode: switch nt.Operator.T { case lex.TokenAnd, lex.TokenLogicAnd, lex.TokenLogicOr: cols = columnsFromNode(from, isLeft, nt.Args[0], cols) cols = columnsFromNode(from, isLeft, nt.Args[1], cols) case lex.TokenEqual, lex.TokenEqualEqual: cols = columnsFromNode(from, isLeft, nt.Args[0], cols) cols = columnsFromNode(from, isLeft, nt.Args[1], cols) default: u.Warnf("un-implemented op: %v", nt.Operator) } default: u.LogTracef(u.INFO, "whoops") u.Warnf("%T node types are not suppored yet for join rewrite %s", node, from.String()) } return cols }