func (this *InitialProject) processTerms(item value.AnnotatedValue, context *Context) bool { n := len(this.plan.Terms()) var f map[string]interface{} if item.Type() == value.OBJECT { f = item.Copy().Fields() } if f == nil { f = make(map[string]interface{}, n) } pv := value.NewAnnotatedValue(f) pv.SetAttachments(item.Attachments()) p := value.NewValue(make(map[string]interface{}, n+32)) pv.SetAttachment("projection", p) for _, term := range this.plan.Terms() { if term.Result().Alias() != "" { v, err := term.Result().Expression().Evaluate(item, context) if err != nil { context.Error(errors.NewError(err, "Error evaluating projection.")) return false } p.SetField(term.Result().Alias(), v) // Explicit aliases override data if term.Result().As() != "" { pv.SetField(term.Result().As(), v) } } else { // Star starval := item.GetValue() if term.Result().Expression() != nil { var err error starval, err = term.Result().Expression().Evaluate(item, context) if err != nil { context.Error(errors.NewError(err, "Error evaluating projection.")) return false } } // Latest star overwrites previous star switch sa := starval.Actual().(type) { case map[string]interface{}: for k, v := range sa { p.SetField(k, v) } } } } return this.sendItem(pv) }
func (this *Unnest) processItem(item value.AnnotatedValue, context *Context) bool { ev, err := this.plan.Term().Expression().Evaluate(item, context) if err != nil { context.Error(errors.NewError(err, "Error evaluating UNNEST path.")) return false } actuals := ev.Actual() switch actuals.(type) { case []interface{}: case nil: actuals = []interface{}(nil) default: actuals = []interface{}{actuals} } acts := actuals.([]interface{}) if len(acts) == 0 { // Outer unnest return !this.plan.Term().Outer() || this.sendItem(item) } // Attach and send for i, act := range acts { var av value.AnnotatedValue if i < len(acts)-1 { av = value.NewAnnotatedValue(item.Copy()) } else { av = item } av.SetField(this.plan.Alias(), value.NewValue(act)) if !this.sendItem(av) { return false } } return true }
func (this *Join) processItem(item value.AnnotatedValue, context *Context) bool { kv, e := this.plan.Term().Keys().Evaluate(item, context) if e != nil { context.Error(errors.NewError(e, "Error evaluating JOIN keys.")) return false } actuals := kv.Actual() switch actuals.(type) { case []interface{}: case nil: actuals = []interface{}(nil) default: actuals = []interface{}{actuals} } acts := actuals.([]interface{}) if len(acts) == 0 { // Outer join return !this.plan.Outer() || this.sendItem(item) } // Build list of keys keys := make([]string, 0, len(acts)) for _, key := range acts { k := value.NewValue(key).Actual() switch k := k.(type) { case string: keys = append(keys, k) } } // Fetch pairs, err := this.plan.Keyspace().Fetch(keys) if err != nil { context.Error(err) return false } found := len(pairs) > 0 // Attach and send for i, pair := range pairs { joinItem := pair.Value var jv value.AnnotatedValue // Apply projection, if any projection := this.plan.Term().Projection() if projection != nil { projectedItem, e := projection.Evaluate(joinItem, context) if e != nil { context.Error(errors.NewError(e, "Error evaluating join path.")) return false } jv = value.NewAnnotatedValue(projectedItem) } else { jv = value.NewAnnotatedValue(joinItem) } jv.SetAttachment("meta", map[string]interface{}{"id": keys[i]}) var av value.AnnotatedValue if i < len(pairs)-1 { av = value.NewAnnotatedValue(item.Copy()) } else { av = item } av.SetField(this.plan.Term().Alias(), jv) if !this.sendItem(av) { return false } } return found || !this.plan.Outer() || this.sendItem(item) }