ConversionTable() {
        //
        // Conversions from NumberDouble
        //
        table[BSONType::NumberDouble][BSONType::NumberDouble] = &performIdentityConversion;
        table[BSONType::NumberDouble][BSONType::String] = &performFormatDouble;
        table[BSONType::NumberDouble][BSONType::Bool] =
            [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
                return Value(inputValue.coerceToBool());
            };
        table[BSONType::NumberDouble][BSONType::Date] = &performCastNumberToDate;
        table[BSONType::NumberDouble][BSONType::NumberInt] = &performCastDoubleToInt;
        table[BSONType::NumberDouble][BSONType::NumberLong] = &performCastDoubleToLong;
        table[BSONType::NumberDouble][BSONType::NumberDecimal] =
            [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
                return Value(inputValue.coerceToDecimal());
            };

        //
        // Conversions from String
        //
        table[BSONType::String][BSONType::NumberDouble] = &parseStringToNumber<double, 0>;
        table[BSONType::String][BSONType::String] = &performIdentityConversion;
        table[BSONType::String][BSONType::jstOID] = &parseStringToOID;
        table[BSONType::String][BSONType::Bool] = &performConvertToTrue;
        table[BSONType::String][BSONType::Date] =
            [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
                return Value(expCtx->timeZoneDatabase->fromString(
                    inputValue.getStringData(), mongo::TimeZoneDatabase::utcZone()));
            };
        table[BSONType::String][BSONType::NumberInt] = &parseStringToNumber<int, 10>;
        table[BSONType::String][BSONType::NumberLong] = &parseStringToNumber<long long, 10>;
        table[BSONType::String][BSONType::NumberDecimal] = &parseStringToNumber<Decimal128, 0>;

        //
        // Conversions from jstOID
        //
        table[BSONType::jstOID][BSONType::String] =
            [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
                return Value(inputValue.getOid().toString());
            };
        table[BSONType::jstOID][BSONType::jstOID] = &performIdentityConversion;
        table[BSONType::jstOID][BSONType::Bool] = &performConvertToTrue;
        table[BSONType::jstOID][BSONType::Date] =
            [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
                return Value(inputValue.getOid().asDateT());
            };

        //
        // Conversions from Bool
        //
        table[BSONType::Bool][BSONType::NumberDouble] =
            [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
                return inputValue.getBool() ? Value(1.0) : Value(0.0);
            };
        table[BSONType::Bool][BSONType::String] =
            [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
                return inputValue.getBool() ? Value("true"_sd) : Value("false"_sd);
            };
        table[BSONType::Bool][BSONType::Bool] = &performIdentityConversion;
        table[BSONType::Bool][BSONType::NumberInt] =
            [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
                return inputValue.getBool() ? Value(int{1}) : Value(int{0});
            };
        table[BSONType::Bool][BSONType::NumberLong] =
            [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
                return inputValue.getBool() ? Value(1LL) : Value(0LL);
            };
        table[BSONType::Bool][BSONType::NumberDecimal] =
            [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
                return inputValue.getBool() ? Value(Decimal128(1)) : Value(Decimal128(0));
            };

        //
        // Conversions from Date
        //
        table[BSONType::Date][BSONType::NumberDouble] =
            [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
                return Value(static_cast<double>(inputValue.getDate().toMillisSinceEpoch()));
            };
        table[BSONType::Date][BSONType::String] =
            [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
                auto dateString = TimeZoneDatabase::utcZone().formatDate(Value::kISOFormatString,
                                                                         inputValue.getDate());
                return Value(dateString);
            };
        table[BSONType::Date][BSONType::Bool] =
            [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
                return Value(inputValue.coerceToBool());
            };
        table[BSONType::Date][BSONType::Date] = &performIdentityConversion;
        table[BSONType::Date][BSONType::NumberLong] =
            [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
                return Value(inputValue.getDate().toMillisSinceEpoch());
            };
        table[BSONType::Date][BSONType::NumberDecimal] =
            [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
                return Value(
                    Decimal128(static_cast<int64_t>(inputValue.getDate().toMillisSinceEpoch())));
            };

        //
        // Conversions from NumberInt
        //
        table[BSONType::NumberInt][BSONType::NumberDouble] =
            [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
                return Value(inputValue.coerceToDouble());
            };
        table[BSONType::NumberInt][BSONType::String] =
            [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
                return Value(static_cast<std::string>(str::stream() << inputValue.getInt()));
            };
        table[BSONType::NumberInt][BSONType::Bool] =
            [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
                return Value(inputValue.coerceToBool());
            };
        table[BSONType::NumberInt][BSONType::NumberInt] = &performIdentityConversion;
        table[BSONType::NumberInt][BSONType::NumberLong] =
            [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
                return Value(static_cast<long long>(inputValue.getInt()));
            };
        table[BSONType::NumberInt][BSONType::NumberDecimal] =
            [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
                return Value(inputValue.coerceToDecimal());
            };

        //
        // Conversions from NumberLong
        //
        table[BSONType::NumberLong][BSONType::NumberDouble] =
            [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
                return Value(inputValue.coerceToDouble());
            };
        table[BSONType::NumberLong][BSONType::String] =
            [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
                return Value(static_cast<std::string>(str::stream() << inputValue.getLong()));
            };
        table[BSONType::NumberLong][BSONType::Bool] =
            [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
                return Value(inputValue.coerceToBool());
            };
        table[BSONType::NumberLong][BSONType::Date] = &performCastNumberToDate;
        table[BSONType::NumberLong][BSONType::NumberInt] = &performCastLongToInt;
        table[BSONType::NumberLong][BSONType::NumberLong] = &performIdentityConversion;
        table[BSONType::NumberLong][BSONType::NumberDecimal] =
            [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
                return Value(inputValue.coerceToDecimal());
            };

        //
        // Conversions from NumberDecimal
        //
        table[BSONType::NumberDecimal][BSONType::NumberDouble] = &performCastDecimalToDouble;
        table[BSONType::NumberDecimal][BSONType::String] =
            [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
                return Value(inputValue.getDecimal().toString());
            };
        table[BSONType::NumberDecimal][BSONType::Bool] =
            [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
                return Value(inputValue.coerceToBool());
            };
        table[BSONType::NumberDecimal][BSONType::Date] = &performCastNumberToDate;
        table[BSONType::NumberDecimal][BSONType::NumberInt] =
            [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
                return performCastDecimalToInt(BSONType::NumberInt, inputValue);
            };
        table[BSONType::NumberDecimal][BSONType::NumberLong] =
            [](const boost::intrusive_ptr<ExpressionContext>& expCtx, Value inputValue) {
                return performCastDecimalToInt(BSONType::NumberLong, inputValue);
            };
        table[BSONType::NumberDecimal][BSONType::NumberDecimal] = &performIdentityConversion;

        //
        // Miscellaneous conversions to Bool
        //
        table[BSONType::Object][BSONType::Bool] = &performConvertToTrue;
        table[BSONType::Array][BSONType::Bool] = &performConvertToTrue;
        table[BSONType::BinData][BSONType::Bool] = &performConvertToTrue;
        table[BSONType::RegEx][BSONType::Bool] = &performConvertToTrue;
        table[BSONType::DBRef][BSONType::Bool] = &performConvertToTrue;
        table[BSONType::Code][BSONType::Bool] = &performConvertToTrue;
        table[BSONType::Symbol][BSONType::Bool] = &performConvertToTrue;
        table[BSONType::CodeWScope][BSONType::Bool] = &performConvertToTrue;
        table[BSONType::bsonTimestamp][BSONType::Bool] = &performConvertToTrue;
    }