INT64 as a number, for the program that asked for it - #6
Merged
Merged
Conversation
`bigIntMode` says how INT64 is spelled on the way out, on a statement or on a connection, and a statement on a connection that named one may name the other. The default does not move: it is `bigint`, everywhere, because zu's integers go to 2^63 and a JavaScript number stops telling one integer from the next at 2^53. An integer past that is refused rather than rounded. The refusal is a ZuUsageError naming the column and the value, so a program that guessed wrong about its own data gets a failure it can act on instead of an answer that is quietly off by one. That is the whole hazard, stated in the types, in the README and in the doc comment: which integers a database holds is a property of the data and not of the program, so the failure arrives at read time on somebody else's machine. The mode reaches the INT64 columns of a result and nothing else. A node's offset, an edge's src, dst and ord, and the nanosecond counts on the temporal classes stay `bigint`, since they are properties of classes the addon registers once rather than values a statement can respell. Ten tests, covering both places the mode is named, the override in either direction, the edge of the exact range, the refusal inside a list and inside a record, a stream that spells its rows the same way, and a mode nobody can spell, which is refused at connect time before a database is created. On 50k rows one INT64 column costs about 190ns a row as numbers against about 220ns as bigints.
33 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
bigIntModesays how INT64 is spelled on the way out. It goes on a statement, or on a connection for all of its statements, and a statement on a connection that named one may still name the other, which is the direction that matters: the one query that counts something large should not need a connection of its own.The default does not move. It is
biginteverywhere, because zu's integers go to 2^63 and a JavaScript number stops telling one integer from the next at 2^53, and a client that returns a number there is a client whose users file "the id came back wrong" a year later.Two things are usually behind the ask.
JSON.stringifythrows on abigint, so a row holding one cannot be handed straight to a response, and arithmetic on abigintwill not mix with anumber, so every+in the reporting code needs a conversion first. Numbers are also a little cheaper to make, since a double is not an allocation: on 50k rows here one INT64 column costs about 190ns a row as numbers against about 220ns as bigints.What is traded for that is the reason this is never the default, and it is written down in the type, in the README and in the doc comment rather than left for somebody to find. Which integers a database holds is a property of the data and not of the program, so a query that returned numbers for every row of a test database is a query that can meet a larger one in production. This client refuses that row rather than rounding it: an integer past 2^53 raises a
ZuUsageErrornaming the column and the value, which turns a wrong answer into a failure that says exactly which column to widen. It is still a failure that arrives at read time on a machine that is not yours, and that is the honest description of the mode.The mode reaches the INT64 columns of a result and nothing else. A node's
offset, an edge'ssrc,dstandord, and the nanosecond counts on the temporal classes staybigintin both modes, because they are properties of classes the addon registers once rather than values a statement can respell. That is a documented edge and there is a test that pins it.Inside, the table names a result carries and the spelling of its integers are now one
Shape, settled once where the connection is held and read by every value of every row, so the streamed path and the whole-result path get the mode from the same place. A mode nobody can spell is read before the database is opened, so a typo in the connect options does not leave a database behind that nobody asked for, and there is a test for that too.Ten new tests, seventy-nine in the suite,
tscandattwclean on all four resolutions, and the install round trip runs a statement out of the packed tarballs in both formats.Milestone DX3, tamnd/zu#169.