php / php/php-src

mysqlnd: Fractional seconds truncated in prepared statements, if value of decimals is AUTO_SEC_PART_DIGITS (=39).

Open
#16,910 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Bug Extension: mysqlnd
Dominant language
C
Stars
40.4k
Forks
8.1k
Avg merge
2d 13h
Merged PRs (30d)
96

Description

Description

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.

The following code:

<?php

$link= mysqli_connect("localhost", "georg", null, "test", 0, "/tmp/mysql.sock");

$stmt = $link->prepare("select FROM_UNIXTIME('1992.1'), FROM_UNIXTIME('1992.0')");
$stmt->execute();
$stmt->bind_result($binval[0],$binval[1]);
$stmt->fetch();
$stmt->close();

$result = $link->query("select FROM_UNIXTIME('1992.1'), FROM_UNIXTIME('1992.0')");
$txtval = $result->fetch_row();
$result->close();
$err_cnt= 0;

for ($i=0; $i < 2; $i++)
    if ($txtval[$i] != $binval[$i])
        printf("[%03d] Expected '%s' (text protocol), got '%s' (binary protocol)\n",
               $err_cnt++, $txtval[$i], $binval[$i]);

printf("Done!\n");
?>

Resulted in this output:

[000] Expected '1970-01-01 01:33:12.100000' (text protocol), got '1970-01-01 01:33:12' (binary protocol)
Done!

But I expected this output instead:

Done!

Metadata sent by server:

$> mariadb --column-type-info -e"select from_unixtime('1922.1')"
Field   1:  `from_unixtime('1922.1')`
Org_field:  ``
Catalog:    `def`
Database:   ``
Table:      ``
Org_table:  ``
Type:       DATETIME
Collation:  binary (63)
Length:     26
Max_length: 26
Decimals:   39
Flags:      BINARY 

PHP Version

PHP 8.4.0-dev

Operating System

No response

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with mysqlnd's binary-protocol handling for DATETIME and TIME metadata, using the provided mysqli prepared-statement reproduction and its text-protocol comparison. Check the case where the server reports decimals as 39 (AUTO_SEC_PART_DIGITS), then add or update regression coverage so fractional seconds are retained and the comparison prints “Done!”. از

Written by the indexing model from the issue text.

Assessment

Tech stack
c, mysql, php
Domain
databases
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.