You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: constraint_builder.go
    path of file: ./repos/cockroach/pkg/sql/opt/memo
    
    the code of the file until where you have to start completion: // Copyright 2018 The Cockroach Authors.
//
// Use of this software is governed by the Business Source License
// included in the file licenses/BSL.txt.
//
// As of the Change Date specified in that file, in accordance with
// the Business Source License, use of this software will be governed
// by the Apache License, Version 2.0, included in the file
// licenses/APL.txt.

package memo

import (
	"regexp"
	"strings"

	"github.com/cockroachdb/cockroach/pkg/sql/opt"
	"github.com/cockroachdb/cockroach/pkg/sql/opt/constraint"
	"github.com/cockroachdb/cockroach/pkg/sql/sem/eval"
	"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
	"github.com/cockroachdb/cockroach/pkg/sql/types"
	"github.com/cockroachdb/errors"
	"github.com/cockroachdb/redact"
)

// BuildConstraints returns a constraint.Set that represents the given scalar
// expression. A "tight" boolean is also returned which is true if the
// constraint is exactly equivalent to the expression.
func BuildConstraints(
	e opt.ScalarExpr, md *opt.Metadata, evalCtx *eval.Context, skipExtraConstraints bool,
) (_ *constraint.Set, tight bool) {
	cb := constraintsBuilder{md: md, evalCtx: evalCtx, skipExtraConstraints: skipExtraConstraints}
	return cb.buildConstraints(e)
}

// Convenience aliases to avoid the constraint prefix everywhere.
const includeBoundary = constraint.IncludeBoundary
const excludeBoundary = constraint.ExcludeBoundary

var emptyKey = constraint.EmptyKey
var unconstrained = constraint.Unconstrained
var contradiction = constraint.Contradiction

// constraintsBuilder is used to create constraints (constraint.Set) from
// boolean scalar expressions
    
func (cb *constraintsBuilder) buildConstraints(e opt.ScalarExpr) (_ *constraint.Set, tight bool) {
	switch t := e.(type) {
	case *FalseExpr, *NullExpr:
		return contradiction, true

	case *VariableExpr:
		// (x) is equivalent to (x = TRUE) if x is boolean.
		if cb.md.ColumnMeta(t.Col).Type.Family() == types.BoolFamily {
			return cb.buildSingleColumnConstraintConst(t.Col, opt.EqOp, tree.DBoolTrue)
		}
		return unconstrained, false

	case *NotExpr:
		// (NOT x) is equivalent to (x = FALSE) if x is boolean.
		if v, ok := t.Input.(*VariableExpr); ok {
			if cb.md.ColumnMeta(v.Col).Type.Family() == types.BoolFamily {
				return cb.buildSingleColumnConstraintConst(v.Col, opt.EqOp, tree.DBoolFalse)
			}
		}
		return unconstrained, false

	case *AndExpr:
		cl, tightl := cb.buildConstraints(t.Left)
		cr, tightr := cb.buildConstraints(t.Right)
		cl = cl.Intersect(cb.evalCtx, cr)
		tightl = tightl && tightr
		return cl, (tightl || cl == contradiction)

	case *OrExpr:
		disjunctions := CollectContiguousOrExprs(e)
		return cb.binaryBuildConstraintsForOr(disjunctions)

	case *RangeExpr:
		return cb.buildConstraints(t.And)

	case *FunctionExpr:
		return cb.buildFunctionConstraints(t)
	}

	if e.ChildCount() < 2 {
		return unconstrained, false
	}

	child0, child1 := e.Child(0), e.Child(1)
	// Check for an operation where the left-hand side is an
	// indexed var for this column.

	// Check for tuple operations.
	if child0.Op() == opt.TupleOp && child1.Op() == opt.TupleOp {
		switch e.Op() {
		case opt.LtOp, opt.LeOp, opt.GtOp, opt.GeOp, opt.NeOp:
			// Tuple inequality.
			return cb.buildConstraintForTupleInequality(e)

		case opt.InOp:
			return cb.buildConstraintForTupleIn(e.(*InExpr))
		}
	}
	if v, ok := child0.(*VariableExpr); ok {
		return cb.buildSingleColumnConstraint(v.Col, e.Op(), child1)
	}
	return unconstrained, false
}