Vai al contenuto

Polyfills on SQLite

A polyfill is how Provisa gives a PostgreSQL client PostgreSQL's behaviour on SQLite (dialect sqlite), as a serving engine or as a source a statement is sent to directly. Each feature has a read polyfill, how its values and operations are computed there, and a write polyfill, how its values reach it; each states its limitations.

This page lists every feature that has a polyfill or a limitation on SQLite. A feature SQLite does natively with no difference from PostgreSQL is left out and counted. The conformance runs check the omission: a feature left out that answers otherwise than PostgreSQL fails the run.

When SQLite is a serving engine reading a source it attaches directly, it may push work into that source, with the source's semantics, so a result can depend on the pair; the cases known are fixed by hints, listed under each source.

Rules on this page: 102, of which 26 are only the name of a rewrite function. A rule is printed as the translator runs it: the PostgreSQL pattern, its holes written $name (typed with ::type), then the dialect's replacement.

88 of the grid's 154 features are native on SQLite and left out.

FeatureRead polyfillRead limitationsWrite polyfillWrite limitations
array_ndims
The number of an array's dimensions.
array_ndims($a::anyarray)
=>
refused (its error is under the limitations)
  • Refused: array_ndims($a::anyarray). 0A000 array_ndims() has no form on sqlite
array_dims
The text of an array's dimensions, such as [1:2][1:3].
array_dims($a::anyarray)
=>
refused (its error is under the limitations)
  • Refused: array_dims($a::anyarray). 0A000 array_dims() has no form on sqlite
array_lower
The lower bound of a dimension: 1, as a list's index starts there.
array_lower($a::anyarray, $d::integer)
=>
refused (its error is under the limitations)
  • Refused: array_lower($a::anyarray, $d::integer). 0A000 array_lower() has no form on sqlite
array_upper
The upper bound of a dimension: its length.
array_upper($a::anyarray, $d::integer)
=>
refused (its error is under the limitations)
  • Refused: array_upper($a::anyarray, $d::integer). 0A000 array_upper() has no form on sqlite
array_length
The length of a dimension; NULL for a dimension the array does not have.
array_length($a::anyarray, 1)
=>
refused (its error is under the limitations)
array_length($a::anyarray, $d::integer)
=>
refused (its error is under the limitations)
  • Refused: array_length($a::anyarray, 1). 0A000 array_length() has no form on sqlite
  • Refused: array_length($a::anyarray, $d::integer). 0A000 array_length() has no form on sqlite
array_fill
An array of a value repeated to the dimensions given.
array_fill($v::anyelement, $dims::integer[])
=>
refused (its error is under the limitations)
array_fill($v::anyelement, $dims::integer[], $lower_bounds::integer[])
=>
refused (its error is under the limitations)
  • Refused: array_fill($v::anyelement, $dims::integer[]). 0A000 array_fill() has no form on sqlite
  • Refused: array_fill($v::anyelement, $dims::integer[], $lower_bounds::integer[]). 0A000 array_fill() has no form on sqlite
array_eq
Two arrays equal, a NULL element equal to a NULL element.
array_eq($a::anyarray, $b::anyarray)
=>
$a = $b
array_ne
Two arrays not equal, a NULL element equal to a NULL element.
array_ne($a::anyarray, $b::anyarray)
=>
$a <> $b
array_position
The position of the first element equal to a value, a NULL equal to a NULL; NULL for none.
array_position($a::anycompatiblearray, $v::anycompatible, $s::integer)
=>
refused (its error is under the limitations)
  • Refused: array_position($a::anycompatiblearray, $v::anycompatible, $s::integer). 0A000 array_position() has no form on sqlite
array_positions
The positions of every element equal to a value, a NULL equal to a NULL.
array_positions($a::anycompatiblearray, $v::anycompatible)
=>
refused (its error is under the limitations)
  • Refused: array_positions($a::anycompatiblearray, $v::anycompatible). 0A000 array_positions() has no form on sqlite
