Пример #1
0
func (this *builder) VisitUpdate(stmt *algebra.Update) (interface{}, error) {
	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(), false)
	if err != nil {
		return nil, err
	}

	subChildren := this.subChildren
	subChildren = append(subChildren, plan.NewClone(ksref.Alias()))

	if stmt.Set() != nil {
		subChildren = append(subChildren, plan.NewSet(stmt.Set()))
	}

	if stmt.Unset() != nil {
		subChildren = append(subChildren, plan.NewUnset(stmt.Unset()))
	}

	subChildren = append(subChildren, plan.NewSendUpdate(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
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
}