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

Adding NUMERIC and DECIMAL types #162

Closed
wants to merge 2 commits into from
Closed

Conversation

elliotchance
Copy link
Owner

SQL Standard E011-03

@elliotchance elliotchance marked this pull request as draft October 17, 2023 04:33
@elliotchance elliotchance force-pushed the numeric-decimal branch 4 times, most recently from 8742dfb to e29e8df Compare October 24, 2023 05:09
This turned out to be a much more involved change that I expected. It
started by adding syntax support for scientific notation (i.e. 32e5) but
ended up overhauling how numbers work in vsql, and solving some major
current and future problems.

All literals in scientific notation are considered `DOUBLE PRECISION`,
that part is pretty straightforward. Furthermore, all approximate
numbers are always formatted in scientific notation, even if smaller
numbers are given a "e0" suffix.

Since this means that exact and approximate numbers now have a different
form we can take a lot of hacky and unreliable guess work out of
literals and implicit casting.

`REAL` and `DOUBLE PRECISION` no longer need to be treated as supertypes
for all other exact types. Which in retrospect makes no sense. The docs
make much more sense on how numbers work and this makes the larger
change of DECIMAL and NUMERIC types coming later much easier to explain
and implement.
`NUMERIC` and `DECIMAL` types are used for arbitrary precision exact
numbers. This has a been long in development. It's required several
rewrites and some major changes and improvements to vsql in previous
versions to lay the foundation for these types to be fully integrated as
first class citizens.

Now, number literals that contains a '.' (even if they are a whole
numbers such as `123.`) are treated as `NUMERIC` with the scale and
precision determined from the number. Arithmetic operations can result
in types that are higher in scale and precision, according to the
standard (which is very specific about all of that).

As far as I'm aware vsql is the only SQL database to treat these as
distinct types according to the standard, rather than being aliases of
the same underlying type. In a nutshell, `NUMERIC` and `DECIMAL` are
both stored as fractions, but `NUMERIC` permits any denominator within
range, whereas a `DECIMAL` must have a base 10 denominator. You can
think of `DECIMAL` as having "exactly" the precision specified (i.e good
for currency), but `NUMERIC` has "at least" the precision specified.
Meaning it's possible to `CAST` a `NUMERIC` to a higher precision and
get more decimal places (from the inherent nature of a fraction). The
docs explain this much better, with examples.

Since this does introduce new storage types, a database file version
bump is required but this likely be the last version bump before v1.0.0
is released.

Along with the two new SQL types, there are some functions that work
directly with exact numbers: `ABS`, `CEIL`, `FLOOR` and `MOD`.

SQL Standard E011-03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant