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
keystone.createList('Payment', {
  fields: {
    timestamp: { type: DateTime, isRequired: true },
    description: { type: Text },
    amount: { type: Decimal, isRequired: true },
  },
});
Config
| Option | Type | Default | Description | 
|---|---|---|---|
| isRequired | Boolean | false | Does this field require a value? | 
| isUnique | Boolean | false | Adds a unique index that allows only unique values to be stored | 
| knexOptions | Object | {} | Optional; see the Knex Adaptor 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 name | Type | Description | 
|---|---|---|
| ${path} | String | The value to be stored | 
Output Fields
| Field name | Type | Description | 
|---|---|---|
| ${path} | String | The 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 name | Type | Description | 
|---|---|---|
| ${path} | String | Equivalent to the value provided | 
| ${path}_not | String | Not equivalent to the value provided | 
| ${path}_in | [String] | In the array provided | 
| ${path}_not_in | [String] | Not in the array provided | 
| ${path}_lt | String | Less than the value provided | 
| ${path}_lte | String | Less than or equivalent to the value provided | 
| ${path}_gt | String | Greater than the value provided | 
| ${path}_gte | String | Greater 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 Adaptor
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 Adaptor
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:
| Option | Type | Default | Description | 
|---|---|---|---|
| precision | Integerornull | 18 | The number of significant decimal digits stored | 
| scale | Integerornull | 4 | The 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:
keystone.createList('Currency', {
  fields: {
    name: { type: Text },
    totalIssued: { type: Decimal, knexOptions: { precision: null, scale: null } },
  },
});
Will produce:
CREATE TABLE keystone."Currency" (
    id integer DEFAULT nextval('keystone."Currency_id_seq"'::regclass) PRIMARY KEY,
    name text,
    "totalIssued" numeric
);