microsoft / ODBC-Specification

Microsoft ODBC Specification
Other
121 stars 40 forks source link

Should we fix the time struct to support fractional seconds? #31

Closed mikepizzo closed 6 years ago

jduo commented 7 years ago

There are some challenges to adding a new field to SQL_TIME_STRUCT.

If the application is built using the ODBC 3.x definition of SQL_TIME_STRUCT, but the driver is built against the 4.0 definition of SQL_TIME_STRUCT, the driver cannot safely access the fractional seconds field since the calling application allocates it without the field. The driver would need to internally check if the ODBC version environment attribute is ODBC 4.

Conversely, if the application is built with the ODBC 4 definition, and the driver is built with the ODBC 3 definition, the driver will never write the new fractional seconds field. So the calling application would need to zero it out before sending it to the driver (the DM could as well, but it'd be unusual for the DM to inspect incoming data).

mikepizzo commented 7 years ago

Applications know the driver version and drivers know the application version. A 3.x application will never set, nor read from, the fractional seconds of the struct. So we could possibly add the fractional seconds and say that: 1) A 4.x driver must never set fractional seconds against a 3.x application. 2) A 4.x driver must never read fractional seconds from a 3.x application. 3) A 4.x application must never set fractional seconds against a 3.x driver. 4) A 4.x application must never read fractional seconds from a 3.x application.

Alternatively (and safer) would be to define a new SQL_TIME2_STRUCT (pick a better name) and corresponding C type that has fractional seconds. 4.x drivers would return the new C type for 4.x applications, and applications could use the new C type to bind to the new structure, and use of the old C type would continue to use the old structure.

mikepizzo commented 7 years ago

Proposal: define a new SQL_TIME_WITH_FRACTIONAL_SECONDS_STRUCT SQL_C_TYPE type that has fractional seconds. 4.x drivers must support binding to either the SQL_TIME_STRUCT (without fractional seconds) or SQL_TIME_WITH_FRACTIONAL_SECONDS_STRUCT (with fractional seconds).

If the application specifies SQL_DEFAULT, then the driver must assume SQL_TIME_STRUCT and not include fractional seconds.

mikepizzo commented 6 years ago

Note: 4.x applications should never use SQL_TIME_WITH_FRACTIONAL_SECONDS_STRUCT SQL_C_TYPE against a 3.x driver.

Discussed trying to have the DM map SQL_TIME_WITH_FRACTIONAL_SECONDS_STRUCT to SQL_C_TIME, but the DM would basically have to bind to its own buffers and copy, and fill the missing fractional seconds with zeros (which is likely wrong, and would lose data precision when round-tripping).

mikepizzo commented 6 years ago

We could have DM should throw an error if 4.x application specifies SQL_TIME_WITH_FRACTIONAL_SECONDS_STRUCT against a 3.x driver, but that would prevent a 3.x driver from only supporting a binding that supports fractional seconds, but the application would have no interoperable way to know that the driver supported that C type.

mikepizzo commented 6 years ago

Should also support SQL_TIME_WITH_TIMEZONE_WITH_FRACTIONAL_SECONDS_STRUCT for time with timezone.

Should we have SQL_C_DEFAULT default to "with fractional seconds" for 4.x client applications?