// RelationsJoined returns the relations for which the unit has entered scope
// and neither left it nor prepared to leave it
422397
func (u *Unit) RelationsJoined() ([]*Relation, error) {
	return u.relations(func(ru *RelationUnit) (bool, error) {
		return ru.Joined()
	})
}
827107
func (s *Account) SetJoinedMethod(v string) *Account {
	s.JoinedMethod = &v
	return s
}
906286
func (jb *join) Wireup(bldr builder, jt *jointab) error {
	err := jb.Right.Wireup(bldr, jt)
	if err != nil {
		return err
	}
	return jb.Left.Wireup(bldr, jt)
}
1057835
func (st *State) AddRelation(eps ...Endpoint) (r *Relation, err error) {
	key := relationKey(eps)
	defer errors.DeferredAnnotatef(&err, "cannot add relation %q", key)
	// Enforce basic endpoint sanity. The epCount restrictions may be relaxed
	// in the future; if so, this method is likely to need significant rework.
	if len(eps) != 2 {
		return nil, errors.Errorf("relation must have two endpoints")
	}
	if !eps[0].CanRelateTo(eps[1]) {
		return nil, errors.Errorf("endpoints do not relate")
	}

	// Check applications are alive and do checks if one is remote.
	app1, err := aliveApplication(st, eps[0].ApplicationName)
	if err != nil {
		return nil, err
	}
	app2, err := aliveApplication(st, eps[1].ApplicationName)
	if err != nil {
		return nil, err
	}
	if app1.IsRemote() && app2.IsRemote() {
		return nil, errors.Errorf("cannot add relation between remote applications %q and %q", eps[0].ApplicationName, eps[1].ApplicationName)
	}
	remoteRelation := app1.IsRemote() || app2.IsRemote()
	ep0ok := app1.IsRemote() || eps[0].Scope == charm.ScopeGlobal
	ep1ok := app2.IsRemote() || eps[1].Scope == charm.ScopeGlobal
	if remoteRelation && (!ep0ok || !ep1ok) {
		return nil, errors.Errorf("local endpoint must be globally scoped for remote relations")
	}

	// If either endpoint has container scope, so must the other; and the
	// applications's series must also match, because they'll be deployed to
	// the same machines.
	compatibleSeries := true
	if eps[0].Scope == charm.ScopeContainer {
		eps[1].Scope = charm.ScopeContainer
	} else if eps[1].Scope == charm.ScopeContainer {
		eps[0].Scope = charm.ScopeContainer
	} else {
		compatibleSeries = false
	}
	// We only get a unique relation id once, to save on roundtrips. If it's
	// -1, we haven't got it yet (we don't get it at this stage, because we
	// still don't know whether it's sane to even attempt creation).
	id := -1
	// If a application's charm is upgraded while we're trying to add a relation,
	// we'll need to re-validate application sanity.
	var doc *relationDoc
	now := st.clock().Now()
	buildTxn := func(attempt int) ([]txn.Op, error) {
		// Perform initial relation sanity check.
		if exists, err := isNotDead(st, relationsC, key); err != nil {
			return nil, errors.Trace(err)
		} else if exists {
			return nil, errors.AlreadyExistsf("relation %v", key)
		}
		// Collect per-application operations, checking sanity as we go.
		var ops []txn.Op
		var subordinateCount int
		appSeries := map[string][]string{}
		for _, ep := range eps {
			app, err := aliveApplication(st, ep.ApplicationName)
			if err != nil {
				return nil, err
			}
			if app.IsRemote() {
				// If the remote application is known to be terminated, we don't
				// allow a relation to it.
				statusInfo, err := app.Status()
				if err != nil && !errors.IsNotFound(err) {
					return nil, errors.Trace(err)
				}
				if err == nil && statusInfo.Status == status.Terminated {
					return nil, errors.Errorf("remote offer %s is terminated", ep.ApplicationName)
				}
				ops = append(ops, txn.Op{
					C:      remoteApplicationsC,
					Id:     st.docID(ep.ApplicationName),
					Assert: bson.D{{"life", Alive}},
					Update: bson.D{{"$inc", bson.D{{"relationcount", 1}}}},
				})
			} else {
				localApp := app.(*Application)
				if localApp.doc.Subordinate {
					subordinateCount++
				}
				ch, _, err := localApp.Charm()
				if err != nil {
					return nil, errors.Trace(err)
				}
				if !ep.ImplementedBy(ch) {
					return nil, errors.Errorf("%q does not implement %q", ep.ApplicationName, ep)
				}
				charmSeries := ch.Meta().Series
				if len(charmSeries) == 0 {
					charmSeries = []string{localApp.doc.Series}
				}
				appSeries[localApp.doc.Name] = charmSeries
				ops = append(ops, txn.Op{
					C:      applicationsC,
					Id:     st.docID(ep.ApplicationName),
					Assert: bson.D{{"life", Alive}, {"charmurl", ch.URL()}},
					Update: bson.D{{"$inc", bson.D{{"relationcount", 1}}}},
				})
			}
		}
		if compatibleSeries && len(appSeries) > 1 {
			// We need to ensure that there's intersection between the supported
			// series of both applications' charms.
			app1Series := set.NewStrings(appSeries[eps[0].ApplicationName]...)
			app2Series := set.NewStrings(appSeries[eps[1].ApplicationName]...)
			if app1Series.Intersection(app2Series).Size() == 0 {
				return nil, errors.Errorf("principal and subordinate applications' series must match")
			}
		}
		if eps[0].Scope == charm.ScopeContainer && subordinateCount < 1 {
			return nil, errors.Errorf("container scoped relation requires at least one subordinate application")
		}

		// Create a new unique id if that has not already been done, and add
		// an operation to create the relation document.
		if id == -1 {
			var err error
			if id, err = sequence(st, "relation"); err != nil {
				return nil, errors.Trace(err)
			}
		}
		docID := st.docID(key)
		doc = &relationDoc{
			DocID:     docID,
			Key:       key,
			ModelUUID: st.ModelUUID(),
			Id:        id,
			Endpoints: eps,
			Life:      Alive,
		}
		relationStatusDoc := statusDoc{
			Status:    status.Joining,
			ModelUUID: st.ModelUUID(),
			Updated:   now.UnixNano(),
		}
		ops = append(ops, txn.Op{
			C:      relationsC,
			Id:     docID,
			Assert: txn.DocMissing,
			Insert: doc,
		}, createStatusOp(st, relationGlobalScope(id), relationStatusDoc))
		return ops, nil
	}
	if err = st.db().Run(buildTxn); err == nil {
		return &Relation{st, *doc}, nil
	}
	return nil, errors.Trace(err)
}
792182
func RelationsOfTypes(rels []Relation, relTypes ...string) []Relation {

	var out []Relation

	for _, rel := range rels {
		for _, relType := range relTypes {
			if rel.TypeOf() == relType {
				out = append(out, rel)
			}
		}
	}

	return out
}
163345
func (s *Server) RoomsJoined(id string) []string {
	rooms := make([]string, len(s.joinedRooms[id]))
	s.joinedRoomsMu.RLock()
	defer s.joinedRoomsMu.RUnlock()

	copy(rooms, s.joinedRooms[id])

	return rooms
}
1219870
func (api *RemoteRelationsAPI) Relations(entities params.Entities) (params.RemoteRelationResults, error) {
	results := params.RemoteRelationResults{
		Results: make([]params.RemoteRelationResult, len(entities.Entities)),
	}
	for i, entity := range entities.Entities {
		remoteRelation, err := api.remoteRelation(entity)
		if err != nil {
			results.Results[i].Error = common.ServerError(err)
			continue
		}
		results.Results[i].Result = remoteRelation
	}
	return results, nil
}
877073
func (this *Dataset) JoinPartitionedSorted(name string, that *Dataset, sortOption *SortOption,
	isLeftOuterJoin, isRightOuterJoin bool) *Dataset {
	ret := this.Flow.NewNextDataset(len(this.Shards))
	ret.IsPartitionedBy = that.IsPartitionedBy
	ret.IsLocalSorted = that.IsLocalSorted

	inputs := []*Dataset{this, that}
	step := this.Flow.MergeDatasets1ShardTo1Step(inputs, ret)
	step.SetInstruction(name, instruction.NewJoinPartitionedSorted(isLeftOuterJoin, isRightOuterJoin, sortOption.Indexes()))
	return ret
}
1134875
func (context *statusContext) getAllRelations() []*state.Relation {
	var out []*state.Relation
	seenRelations := make(map[int]bool)
	for _, relations := range context.relations {
		for _, relation := range relations {
			if _, found := seenRelations[relation.Id()]; !found {
				out = append(out, relation)
				seenRelations[relation.Id()] = true
			}
		}
	}
	return out
}
64309
func deriveJoin(in <-chan (<-chan int)) <-chan int {
	out := make(chan int)
	go func() {
		wait := sync.WaitGroup{}
		for c := range in {
			wait.Add(1)
			res := c
			go func() {
				for r := range res {
					out <- r
				}
				wait.Done()
			}()
		}
		wait.Wait()
		close(out)
	}()
	return out
}
36508
func (b *SelectStmt) RightJoin(table, on interface{}) *SelectStmt {
	b.JoinTable = append(b.JoinTable, join(right, table, on))
	return b
}
603623
func (b *Builder) CrossJoin(joinTable string, joinCond interface{}) *Builder {
	return b.Join("CROSS", joinTable, joinCond)
}
1099935
func (op *DestroyRelationOperation) Done(err error) error {
	if err != nil {
		if !op.Force {
			return errors.Annotatef(err, "cannot destroy relation %q", op.r)
		}
		op.AddError(errors.Errorf("forcefully destroying relation %v proceeded despite encountering ERROR %v", op.r, err))
	}
	return nil
}
248375
func join(row virtualRow, relations map[string]*Relation, predicates []joiner, predicateIndex int, selectPredicates []PredicateLinker, functors []selectFunctor) error {

	// Skip directly to selectRows if there is no joiner to run
	if len(predicates) == 0 {
		return selectRows(row, selectPredicates, functors)
	}

	// get current predicates
	predicate := predicates[predicateIndex]

	// last := is it last join ?
	last := false
	if predicateIndex >= len(predicates)-1 {
		last = true
	}

	// for each row in relations[pred.Table()]
	r := relations[predicate.On()]
	for i := range r.rows {
		ok, err := predicate.Evaluate(row, r, i)
		if err != nil {
			return err
		}
		// if predicate not ok
		if !ok {
			continue
		}

		// combine columns to existing virtual row
		for index := range r.rows[i].Values {
			v := Value{
				v:      r.rows[i].Values[index],
				valid:  true,
				lexeme: r.table.attributes[index].name,
				table:  r.table.name,
			}
			row[v.table+"."+v.lexeme] = v
		}

		// if last predicate
		if last {
			err = selectRows(row, selectPredicates, functors)
		} else {
			err = join(row, relations, predicates, predicateIndex+1, selectPredicates, functors)
		}
		if err != nil {
			return err
		}
	}

	return nil
}
1015751
func (s *REST) getRelatedObjects(ctx context.Context, name string, options *metav1.GetOptions) (
	identity *userapi.Identity, identityErr error,
	user *userapi.User, userErr error,
	mapping *userinternal.UserIdentityMapping, mappingErr error,
) {
	// Initialize errors to NotFound
	identityErr = kerrs.NewNotFound(userapi.Resource("identity"), name)
	userErr = kerrs.NewNotFound(userapi.Resource("user"), "")
	mappingErr = kerrs.NewNotFound(userapi.Resource("useridentitymapping"), name)

	// GetIdentities identity
	identity, identityErr = s.identityClient.Get(name, *options)
	if identityErr != nil {
		return
	}
	if !hasUserMapping(identity) {
		return
	}

	// GetIdentities user
	user, userErr = s.userClient.Get(identity.User.Name, *options)
	if userErr != nil {
		return
	}

	// Ensure relational integrity
	if !identityReferencesUser(identity, user) {
		return
	}
	if !userReferencesIdentity(user, identity) {
		return
	}

	mapping, mappingErr = mappingFor(user, identity)

	return
}
193903
func (s *Server) IsJoined(roomName string, connID string) bool {
	s.mu.RLock()
	room := s.rooms[roomName]
	s.mu.RUnlock()

	if room == nil {
		return false
	}

	for _, connid := range room {
		if connID == connid {
			return true
		}
	}

	return false
}
254457
func (p *LogicalJoin) outerJoinPropConst(predicates []expression.Expression) []expression.Expression {
	outerTable := p.children[0]
	innerTable := p.children[1]
	if p.JoinType == RightOuterJoin {
		innerTable, outerTable = outerTable, innerTable
	}
	lenJoinConds := len(p.EqualConditions) + len(p.LeftConditions) + len(p.RightConditions) + len(p.OtherConditions)
	joinConds := make([]expression.Expression, 0, lenJoinConds)
	for _, equalCond := range p.EqualConditions {
		joinConds = append(joinConds, equalCond)
	}
	joinConds = append(joinConds, p.LeftConditions...)
	joinConds = append(joinConds, p.RightConditions...)
	joinConds = append(joinConds, p.OtherConditions...)
	p.EqualConditions = nil
	p.LeftConditions = nil
	p.RightConditions = nil
	p.OtherConditions = nil
	nullSensitive := (p.JoinType == AntiLeftOuterSemiJoin || p.JoinType == LeftOuterSemiJoin)
	joinConds, predicates = expression.PropConstOverOuterJoin(p.ctx, joinConds, predicates, outerTable.Schema(), innerTable.Schema(), nullSensitive)
	p.attachOnConds(joinConds)
	return predicates
}