/* Qualify all identifiers for the parent expression. Checks for duplicate aliases. */ func (this *SubqueryTerm) Formalize(parent *expression.Formalizer) (f *expression.Formalizer, err error) { err = this.subquery.Formalize() if err != nil { return } alias := this.Alias() if alias == "" { err = errors.NewError(nil, "FROM term must have a name or alias.") return } _, ok := parent.Allowed.Field(alias) if ok { err = errors.NewError(nil, fmt.Sprintf("Duplicate subquery alias %s.", alias)) return nil, err } allowed := value.NewScopeValue(make(map[string]interface{}), parent.Allowed) allowed.SetField(alias, alias) f = expression.NewFormalizer() f.Keyspace = alias f.Allowed = allowed return }
func (this *spanScan) RunOnce(context *Context, parent value.Value) { this.once.Do(func() { defer context.Recover() // Recover from any panic defer close(this.itemChannel) // Broadcast that I have stopped defer this.notify() // Notify that I have stopped conn := datastore.NewIndexConnection(context) defer notifyConn(conn) // Notify index that I have stopped go this.scan(context, conn) var entry *datastore.IndexEntry ok := true for ok { select { case <-this.stopChannel: return default: } select { case entry, ok = <-conn.EntryChannel(): if ok { cv := value.NewScopeValue(make(map[string]interface{}), parent) av := value.NewAnnotatedValue(cv) av.SetAttachment("meta", map[string]interface{}{"id": entry.PrimaryKey}) ok = this.sendItem(av) } case <-this.stopChannel: return } } }) }
/* Qualify all identifiers for the parent expression. Checks for duplicate aliases. */ func (this *KeyspaceTerm) Formalize(parent *expression.Formalizer) (f *expression.Formalizer, err error) { keyspace := this.Alias() if keyspace == "" { err = errors.NewError(nil, "FROM term must have a name or alias.") return } if this.keys != nil { _, err = this.keys.Accept(parent) if err != nil { return } } _, ok := parent.Allowed.Field(keyspace) if ok { err = errors.NewError(nil, fmt.Sprintf("Duplicate subquery alias %s.", keyspace)) return nil, err } allowed := value.NewScopeValue(make(map[string]interface{}), parent.Allowed) allowed.SetField(keyspace, keyspace) f = expression.NewFormalizer() f.Keyspace = keyspace f.Allowed = allowed return }
func (this *PrimaryScan) scanPrimary(context *Context, parent value.Value) { conn := datastore.NewIndexConnection(context) defer notifyConn(conn) // Notify index that I have stopped go this.scanEntries(context, conn) var entry *datastore.IndexEntry ok := true for ok { select { case <-this.stopChannel: return default: } select { case entry, ok = <-conn.EntryChannel(): if ok { cv := value.NewScopeValue(make(map[string]interface{}), parent) av := value.NewAnnotatedValue(cv) av.SetAttachment("meta", map[string]interface{}{"id": entry.PrimaryKey}) ok = this.sendItem(av) } case <-this.stopChannel: return } } }
func (this *KeyScan) RunOnce(context *Context, parent value.Value) { this.once.Do(func() { defer context.Recover() // Recover from any panic defer close(this.itemChannel) // Broadcast that I have stopped defer this.notify() // Notify that I have stopped keys, e := this.plan.Keys().Evaluate(parent, context) if e != nil { context.Error(errors.NewError(e, "Error evaluating KEYS.")) return } actuals := keys.Actual() switch actuals.(type) { case []interface{}: case nil: actuals = []interface{}(nil) default: actuals = []interface{}{actuals} } acts := actuals.([]interface{}) for _, key := range acts { cv := value.NewScopeValue(make(map[string]interface{}), parent) av := value.NewAnnotatedValue(cv) av.SetAttachment("meta", map[string]interface{}{"id": key}) if !this.sendItem(av) { return } } }) }
func buildFor(f *algebra.UpdateFor, val value.Value, arrays []value.Value, context *Context) ([]value.Value, error) { n := -1 for _, a := range arrays { act := a.Actual() switch act := act.(type) { case []interface{}: if n < 0 || len(act) < n { n = len(act) } } } if n < 0 { return nil, nil } rv := make([]value.Value, n) for i, _ := range rv { rv[i] = value.NewScopeValue(make(map[string]interface{}, len(f.Bindings())), val) for j, b := range f.Bindings() { v, ok := arrays[j].Index(i) if ok { rv[i].SetField(b.Variable(), v) } } } return rv, nil }
/* This method evaluates the EVERY range predicate and returns a boolean value representing the result. The first step is to accumulate the elements or attributes of a collection/object. This is done by ranging over the bindings, evaluating the expressions and populating a slice of descendants if present. If any of these binding values are mising or null then, return a missing/null. The next step is to get the number of elements/attributes by ranging over the bindings slice. In order to evaluate the every clause, evaluate the satisfies condition with respect to the collection. If this returns false for any condition, then return false (as every condition needs to evaluate to true). If the condition over all elements/attributes have been satisfied, return true. */ func (this *Every) Evaluate(item value.Value, context Context) (value.Value, error) { missing := false null := false barr := make([][]interface{}, len(this.bindings)) for i, b := range this.bindings { bv, err := b.Expression().Evaluate(item, context) if err != nil { return nil, err } if b.Descend() { buffer := make([]interface{}, 0, 256) bv = value.NewValue(bv.Descendants(buffer)) } switch bv.Type() { case value.ARRAY: barr[i] = bv.Actual().([]interface{}) case value.MISSING: missing = true default: null = true } } if missing { return value.MISSING_VALUE, nil } if null { return value.NULL_VALUE, nil } n := -1 for _, b := range barr { if n < 0 || len(b) < n { n = len(b) } } for i := 0; i < n; i++ { cv := value.NewScopeValue(make(map[string]interface{}, len(this.bindings)), item) for j, b := range this.bindings { cv.SetField(b.Variable(), barr[j][i]) } sv, e := this.satisfies.Evaluate(cv, context) if e != nil { return nil, e } if !sv.Truth() { return value.NewValue(false), nil } } return value.NewValue(true), nil }
func (this *DummyScan) RunOnce(context *Context, parent value.Value) { this.once.Do(func() { defer context.Recover() // Recover from any panic defer close(this.itemChannel) // Broadcast that I have stopped defer this.notify() // Notify that I have stopped cv := value.NewScopeValue(nil, parent) av := value.NewAnnotatedValue(cv) this.sendItem(av) }) }
func (this *InitialProject) processItem(item value.AnnotatedValue, context *Context) bool { terms := this.plan.Terms() n := len(terms) if n > 1 { return this.processTerms(item, context) } if n == 0 { return this.sendItem(item) } // n == 1 result := terms[0].Result() expr := result.Expression() if expr == nil { // Unprefixed star if item.Type() == value.OBJECT { return this.sendItem(item) } else { return this.sendItem(_EMPTY_ANNOTATED_VALUE) } } else if this.plan.Projection().Raw() { // Raw projection of an expression v, err := expr.Evaluate(item, context) if err != nil { context.Error(errors.NewError(err, "Error evaluating projection.")) return false } if result.As() == "" { return this.sendItem(value.NewAnnotatedValue(v)) } sv := value.NewScopeValue(make(map[string]interface{}, 1), item) sv.SetField(result.As(), v) av := value.NewAnnotatedValue(sv) av.SetAttachment("projection", v) return this.sendItem(av) } else { // Any other projection return this.processTerms(item, context) } }
func (this *CountScan) RunOnce(context *Context, parent value.Value) { this.once.Do(func() { defer context.Recover() // Recover from any panic defer close(this.itemChannel) // Broadcast that I have stopped defer this.notify() // Notify that I have stopped count, e := this.plan.Keyspace().Count() if e != nil { context.Error(e) return } cv := value.NewScopeValue(nil, parent) av := value.NewAnnotatedValue(cv) av.SetAttachment("count", value.NewValue(count)) this.sendItem(av) }) }
func (this *Let) processItem(item value.AnnotatedValue, context *Context) bool { n := len(this.plan.Bindings()) cv := value.NewScopeValue(make(map[string]interface{}, n), item) lv := value.NewAnnotatedValue(cv) lv.SetAttachments(item.Attachments()) for _, b := range this.plan.Bindings() { v, e := b.Expression().Evaluate(item, context) if e != nil { context.Error(errors.NewError(e, "Error evaluating LET.")) return false } lv.SetField(b.Variable(), v) } return this.sendItem(lv) }
/* Visitor method for Bindings. Value is a new map from string to interface which is populated using the bindings in the scope of the parent which is listed by the value Allowed. Bring the bindings that have parrent Allowed into scope. */ func (this *Formalizer) PushBindings(bindings Bindings) (sv *value.ScopeValue, err error) { sv = value.NewScopeValue(make(map[string]interface{}, len(bindings)), this.Allowed) var expr Expression for _, b := range bindings { _, ok := this.Allowed.Field(b.Variable()) if ok { return nil, fmt.Errorf("Bind alias %s already in scope.", b.Variable()) } expr, err = this.Map(b.Expression()) if err != nil { return nil, err } b.SetExpression(expr) sv.SetField(b.Variable(), b.Variable()) } this.Allowed = sv return sv, nil }