// outerJoinSimplify simplifies outer join.
165190
func outerJoinSimplify(p *Join, predicates []expression.Expression) error {
	var innerTable, outerTable LogicalPlan
	child1 := p.GetChildByIndex(0).(LogicalPlan)
	child2 := p.GetChildByIndex(1).(LogicalPlan)
	var fullConditions []expression.Expression
	if p.JoinType == LeftOuterJoin {
		innerTable = child2
		outerTable = child1
	} else if p.JoinType == RightOuterJoin || p.JoinType == InnerJoin {
		innerTable = child1
		outerTable = child2
	} else {
		return nil
	}
	// first simplify embedded outer join.
	// When trying to simplify an embedded outer join operation in a query,
	// we must take into account the join condition for the embedding outer join together with the WHERE condition.
	if innerPlan, ok := innerTable.(*Join); ok {
		fullConditions = concatOnAndWhereConds(p, predicates)
		err := outerJoinSimplify(innerPlan, fullConditions)
		if err != nil {
			return errors.Trace(err)
		}
	}
	if outerPlan, ok := outerTable.(*Join); ok {
		if fullConditions != nil {
			fullConditions = concatOnAndWhereConds(p, predicates)
		}
		err := outerJoinSimplify(outerPlan, fullConditions)
		if err != nil {
			return errors.Trace(err)
		}
	}
	if p.JoinType == InnerJoin {
		return nil
	}
	// then simplify embedding outer join.
	canBeSimplified := false
	for _, expr := range predicates {
		isOk, err := isNullRejected(p.ctx, innerTable.GetSchema(), expr)
		if err != nil {
			return errors.Trace(err)
		}
		if isOk {
			canBeSimplified = true
			break
		}
	}
	if canBeSimplified {
		p.JoinType = InnerJoin
	}
	return nil
}
25907
func (b *Builder) InnerJoin(joinTable string, joinCond interface{}) *Builder {
	return b.Join("INNER", joinTable, joinCond)
}
1142103
func Join(sep cty.Value, lists ...cty.Value) (cty.Value, error) {
	args := make([]cty.Value, len(lists)+1)
	args[0] = sep
	copy(args[1:], lists)
	return JoinFunc.Call(args)
}
384712
func (d *Dataset) Join(name string, other *Dataset, sortOption *SortOption) *Dataset {
	return d.DoJoin(name, other, false, false, sortOption)
}
2377
func (qb *TiDBQueryBuilder) LeftJoin(table string) QueryBuilder {
	qb.Tokens = append(qb.Tokens, "LEFT JOIN", table)
	return qb
}
436057
func linkJoin(base, link string) string {
	if filepath.IsAbs(link) {
		return link
	}
	return filepath.Join(base, link)
}
993833
func (me *Dataset) NaturalJoin(table Expression) *Dataset {
	return me.joinTable(NATURAL_JOIN, table, nil)
}
626766
func Simplify(inp tree.Expression) tree.Expression {
	return reduceTransformers(inp,
		// X in [P]  ==>  P == Q
		// X in [P, Q, R]  where X and R can be determined to not be equal  ==>  X in [P, Q]
		// X in [P, Q, R]  where X and one of the values can be determined to be equal  ==>  true
		// X notIn [P]  ==>  X != P
		// X notIn [P, Q, R]  where X and R can be determined to not be equal  ==>  X notIn [P, Q]
		// X notIn [P, Q, R]  where X and one of the values can be determined to be equal  ==>  false
		createInclusionSimplifier(),

		// X in [P, Q, R]     ==>  X == P || X == Q || X == R
		// X notIn [P, Q, R]  ==>  X != P && X != Q && X != R
		createInclusionRemoverSimplifier(),

		// X < Y    ==>  Y >= X
		// X <= Y   ==>  Y > X
		createLtExpressionsSimplifier(),

		// Where X and Y can be determined statically:
		// X + Y   ==>  [X+Y]
		// X - Y   ==>  [X-Y]
		// X * Y   ==>  [X*Y]
		// X / Y   ==>  [X/Y]
		// X % Y   ==>  [X%Y]
		// X & Y   ==>  [X&Y]
		// X | Y   ==>  [X|Y]
		// X ^ Y   ==>  [X^Y]
		// X << Y  ==>  [X<<Y]
		// X >> Y  ==>  [X<<Y]
		// ~X      ==>  [~X]
		// Note that these calculations will all be done on 64bit unsigned values
		// - this could lead to different result than if they were evaluated by the BPF engine.
		createArithmeticSimplifier(),

		// Where X and Y can be determined statically:
		// X == Y  where X == Y  ==>  true
		// X == Y  where X != Y  ==>  false
		// X != Y  where X == Y  ==>  false
		// X != Y  where X != Y  ==>  true
		// X > Y   where X > Y   ==>  true
		// X > Y   where X <= Y  ==>  false
		// X >= Y  where X >= Y  ==>  true
		// X >= Y  where X < Y   ==>  false
		// X < Y   where X < Y   ==>  true
		// X < Y   where X >= Y  ==>  false
		// X <= Y  where X <= Y  ==>  true
		// X <= Y  where X > Y   ==>  false
		createComparisonSimplifier(),

		// !true           ==>  false
		// !false          ==>  true
		// false || Y      ==>  Y
		// false || true   ==>  true
		// false || false  ==>  false
		// true  || Y      ==>  true
		// true  && true   ==>  true
		// true  && false  ==>  false
		// true  && Y      ==>  Y
		// false && [any]  ==>  false
		createBooleanSimplifier(),

		// ~X  ==> X ^ 0xFFFFFFFFFFFFFFFF
		createBinaryNegationSimplifier(),

		// Where X can be determined statically (the opposite order is also valid)
		// arg0 == X     ==>  argL0 == X.low && argH0 == X.high
		// arg0 != X     ==>  argL0 != X.low || argH0 != X.high
		// arg0 > X      ==>  argH0 > X.high || (argH0 == X.high && argL0 > X.low)
		// arg0 >= X     ==>  argH0 > X.high || (argH0 == X.high && argL0 >= X.low)
		// arg0 == arg1  ==>  argL0 == argL1 && argH0 == argH1
		// arg0 != arg1  ==>  argL0 != argL1 || argH0 != argH1
		// arg0 > arg1   ==>  argH0 > argH1  || (argH0 == argH1 && argL0 > argL1)
		// arg0 >= arg1  ==>  argH0 > argH1  || (argH0 == argH1 && argL0 >= argL1)
		createFullArgumentSplitterSimplifier(),

		// We repeat some of the simplifiers in the hope that the above operations have opened up new avenues of simplification
		createArithmeticSimplifier(),
		createComparisonSimplifier(),
		createBooleanSimplifier(),
		createBinaryNegationSimplifier(),
	)
}
578540
func (j TableJoin) GetJoinExpression() string {
	return fmt.Sprintf(`LEFT JOIN %s "%s" ON %s`, j.TableName, j.TableAlias, j.On)
}
1196086
func (s *DouglasPeuckerSimplifier) Simplify(g orb.Geometry) orb.Geometry {
	return simplify(s, g)
}
1138489
func newJoin(lpb, rpb *primitiveBuilder, ajoin *sqlparser.JoinTableExpr) error {
	// This function converts ON clauses to WHERE clauses. The WHERE clause
	// scope can see all tables, whereas the ON clause can only see the
	// participants of the JOIN. However, since the ON clause doesn't allow
	// external references, and the FROM clause doesn't allow duplicates,
	// it's safe to perform this conversion and still expect the same behavior.

	opcode := engine.NormalJoin
	if ajoin != nil {
		switch {
		case ajoin.Join == sqlparser.LeftJoinStr:
			opcode = engine.LeftJoin

			// For left joins, we have to push the ON clause into the RHS.
			// We do this before creating the join primitive.
			// However, variables of LHS need to be visible. To allow this,
			// we mark the LHS symtab as outer scope to the RHS, just like
			// a subquery. This make the RHS treat the LHS symbols as external.
			// This will prevent constructs from escaping out of the rpb scope.
			// At this point, the LHS symtab also contains symbols of the RHS.
			// But the RHS will hide those, as intended.
			rpb.st.Outer = lpb.st
			if err := rpb.pushFilter(ajoin.Condition.On, sqlparser.WhereStr); err != nil {
				return err
			}
		case ajoin.Condition.Using != nil:
			return errors.New("unsupported: join with USING(column_list) clause")
		}
	}
	lpb.bldr = &join{
		Left:  lpb.bldr,
		Right: rpb.bldr,
		ejoin: &engine.Join{
			Opcode: opcode,
			Vars:   make(map[string]int),
		},
	}
	lpb.bldr.Reorder(0)
	if ajoin == nil || opcode == engine.LeftJoin {
		return nil
	}
	return lpb.pushFilter(ajoin.Condition.On, sqlparser.WhereStr)
}
846251
func (e *joinReOrderSolver) makeBushyJoin(cartesianJoinGroup []LogicalPlan) {
	for len(cartesianJoinGroup) > 1 {
		resultJoinGroup := make([]LogicalPlan, 0, len(cartesianJoinGroup))
		for i := 0; i < len(cartesianJoinGroup); i += 2 {
			if i+1 == len(cartesianJoinGroup) {
				resultJoinGroup = append(resultJoinGroup, cartesianJoinGroup[i])
				break
			}
			resultJoinGroup = append(resultJoinGroup, e.newJoin(cartesianJoinGroup[i], cartesianJoinGroup[i+1]))
		}
		cartesianJoinGroup = resultJoinGroup
	}
	e.resultJoin = cartesianJoinGroup[0]
}
605848
func newJointab(bindvars map[string]struct{}) *jointab {
	return &jointab{
		refs: make(map[*column]string),
		vars: bindvars,
	}
}
581279
func (s *DB) Joins(query string, args ...interface{}) *DB {
	return s.clone().search.Joins(query, args...).db
}
1223558
func (c Context) Join(a []string, sep string) string {
	return strings.Join(a, sep)
}
198644
func (joins *TableJoinMap) ActivateRequiredJoins() error {
	for k, join := range *joins {
		if !join.Active {
			continue
		}

		for _, name := range join.ActivateOtherJoins {
			other, exists := (*joins)[name]
			if !exists {
				return errs.Errorf(`join "%s" not found for "%s" join`, name, k)
			}

			// Check if dependend join is already active
			if other.Active {
				continue
			}

			other.Active = true
			if err := joins.ActivateRequiredJoins(); err != nil {
				return errs.Wrapf(err, `failed to activate required joins for "%s" join`, k)
			}
		}
	}
	return nil
}
693097
func (me *Dataset) Join(table Expression, condition joinExpression) *Dataset {
	return me.InnerJoin(table, condition)
}