array_replace
Each element equal to a value replaced by another, a NULL equal to a NULL.
array_replace($a::anycompatiblearray, $v::anycompatible, $w::anycompatible)
=>
refused (its error is under the limitations)
  • Refused: array_replace($a::anycompatiblearray, $v::anycompatible, $w::anycompatible). 0A000 array_replace() has no form on sqlite
array_sample
A number of an array's elements, chosen at random.
array_sample($a::anyarray, $n::integer)
=>
refused (its error is under the limitations)
  • Refused: array_sample($a::anyarray, $n::integer). 0A000 array_sample() has no form on sqlite
array_shuffle
An array's elements in a random order.
array_shuffle($a::anyarray)
=>
refused (its error is under the limitations)
  • Refused: array_shuffle($a::anyarray). 0A000 array_shuffle() has no form on sqlite
trim_array
An array without its last elements.
trim_array($a::anyarray, $n::integer)
=>
refused (its error is under the limitations)
  • Refused: trim_array($a::anyarray, $n::integer). 0A000 trim_array() has no form on sqlite
generate_subscripts
The subscripts of a dimension, as rows, in either order.
generate_subscripts($a::anyarray, $d::integer, $reverse::boolean)
=>
refused (its error is under the limitations)
generate_subscripts($a::anyarray, $d::integer)
=>
function provisa.transpiler.polyfill.trino.kept: The old table's form (provisa.transpiler.function_macros): this row writes Trino's only.
  • Refused: generate_subscripts($a::anyarray, $d::integer, $reverse::boolean). 0A000 generate_subscripts() has no form on sqlite
array_cat
Two arrays concatenated; a NULL array is the other one, and two NULL arrays are NULL.
array_cat(NULL::anycompatiblearray, $b::anycompatiblearray)
=>
refused (its error is under the limitations)
array_cat($a::anycompatiblearray, NULL::anycompatiblearray)
=>
refused (its error is under the limitations)
array_cat($a::anycompatiblearray, $b::anycompatiblearray)
=>
refused (its error is under the limitations)
  • Refused: array_cat(NULL::anycompatiblearray, $b::anycompatiblearray). 0A000 array_cat() has no form on sqlite
  • Refused: array_cat($a::anycompatiblearray, NULL::anycompatiblearray). 0A000 array_cat() has no form on sqlite
  • Refused: array_cat($a::anycompatiblearray, $b::anycompatiblearray). 0A000 array_cat() has no form on sqlite
array_lt
One array before another, a NULL element after any value.
array_lt($a::anyarray, $b::anyarray)
=>
$a < $b
array_le
One array before or equal to another, a NULL element after any value.
array_le($a::anyarray, $b::anyarray)
=>
$a <= $b
array_gt
One array after another, a NULL element after any value.
array_gt($a::anyarray, $b::anyarray)
=>
$a > $b
array_ge
One array after or equal to another, a NULL element after any value.
array_ge($a::anyarray, $b::anyarray)
=>
$a >= $b
array_larger
The larger of two arrays, a NULL element after any value.
array_larger($a::anyarray, $b::anyarray)
=>
CASE WHEN $a > $b THEN $a WHEN $a <= $b THEN $b END
array_smaller
The smaller of two arrays, a NULL element after any value.
array_smaller($a::anyarray, $b::anyarray)
=>
CASE WHEN $a < $b THEN $a WHEN $a >= $b THEN $b END
btarraycmp
btree's comparison of two arrays: -1, 0 or 1, a NULL element after any value.
btarraycmp($a::anyarray, $b::anyarray)
=>
function provisa.transpiler.polyfill.trino.kept: The old table's form (provisa.transpiler.function_macros): this row writes Trino's only.
pg_timezone_names
The zones of the tz database, each with its abbreviation, offset and daylight flag now.
pg_timezone_names()
=>
refused (its error is under the limitations)
  • Refused: pg_timezone_names(). 0A000 pg_timezone_names() has no form on sqlite
