Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/buffer/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -251,9 +251,9 @@ abstract class SenderBufferBase implements SenderBuffer {
* @return {SenderBuffer} Returns with a reference to this buffer.
* @throws Error if the value is not an integer
*/
intColumn(name: string, value: number): SenderBuffer {
if (!Number.isInteger(value)) {
throw new Error(`Value must be an integer, received ${value}`);
intColumn(name: string, value: number | bigint): SenderBuffer {
if (typeof value !== "bigint" && !Number.isInteger(value)) {
throw new Error(`Value must be an integer or BigInt, received ${value}`);
}
this.writeColumn(name, value, () => {
const valueStr = value.toString();
Expand Down
7 changes: 4 additions & 3 deletions src/buffer/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,11 +137,12 @@ interface SenderBuffer {
* Writes a 64-bit signed integer into the buffer.
* Use it to insert into LONG, INT, SHORT and BYTE columns.
* @param name - Column name.
* @param value - Column value, accepts only number values.
* @param value - Column value, accepts integer or `BigInt` values. Use a
* `BigInt` for LONG values outside the safe integer range of `number`.
* @returns Returns with a reference to this buffer.
* @throws Error if the value is not an integer
* @throws Error if the value is not an integer or a `BigInt`
*/
intColumn(name: string, value: number): SenderBuffer;
intColumn(name: string, value: number | bigint): SenderBuffer;

/**
* Writes a timestamp column and its value into the buffer.
Expand Down
9 changes: 6 additions & 3 deletions src/sender.ts
Original file line number Diff line number Diff line change
Expand Up @@ -299,11 +299,14 @@ class Sender {
* Use it to insert into LONG, INT, SHORT and BYTE columns.
*
* @param {string} name - Column name.
* @param {number} value - Column value, accepts only number values.
* @param {number | bigint} value - Column value, accepts integer or `BigInt`
* values. QuestDB's LONG is a 64-bit signed integer, which is wider than the
* safe integer range of `number`, so use a `BigInt` beyond
* `Number.MAX_SAFE_INTEGER` to avoid losing precision.
* @return {Sender} Returns with a reference to this sender.
* @throws Error if the value is not an integer
* @throws Error if the value is not an integer or a `BigInt`
*/
intColumn(name: string, value: number): Sender {
intColumn(name: string, value: number | bigint): Sender {
this.buffer.intColumn(name, value);
return this;
}
Expand Down
39 changes: 38 additions & 1 deletion test/sender.buffer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -986,7 +986,44 @@ describe("Sender message builder test suite (anything not covered in client inte
});
expect(() =>
sender.table("tableName").intColumn("intField", 123.222),
).toThrow("Value must be an integer, received 123.222");
).toThrow("Value must be an integer or BigInt, received 123.222");
await sender.close();
});

it("supports BigInt values in integer fields", async function () {
const sender = new Sender({
protocol: "tcp",
protocol_version: "1",
host: "host",
init_buf_size: 1024,
});
await sender
.table("tableName")
.intColumn("small", 42n)
.intColumn("negative", -42n)
.at(1658484769000000, "us");
expect(bufferContent(sender)).toBe(
"tableName small=42i,negative=-42i 1658484769000000000\n",
);
await sender.close();
});

it("keeps full LONG precision above Number.MAX_SAFE_INTEGER", async function () {
const sender = new Sender({
protocol: "tcp",
protocol_version: "1",
host: "host",
init_buf_size: 1024,
});
// 2^63-1, the largest QuestDB LONG. As a `number` this rounds to
// 9223372036854775808, which is out of range for the column.
await sender
.table("tableName")
.intColumn("maxLong", 9223372036854775807n)
.at(1658484769000000, "us");
expect(bufferContent(sender)).toBe(
"tableName maxLong=9223372036854775807i 1658484769000000000\n",
);
await sender.close();
});

Expand Down