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

    • Type: Icon: Bug Bug
    • Resolution: Unresolved
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: None
    • Component/s: None
    • Labels:
      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.

      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.

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

              Created:
              Updated: