Uploaded image for project: 'Core Server'
  1. Core Server
  2. SERVER-67528

Struct field in IDL cannot have a type of a variant that contains a long

    XMLWordPrintableJSON

Details

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: Major - P3 Major - P3
    • None
    • None
    • None
    • None
    • Service Arch
    • ALL
    • Hide

      Create an IDL struct with a field that has a variant containing a long:

      structs:    
          SampleStruct:
              strict: true
              fields:
                  f:
                      unstable: true
                      type:
                          variant: [int, long]

      The field in the generated IDL struct has this type:

      stdx::variant<std::int32_t, std::int64_t> _f; 

      And will throw this error from within the generated parseProtected() function:

      error: no viable overloaded '='
                      _min = element._numberLong();
                      ~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~
      src/third_party/variant-1.4.0/include/mpark/variant.hpp:1643:14: note: candidate function not viable: no known conversion from 'long long' to 'const mpark::variant<int, long>' for 1st argument
          variant &operator=(const variant &) = default;
                   ^
      src/third_party/variant-1.4.0/include/mpark/variant.hpp:1644:14: note: candidate function not viable: no known conversion from 'long long' to 'mpark::variant<int, long>' for 1st argument
          variant &operator=(variant &&) = default;
                   ^
      src/third_party/variant-1.4.0/include/mpark/variant.hpp:1654:21: note: candidate template ignored: substitution failure [with Arg = long long, $1 = 0]: no type named 'type' in 'mpark::lib::cpp17::detail::invoke_result<void, mpark::detail::overload_impl<int, long>::impl<std::integer_sequence<unsigned long, 0, 1> >, long long &&>'
          inline variant &operator=(Arg &&arg) noexcept(
                          ^
      1 error generated. 

      Show
      Create an IDL struct with a field that has a variant containing a long: structs:    SampleStruct: strict: true         fields:             f:                 unstable: true                 type:                     variant: [ int , long ] The field in the generated IDL struct has this type: stdx::variant<std::int32_t, std::int64_t> _f; And will throw this error from within the generated parseProtected() function: error: no viable overloaded '='                 _min = element._numberLong();                 ~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~ src/third_party/variant- 1.4 . 0 /include/mpark/variant.hpp: 1643 : 14 : note: candidate function not viable: no known conversion from 'long long' to 'const mpark::variant<int, long>' for 1st argument     variant &operator=( const variant &) = default ;              ^ src/third_party/variant- 1.4 . 0 /include/mpark/variant.hpp: 1644 : 14 : note: candidate function not viable: no known conversion from 'long long' to 'mpark::variant<int, long>' for 1st argument     variant &operator=(variant &&) = default ;              ^ src/third_party/variant- 1.4 . 0 /include/mpark/variant.hpp: 1654 : 21 : note: candidate template ignored: substitution failure [with Arg = long long , $ 1 = 0 ]: no type named 'type' in 'mpark::lib::cpp17::detail::invoke_result<void, mpark::detail::overload_impl<int, long>::impl<std::integer_sequence<unsigned long, 0, 1> >, long long &&>'     inline variant &operator=(Arg &&arg) noexcept(                     ^ 1 error generated.

    Description

      It seems like there’s a mismatch between the type that the IDL uses to support longs (int64_t) and the type that the BSON library uses internally (long long) that shows up when trying to add long as a component with a variant.

      I think this is due to a known mismatch in our codebase between long long used in the BSON library and int64_t used outside of it. My guess is that it’s not able to do an implicit cast through the variant implicit constructor.

      A possible solution is to add an explicit cast from long long to int64_t when generating the parsing code for variant types, so that the line in the generated file reads:

      _min = (int64_t) element._numberLong(); 

      long long is defined as being at least 64 bits, and considering it's representing NumberLong BSONType here which is defined as being a 64-bit integer, I believe it is safe to cast the output of element._numberLong() to int64_t.

      AC: Investigate whether this modification exposes any unexpected behavior on esoteric architectures, and also do some thinking of whether this change is a good idea at all. Themes include investigating the interaction between BSON and the IDL library, and potential upgrade/downgrade concerns. We could follow up with Storage Execution, who owns BSON more generally.

      Attachments

        Activity

          People

            backlog-server-servicearch Backlog - Service Architecture
            davis.haupt@mongodb.com Davis Haupt (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

              Created:
              Updated: