コード例 #1
0
ファイル: build_delete.go プロジェクト: mschoch/query
func (this *builder) VisitDelete(stmt *algebra.Delete) (interface{}, error) {
	this.cover = stmt
	this.where = stmt.Where()

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

	err = this.beginMutate(keyspace, ksref, stmt.Keys(), stmt.Indexes(), stmt.Limit())
	if err != nil {
		return nil, err
	}

	subChildren := this.subChildren
	subChildren = append(subChildren, plan.NewSendDelete(keyspace, ksref.Alias(), stmt.Limit()))

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

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

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

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

	return plan.NewSequence(this.children...), nil
}
コード例 #2
0
ファイル: build_select.go プロジェクト: jmptrader/query
func (this *builder) VisitSelect(stmt *algebra.Select) (interface{}, error) {
	// Restore previous values when exiting. VisitSelect()
	// can be called multiple times by set operators
	prevCover := this.cover
	prevOrder := this.order
	prevLimit := this.limit
	prevProjection := this.delayProjection
	defer func() {
		this.cover = prevCover
		this.order = prevOrder
		this.limit = prevLimit
		this.delayProjection = prevProjection
	}()

	order := stmt.Order()
	offset := stmt.Offset()
	limit := stmt.Limit()

	this.order = order
	if order != nil {
		// If there is an ORDER BY, delay the final projection
		this.delayProjection = true
		this.cover = stmt
	} else {
		this.cover = nil
	}

	if order != nil || offset != nil {
		this.limit = nil
	} else if limit != nil {
		this.limit = limit
	}

	sub, err := stmt.Subresult().Accept(this)
	if err != nil {
		return nil, err
	}

	if order == nil && offset == nil && limit == nil {
		return sub, nil
	}

	children := make([]plan.Operator, 0, 5)
	children = append(children, sub.(plan.Operator))

	if order != nil {
		children = append(children, plan.NewOrder(order))
	}

	if offset != nil {
		children = append(children, plan.NewOffset(offset))
	}

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

	// Perform the delayed final projection now, after the ORDER BY
	if this.delayProjection {
		children = append(children, plan.NewFinalProject())
	}

	return plan.NewSequence(children...), nil
}
コード例 #3
0
ファイル: build_merge.go プロジェクト: pkdevboxy/query
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
}