func mergeValuesMsgs(lmsgs, rmsgs []datasource.Message, lcols, rcols []*expr.Column, cols map[string]*expr.Column) []*datasource.SqlDriverMessageMap { out := make([]*datasource.SqlDriverMessageMap, 0) //u.Infof("merge values: %v:%v", len(lcols), len(rcols)) for _, lm := range lmsgs { switch lmt := lm.(type) { case *datasource.SqlDriverMessage: //u.Warnf("got sql driver message: %#v", lmt.Vals) for _, rm := range rmsgs { switch rmt := rm.(type) { case *datasource.SqlDriverMessage: // for k, val := range rmt.Vals { // u.Debugf("k=%v v=%v", k, val) // } newMsg := datasource.NewSqlDriverMessageMap() newMsg = reAlias2(newMsg, lmt.Vals, lcols) newMsg = reAlias2(newMsg, rmt.Vals, rcols) //u.Debugf("pre: %#v", lmt.Vals) //u.Debugf("newMsg: %#v", newMsg.Vals) out = append(out, newMsg) default: u.Warnf("uknown type: %T", rm) } } default: u.Warnf("uknown type: %T %T", lmt, lm) } } return out }
func (m *JoinMerge) mergeValueMessages(lmsgs, rmsgs []*datasource.SqlDriverMessageMap) []*datasource.SqlDriverMessageMap { // m.leftStmt.Columns, m.rightStmt.Columns, nil //func mergeValuesMsgs(lmsgs, rmsgs []datasource.Message, lcols, rcols []*rel.Column, cols map[string]*rel.Column) []*datasource.SqlDriverMessageMap { out := make([]*datasource.SqlDriverMessageMap, 0) //u.Infof("merge values: %v:%v", len(lcols), len(rcols)) for _, lm := range lmsgs { //u.Warnf("nice SqlDriverMessageMap: %#v", lmt) for _, rm := range rmsgs { vals := make([]driver.Value, len(m.colIndex)) vals = m.valIndexing(vals, lm.Values(), m.leftStmt.Source.Columns) vals = m.valIndexing(vals, rm.Values(), m.rightStmt.Source.Columns) newMsg := datasource.NewSqlDriverMessageMap(0, vals, m.colIndex) //u.Infof("out: %+v", newMsg) out = append(out, newMsg) } } return out }
func (m *SourceJoin) mergeValueMessages(lmsgs, rmsgs []datasource.Message) []*datasource.SqlDriverMessageMap { // m.leftStmt.Columns, m.rightStmt.Columns, nil //func mergeValuesMsgs(lmsgs, rmsgs []datasource.Message, lcols, rcols []*expr.Column, cols map[string]*expr.Column) []*datasource.SqlDriverMessageMap { out := make([]*datasource.SqlDriverMessageMap, 0) //u.Infof("merge values: %v:%v", len(lcols), len(rcols)) for _, lm := range lmsgs { switch lmt := lm.(type) { case *datasource.SqlDriverMessage: //u.Warnf("got sql driver message: %#v", lmt) for _, rm := range rmsgs { switch rmt := rm.(type) { case *datasource.SqlDriverMessage: // for k, val := range rmt.Vals { // u.Debugf("k=%v v=%v", k, val) // } // newMsg := datasource.NewSqlDriverMessageMapEmpty() // newMsg = reAlias2(newMsg, lmt.Vals, m.leftStmt.Columns) // newMsg = reAlias2(newMsg, rmt.Vals, m.rightStmt.Columns) vals := make([]driver.Value, len(m.colIndex)) vals = m.valIndexing(vals, lmt.Vals, m.leftStmt.Columns) vals = m.valIndexing(vals, rmt.Vals, m.rightStmt.Columns) newMsg := datasource.NewSqlDriverMessageMap(0, vals, m.colIndex) //u.Debugf("pre: left:%#v right:%#v", lmt.Vals, rmt.Vals) //u.Debugf("newMsg: %#v", newMsg.Row()) out = append(out, newMsg) case *datasource.SqlDriverMessageMap: // for k, val := range rmt.Row() { // u.Debugf("k=%v v=%v", k, val) // } newMsg := datasource.NewSqlDriverMessageMapEmpty() newMsg = reAlias2(newMsg, lmt.Vals, m.leftStmt.Columns) newMsg = reAlias2(newMsg, rmt.Values(), m.rightStmt.Columns) //u.Debugf("pre: %#v", lmt.Row()) //u.Debugf("newMsg: %#v", newMsg.Row()) out = append(out, newMsg) default: u.Warnf("uknown type: %T", rm) } } case *datasource.SqlDriverMessageMap: for _, rm := range rmsgs { switch rmt := rm.(type) { case *datasource.SqlDriverMessage: // for k, val := range rmt.Row() { // u.Debugf("k=%v v=%v", k, val) // } u.Warnf("not implemented") //newMsg := datasource.NewSqlDriverMessageMapEmpty() //newMsg = m.reAlias(newMsg, lmt.Values(), m.leftStmt.Columns) //newMsg = m.reAlias(newMsg, rmt.Values(), m.rightStmt.Columns) //u.Debugf("pre: %#v", lmt.Row()) //u.Debugf("newMsg: %#v", newMsg.Row()) //out = append(out, newMsg) case *datasource.SqlDriverMessageMap: // for k, val := range rmt.Row() { // u.Debugf("k=%v v=%v", k, val) // } vals := make([]driver.Value, len(m.colIndex)) vals = m.valIndexing(vals, lmt.Values(), m.leftStmt.Columns) vals = m.valIndexing(vals, rmt.Values(), m.rightStmt.Columns) newMsg := datasource.NewSqlDriverMessageMap(0, vals, m.colIndex) out = append(out, newMsg) default: u.Warnf("uknown type: %T", rm) } } default: u.Warnf("uknown type: %T %T", lmt, lm) } } return out }
// 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 } } }
// interface for Upsert.Put() func (m *StaticDataSource) Put(ctx context.Context, key datasource.Key, row interface{}) (datasource.Key, error) { switch rowVals := row.(type) { case []driver.Value: if len(rowVals) != len(m.Columns()) { return nil, fmt.Errorf("Wrong number of columns, got %v expected %v", len(rowVals), len(m.Columns())) } id := makeId(rowVals[m.indexCol]) sdm := datasource.NewSqlDriverMessageMap(id, rowVals, m.tbl.FieldPositions) item := DriverItem{sdm} m.bt.ReplaceOrInsert(&item) //u.Debugf("PUT: %#v", rowVals) return NewKey(id), nil case map[string]driver.Value: // We need to convert the key:value to []driver.Value so // we need to look up column index for each key, and write to vals // TODO: if this is a partial update, we need to look up vals row := make([]driver.Value, len(m.Columns())) if len(rowVals) < len(m.Columns()) { // How do we get the key? //m.Get(key) } for key, val := range rowVals { if keyIdx, ok := m.tbl.FieldPositions[key]; ok { row[keyIdx] = val } else { return nil, fmt.Errorf("Found column in Put that doesn't exist in cols: %v", key) } } id := uint64(0) if key == nil { if row[m.indexCol] == nil { // Since we do not have an indexed column to work off of, // the ideal would be to get the job builder/planner to do // a scan with whatever info we have and feed that in? Instead // of us implementing our own scan? u.Warnf("wtf, nil key? %v %v", m.indexCol, row) return nil, fmt.Errorf("cannot update on non index column ") } id = makeId(row[m.indexCol]) } else { id = makeId(key) sdm, _ := m.Get(key) //u.Debugf("sdm: %#v err%v", sdm, err) if sdm != nil { if dmval, ok := sdm.Body().(*datasource.SqlDriverMessageMap); ok { for i, val := range dmval.Values() { if row[i] == nil { row[i] = val } } } } } //u.Debugf("PUT: %#v", row) //u.Infof("PUT: %v key:%v row:%v", id, key, row) sdm := datasource.NewSqlDriverMessageMap(id, row, m.tbl.FieldPositions) item := DriverItem{sdm} m.bt.ReplaceOrInsert(&item) return NewKey(id), nil default: u.Warnf("not implemented %T", row) return nil, fmt.Errorf("Expected []driver.Value but got %T", row) } return nil, nil }