Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sql: refactor dates to be fully PG compatible #36938

Merged
merged 2 commits into from
May 2, 2019
Merged

sql: refactor dates to be fully PG compatible #36938

merged 2 commits into from
May 2, 2019

Commits on May 2, 2019

  1. sql: refactor dates to be fully PG compatible

    Previously dates were an int64 number of days from 1970-01-01. Functions
    and operators needing to act on a date could manipulate the value of
    the date without any overflow checks, causing multiple bugs:
    
    - The postgres binary wire protocol uses an int32 number of days since
    2000-01-01, thus it was possible to have dates in cockroach outside
    of the expressible range over the wire. We were blindly converting the
    int64 to an int32, possibly discarding data.
    - Adding dates to ints was done by normal addition. However this could
    overflow. Our normal int + int path uses overflow-checked addition,
    but dates were not subject to such checks.
    - Converting dates to a text representation (for sending over pgwire or
    our distsql serialization) converted the number of days to a time.Time
    using the standard library time.Date method, which (more-or-less) stores
    time as an int64 number of nanos. A very high year could overflow the
    nanosecond part causing it to silently by incorrect.
    - The infinity dates were not treated as infinity, but converted to an
    actual date.
    
    This change adds a new pgdate.Date type. It internally represented as
    an int32 number of days since 2000-01-01, because that's exactly what
    is needed by the postgres wire protocol. It doesn't export any internal
    properties, and instead forces users of it to use its API, which is
    guaranteed to be safe. The API does all overflow and bounds checking,
    and correctly handles the infinity dates. This fixes the above bugs
    since it's now not possible to mistakenly misuse Dates.
    
    When reading from any existing on-disk data, dates outside of the postgres
    bounds are converted to +/- infinity. This presents a problem since
    datums need to roundtrip to the same on-disk encoding so that old index
    entries can be deleted. In order to round trip correctly, the original
    on-disk integer is saved and used during serialization if it exists.
    
    Fixes #36557
    
    Release note (sql change): Dates are now fully Postgres-compatible,
    including support for sentinel values (+/- infinity) and the Postgres
    date range (4714-11-24 BC to 5874897-12-31). Existing dates outside of
    this range will be converted to the +/- infinity dates.
    maddyblue committed May 2, 2019
    Configuration menu
    Copy the full SHA
    3dfd6cb View commit details
    Browse the repository at this point in the history
  2. sql/sem/tree: use arith package for sub overflow checking

    This puts all the overflow logic into a single package.
    maddyblue committed May 2, 2019
    Configuration menu
    Copy the full SHA
    7a0b7b6 View commit details
    Browse the repository at this point in the history