Project: userver (App Definition and Development / Streaming & Messaging)
File: supported_types.md

The uMySQL driver supports various `std::` types for both input and output directions and some userver-specific types. <br> The driver also supports aggregates of supported types as input or output parameters:<br> whenever there is a row-wise mapping to/from `T`, `T` is expected to be an SimpleAggregate, that is an aggregate type without base classes, const fields, references, or C arrays. The following table shows how types are mapped from C++ to MySQL types. | Input C++ types | Corresponding MySQLType | |-|-| | `std::uint8t`/`std::int8t` | `TINYINT` | | `std::uint16t`/`std::int16t` | `SMALLINT` | | `std::uint32t`/`std::int32t` | `INT` | | `std::uint64t`/`std::int64t` | `BIGINT` | | `float` | `FLOAT` | | `double` | `DOUBLE` | | `std::string` | `TEXT` | | `std::string_view` | `TEXT` | | `const char *` | `TEXT` | | `std::chrono::system_clock::timepoint` | `TIMESTAMP` | | storages::mysql::Date | `DATE` | | storages::mysql::DateTime | `DATETIME` | | formats::json::Value | `TEXT` | | decimal64::Decimal<Prec, Policy> | `DECIMAL` | The driver also supports std::optional<T> for every supported type, and that maps to either NULL or exactly as T does, depending on whether is optional engaged or not. Mapping MySQL types to C++ types is a more complicated matter: First, the driver forbids mapping signed to unsigned or vice versa - an attempt to do so will abort in debug build and throw in release (this behavior is referred as UINVARIANT later), this check happens before actual extraction. <br> Second, the driver forbids mapping NULLABLE column into non-optional C++ type, an attempt to do so will UINVARIANT, this check happens before actual

However, other combinations of optional/non-optional<->NULL/NOT NULL are supported: | Is column NULLABLE | Is type optional | behavior | |--||--| | `true` | `true` | allowed | | `true` | `false` | `UINVARIANT` | | `false` | `true` | allowed | | `false` | `false` | allowed | Third, an attempt to parse `DECIMAL` will throw at extraction stage if precision/rounding policy of corresponding `decimal::Decimal64<Prec, Policy>` is violated. Fourth, an attempt to parse `DATE` or `DATETIME` not within `TIMEPOINT` range into `std::chrono::system_clock::timepoint` will throw at extraction stage. The decision was made to allow this conversion, since it might be very convenient to use, but in general this conversion is narrowing. Fifth, general type mismatch will `UINVARIANT`, however widening numeric conversions are allowed, this check happens before actual extraction. You can see to what C++ types MySQL types can map in the following table: | Output C++ type | Allowed MySQL types | |-|| | `std::uint8_t` | `TINYINT UNSIGNED NOT NULL` | | `std::int8_t` | `TINYINT NOT NULL` | | `std::optional<std::uint8_t>` | `TINYINT UNSIGNED NOT NULL`, `TINYINT UNSIGNED` | | `std::optional<std::int8_t>` | `TINYINT NOT NULL`, `TINYINT` | | `std::uint16t`/`std::int16t`/`optional` | `SMALLINT` + all types above, with respect to signed/unsigned and NULL/NOT NULL | | `std::uint32t`/`std::int32t`/`optional` | `INT`, `INT24` + all types above, with respect to signed/unsigned and NULL/NOT NULL | | `std::uint64t`/`std::int64t`/`optional` | `BIGINT` + all types above, with respect to signed/unsigned and NULL/NOT NULL | | `float` | `FLOAT NOT NULL` | | `std::optional<float>` | `FLOAT NOT NULL`, `FLOAT` | | `double` | `DOUBLE NOT NULL`, `FLOAT NOT NULL` | | `std::optional<double>` | `DOUBLE`, `DOUBLE NOT NULL`, `FLOAT`, `FLOAT NOT NULL` | | `std::string/optional` | `CHAR`, `BINARY`, `VARCHAR`, `VARBINARY`, `TINYBLOB`, `TINYTEXT`, `BLOB`, `TEXT`, `MEDIUMBLOB`, `MEDIUMTEXT`, `LONGBLOB`, `LONGTEXT`, with respect to NULL/NOT NULL | | `std::chrono::system_clock::timepoint/optional` | `TIMEPOINT`, `DATETIME`, `DATE`, with respect to NULL/NOT NULL | | storages::mysql::Date + optional | `DATE`, with respect to NULL/NOT NULL | | storages::mysql::DateTime +optional | `DATETIME`, with respect to NULL/NOT NULL | | formats::json::Value + optional | `JSON`, with respect to NULL/NOT NULL | | decimal64::Decimal<Prec, Policy> + optional | `DECIMAL`, with respect to NULL/NOT NULL | @htmlonly <div class="bottom-nav"> @endhtmlonly @ref scripts/docs/en/userver/mysql/mysqldriver.md | @ref scripts/docs/en/userver/mysql/designand_details.md @htmlonly </div> @endhtmlonly