예제 #1
0
func (this *builder) visitGroup(group *algebra.Group, aggs map[string]algebra.Aggregate) {
	aggn := make(sort.StringSlice, 0, len(aggs))
	for n, _ := range aggs {
		aggn = append(aggn, n)
	}

	aggn.Sort()
	aggv := make(algebra.Aggregates, len(aggs))
	for i, n := range aggn {
		aggv[i] = aggs[n]
	}

	this.subChildren = append(this.subChildren, plan.NewInitialGroup(group.By(), aggv))
	this.children = append(this.children, plan.NewParallel(plan.NewSequence(this.subChildren...), this.maxParallelism))
	this.children = append(this.children, plan.NewIntermediateGroup(group.By(), aggv))
	this.children = append(this.children, plan.NewFinalGroup(group.By(), aggv))
	this.subChildren = make([]plan.Operator, 0, 8)

	letting := group.Letting()
	if letting != nil {
		this.subChildren = append(this.subChildren, plan.NewLet(letting))
	}

	having := group.Having()
	if having != nil {
		this.subChildren = append(this.subChildren, plan.NewFilter(having))
	}
}
예제 #2
0
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
}
예제 #3
0
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
}
예제 #4
0
func (this *builder) VisitMerge(stmt *algebra.Merge) (interface{}, error) {
	children := make([]plan.Operator, 0, 8)
	subChildren := make([]plan.Operator, 0, 8)
	source := stmt.Source()

	if source.Select() != nil {
		sel, err := source.Select().Accept(this)
		if err != nil {
			return nil, err
		}

		children = append(children, sel.(plan.Operator))
	} else {
		if source.From() == nil {
			return nil, fmt.Errorf("MERGE missing source.")
		}

		_, err := source.From().Accept(this)
		if err != nil {
			return nil, err
		}

		// Update local operator slices with results of building From:
		children = append(children, this.children...)
		subChildren = append(subChildren, this.subChildren...)

	}

	if source.As() != "" {
		subChildren = append(subChildren, plan.NewAlias(source.As()))
	}

	ksref := stmt.KeyspaceRef()
	ksref.SetDefaultNamespace(this.namespace)

	keyspace, err := this.getNameKeyspace(ksref.Namespace(), ksref.Keyspace())
	if err != nil {
		return nil, err
	}

	actions := stmt.Actions()
	var update, delete, insert plan.Operator

	if actions.Update() != nil {
		act := actions.Update()
		ops := make([]plan.Operator, 0, 5)

		if act.Where() != nil {
			ops = append(ops, plan.NewFilter(act.Where()))
		}

		ops = append(ops, plan.NewClone(ksref.Alias()))

		if act.Set() != nil {
			ops = append(ops, plan.NewSet(act.Set()))
		}

		if act.Unset() != nil {
			ops = append(ops, plan.NewUnset(act.Unset()))
		}

		ops = append(ops, plan.NewSendUpdate(keyspace, ksref.Alias(), stmt.Limit()))
		update = plan.NewSequence(ops...)
	}

	if actions.Delete() != nil {
		act := actions.Delete()
		ops := make([]plan.Operator, 0, 4)

		if act.Where() != nil {
			ops = append(ops, plan.NewFilter(act.Where()))
		}

		ops = append(ops, plan.NewSendDelete(keyspace, ksref.Alias(), stmt.Limit()))
		delete = plan.NewSequence(ops...)
	}

	if actions.Insert() != nil {
		act := actions.Insert()
		ops := make([]plan.Operator, 0, 4)

		if act.Where() != nil {
			ops = append(ops, plan.NewFilter(act.Where()))
		}

		ops = append(ops, plan.NewSendInsert(keyspace, ksref.Alias(), stmt.Key(), act.Value(), stmt.Limit()))
		insert = plan.NewSequence(ops...)
	}

	merge := plan.NewMerge(keyspace, ksref, stmt.Key(), update, delete, insert)
	subChildren = append(subChildren, merge)

	if stmt.Returning() != nil {
		subChildren = append(subChildren, plan.NewInitialProject(stmt.Returning()), plan.NewFinalProject())
	}

	parallel := plan.NewParallel(plan.NewSequence(subChildren...), this.maxParallelism)
	children = append(children, parallel)

	if stmt.Limit() != nil {
		children = append(children, plan.NewLimit(stmt.Limit()))
	}

	if stmt.Returning() == nil {
		children = append(children, plan.NewDiscard())
	}

	return plan.NewSequence(children...), nil
}