func (m *Upsert) insertRows(ctx *Context, rows [][]*expr.ValueColumn) error { for _, row := range rows { //u.Infof("In Insert Scanner iter %#v", row) select { case <-m.SigChan(): return nil default: vals := make([]driver.Value, len(row)) for x, val := range row { if val.Expr != nil { exprVal, ok := vm.Eval(nil, val.Expr) if !ok { u.Errorf("Could not evaluate: %v", val.Expr) return fmt.Errorf("Could not evaluate expression: %v", val.Expr) } vals[x] = exprVal.Value() } else { vals[x] = val.Value.Value() } //u.Debugf("%d col: %v vals:%v", x, val, vals[x]) } if _, err := m.db.Put(ctx, nil, vals); err != nil { u.Errorf("Could not put values: %v", err) return err } // continue } } return nil }
func joinValue(ctx *Context, node expr.Node, msg datasource.Message) (string, bool) { if msg == nil { u.Warnf("got nil message?") } if msgReader, ok := msg.Body().(expr.ContextReader); ok { joinVal, ok := vm.Eval(msgReader, node) //u.Debugf("msg: %#v", msgReader) //u.Infof("evaluating: ok?%v T:%T result=%v node expr:%v", ok, joinVal, joinVal.ToString(), node.StringAST()) if !ok { u.Errorf("could not evaluate: %v", msg) return "", false } switch val := joinVal.(type) { case value.StringValue: return val.Val(), true default: u.Warnf("unknown type? %T", joinVal) } } else { u.Errorf("could not convert to message reader: %T", msg.Body()) } return "", false }
func evalSetExpression(col *rel.CommandColumn, ctx expr.ContextReadWriter, arg expr.Node) error { switch bn := arg.(type) { case *expr.BinaryNode: _, ok := bn.Args[0].(*expr.IdentityNode) if !ok { u.Warnf("expected identity but got %T in %s", bn.Args[0], arg.String()) return fmt.Errorf("Expected identity but got %T", bn.Args[0]) } rhv, ok := vm.Eval(ctx, bn.Args[1]) if !ok { u.Warnf("expected right side value but got %T in %s", bn.Args[1], arg.String()) return fmt.Errorf("Expected value but got %T", bn.Args[1]) } //u.Infof(`writeContext.Put("%v",%v)`, col.Key(), rhv.Value()) ctx.Put(col, ctx, rhv) case nil: // Special statements name := strings.ToLower(col.Name) switch { case strings.HasPrefix(name, "names ") || strings.HasPrefix(name, "character set"): // http://dev.mysql.com/doc/refman/5.7/en/charset-connection.html // hm, no idea what to do /* SET character_set_client = charset_name; SET character_set_results = charset_name; SET character_set_connection = charset_name; */ } default: u.Errorf("SET command only accepts binary nodes but got type: %#v", arg) return fmt.Errorf("Un recognized command %T", arg) } return nil }
func joinValue(ctx *Context, node expr.Node, msg datasource.Message, cols map[string]*expr.Column) (string, bool) { if msg == nil { u.Warnf("got nil message?") } //u.Infof("got message: %T %#v", msg, cols) switch mt := msg.(type) { case *datasource.SqlDriverMessage: msgReader := datasource.NewValueContextWrapper(mt, cols) joinVal, ok := vm.Eval(msgReader, node) //u.Debugf("msg: %#v", msgReader) //u.Debugf("evaluating: ok?%v T:%T result=%v node '%v'", ok, joinVal, joinVal.ToString(), node.String()) if !ok { u.Errorf("could not evaluate: %T %#v %v", joinVal, joinVal, msg) return "", false } switch val := joinVal.(type) { case value.StringValue: return val.Val(), true default: u.Warnf("unknown type? %T", joinVal) } default: if msgReader, ok := msg.Body().(expr.ContextReader); ok { joinVal, ok := vm.Eval(msgReader, node) //u.Debugf("msg: %#v", msgReader) //u.Infof("evaluating: ok?%v T:%T result=%v node expr:%v", ok, joinVal, joinVal.ToString(), node.StringAST()) if !ok { u.Errorf("could not evaluate: %v", msg) return "", false } switch val := joinVal.(type) { case value.StringValue: return val.Val(), true default: u.Warnf("unknown type? %T", joinVal) } } else { u.Errorf("could not convert to message reader: %T", msg.Body()) } } return "", false }
func (m *Upsert) updateValues(ctx *expr.Context) (int64, error) { select { case <-m.SigChan(): return 0, nil default: // fall through } valmap := make(map[string]driver.Value, len(m.update.Values)) for key, valcol := range m.update.Values { //u.Debugf("key:%v val:%v", key, valcol) // TODO: #13 Need a way of expressing which layer (here, db) this expr should run in? // - ie, run in backend datasource? or here? translate the expr to native language if valcol.Expr != nil { exprVal, ok := vm.Eval(nil, valcol.Expr) if !ok { u.Errorf("Could not evaluate: %s", valcol.Expr) return 0, fmt.Errorf("Could not evaluate expression: %v", valcol.Expr) } valmap[key] = exprVal.Value() } else { u.Debugf("%T %v", valcol.Value.Value(), valcol.Value.Value()) valmap[key] = valcol.Value.Value() } //u.Debugf("key:%v col: %v vals:%v", key, valcol, valmap[key]) } // if our backend source supports Where-Patches, ie update multiple dbpatch, ok := m.db.(datasource.PatchWhere) if ok { updated, err := dbpatch.PatchWhere(ctx, m.update.Where, valmap) u.Infof("patch: %v %v", updated, err) if err != nil { return updated, err } return updated, nil } // TODO: If it does not implement Where Patch then we need to do a poly fill // Do we have to recognize if the Where is on a primary key? // - for sources/queries that can't do partial updates we need to do a read first //u.Infof("does not implement PatchWhere") // Create a key from Where key := datasource.KeyFromWhere(m.update.Where) //u.Infof("key: %v", key) if _, err := m.db.Put(ctx, key, valmap); err != nil { u.Errorf("Could not put values: %v", err) return 0, err } u.Debugf("returning 1") return 1, nil }
func (m *JoinKey) Run() error { defer m.Ctx.Recover() defer close(m.msgOutCh) outCh := m.MessageOut() inCh := m.MessageIn() joinNodes := m.p.Source.Stmt.JoinNodes() for { select { case <-m.SigChan(): //u.Debugf("got signal quit") return nil case msg, ok := <-inCh: if !ok { //u.Debugf("NICE, got msg shutdown") return nil } //u.Infof("In joinkey msg %#v", msg) msgTypeSwitch: switch mt := msg.(type) { case *datasource.SqlDriverMessageMap: vals := make([]string, len(joinNodes)) for i, node := range joinNodes { joinVal, ok := vm.Eval(mt, node) //u.Debugf("evaluating: ok?%v T:%T result=%v node '%v'", ok, joinVal, joinVal.ToString(), node.String()) if !ok { u.Errorf("could not evaluate: %T %#v %v", joinVal, joinVal, msg) break msgTypeSwitch } vals[i] = joinVal.ToString() } //u.Infof("joinkey: %v row:%v", vals, mt) key := strings.Join(vals, string(byte(0))) mt.SetKeyHashed(key) outCh <- mt default: return fmt.Errorf("To use JoinKey must use SqlDriverMessageMap but got %T", msg) } } } return nil }
func (m *Upsert) updateValues(ctx *Context) error { select { case <-m.SigChan(): return nil default: // fall through } valmap := make(map[string]driver.Value, len(m.update.Values)) for key, valcol := range m.update.Values { //u.Debugf("key:%v val:%v", key, valcol) if valcol.Expr != nil { exprVal, ok := vm.Eval(nil, valcol.Expr) if !ok { u.Errorf("Could not evaluate: %s", valcol.Expr) return fmt.Errorf("Could not evaluate expression: %v", valcol.Expr) } valmap[key] = exprVal.Value() } else { valmap[key] = valcol.Value.Value() } //u.Debugf("key:%v col: %v vals:%v", key, valcol, valmap[key]) } if dbpatch, ok := m.db.(datasource.PatchWhere); ok { updated, err := dbpatch.PatchWhere(ctx, m.update.Where, valmap) u.Infof("patch: %v %v", updated, err) if err != nil { return err } } else { //u.Warnf("does not implement PatchWhere") } // Need a way to PolyFill and do scan/match? // Create a key from Where key := keyFromWhere(m.update.Where) //u.Infof("key: %v", key) if _, err := m.db.Put(ctx, key, valmap); err != nil { u.Errorf("Could not put values: %v", err) return err } return nil }
func (m *Upsert) insertRows(ctx *expr.Context, rows [][]*expr.ValueColumn) (int64, error) { for i, row := range rows { //u.Infof("In Insert Scanner iter %#v", row) select { case <-m.SigChan(): if i == 0 { return 0, nil } return int64(i) - 1, nil default: vals := make([]driver.Value, len(row)) for x, val := range row { if val.Expr != nil { exprVal, ok := vm.Eval(nil, val.Expr) if !ok { u.Errorf("Could not evaluate: %v", val.Expr) return 0, fmt.Errorf("Could not evaluate expression: %v", val.Expr) } //u.Debugf("%T %v", exprVal.Value(), exprVal.Value()) vals[x] = exprVal.Value() } else { //u.Debugf("%T %v", val.Value.Value(), val.Value.Value()) vals[x] = val.Value.Value() } //u.Debugf("%d col: %v vals:%v", x, val, vals[x]) } //u.Debugf("db.Put() db:%T %v", m.db, vals) if _, err := m.db.Put(ctx, nil, vals); err != nil { u.Errorf("Could not put values: %v", err) return 0, err } // continue } } //u.Debugf("about to return from Insert: %v", len(rows)) return int64(len(rows)), nil }
// Create handler function for evaluation (ie, field selection from tuples) func (m *Projection) projectionEvaluator(isFinal bool) MessageHandler { out := m.MessageOut() columns := m.p.Stmt.Columns colIndex := m.p.Stmt.ColIndexes() limit := m.p.Stmt.Limit if limit == 0 { limit = math.MaxInt32 } colCt := len(columns) // If we have a projection, use that as col count if m.p.Proj != nil { colCt = len(m.p.Proj.Columns) } // if m.p.Proj == nil { // u.Warnf("What, requires Projection? %#v", m.p) // } //u.Debugf("limit: %d colindex: %#v", limit, colIndex) //u.Debugf("plan projection columns: %#v", m.p.Proj.Columns) //u.Debugf("columns: %#v", columns) rowCt := 0 return func(ctx *plan.Context, msg schema.Message) bool { select { case <-m.SigChan(): u.Debugf("%p closed, returning", m) return false default: } //u.Infof("got projection message: %T %#v", msg, msg.Body()) var outMsg schema.Message switch mt := msg.(type) { case *datasource.SqlDriverMessageMap: // use our custom write context for example purposes row := make([]driver.Value, colCt) rdr := datasource.NewNestedContextReader([]expr.ContextReader{ mt, ctx.Session, }, mt.Ts()) //u.Debugf("about to project: %#v", mt) colCt := 0 for i, col := range columns { //u.Debugf("col: idx:%v sidx: %v pidx:%v key:%v %s", col.Index, col.SourceIndex, col.ParentIndex, col.Key(), col.Expr) if isFinal && col.ParentIndex < 0 { continue } if col.Guard != nil { ifColValue, ok := vm.Eval(rdr, col.Guard) if !ok { u.Errorf("Could not evaluate if: %v", col.Guard.String()) //return fmt.Errorf("Could not evaluate if clause: %v", col.Guard.String()) } //u.Debugf("if eval val: %T:%v", ifColValue, ifColValue) switch ifColVal := ifColValue.(type) { case value.BoolValue: if ifColVal.Val() == false { //u.Debugf("Filtering out col") continue } } } if col.Star { starRow := mt.Values() //u.Infof("star row: %#v", starRow) if len(columns) > 1 { // select *, myvar, 1 newRow := make([]driver.Value, len(starRow)+len(colIndex)-1) for curi := 0; curi < i; curi++ { newRow[curi] = row[curi] } row = newRow for _, v := range starRow { colCt += 1 //writeContext.Put(&expr.Column{As: k}, nil, value.NewValue(v)) row[i+colCt] = v } } else { colCt-- for _, v := range starRow { colCt += 1 //writeContext.Put(&expr.Column{As: k}, nil, value.NewValue(v)) //u.Infof("i:%d colct: %v v:%v", i, colCt, v) row[i+colCt] = v } } } else if col.Expr == nil { u.Warnf("wat? nil col expr? %#v", col) } else { v, ok := vm.Eval(rdr, col.Expr) if !ok { u.Warnf("failed eval key=%v val=%#v expr:%s mt:%#v", col.Key(), v, col.Expr, mt) // for k, v := range ctx.Session.Row() { // u.Infof("%p session? %s: %v", ctx.Session, k, v.Value()) // } } else if v == nil { //u.Debugf("%#v", col) //u.Debugf("evaled nil? key=%v val=%v expr:%s", col.Key(), v, col.Expr.String()) //writeContext.Put(col, mt, v) //u.Infof("mt: %T mt %#v", mt, mt) row[i+colCt] = nil //v.Value() } else { //u.Debugf("evaled: key=%v val=%v", col.Key(), v.Value()) //writeContext.Put(col, mt, v) row[i+colCt] = v.Value() } } } //u.Infof("row: %#v", row) //u.Infof("row cols: %v", colIndex) outMsg = datasource.NewSqlDriverMessageMap(0, row, colIndex) case expr.ContextReader: //u.Warnf("nice, got context reader? %T", mt) row := make([]driver.Value, len(columns)) //u.Debugf("about to project: %#v", mt) colCt := 0 for i, col := range columns { //u.Debugf("col: idx:%v sidx: %v pidx:%v key:%v %s", col.Index, col.SourceIndex, col.ParentIndex, col.Key(), col.Expr) if isFinal && col.ParentIndex < 0 { continue } if col.Guard != nil { ifColValue, ok := vm.Eval(mt, col.Guard) if !ok { u.Errorf("Could not evaluate if: %v", col.Guard.String()) //return fmt.Errorf("Could not evaluate if clause: %v", col.Guard.String()) } //u.Debugf("if eval val: %T:%v", ifColValue, ifColValue) switch ifColVal := ifColValue.(type) { case value.BoolValue: if ifColVal.Val() == false { //u.Debugf("Filtering out col") continue } } } if col.Star { starRow := mt.Row() newRow := make([]driver.Value, len(starRow)+len(colIndex)) for curi := 0; curi < i; curi++ { newRow[curi] = row[curi] } row = newRow for _, v := range starRow { colCt += 1 //writeContext.Put(&expr.Column{As: k}, nil, value.NewValue(v)) row[i+colCt] = v } } else if col.Expr == nil { u.Warnf("wat? nil col expr? %#v", col) } else { v, ok := vm.Eval(mt, col.Expr) if !ok { //u.Warnf("failed eval key=%v val=%#v expr:%s mt:%#v", col.Key(), v, col.Expr, mt.Row()) } else if v == nil { //u.Debugf("%#v", col) //u.Debugf("evaled nil? key=%v val=%v expr:%s", col.Key(), v, col.Expr.String()) //writeContext.Put(col, mt, v) //u.Infof("mt: %T mt %#v", mt, mt) row[i+colCt] = nil //v.Value() } else { //u.Debugf("evaled: key=%v val=%v", col.Key(), v.Value()) //writeContext.Put(col, mt, v) row[i+colCt] = v.Value() } } } //u.Infof("row: %#v cols:%#v", row, colIndex) //u.Infof("row cols: %v", colIndex) outMsg = datasource.NewSqlDriverMessageMap(0, row, colIndex) default: u.Errorf("could not project msg: %T", msg) } if rowCt >= limit { //u.Debugf("%p Projection reaching Limit!!! rowct:%v limit:%v", m, rowCt, limit) out <- nil // Sending nil message is a message to downstream to shutdown m.Quit() // should close rest of dag as well return false } rowCt++ //u.Debugf("row:%d completed projection for: %p %#v", rowCt, out, outMsg) select { case out <- outMsg: return true case <-m.SigChan(): return false } } }
// Create handler function for evaluation (ie, field selection from tuples) func (m *Projection) projectionEvaluator() MessageHandler { out := m.MessageOut() columns := m.sql.Columns // if len(m.sql.From) > 1 && m.sql.From[0].Source != nil && len(m.sql.From[0].Source.Columns) > 0 { // // we have re-written this query, lets build new list of columns // columns = make(expr.Columns, 0) // for _, from := range m.sql.From { // for _, col := range from.Source.Columns { // columns = append(columns, col) // } // } // } return func(ctx *expr.Context, msg datasource.Message) bool { // defer func() { // if r := recover(); r != nil { // u.Errorf("crap, %v", r) // } // }() //u.Infof("got projection message: %T %#v", msg, msg.Body()) var outMsg datasource.Message switch mt := msg.(type) { case *datasource.SqlDriverMessageMap: // readContext := datasource.NewContextUrlValues(uv) // use our custom write context for example purposes writeContext := datasource.NewContextSimple() outMsg = writeContext //u.Debugf("about to project: %#v", mt) for _, col := range columns { if col.ParentIndex < 0 { continue } //u.Debugf("col: idx:%v pidx:%v key:%v %s", col.Index, col.ParentIndex, col.Key(), col.Expr) if col.Guard != nil { ifColValue, ok := vm.Eval(mt, col.Guard) if !ok { u.Errorf("Could not evaluate if: %v", col.Guard.String()) //return fmt.Errorf("Could not evaluate if clause: %v", col.Guard.String()) } //u.Debugf("if eval val: %T:%v", ifColValue, ifColValue) switch ifColVal := ifColValue.(type) { case value.BoolValue: if ifColVal.Val() == false { //u.Debugf("Filtering out col") continue } } } if col.Star { for k, v := range mt.Row() { writeContext.Put(&expr.Column{As: k}, nil, value.NewValue(v)) } } else { v, ok := vm.Eval(mt, col.Expr) if !ok { u.Warnf("failed eval key=%v val=%#v expr:%s mt:%#v", col.Key(), v, col.Expr, mt) } else if v == nil { u.Debugf("evaled: key=%v val=%v", col.Key(), v) writeContext.Put(col, mt, v) } else { //u.Debugf("evaled: key=%v val=%v", col.Key(), v.Value()) writeContext.Put(col, mt, v) } } } case *datasource.ContextUrlValues: // readContext := datasource.NewContextUrlValues(uv) // use our custom write context for example purposes writeContext := datasource.NewContextSimple() outMsg = writeContext //u.Infof("about to project: colsct%v %#v", len(sql.Columns), outMsg) for _, col := range columns { //u.Debugf("col: %#v", col) if col.Guard != nil { ifColValue, ok := vm.Eval(mt, col.Guard) if !ok { u.Errorf("Could not evaluate if: %v", col.Guard.String()) //return fmt.Errorf("Could not evaluate if clause: %v", col.Guard.String()) } //u.Debugf("if eval val: %T:%v", ifColValue, ifColValue) switch ifColVal := ifColValue.(type) { case value.BoolValue: if ifColVal.Val() == false { //u.Debugf("Filtering out col") continue } } } if col.Star { for k, v := range mt.Row() { writeContext.Put(&expr.Column{As: k}, nil, v) } } else { //u.Debugf("tree.Root: as?%v %#v", col.As, col.Expr) v, ok := vm.Eval(mt, col.Expr) //u.Debugf("evaled: ok?%v key=%v val=%v", ok, col.Key(), v) if ok { writeContext.Put(col, mt, v) } } } default: u.Errorf("could not project msg: %T", msg) } //u.Debugf("completed projection for: %p %#v", out, outMsg) select { case out <- outMsg: return true case <-m.SigChan(): return false } } }
// Create handler function for evaluation (ie, field selection from tuples) func projectionEvaluator(sql *expr.SqlSelect, task TaskRunner) MessageHandler { out := task.MessageOut() //evaluator := vm.Evaluator(where) return func(ctx *Context, msg datasource.Message) bool { defer func() { if r := recover(); r != nil { u.Errorf("crap, %v", r) } }() //u.Infof("got projection message: %#v", msg.Body()) var outMsg datasource.Message switch mt := msg.(type) { case *datasource.SqlDriverMessageMap: // readContext := datasource.NewContextUrlValues(uv) // use our custom write context for example purposes writeContext := datasource.NewContextSimple() outMsg = writeContext //u.Infof("about to project: colsct%v %#v", len(sql.Columns), outMsg) for _, from := range sql.From { for _, col := range from.Columns { //u.Debugf("col: %#v", col) if col.Guard != nil { ifColValue, ok := vm.Eval(mt, col.Guard) if !ok { u.Errorf("Could not evaluate if: %v", col.Guard.StringAST()) //return fmt.Errorf("Could not evaluate if clause: %v", col.Guard.String()) } //u.Debugf("if eval val: %T:%v", ifColValue, ifColValue) switch ifColVal := ifColValue.(type) { case value.BoolValue: if ifColVal.Val() == false { //u.Debugf("Filtering out col") continue } } } if col.Star { for k, v := range mt.Vals { writeContext.Put(&expr.Column{As: k}, nil, value.NewValue(v)) } } else { //u.Debugf("tree.Root: as?%v %v", col.As, col.Expr.String()) v, ok := vm.Eval(mt, col.Expr) //u.Debugf("evaled: ok?%v key=%v val=%v", ok, col.Key(), v) if ok { writeContext.Put(col, mt, v) } } } } case *datasource.ContextUrlValues: // readContext := datasource.NewContextUrlValues(uv) // use our custom write context for example purposes writeContext := datasource.NewContextSimple() outMsg = writeContext //u.Infof("about to project: colsct%v %#v", len(sql.Columns), outMsg) for _, col := range sql.Columns { //u.Debugf("col: %#v", col) if col.Guard != nil { ifColValue, ok := vm.Eval(mt, col.Guard) if !ok { u.Errorf("Could not evaluate if: %v", col.Guard.StringAST()) //return fmt.Errorf("Could not evaluate if clause: %v", col.Guard.String()) } //u.Debugf("if eval val: %T:%v", ifColValue, ifColValue) switch ifColVal := ifColValue.(type) { case value.BoolValue: if ifColVal.Val() == false { //u.Debugf("Filtering out col") continue } } } if col.Star { for k, v := range mt.Row() { writeContext.Put(&expr.Column{As: k}, nil, v) } } else { //u.Debugf("tree.Root: as?%v %#v", col.As, col.Expr) v, ok := vm.Eval(mt, col.Expr) //u.Debugf("evaled: ok?%v key=%v val=%v", ok, col.Key(), v) if ok { writeContext.Put(col, mt, v) } } } default: u.Errorf("could not project msg: %T", msg) } //u.Debugf("completed projection for: %p %#v", out, outMsg) select { case out <- outMsg: return true case <-task.SigChan(): return false } } }