record_eq
Two records equal, a NULL field equal to a NULL field.
record_eq($a, $b)
=>
($a) = ($b)
record_ne
Two records not equal, a NULL field equal to a NULL field.
record_ne($a, $b)
=>
($a) <> ($b)
record_image_eq
Two records of equal images, a NULL field equal to a NULL field.
record_image_eq($a, $b)
=>
($a) = ($b)
record_image_ne
Two records of images not equal, a NULL field equal to a NULL field.
record_image_ne($a, $b)
=>
($a) <> ($b)
record_lt
One record before another.
record_lt($a, $b)
=>
($a) < ($b)
record_le
One record before or equal to another.
record_le($a, $b)
=>
($a) <= ($b)
record_gt
One record after another.
record_gt($a, $b)
=>
($a) > ($b)
record_ge
One record after or equal to another.
record_ge($a, $b)
=>
($a) >= ($b)
record_image_lt
One record image before another.
record_image_lt($a, $b)
=>
($a) < ($b)
record_image_le
One record image before or equal to another.
record_image_le($a, $b)
=>
($a) <= ($b)
record_image_gt
One record image after another.
record_image_gt($a, $b)
=>
($a) > ($b)
record_image_ge
One record image after or equal to another.
record_image_ge($a, $b)
=>
($a) >= ($b)
money_text
money's text, as cash_out writes it: $1,234.50, NULL for a NULL.
money_text($v)
=>
refused (its error is under the limitations)
  • Refused: money_text($v). XX000 cast to text on a money column needs money's own semantics, which sqlite neither has nor emulates; it is not answered over the column's text form
interval_in
interval_in of a NULL: PostgreSQL's NULL of interval; of a constant, its interval.
interval_in(NULL, $o, $t)
=>
refused (its error is under the limitations)
interval_in($v, NULL, $t)
=>
refused (its error is under the limitations)
interval_in($v, $o, NULL)
=>
refused (its error is under the limitations)
interval_in('infinity', $o, $t)
=>
refused (its error is under the limitations)
interval_in('-infinity', $o, $t)
=>
refused (its error is under the limitations)
  • Refused: interval_in(NULL, $o, $t). 0A000 interval_in does not read this value
  • Refused: interval_in($v, NULL, $t). 0A000 interval_in does not read this value
  • Refused: interval_in($v, $o, NULL). 0A000 interval_in does not read this value
  • Refused: interval_in('infinity', $o, $t). 0A000 interval_in does not read this value
  • Refused: interval_in('-infinity', $o, $t). 0A000 interval_in does not read this value
  • A NULL of interval would be described as text: the call is refused. 0A000 interval_in does not read this value
  • A constant is folded to its text, which pgwire describes as interval; infinity, which pgwire has no interval value of, is refused. 0A000 interval_in does not read this value
jsonb_in
jsonb_in of a NULL: PostgreSQL's NULL of jsonb.
jsonb_in(NULL)
=>
refused (its error is under the limitations)
  • Refused: jsonb_in(NULL). 0A000 jsonb_in does not read this value
  • A NULL of jsonb would be described as text: the call is refused. 0A000 jsonb_in does not read this value
xid8in
xid8in of a NULL: PostgreSQL's NULL of xid8.
xid8in(NULL)
=>
refused (its error is under the limitations)
  • Refused: xid8in(NULL). 0A000 xid8in does not read this value
  • A NULL of xid8 would be described as text: the call is refused. 0A000 xid8in does not read this value
