Numerical values

The driver provides support for all the CQL numerical datatypes, such as int, float, double, bigint, varint, and decimal. There is only one numerical datatype in ECMAScript standard, Number which represent a double-precision 64-bit value. It is used by the driver to handle double, float, int, smallint and tinyint values.

int, float, and double

JavaScript provides methods to operate with Numbers (that is, IEEE 754 double-precision floats) and built-in operators (sum, subtraction, division, bitwise, etc), making it a good fit for CQL datatypes int, float. and double.

When decoding any of these datatype values, it is returned as a Number.

client.execute('SELECT int_val, float_val, double_val FROM tbl')
  .then(function (result) {
    console.log(typeof result.rows[0]['int_val']);    // Number
    console.log(typeof result.rows[0]['float_val']);  // Number
    console.log(typeof result.rows[0]['double_val']); // Number
  });

When encoding the data, the driver tries to encode a Number as double because it can not automatically determine if is dealing with an int, a float, or a double.

Inserting a Number value as a double succeeds:

const query = 'INSERT INTO tbl (id, double_val) VALUES (?, ?)';
client.execute(query, [ id, 1.2 ]);

But doing the same with a float fails:

const query = 'INSERT INTO tbl (id, float_val) VALUES (?, ?)';
client.execute(query, [ id, 1.2 ])
  .catch(function (err) {
    console.log(err) // ResponseError: Expected 4 or 0 byte value for a float (8)
  });

Trying to do the same with an int, also fails because Cassandra expects a float or an int, and the driver sent a 64-bit double.

const query = 'INSERT INTO tbl (id, int_val) VALUES (?, ?)';
client.execute(query, [ id, 1 ])
  .catch(function (err) {
    console.log(err) // ResponseError: Expected 4 or 0 byte int (8)
  });

To overcome this limitation, you should prepare your queries. Because preparing and executing statements in the driver does not require chaining two asynchronous calls, you can set the prepare flag in the query options and the driver handles the rest.

The previous query, using the prepare flag, succeeds no matter if it is an int, float, or double:

const query = 'INSERT INTO tbl (id, int_val) VALUES (?, ?)';
client.execute(query, [ id, 1 ], { prepare: true });

decimal

The BigDecimal class provides support for representing the CQL decimal datatype, because JavaScript has no built-in arbitrary precision decimal representation.

const BigDecimal = require('cassandra-driver').types.BigDecimal;
const value1 = new BigDecimal(153, 2);
const value2 = BigDecimal.fromString('1.53');
console.log(value1.toString());     // 1.53
console.log(value2.toString());     // 1.53
console.log(value1.equals(value2)); // true

The driver decodes CQL decimal datatype values as instances of BigDecimal.

client.execute('SELECT decimal_val FROM users')
  .then(function (result) {
    console.log(result.rows[0]['decimal_val'] instanceof BigDecimal); // true
  });

bigint

The Long class provides support for representing the CQL bigint datatype, because JavaScript has no built-in 64-bit integer representation.

const Long = require('cassandra-driver').types.Long;
const value1 = Long.fromNumber(101);
const value2 = Long.fromString('101');
console.log(value1.toString());             // 101
console.log(value2.toString());             // 101
console.log(value1.equals(value2));         // true
console.log(value1.add(value2).toString()); // 202

The driver decodes CQL bigint datatype values as instances of Long.

client.execute('SELECT bigint_val FROM users')
  .then(function (result) {
    console.log(result.rows[0]['bigint_val'] instanceof Long); // true
  });

varint

The Integer class, originally part of the Google Closure math library, provides support for representing CQL varint datatype values, because JavaScript has no arbitrarily-large signed integer representation.

const Integer = require('cassandra-driver').types.Integer;
const value1 = Integer.fromNumber(404);
const value2 = Integer.fromString(404);
console.log(value1.toString());             // 404
console.log(value2.toString());             // 404
console.log(value1.equals(value2));         // true
console.log(value1.add(value2).toString()); // 808

The driver decodes CQL varint datatype values as instances of Integer.

client.execute('SELECT varint_val FROM users')
  .then(function (result) {
    console.log(result.rows[0]['varint_val'] instanceof Integer); // true
  });

smallint and tinyint

Cassandra 2.2 introduced smallint for 2-byte numerical representation and tinyint for 1-byte numerical representation.

The driver represents these types as Number to take advantage of the ECMAScript built-in operations for Number (sum, subtraction, division, bitwise, etc).

For tinyint, only Numbers between -128 and 127 are valid, and for smallint only Numbers between -32768 and 32767. Numbers outside valid ranges will callback with TypeError when executing.

ECMAScript BigInt support

On modern JavaScript engines with BigInt support (e.g., Node.js 10+), you can use ECMAScript BigInt to represent varint and/or bigint CQL data types with the Node.js driver.

To enable this option, you must specify it in the client options:

const client = new Client({
  contactPoints,
  localDataCenter,
  encoding: { 
      useBigIntAsLong: true,
      useBigIntAsVarint: true
  }
});

You can use BigInt to represent varint or bigint CQL data types or both.

client.execute('SELECT varint_value FROM table')
  .then(rs => console.log(typeof rs.rows[0]['varint_value'])); // "bigint"