func (this *builder) beginMutate(keyspace datastore.Keyspace, ksref *algebra.KeyspaceRef, keys expression.Expression, indexes algebra.IndexRefs, limit expression.Expression, isDelete bool) error { ksref.SetDefaultNamespace(this.namespace) term := algebra.NewKeyspaceTerm(ksref.Namespace(), ksref.Keyspace(), nil, ksref.As(), keys, indexes) this.children = make([]plan.Operator, 0, 8) this.subChildren = make([]plan.Operator, 0, 8) if this.where != nil { limit = nil } scan, err := this.selectScan(keyspace, term, limit) if err != nil { return err } this.children = append(this.children, scan) if this.coveringScan != nil { coverer := expression.NewCoverer(this.coveringScan.Covers()) err = this.cover.MapExpressions(coverer) if err != nil { return err } if this.where != nil { this.where, err = coverer.Map(this.where) if err != nil { return err } } } else { var fetch plan.Operator if isDelete && this.where == nil && isKeyScan(scan) { fetch = plan.NewDummyFetch(keyspace, term) } else { fetch = plan.NewFetch(keyspace, term) } this.subChildren = append(this.subChildren, fetch) } if this.where != nil { this.subChildren = append(this.subChildren, plan.NewFilter(this.where)) } return nil }
func (this *builder) VisitSubselect(node *algebra.Subselect) (interface{}, error) { prevCover := this.cover prevCorrelated := this.correlated defer func() { this.cover = prevCover this.correlated = prevCorrelated }() this.correlated = node.IsCorrelated() if this.cover == nil { this.cover = node } aggs, err := allAggregates(node, this.order) if err != nil { return nil, err } this.where = node.Where() group := node.Group() if group == nil && len(aggs) > 0 { group = algebra.NewGroup(nil, nil, nil) this.where = constrainAggregate(this.where, aggs) } this.children = make([]plan.Operator, 0, 16) // top-level children, executed sequentially this.subChildren = make([]plan.Operator, 0, 16) // sub-children, executed across data-parallel streams err = this.visitFrom(node, group) if err != nil { return nil, err } if this.coveringScan != nil { coverer := expression.NewCoverer(this.coveringScan.Covers()) err = this.cover.MapExpressions(coverer) if err != nil { return nil, err } if this.where != nil { this.where, err = coverer.Map(this.where) if err != nil { return nil, err } } } if node.Let() != nil { this.subChildren = append(this.subChildren, plan.NewLet(node.Let())) } if node.Where() != nil { this.subChildren = append(this.subChildren, plan.NewFilter(node.Where())) } if group != nil { this.visitGroup(group, aggs) } projection := node.Projection() this.subChildren = append(this.subChildren, plan.NewInitialProject(projection)) // Initial DISTINCT (parallel) if projection.Distinct() || this.distinct { this.subChildren = append(this.subChildren, plan.NewDistinct()) } if !this.delayProjection { // Perform the final projection if there is no subsequent ORDER BY this.subChildren = append(this.subChildren, plan.NewFinalProject()) } // Parallelize the subChildren this.children = append(this.children, plan.NewParallel(plan.NewSequence(this.subChildren...), this.maxParallelism)) // Final DISTINCT (serial) if projection.Distinct() || this.distinct { this.children = append(this.children, plan.NewDistinct()) } // Serialize the top-level children return plan.NewSequence(this.children...), nil }