pg_collation_for
The collation a COLLATE clause gives a value, as quote_ident writes its name.
pg_collation_for($v::text COLLATE "default")
=>
'"default"'
pg_collation_for($v::character COLLATE "default")
=>
'"default"'
pg_collation_for($v::name COLLATE "default")
=>
'"default"'
pg_collation_for($v::text COLLATE "C")
=>
'"C"'
pg_collation_for($v::character COLLATE "C")
=>
'"C"'
pg_collation_for($v::name COLLATE "C")
=>
'"C"'
pg_collation_for($v::text COLLATE "POSIX")
=>
'"POSIX"'
pg_collation_for($v::character COLLATE "POSIX")
=>
'"POSIX"'
pg_collation_for($v::name COLLATE "POSIX")
=>
'"POSIX"'
pg_collation_for($v::text COLLATE "ucs_basic")
=>
'ucs_basic'
pg_collation_for($v::character COLLATE "ucs_basic")
=>
'ucs_basic'
pg_collation_for($v::name COLLATE "ucs_basic")
=>
'ucs_basic'
pg_collation_for($v::text COLLATE ucs_basic)
=>
'ucs_basic'
pg_collation_for($v::character COLLATE ucs_basic)
=>
'ucs_basic'
pg_collation_for($v::name COLLATE ucs_basic)
=>
'ucs_basic'
pg_collation_for($v::text COLLATE "unicode")
=>
'unicode'
pg_collation_for($v::character COLLATE "unicode")
=>
'unicode'
pg_collation_for($v::name COLLATE "unicode")
=>
'unicode'
pg_collation_for($v::text COLLATE unicode)
=>
'unicode'
pg_collation_for($v::character COLLATE unicode)
=>
'unicode'
pg_collation_for($v::name COLLATE unicode)
=>
'unicode'
pg_collation_for($v::text COLLATE "pg_c_utf8")
=>
'pg_c_utf8'
pg_collation_for($v::character COLLATE "pg_c_utf8")
=>
'pg_c_utf8'
pg_collation_for($v::name COLLATE "pg_c_utf8")
=>
'pg_c_utf8'
pg_collation_for($v::text COLLATE pg_c_utf8)
=>
'pg_c_utf8'
pg_collation_for($v::character COLLATE pg_c_utf8)
=>
'pg_c_utf8'
pg_collation_for($v::name COLLATE pg_c_utf8)
=>
'pg_c_utf8'
pg_collation_for($v COLLATE $c)
=>
refused (its error is under the limitations)
  • Refused: pg_collation_for($v COLLATE $c). 0A000 pg_collation_for does not read this value
  • Only the built-in collations (default, C, POSIX, ucs_basic, unicode, pg_c_utf8) of a text, character or name value: any other COLLATE is refused. 0A000 pg_collation_for does not read this value
