You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
mysqlnd: Fractional seconds truncated in prepared statements, if value of decimals is AUTO_SEC_PART_DIGITS (=39). #16910
This issue was initially reported for MariaDB Connector/C (which uses part of mysqlnd):
In some cases both MySQL and MariaDB server will send the value 39 (=AUTO_SEC_PART_DIGITS) for datetime and time decimals. The binary protocol implementation however will only set fractional seconds if decimals is <= 6.
Still happens on 8.5.11 and on master (2f7b01b) with MariaDB 13.0.2, for mysqli prepared statements and for PDO with PDO::ATTR_EMULATE_PREPARES => false:
$link->query("SET time_zone = '+00:00'");
$sql = "SELECT FROM_UNIXTIME('1992.1'), FROM_UNIXTIME('1992.0')";
$link->query($sql)->fetch_row(); // "1970-01-01 00:33:12.100000", "1970-01-01 00:33:12"$stmt = $link->prepare($sql); // decimals is 39 for both columns$stmt->execute();
$stmt->get_result()->fetch_row(); // "1970-01-01 00:33:12", "1970-01-01 00:33:12"
ps_fetch_time() and ps_fetch_datetime() only print second_part when decimals is 1 to 6 (the check from bug #76386), so 39 falls through to the format without a fraction.
I'd handle 39 the way MariaDB Connector/C does, six digits when second_part is non-zero and none otherwise, which gives the same strings as the text protocol. The alternative is to treat every value above 6 that way. @9EOR9@bukka does the first sound right? If so I can take over from #16911 and do it against PHP-8.4, with a fake-server test so CI covers it without MariaDB.
@ojuschugh1 Feel free to open a PR and we will review it. If it's a real life behaviour, you should not use fake-server; that's only for testing behaviour that doesn't happen with real servers.
Hi,
text and binary protocol should always return the same values - so this is
a bug in the prepared statement implementation.
Decimals value of 39 is internally defined as NOT_FIXED_DEC (In MySQL it is
31) - it doesn't represent the number of digits but acts as a sentinel. For
temporal types you should use min(decimals,6) if decimal is not zero.
/Georg
Activity
ojuschugh1 commentedon Oct 20, 2026
Still happens on 8.5.11 and on master (2f7b01b) with MariaDB 13.0.2, for mysqli prepared statements and for PDO with
PDO::ATTR_EMULATE_PREPARES => false:ps_fetch_time()andps_fetch_datetime()only printsecond_partwhendecimalsis 1 to 6 (the check from bug #76386), so 39 falls through to the format without a fraction.I'd handle 39 the way MariaDB Connector/C does, six digits when
second_partis non-zero and none otherwise, which gives the same strings as the text protocol. The alternative is to treat every value above 6 that way. @9EOR9 @bukka does the first sound right? If so I can take over from #16911 and do it against PHP-8.4, with a fake-server test so CI covers it without MariaDB.kamil-tekiela commentedon Oct 20, 2026
@ojuschugh1 Feel free to open a PR and we will review it. If it's a real life behaviour, you should not use fake-server; that's only for testing behaviour that doesn't happen with real servers.
9EOR9 commentedon Oct 21, 2026
ojuschugh1 commentedon Oct 21, 2026
Thanks @9EOR9 for the clarification.