Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

sql.decimal

import sql.decimal

sql lifts part of this module out to its own top level; each name below is shown with the path that reaches it. Anything still spelled sql.decimal.* needs import sql.decimal.

Exact decimal numbers, for the money column that must not be a float.

PostgreSQL’s numeric holds a decimal value exactly. A number in Zuri is a double, which holds 0.1 only approximately, so reading a balance of 0.10 into one and writing it back is not guaranteed to store what was there before. Decimal keeps the value as an integer and a scale, so 10.05 is exactly ten and five hundredths and stays that way through every read and write.

var price = Decimal('19.99')
var tax = price.multiply(Decimal('0.20'))

echo tax.to_string()
# 3.9980

Addition, subtraction and multiplication are exact. Division is not, in general, so it takes the number of decimal places to produce and rounds half away from zero, the rule money is normally counted by.

Functions

decimal()

sql.decimal(value, scale) -> Decimal

Builds a decimal, the same as Decimal() but as a function.

Parameters

  • value (string|number|bigint)
  • scale (number|nil)

Returns Decimal

Classes

Decimal

class sql.Decimal

An exact decimal number.

Held as an integer and a scale: unscaled is the digits with the point removed, scale is how many of them are after the point. So 1.05 is 105 at scale 2, and 1.050 is 1050 at scale 3. The two are equal in value and differ in how they print, which is what lets a column declared numeric(10, 3) round trip without gaining or losing a trailing zero.

  • printable — has a @to_string(), so echo and print() show something useful

Fields

FieldTypeDescription
unscaledbigintThe digits, with the decimal point removed, as a bigint.
scalenumberHow many digits are after the decimal point.

Constructor

sql.Decimal(value, scale)

Builds a decimal.

From text, which is the exact form and the one to prefer:

Decimal('19.99')
Decimal('-0.0001')
Decimal('1.2e3')

From a number, which is only as exact as the double was:

Decimal(19.99)

Or from the parts, which is what the PostgreSQL adapter uses:

Decimal(1999, 2)

Parameters

  • value (string|number|bigint) — The value, or its unscaled digits when scale is given.
  • scale (number|nil) — The number of decimal places, when value is the unscaled integer.

Raises QueryError if the text is not a number.

Decimal.is_negative()

sql.Decimal.is_negative() -> bool

Whether this is negative.

Returns bool

Decimal.is_zero()

sql.Decimal.is_zero() -> bool

Whether this is exactly zero, whatever its scale.

Returns bool

Decimal.rescale()

sql.Decimal.rescale(places: number) -> Decimal

The same value at a different number of decimal places.

Adding places is exact. Removing them rounds half away from zero, so 2.5 to no places is 3 and -2.5 is -3.

Parameters

  • places (number)

Returns Decimal

Decimal.add()

sql.Decimal.add(other) -> Decimal

The sum of this and other, exactly.

The result carries the larger of the two scales, so no digit is lost.

Parameters

  • other (Decimal)

Returns Decimal

Decimal.subtract()

sql.Decimal.subtract(other) -> Decimal

The difference, exactly.

Parameters

  • other (Decimal)

Returns Decimal

Decimal.multiply()

sql.Decimal.multiply(other) -> Decimal

The product, exactly.

The scales add, as they do when multiplying by hand: two places times two places is four places.

Parameters

  • other (Decimal)

Returns Decimal

Decimal.divide()

sql.Decimal.divide(other, places: number) -> Decimal

The quotient to places decimal places, rounded half away from zero.

Division is the one operation with no exact answer in general, so the number of places is required rather than guessed.

Parameters

  • other (Decimal)
  • places (number)

Returns Decimal

Raises QueryError if other is zero.

Decimal.to_number()

sql.Decimal.to_number() -> number

The value as a number, which is approximate for anything a double cannot hold exactly.

Returns number

Decimal.compare()

sql.Decimal.compare(other) -> number

Compares this with other: negative, zero or positive, the same shape a sort comparator takes.

Parameters

  • other (Decimal)

Returns number

Decimal.equals()

sql.Decimal.equals(other) -> bool

Whether this and other are the same value, whatever their scales. 1.5 and 1.50 are equal.

Parameters

  • other (Decimal)

Returns bool

Decimal.to_string()

sql.Decimal.to_string() -> string

The value written out, with exactly scale digits after the point.

Returns string


2026, Richard Ore and Zuri contributors