Skip to content
KeystoneJS LogoKeystoneJS
👋🏻 Keystone 5 has officially moved to maintenance only. For the latest release of Keystone please visit the Keystone website.

Decimal

Decimal fields store exact numeric values. They're safe for base-10 fractional value like currency.

There are some differences in underlying implementation, depending on your DB adapter. See the Storage section for specifics.

Usage

JS
const { DateTime, Decimal, Text } = require('@keystonejs/fields');

keystone.createList('Payment', {
  fields: {
    timestamp: { type: DateTime },
    description: { type: Text },
    amount: { type: Decimal },
  },
});

Config

OptionTypeDefaultDescription
isRequiredBooleanfalseDoes this field require a value?
isUniqueBooleanfalseAdds a unique index that allows only unique values to be stored
knexOptionsObject{}Optional; see the Knex Adapter section for details

GraphQL

Since Decimal values can't be represented in JavaScript (or JSON) they are transmitted using the String type.

Input fields

Field nameTypeDescription
${path}StringThe value to be stored

Output fields

Field nameTypeDescription
${path}StringThe value stored

Filters

Despite being specified as strings, all comparisons are performed on numerical equivalence. In essence, this means leading and trailing zeros are ignored. Eg. 04.53000 === 4.53.

Field nameTypeDescription
${path}StringEquivalent to the value provided
${path}_notStringNot equivalent to the value provided
${path}_in[String]In the array provided
${path}_not_in[String]Not in the array provided
${path}_ltStringLess than the value provided
${path}_lteStringLess than or equivalent to the value provided
${path}_gtStringGreater than the value provided
${path}_gteStringGreater than or equivalent to the value provided

Storage

Although their intent is the same, the core DB adapters use different underlying implementations of this type.

Mongoose adapter

Values are stored using the Mongoose Decimal128 SchemaType which in turn uses the underlying Decimal128 BSON type.

The Decimal128 standard is..

a decimal floating-point computer numbering format that occupies 16 bytes (128 bits) in computer memory. It is intended for applications where it is necessary to emulate decimal rounding exactly, such as financial and tax computations.

-- decimal128 floating-point format on Wikipedia

Knex adapter

The Knex adapter uses the decimal schema type which maps directly to underlying Decimal or Numeric types in most DB platforms.

Usually, in a relational DB, Decimal fields have a fixed precision. As such, the Knex field adapter supports two additional config options:

OptionTypeDefaultDescription
precisionInteger or null18The number of significant decimal digits stored
scaleInteger or null4The number of significant fractional decimal digits stored (ie. on the right side of the decimal place)

If specified scale must be greater than precision.

Non-fixed precision

Some DB platforms (Oracle, SQLite and Postgres) support Decimal types without a fixed precision. This can be configured by passing both the precision and scale as null, eg:

JS
keystone.createList('Currency', {
  fields: {
    name: { type: Text },
    totalIssued: { type: Decimal, knexOptions: { precision: null, scale: null } },
  },
});

Will produce:

SQL
CREATE TABLE keystone."Currency" (
    id integer DEFAULT nextval('keystone."Currency_id_seq"'::regclass) PRIMARY KEY,
    name text,
    "totalIssued" numeric
);

Prisma adapter

The Prisma adapter uses the Decimal prisma type.

The Prisma field adapter supports two additional config options:

OptionTypeDefaultDescription
precisionInteger or null18The number of significant decimal digits stored
scaleInteger or null4The number of significant fractional decimal digits stored (ie. on the right side of the decimal place)

If specified scale must be greater than precision.

Note: The Decimal field type in Prisma is still considered a preview feature, and should not be used in production.

On this page

Edit on GitHub