macaddr_and
The bitwise AND of two MAC addresses.
macaddr_and($a, $b)
=>
function provisa.transpiler.polyfill.trino.kept: The old table's form (provisa.transpiler.function_macros): this row writes Trino's only.
macaddr_or
The bitwise OR of two MAC addresses.
macaddr_or($a, $b)
=>
function provisa.transpiler.polyfill.trino.kept: The old table's form (provisa.transpiler.function_macros): this row writes Trino's only.
macaddr_not
The bitwise NOT of a MAC address.
macaddr_not($a)
=>
function provisa.transpiler.polyfill.trino.kept: The old table's form (provisa.transpiler.function_macros): this row writes Trino's only.
trunc
A MAC address with its last three (macaddr) or five (macaddr8) bytes set to zero.
trunc($m)
=>
function provisa.transpiler.polyfill.trino.kept: The old table's form (provisa.transpiler.function_macros): this row writes Trino's only.
int2_sum
A step of an integer sum, in a bigint that wraps past its range.
int2_sum($a, $b)
=>
function provisa.transpiler.polyfill.trino.kept: The old table's form (provisa.transpiler.function_macros): this row writes Trino's only.
int4_sum
A step of an integer sum, in a bigint that wraps past its range.
int4_sum($a, $b)
=>
function provisa.transpiler.polyfill.trino.kept: The old table's form (provisa.transpiler.function_macros): this row writes Trino's only.
int8shl
A bigint shifted left, its count taken modulo 64, the result wrapping.
int8shl($a, $b)
=>
function provisa.transpiler.polyfill.trino.kept: The old table's form (provisa.transpiler.function_macros): this row writes Trino's only.
int2shr
A smallint shifted right, its sign kept, its count taken modulo 32.
int2shr($a, $b)
=>
function provisa.transpiler.polyfill.trino.kept: The old table's form (provisa.transpiler.function_macros): this row writes Trino's only.
int4shr
A integer shifted right, its sign kept, its count taken modulo 32.
int4shr($a, $b)
=>
function provisa.transpiler.polyfill.trino.kept: The old table's form (provisa.transpiler.function_macros): this row writes Trino's only.
int8shr
A bigint shifted right, its sign kept, its count taken modulo 64.
int8shr($a, $b)
=>
function provisa.transpiler.polyfill.trino.kept: The old table's form (provisa.transpiler.function_macros): this row writes Trino's only.
factorial
The product of the integers from 1 to n.
factorial($n)
=>
function provisa.transpiler.polyfill.trino.kept: The old table's form (provisa.transpiler.function_macros): this row writes Trino's only.
numeric
An integer as a numeric.
numeric($v)
=>
function provisa.transpiler.polyfill.trino.kept: The old table's form (provisa.transpiler.function_macros): this row writes Trino's only.
bool
An integer as a truth value: false for 0.
bool($v)
=>
function provisa.transpiler.polyfill.trino.kept: The old table's form (provisa.transpiler.function_macros): this row writes Trino's only.
oid
A bigint as an oid.
oid($v)
=>
function provisa.transpiler.polyfill.trino.kept: The old table's form (provisa.transpiler.function_macros): this row writes Trino's only.
random
A uniform random integer between two bounds, both included.
random($lo, $hi)
=>
function provisa.transpiler.polyfill.trino.kept: The old table's form (provisa.transpiler.function_macros): this row writes Trino's only.
date_mi
The days from one date to another.
date_mi($a, $b)
=>
function provisa.transpiler.polyfill.trino.kept: The old table's form (provisa.transpiler.function_macros): this row writes Trino's only.
date_pli
A date moved forward by a number of days.
date_pli($a, $b)
=>
function provisa.transpiler.polyfill.trino.kept: The old table's form (provisa.transpiler.function_macros): this row writes Trino's only.
date_mii
A date moved back by a number of days.
date_mii($a, $b)
=>
function provisa.transpiler.polyfill.trino.kept: The old table's form (provisa.transpiler.function_macros): this row writes Trino's only.
make_date
A date of a year, a month and a day.
make_date($y, $m, $d)
=>
function provisa.transpiler.polyfill.trino.kept: The old table's form (provisa.transpiler.function_macros): this row writes Trino's only.
transaction_timestamp
The time the transaction began: now(), as Provisa answers it.
transaction_timestamp()
=>
function provisa.transpiler.polyfill.trino.kept: The old table's form (provisa.transpiler.function_macros): this row writes Trino's only.
mxid_age
The age of a multixact id: INT_MAX for 0, and 1 less it, as Provisa makes no multixact.
mxid_age($x)
=>
function provisa.transpiler.polyfill.trino.kept: The old table's form (provisa.transpiler.function_macros): this row writes Trino's only.
pg_char_to_encoding
An encoding's number by any of PostgreSQL's names of it; -1 for a name of none.
pg_char_to_encoding($n)
=>
refused (its error is under the limitations)
  • Refused: pg_char_to_encoding($n). 0A000 pg_char_to_encoding() has no form on sqlite
ntile
The bucket of a row in a window, as an integer.
function provisa.transpiler.polyfill.clickhouse.bucketed: ntile over a window, as PostgreSQL's integer: every engine's is a bigint. On ClickHouse a
numeric_mod
The remainder of one numeric divided by another, at the larger scale of the two.
numeric_mod($a, $b)
=>
function provisa.transpiler.polyfill.trino.kept: The old table's form (provisa.transpiler.function_macros): this row writes Trino's only.
spg_poly_quad_compress
A polygon's bounding box, as the SP-GiST quad tree's compress function answers it.
spg_poly_quad_compress($v)
=>
function provisa.transpiler.polyfill.trino.kept: The old table's form (provisa.transpiler.function_macros): this row writes Trino's only.