Skip to content

PostgreSQL compatibility: extract(second ...) should preserve fractional seconds #22266

Open

Description

@Dandandan

Split out from #22247.

Mismatch

extract(second ...) should preserve fractional seconds.

SELECT extract(second from timestamp '2020-01-01 00:00:12.345678');

PostgreSQL:

12.345678

DataFusion:

12

Expected behavior

For PostgreSQL-compatible SQL semantics, DataFusion should either match PostgreSQL's result or raise the same class of domain/semantic error.

Activity

  1. aguilaredu commented on May 16, 2026

    @aguilaredu
    Contributor

    take

  2. kumarUjjawal commented on May 18, 2026

    @kumarUjjawal
    Contributor

    duckdb

    memory D   SELECT extract(second FROM TIMESTAMP '2020-01-01 00:00:12.345678');
    ┌───────────────────────────────────────────────────────────────────────────┐
    │ main.date_part('second', CAST('2020-01-01 00:00:12.345678' AS TIMESTAMP)) │
    │                                   int64                                   │
    ├───────────────────────────────────────────────────────────────────────────┤
    │                                                                        12 │
    
    

    DuckDB's date-part design returns integers across all sub-day fields.

  3. aguilaredu commented on May 18, 2026

    @aguilaredu
    Contributor

    The date_part function previously returned float64. It was changed to follow ANSI SQL convention and also as a broader effort to improve ClickBench performance. See #13482 and #13449.

    Additionally, this other issue could also be solved if the microsecond calculations were made with f64: #14738. However, it was concluded that the fix should be made in arrow-rs.

    I am still working on the change, but wanted to bring it up for discussion.

    cc @Dandandan @kumarUjjawal @alamb

  4. kumarUjjawal commented on May 18, 2026

    @kumarUjjawal
    Contributor

    Duckdb behaviour: except for julian and epoch, which return DOUBLEs, all parts are extracted as integers. Fractional precision is intentionally exposed through separate parts (millisecond, microsecond) rather than as the fractional component of second.

  5. alamb commented on May 18, 2026

    @alamb
    Contributor

    I don't know about this particular issue, but I think we should be careful with changing semantics just to conform more closely to some particular implementation

    I tried in the past to get consensus on what semantics to follow but we did not reach it:

  6. kumarUjjawal commented on May 19, 2026

    @kumarUjjawal
    Contributor

    IMO we should stick to the current behavior unless someone has a use case where they would benefit from semantics change like this.

  7. neilconway commented on May 22, 2026

    @neilconway
    Contributor

    My two cents, on the topic of Postgres compatibility / SQL dialect in general:

    • I think the SQL standard is a good place to start. In most situations, that is what Postgres follows, usually unless there is a good reason to deviate.
    • I think that's a reasonable rule of thumb for us as well: follow the SQL spec and/or Postgres in most circumstances / as a reasonable default, but if there is a good reason to deviate, that can be justified.

    As far as when to preserve existing behavior, I think DataFusion's current behavior in a lot of corner cases is either unintentional or actively buggy (#14612, #14272, #15161 are a few examples that come to mind in just type coercion!). SQL is a large and complex language and DF's implementation is relatively new -- there will (hopefully!) be many more new users in DataFusion in the coming years than there are today :) So while I think we should be aware of SQL backward compatibility and try to ease migration pain as much as we can (e.g., clear release notes / upgrade guidance, config flags when necessary), I do think evolving the SQL dialect to be more consistent and standards-conformant is a good thing.

  8. alamb commented on May 22, 2026

    @alamb
    Contributor

    I think the SQL standard is a good place to start. In most situations, that is what Postgres follows, usually unless there is a good reason to deviate.

    I know people love to bandy around the term "SQL Standard" (and I have a copy of "Information technology — Database languages —SQL — Part 2: Foundation (SQL/Foundation)" !) but it is a pretty bad example of a spec in my opinion and leaves a lot of things "implementations defined"

    For example here is an excerpt about extract

    1. If is specified, then
      Case:
      a) If is a that does not specify SECOND or is
      not a , then the declared type of the result is an implementation-defined exact
      numeric type with scale 0 (zero).
      b) Otherwise, the declared type of the result is an implementation-defined exact numeric type with scale
      not less than the specified or implied or , as appropriate, of the SECOND of the .
  9. neilconway commented on May 22, 2026

    @neilconway
    Contributor

    it is a pretty bad example of a spec in my opinion and leaves a lot of things "implementations defined"

    No argument from me that the SQL spec isn't perfect 😊 I do think it's often a good data point to consider, along with Postgres (which usually does a pretty decent job of trying to follow the spec).

  10. alamb commented on May 25, 2026

    @alamb
    Contributor

    it is a pretty bad example of a spec in my opinion and leaves a lot of things "implementations defined"

    No argument from me that the SQL spec isn't perfect 😊 I do think it's often a good data point to consider, along with Postgres (which usually does a pretty decent job of trying to follow the spec).

    I just harbor suspicions that vendors claiming "we follow the ANSI SQL spec" is often somwaht specious -- because there is so much wiggle room allowed the actual spec.

    But anyhow that is just my own bias

  11. aguilaredu commented on May 28, 2026

    @aguilaredu
    Contributor

    My two cents based on the discussion:

    • Following an established vendor like PostgreSQL feels like a sane default, especially if the project doesn't have the bandwidth to interpret the SQL standard from scratch.
    • Picking a direction is better than being stuck in limbo (which causes reworks, like this one). Mirroring a battle tested DB seems like a pretty safe bet (even if sub optimal).
    • Using them as a baseline shouldn't limit DataFusion. We can match their behavior where they have it, but we can take liberties with features they don't support.
    • Deviating from the reference is fine as long as there’s a good reason for it and we document it centrally.

    This at least gives the project a framework to have discussions on smaller features (like this one).

    P.S. This is my very first contribution to the project, so I might be missing some historical context! That said, I've got a PR up implementing this and would absolutely love some feedback: #22504

  12. kumarUjjawal commented on May 28, 2026

    @kumarUjjawal
    Contributor

    I think the best source to follow is not a vendor or a spec but rather use cases and the people who use and integrate datafusion extensively in production. They will have more ideas about what problems they face and what is the best case for them. Once we have a known issue with any semantics I think people are quick to figure out a solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't workinggood first issueGood for newcomers

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions