Replace our traditional initial-catalog-data format with a better design.
Historically, the initial catalog data to be installed during bootstrap
has been written in DATA() lines in the catalog header files. This had
lots of disadvantages: the format was badly underdocumented, it was
very difficult to edit the data in any mechanized way, and due to the
lack of any abstraction the data was verbose, hard to read/understand,
and easy to get wrong.
Hence, move this data into separate ".dat" files and represent it in a way
that can easily be read and rewritten by Perl scripts. The new format is
essentially "key => value" for each column; while it's a bit repetitive,
explicit labeling of each value makes the data far more readable and less
error-prone. Provide a way to abbreviate entries by omitting field values
that match a specified default value for their column. This allows removal
of a large amount of repetitive boilerplate and also lowers the barrier to
adding new columns.
Also teach genbki.pl how to translate symbolic OID references into
numeric OIDs for more cases than just "regproc"-like pg_proc references.
It can now do that for regprocedure-like references (thus solving the
problem that regproc is ambiguous for overloaded functions), operators,
types, opfamilies, opclasses, and access methods. Use this to turn
nearly all OID cross-references in the initial data into symbolic form.
This represents a very large step forward in readability and error
resistance of the initial catalog data. It should also reduce the
difficulty of renumbering OID assignments in uncommitted patches.
Also, solve the longstanding problem that frontend code that would like to
use OID macros and other information from the catalog headers often had
difficulty with backend-only code in the headers. To do this, arrange for
all generated macros, plus such other declarations as we deem fit, to be
placed in "derived" header files that are safe for frontend inclusion.
(Once clients migrate to using these pg_*_d.h headers, it will be possible
to get rid of the pg_*_fn.h headers, which only exist to quarantine code
away from clients. That is left for follow-on patches, however.)
The now-automatically-generated macros include the Anum_xxx and Natts_xxx
constants that we used to have to update by hand when adding or removing
catalog columns.
Replace the former manual method of generating OID macros for pg_type
entries with an automatic method, ensuring that all built-in types have
OID macros. (But note that this patch does not change the way that
OID macros for pg_proc entries are built and used. It's not clear that
making that match the other catalogs would be worth extra code churn.)
Add SGML documentation explaining what the new data format is and how to
work with it.
Despite being a very large change in the catalog headers, there is no
catversion bump here, because postgres.bki and related output files
haven't changed at all.
John Naylor, based on ideas from various people; review and minor
additional coding by me; previous review by Alvaro Herrera
Discussion: https://postgr.es/m/CAJVSVGWO48JbbwXkJz_yBFyGYW-M9YWxnPdxJBUosDC9ou_F0Q@mail.gmail.com
2018-04-08 19:16:50 +02:00
|
|
|
#----------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# pg_cast.dat
|
2018-04-19 23:14:09 +02:00
|
|
|
# Initial contents of the pg_cast system catalog.
|
Replace our traditional initial-catalog-data format with a better design.
Historically, the initial catalog data to be installed during bootstrap
has been written in DATA() lines in the catalog header files. This had
lots of disadvantages: the format was badly underdocumented, it was
very difficult to edit the data in any mechanized way, and due to the
lack of any abstraction the data was verbose, hard to read/understand,
and easy to get wrong.
Hence, move this data into separate ".dat" files and represent it in a way
that can easily be read and rewritten by Perl scripts. The new format is
essentially "key => value" for each column; while it's a bit repetitive,
explicit labeling of each value makes the data far more readable and less
error-prone. Provide a way to abbreviate entries by omitting field values
that match a specified default value for their column. This allows removal
of a large amount of repetitive boilerplate and also lowers the barrier to
adding new columns.
Also teach genbki.pl how to translate symbolic OID references into
numeric OIDs for more cases than just "regproc"-like pg_proc references.
It can now do that for regprocedure-like references (thus solving the
problem that regproc is ambiguous for overloaded functions), operators,
types, opfamilies, opclasses, and access methods. Use this to turn
nearly all OID cross-references in the initial data into symbolic form.
This represents a very large step forward in readability and error
resistance of the initial catalog data. It should also reduce the
difficulty of renumbering OID assignments in uncommitted patches.
Also, solve the longstanding problem that frontend code that would like to
use OID macros and other information from the catalog headers often had
difficulty with backend-only code in the headers. To do this, arrange for
all generated macros, plus such other declarations as we deem fit, to be
placed in "derived" header files that are safe for frontend inclusion.
(Once clients migrate to using these pg_*_d.h headers, it will be possible
to get rid of the pg_*_fn.h headers, which only exist to quarantine code
away from clients. That is left for follow-on patches, however.)
The now-automatically-generated macros include the Anum_xxx and Natts_xxx
constants that we used to have to update by hand when adding or removing
catalog columns.
Replace the former manual method of generating OID macros for pg_type
entries with an automatic method, ensuring that all built-in types have
OID macros. (But note that this patch does not change the way that
OID macros for pg_proc entries are built and used. It's not clear that
making that match the other catalogs would be worth extra code churn.)
Add SGML documentation explaining what the new data format is and how to
work with it.
Despite being a very large change in the catalog headers, there is no
catversion bump here, because postgres.bki and related output files
haven't changed at all.
John Naylor, based on ideas from various people; review and minor
additional coding by me; previous review by Alvaro Herrera
Discussion: https://postgr.es/m/CAJVSVGWO48JbbwXkJz_yBFyGYW-M9YWxnPdxJBUosDC9ou_F0Q@mail.gmail.com
2018-04-08 19:16:50 +02:00
|
|
|
#
|
2019-01-02 18:44:25 +01:00
|
|
|
# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
|
Replace our traditional initial-catalog-data format with a better design.
Historically, the initial catalog data to be installed during bootstrap
has been written in DATA() lines in the catalog header files. This had
lots of disadvantages: the format was badly underdocumented, it was
very difficult to edit the data in any mechanized way, and due to the
lack of any abstraction the data was verbose, hard to read/understand,
and easy to get wrong.
Hence, move this data into separate ".dat" files and represent it in a way
that can easily be read and rewritten by Perl scripts. The new format is
essentially "key => value" for each column; while it's a bit repetitive,
explicit labeling of each value makes the data far more readable and less
error-prone. Provide a way to abbreviate entries by omitting field values
that match a specified default value for their column. This allows removal
of a large amount of repetitive boilerplate and also lowers the barrier to
adding new columns.
Also teach genbki.pl how to translate symbolic OID references into
numeric OIDs for more cases than just "regproc"-like pg_proc references.
It can now do that for regprocedure-like references (thus solving the
problem that regproc is ambiguous for overloaded functions), operators,
types, opfamilies, opclasses, and access methods. Use this to turn
nearly all OID cross-references in the initial data into symbolic form.
This represents a very large step forward in readability and error
resistance of the initial catalog data. It should also reduce the
difficulty of renumbering OID assignments in uncommitted patches.
Also, solve the longstanding problem that frontend code that would like to
use OID macros and other information from the catalog headers often had
difficulty with backend-only code in the headers. To do this, arrange for
all generated macros, plus such other declarations as we deem fit, to be
placed in "derived" header files that are safe for frontend inclusion.
(Once clients migrate to using these pg_*_d.h headers, it will be possible
to get rid of the pg_*_fn.h headers, which only exist to quarantine code
away from clients. That is left for follow-on patches, however.)
The now-automatically-generated macros include the Anum_xxx and Natts_xxx
constants that we used to have to update by hand when adding or removing
catalog columns.
Replace the former manual method of generating OID macros for pg_type
entries with an automatic method, ensuring that all built-in types have
OID macros. (But note that this patch does not change the way that
OID macros for pg_proc entries are built and used. It's not clear that
making that match the other catalogs would be worth extra code churn.)
Add SGML documentation explaining what the new data format is and how to
work with it.
Despite being a very large change in the catalog headers, there is no
catversion bump here, because postgres.bki and related output files
haven't changed at all.
John Naylor, based on ideas from various people; review and minor
additional coding by me; previous review by Alvaro Herrera
Discussion: https://postgr.es/m/CAJVSVGWO48JbbwXkJz_yBFyGYW-M9YWxnPdxJBUosDC9ou_F0Q@mail.gmail.com
2018-04-08 19:16:50 +02:00
|
|
|
# Portions Copyright (c) 1994, Regents of the University of California
|
|
|
|
#
|
|
|
|
# src/include/catalog/pg_cast.dat
|
|
|
|
#
|
|
|
|
#----------------------------------------------------------------------
|
|
|
|
|
|
|
|
[
|
|
|
|
|
|
|
|
# Note: this table has OIDs, but we don't bother to assign them manually,
|
|
|
|
# since nothing needs to know the specific OID of any built-in cast.
|
|
|
|
|
|
|
|
# Numeric category: implicit casts are allowed in the direction
|
|
|
|
# int2->int4->int8->numeric->float4->float8, while casts in the
|
|
|
|
# reverse direction are assignment-only.
|
|
|
|
{ castsource => 'int8', casttarget => 'int2', castfunc => 'int2(int8)',
|
|
|
|
castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'int8', casttarget => 'int4', castfunc => 'int4(int8)',
|
|
|
|
castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'int8', casttarget => 'float4', castfunc => 'float4(int8)',
|
|
|
|
castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'int8', casttarget => 'float8', castfunc => 'float8(int8)',
|
|
|
|
castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'int8', casttarget => 'numeric', castfunc => 'numeric(int8)',
|
|
|
|
castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'int2', casttarget => 'int8', castfunc => 'int8(int2)',
|
|
|
|
castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'int2', casttarget => 'int4', castfunc => 'int4(int2)',
|
|
|
|
castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'int2', casttarget => 'float4', castfunc => 'float4(int2)',
|
|
|
|
castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'int2', casttarget => 'float8', castfunc => 'float8(int2)',
|
|
|
|
castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'int2', casttarget => 'numeric', castfunc => 'numeric(int2)',
|
|
|
|
castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'int4', casttarget => 'int8', castfunc => 'int8(int4)',
|
|
|
|
castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'int4', casttarget => 'int2', castfunc => 'int2(int4)',
|
|
|
|
castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'int4', casttarget => 'float4', castfunc => 'float4(int4)',
|
|
|
|
castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'int4', casttarget => 'float8', castfunc => 'float8(int4)',
|
|
|
|
castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'int4', casttarget => 'numeric', castfunc => 'numeric(int4)',
|
|
|
|
castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'float4', casttarget => 'int8', castfunc => 'int8(float4)',
|
|
|
|
castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'float4', casttarget => 'int2', castfunc => 'int2(float4)',
|
|
|
|
castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'float4', casttarget => 'int4', castfunc => 'int4(float4)',
|
|
|
|
castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'float4', casttarget => 'float8', castfunc => 'float8(float4)',
|
|
|
|
castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'float4', casttarget => 'numeric',
|
|
|
|
castfunc => 'numeric(float4)', castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'float8', casttarget => 'int8', castfunc => 'int8(float8)',
|
|
|
|
castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'float8', casttarget => 'int2', castfunc => 'int2(float8)',
|
|
|
|
castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'float8', casttarget => 'int4', castfunc => 'int4(float8)',
|
|
|
|
castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'float8', casttarget => 'float4', castfunc => 'float4(float8)',
|
|
|
|
castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'float8', casttarget => 'numeric',
|
|
|
|
castfunc => 'numeric(float8)', castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'numeric', casttarget => 'int8', castfunc => 'int8(numeric)',
|
|
|
|
castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'numeric', casttarget => 'int2', castfunc => 'int2(numeric)',
|
|
|
|
castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'numeric', casttarget => 'int4', castfunc => 'int4(numeric)',
|
|
|
|
castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'numeric', casttarget => 'float4',
|
|
|
|
castfunc => 'float4(numeric)', castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'numeric', casttarget => 'float8',
|
|
|
|
castfunc => 'float8(numeric)', castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'money', casttarget => 'numeric', castfunc => 'numeric(money)',
|
|
|
|
castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'numeric', casttarget => 'money', castfunc => 'money(numeric)',
|
|
|
|
castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'int4', casttarget => 'money', castfunc => 'money(int4)',
|
|
|
|
castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'int8', casttarget => 'money', castfunc => 'money(int8)',
|
|
|
|
castcontext => 'a', castmethod => 'f' },
|
|
|
|
|
|
|
|
# Allow explicit coercions between int4 and bool
|
|
|
|
{ castsource => 'int4', casttarget => 'bool', castfunc => 'bool(int4)',
|
|
|
|
castcontext => 'e', castmethod => 'f' },
|
|
|
|
{ castsource => 'bool', casttarget => 'int4', castfunc => 'int4(bool)',
|
|
|
|
castcontext => 'e', castmethod => 'f' },
|
|
|
|
|
|
|
|
# OID category: allow implicit conversion from any integral type (including
|
|
|
|
# int8, to support OID literals > 2G) to OID, as well as assignment coercion
|
|
|
|
# from OID to int4 or int8. Similarly for each OID-alias type. Also allow
|
|
|
|
# implicit coercions between OID and each OID-alias type, as well as
|
|
|
|
# regproc<->regprocedure and regoper<->regoperator. (Other coercions
|
|
|
|
# between alias types must pass through OID.) Lastly, there are implicit
|
|
|
|
# casts from text and varchar to regclass, which exist mainly to support
|
|
|
|
# legacy forms of nextval() and related functions.
|
|
|
|
{ castsource => 'int8', casttarget => 'oid', castfunc => 'oid',
|
|
|
|
castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'int2', casttarget => 'oid', castfunc => 'int4(int2)',
|
|
|
|
castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'int4', casttarget => 'oid', castfunc => '0',
|
|
|
|
castcontext => 'i', castmethod => 'b' },
|
|
|
|
{ castsource => 'oid', casttarget => 'int8', castfunc => 'int8(oid)',
|
|
|
|
castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'oid', casttarget => 'int4', castfunc => '0',
|
|
|
|
castcontext => 'a', castmethod => 'b' },
|
|
|
|
{ castsource => 'oid', casttarget => 'regproc', castfunc => '0',
|
|
|
|
castcontext => 'i', castmethod => 'b' },
|
|
|
|
{ castsource => 'regproc', casttarget => 'oid', castfunc => '0',
|
|
|
|
castcontext => 'i', castmethod => 'b' },
|
|
|
|
{ castsource => 'int8', casttarget => 'regproc', castfunc => 'oid',
|
|
|
|
castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'int2', casttarget => 'regproc', castfunc => 'int4(int2)',
|
|
|
|
castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'int4', casttarget => 'regproc', castfunc => '0',
|
|
|
|
castcontext => 'i', castmethod => 'b' },
|
|
|
|
{ castsource => 'regproc', casttarget => 'int8', castfunc => 'int8(oid)',
|
|
|
|
castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'regproc', casttarget => 'int4', castfunc => '0',
|
|
|
|
castcontext => 'a', castmethod => 'b' },
|
|
|
|
{ castsource => 'regproc', casttarget => 'regprocedure', castfunc => '0',
|
|
|
|
castcontext => 'i', castmethod => 'b' },
|
|
|
|
{ castsource => 'regprocedure', casttarget => 'regproc', castfunc => '0',
|
|
|
|
castcontext => 'i', castmethod => 'b' },
|
|
|
|
{ castsource => 'oid', casttarget => 'regprocedure', castfunc => '0',
|
|
|
|
castcontext => 'i', castmethod => 'b' },
|
|
|
|
{ castsource => 'regprocedure', casttarget => 'oid', castfunc => '0',
|
|
|
|
castcontext => 'i', castmethod => 'b' },
|
|
|
|
{ castsource => 'int8', casttarget => 'regprocedure', castfunc => 'oid',
|
|
|
|
castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'int2', casttarget => 'regprocedure', castfunc => 'int4(int2)',
|
|
|
|
castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'int4', casttarget => 'regprocedure', castfunc => '0',
|
|
|
|
castcontext => 'i', castmethod => 'b' },
|
|
|
|
{ castsource => 'regprocedure', casttarget => 'int8', castfunc => 'int8(oid)',
|
|
|
|
castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'regprocedure', casttarget => 'int4', castfunc => '0',
|
|
|
|
castcontext => 'a', castmethod => 'b' },
|
|
|
|
{ castsource => 'oid', casttarget => 'regoper', castfunc => '0',
|
|
|
|
castcontext => 'i', castmethod => 'b' },
|
|
|
|
{ castsource => 'regoper', casttarget => 'oid', castfunc => '0',
|
|
|
|
castcontext => 'i', castmethod => 'b' },
|
|
|
|
{ castsource => 'int8', casttarget => 'regoper', castfunc => 'oid',
|
|
|
|
castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'int2', casttarget => 'regoper', castfunc => 'int4(int2)',
|
|
|
|
castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'int4', casttarget => 'regoper', castfunc => '0',
|
|
|
|
castcontext => 'i', castmethod => 'b' },
|
|
|
|
{ castsource => 'regoper', casttarget => 'int8', castfunc => 'int8(oid)',
|
|
|
|
castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'regoper', casttarget => 'int4', castfunc => '0',
|
|
|
|
castcontext => 'a', castmethod => 'b' },
|
|
|
|
{ castsource => 'regoper', casttarget => 'regoperator', castfunc => '0',
|
|
|
|
castcontext => 'i', castmethod => 'b' },
|
|
|
|
{ castsource => 'regoperator', casttarget => 'regoper', castfunc => '0',
|
|
|
|
castcontext => 'i', castmethod => 'b' },
|
|
|
|
{ castsource => 'oid', casttarget => 'regoperator', castfunc => '0',
|
|
|
|
castcontext => 'i', castmethod => 'b' },
|
|
|
|
{ castsource => 'regoperator', casttarget => 'oid', castfunc => '0',
|
|
|
|
castcontext => 'i', castmethod => 'b' },
|
|
|
|
{ castsource => 'int8', casttarget => 'regoperator', castfunc => 'oid',
|
|
|
|
castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'int2', casttarget => 'regoperator', castfunc => 'int4(int2)',
|
|
|
|
castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'int4', casttarget => 'regoperator', castfunc => '0',
|
|
|
|
castcontext => 'i', castmethod => 'b' },
|
|
|
|
{ castsource => 'regoperator', casttarget => 'int8', castfunc => 'int8(oid)',
|
|
|
|
castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'regoperator', casttarget => 'int4', castfunc => '0',
|
|
|
|
castcontext => 'a', castmethod => 'b' },
|
|
|
|
{ castsource => 'oid', casttarget => 'regclass', castfunc => '0',
|
|
|
|
castcontext => 'i', castmethod => 'b' },
|
|
|
|
{ castsource => 'regclass', casttarget => 'oid', castfunc => '0',
|
|
|
|
castcontext => 'i', castmethod => 'b' },
|
|
|
|
{ castsource => 'int8', casttarget => 'regclass', castfunc => 'oid',
|
|
|
|
castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'int2', casttarget => 'regclass', castfunc => 'int4(int2)',
|
|
|
|
castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'int4', casttarget => 'regclass', castfunc => '0',
|
|
|
|
castcontext => 'i', castmethod => 'b' },
|
|
|
|
{ castsource => 'regclass', casttarget => 'int8', castfunc => 'int8(oid)',
|
|
|
|
castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'regclass', casttarget => 'int4', castfunc => '0',
|
|
|
|
castcontext => 'a', castmethod => 'b' },
|
|
|
|
{ castsource => 'oid', casttarget => 'regtype', castfunc => '0',
|
|
|
|
castcontext => 'i', castmethod => 'b' },
|
|
|
|
{ castsource => 'regtype', casttarget => 'oid', castfunc => '0',
|
|
|
|
castcontext => 'i', castmethod => 'b' },
|
|
|
|
{ castsource => 'int8', casttarget => 'regtype', castfunc => 'oid',
|
|
|
|
castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'int2', casttarget => 'regtype', castfunc => 'int4(int2)',
|
|
|
|
castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'int4', casttarget => 'regtype', castfunc => '0',
|
|
|
|
castcontext => 'i', castmethod => 'b' },
|
|
|
|
{ castsource => 'regtype', casttarget => 'int8', castfunc => 'int8(oid)',
|
|
|
|
castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'regtype', casttarget => 'int4', castfunc => '0',
|
|
|
|
castcontext => 'a', castmethod => 'b' },
|
|
|
|
{ castsource => 'oid', casttarget => 'regconfig', castfunc => '0',
|
|
|
|
castcontext => 'i', castmethod => 'b' },
|
|
|
|
{ castsource => 'regconfig', casttarget => 'oid', castfunc => '0',
|
|
|
|
castcontext => 'i', castmethod => 'b' },
|
|
|
|
{ castsource => 'int8', casttarget => 'regconfig', castfunc => 'oid',
|
|
|
|
castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'int2', casttarget => 'regconfig', castfunc => 'int4(int2)',
|
|
|
|
castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'int4', casttarget => 'regconfig', castfunc => '0',
|
|
|
|
castcontext => 'i', castmethod => 'b' },
|
|
|
|
{ castsource => 'regconfig', casttarget => 'int8', castfunc => 'int8(oid)',
|
|
|
|
castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'regconfig', casttarget => 'int4', castfunc => '0',
|
|
|
|
castcontext => 'a', castmethod => 'b' },
|
|
|
|
{ castsource => 'oid', casttarget => 'regdictionary', castfunc => '0',
|
|
|
|
castcontext => 'i', castmethod => 'b' },
|
|
|
|
{ castsource => 'regdictionary', casttarget => 'oid', castfunc => '0',
|
|
|
|
castcontext => 'i', castmethod => 'b' },
|
|
|
|
{ castsource => 'int8', casttarget => 'regdictionary', castfunc => 'oid',
|
|
|
|
castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'int2', casttarget => 'regdictionary', castfunc => 'int4(int2)',
|
|
|
|
castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'int4', casttarget => 'regdictionary', castfunc => '0',
|
|
|
|
castcontext => 'i', castmethod => 'b' },
|
|
|
|
{ castsource => 'regdictionary', casttarget => 'int8', castfunc => 'int8(oid)',
|
|
|
|
castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'regdictionary', casttarget => 'int4', castfunc => '0',
|
|
|
|
castcontext => 'a', castmethod => 'b' },
|
|
|
|
{ castsource => 'text', casttarget => 'regclass', castfunc => 'regclass',
|
|
|
|
castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'varchar', casttarget => 'regclass', castfunc => 'regclass',
|
|
|
|
castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'oid', casttarget => 'regrole', castfunc => '0',
|
|
|
|
castcontext => 'i', castmethod => 'b' },
|
|
|
|
{ castsource => 'regrole', casttarget => 'oid', castfunc => '0',
|
|
|
|
castcontext => 'i', castmethod => 'b' },
|
|
|
|
{ castsource => 'int8', casttarget => 'regrole', castfunc => 'oid',
|
|
|
|
castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'int2', casttarget => 'regrole', castfunc => 'int4(int2)',
|
|
|
|
castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'int4', casttarget => 'regrole', castfunc => '0',
|
|
|
|
castcontext => 'i', castmethod => 'b' },
|
|
|
|
{ castsource => 'regrole', casttarget => 'int8', castfunc => 'int8(oid)',
|
|
|
|
castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'regrole', casttarget => 'int4', castfunc => '0',
|
|
|
|
castcontext => 'a', castmethod => 'b' },
|
|
|
|
{ castsource => 'oid', casttarget => 'regnamespace', castfunc => '0',
|
|
|
|
castcontext => 'i', castmethod => 'b' },
|
|
|
|
{ castsource => 'regnamespace', casttarget => 'oid', castfunc => '0',
|
|
|
|
castcontext => 'i', castmethod => 'b' },
|
|
|
|
{ castsource => 'int8', casttarget => 'regnamespace', castfunc => 'oid',
|
|
|
|
castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'int2', casttarget => 'regnamespace', castfunc => 'int4(int2)',
|
|
|
|
castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'int4', casttarget => 'regnamespace', castfunc => '0',
|
|
|
|
castcontext => 'i', castmethod => 'b' },
|
|
|
|
{ castsource => 'regnamespace', casttarget => 'int8', castfunc => 'int8(oid)',
|
|
|
|
castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'regnamespace', casttarget => 'int4', castfunc => '0',
|
|
|
|
castcontext => 'a', castmethod => 'b' },
|
|
|
|
|
|
|
|
# String category
|
|
|
|
{ castsource => 'text', casttarget => 'bpchar', castfunc => '0',
|
|
|
|
castcontext => 'i', castmethod => 'b' },
|
|
|
|
{ castsource => 'text', casttarget => 'varchar', castfunc => '0',
|
|
|
|
castcontext => 'i', castmethod => 'b' },
|
|
|
|
{ castsource => 'bpchar', casttarget => 'text', castfunc => 'text(bpchar)',
|
|
|
|
castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'bpchar', casttarget => 'varchar', castfunc => 'text(bpchar)',
|
|
|
|
castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'varchar', casttarget => 'text', castfunc => '0',
|
|
|
|
castcontext => 'i', castmethod => 'b' },
|
|
|
|
{ castsource => 'varchar', casttarget => 'bpchar', castfunc => '0',
|
|
|
|
castcontext => 'i', castmethod => 'b' },
|
|
|
|
{ castsource => 'char', casttarget => 'text', castfunc => 'text(char)',
|
|
|
|
castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'char', casttarget => 'bpchar', castfunc => 'bpchar(char)',
|
|
|
|
castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'char', casttarget => 'varchar', castfunc => 'text(char)',
|
|
|
|
castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'name', casttarget => 'text', castfunc => 'text(name)',
|
|
|
|
castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'name', casttarget => 'bpchar', castfunc => 'bpchar(name)',
|
|
|
|
castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'name', casttarget => 'varchar', castfunc => 'varchar(name)',
|
|
|
|
castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'text', casttarget => 'char', castfunc => 'char(text)',
|
|
|
|
castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'bpchar', casttarget => 'char', castfunc => 'char(text)',
|
|
|
|
castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'varchar', casttarget => 'char', castfunc => 'char(text)',
|
|
|
|
castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'text', casttarget => 'name', castfunc => 'name(text)',
|
|
|
|
castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'bpchar', casttarget => 'name', castfunc => 'name(bpchar)',
|
|
|
|
castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'varchar', casttarget => 'name', castfunc => 'name(varchar)',
|
|
|
|
castcontext => 'i', castmethod => 'f' },
|
|
|
|
|
|
|
|
# Allow explicit coercions between int4 and "char"
|
|
|
|
{ castsource => 'char', casttarget => 'int4', castfunc => 'int4(char)',
|
|
|
|
castcontext => 'e', castmethod => 'f' },
|
|
|
|
{ castsource => 'int4', casttarget => 'char', castfunc => 'char(int4)',
|
|
|
|
castcontext => 'e', castmethod => 'f' },
|
|
|
|
|
|
|
|
# pg_node_tree can be coerced to, but not from, text
|
|
|
|
{ castsource => 'pg_node_tree', casttarget => 'text', castfunc => '0',
|
|
|
|
castcontext => 'i', castmethod => 'b' },
|
|
|
|
|
|
|
|
# pg_ndistinct can be coerced to, but not from, bytea and text
|
|
|
|
{ castsource => 'pg_ndistinct', casttarget => 'bytea', castfunc => '0',
|
|
|
|
castcontext => 'i', castmethod => 'b' },
|
|
|
|
{ castsource => 'pg_ndistinct', casttarget => 'text', castfunc => '0',
|
|
|
|
castcontext => 'i', castmethod => 'i' },
|
|
|
|
|
|
|
|
# pg_dependencies can be coerced to, but not from, bytea and text
|
|
|
|
{ castsource => 'pg_dependencies', casttarget => 'bytea', castfunc => '0',
|
|
|
|
castcontext => 'i', castmethod => 'b' },
|
|
|
|
{ castsource => 'pg_dependencies', casttarget => 'text', castfunc => '0',
|
|
|
|
castcontext => 'i', castmethod => 'i' },
|
|
|
|
|
Add support for multivariate MCV lists
Introduce a third extended statistic type, supported by the CREATE
STATISTICS command - MCV lists, a generalization of the statistic
already built and used for individual columns.
Compared to the already supported types (n-distinct coefficients and
functional dependencies), MCV lists are more complex, include column
values and allow estimation of much wider range of common clauses
(equality and inequality conditions, IS NULL, IS NOT NULL etc.).
Similarly to the other types, a new pseudo-type (pg_mcv_list) is used.
Author: Tomas Vondra
Reviewed-by: Dean Rasheed, David Rowley, Mark Dilger, Alvaro Herrera
Discussion: https://postgr.es/m/dfdac334-9cf2-2597-fb27-f0fb3753f435@2ndquadrant.com
2019-03-27 18:32:18 +01:00
|
|
|
# pg_mcv_list can be coerced to, but not from, bytea and text
|
|
|
|
{ castsource => 'pg_mcv_list', casttarget => 'bytea', castfunc => '0',
|
|
|
|
castcontext => 'i', castmethod => 'b' },
|
|
|
|
{ castsource => 'pg_mcv_list', casttarget => 'text', castfunc => '0',
|
|
|
|
castcontext => 'i', castmethod => 'i' },
|
|
|
|
|
Replace our traditional initial-catalog-data format with a better design.
Historically, the initial catalog data to be installed during bootstrap
has been written in DATA() lines in the catalog header files. This had
lots of disadvantages: the format was badly underdocumented, it was
very difficult to edit the data in any mechanized way, and due to the
lack of any abstraction the data was verbose, hard to read/understand,
and easy to get wrong.
Hence, move this data into separate ".dat" files and represent it in a way
that can easily be read and rewritten by Perl scripts. The new format is
essentially "key => value" for each column; while it's a bit repetitive,
explicit labeling of each value makes the data far more readable and less
error-prone. Provide a way to abbreviate entries by omitting field values
that match a specified default value for their column. This allows removal
of a large amount of repetitive boilerplate and also lowers the barrier to
adding new columns.
Also teach genbki.pl how to translate symbolic OID references into
numeric OIDs for more cases than just "regproc"-like pg_proc references.
It can now do that for regprocedure-like references (thus solving the
problem that regproc is ambiguous for overloaded functions), operators,
types, opfamilies, opclasses, and access methods. Use this to turn
nearly all OID cross-references in the initial data into symbolic form.
This represents a very large step forward in readability and error
resistance of the initial catalog data. It should also reduce the
difficulty of renumbering OID assignments in uncommitted patches.
Also, solve the longstanding problem that frontend code that would like to
use OID macros and other information from the catalog headers often had
difficulty with backend-only code in the headers. To do this, arrange for
all generated macros, plus such other declarations as we deem fit, to be
placed in "derived" header files that are safe for frontend inclusion.
(Once clients migrate to using these pg_*_d.h headers, it will be possible
to get rid of the pg_*_fn.h headers, which only exist to quarantine code
away from clients. That is left for follow-on patches, however.)
The now-automatically-generated macros include the Anum_xxx and Natts_xxx
constants that we used to have to update by hand when adding or removing
catalog columns.
Replace the former manual method of generating OID macros for pg_type
entries with an automatic method, ensuring that all built-in types have
OID macros. (But note that this patch does not change the way that
OID macros for pg_proc entries are built and used. It's not clear that
making that match the other catalogs would be worth extra code churn.)
Add SGML documentation explaining what the new data format is and how to
work with it.
Despite being a very large change in the catalog headers, there is no
catversion bump here, because postgres.bki and related output files
haven't changed at all.
John Naylor, based on ideas from various people; review and minor
additional coding by me; previous review by Alvaro Herrera
Discussion: https://postgr.es/m/CAJVSVGWO48JbbwXkJz_yBFyGYW-M9YWxnPdxJBUosDC9ou_F0Q@mail.gmail.com
2018-04-08 19:16:50 +02:00
|
|
|
# Datetime category
|
|
|
|
{ castsource => 'date', casttarget => 'timestamp',
|
|
|
|
castfunc => 'timestamp(date)', castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'date', casttarget => 'timestamptz',
|
|
|
|
castfunc => 'timestamptz(date)', castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'time', casttarget => 'interval', castfunc => 'interval(time)',
|
|
|
|
castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'time', casttarget => 'timetz', castfunc => 'timetz(time)',
|
|
|
|
castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'timestamp', casttarget => 'date',
|
|
|
|
castfunc => 'date(timestamp)', castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'timestamp', casttarget => 'time',
|
|
|
|
castfunc => 'time(timestamp)', castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'timestamp', casttarget => 'timestamptz',
|
|
|
|
castfunc => 'timestamptz(timestamp)', castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'timestamptz', casttarget => 'date',
|
|
|
|
castfunc => 'date(timestamptz)', castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'timestamptz', casttarget => 'time',
|
|
|
|
castfunc => 'time(timestamptz)', castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'timestamptz', casttarget => 'timestamp',
|
|
|
|
castfunc => 'timestamp(timestamptz)', castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'timestamptz', casttarget => 'timetz',
|
|
|
|
castfunc => 'timetz(timestamptz)', castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'interval', casttarget => 'time', castfunc => 'time(interval)',
|
|
|
|
castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'timetz', casttarget => 'time', castfunc => 'time(timetz)',
|
|
|
|
castcontext => 'a', castmethod => 'f' },
|
|
|
|
|
|
|
|
# Geometric category
|
|
|
|
{ castsource => 'point', casttarget => 'box', castfunc => 'box(point)',
|
|
|
|
castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'lseg', casttarget => 'point', castfunc => 'point(lseg)',
|
|
|
|
castcontext => 'e', castmethod => 'f' },
|
|
|
|
{ castsource => 'path', casttarget => 'point', castfunc => 'point(path)',
|
|
|
|
castcontext => 'e', castmethod => 'f' },
|
|
|
|
{ castsource => 'path', casttarget => 'polygon', castfunc => 'polygon(path)',
|
|
|
|
castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'box', casttarget => 'point', castfunc => 'point(box)',
|
|
|
|
castcontext => 'e', castmethod => 'f' },
|
|
|
|
{ castsource => 'box', casttarget => 'lseg', castfunc => 'lseg(box)',
|
|
|
|
castcontext => 'e', castmethod => 'f' },
|
|
|
|
{ castsource => 'box', casttarget => 'polygon', castfunc => 'polygon(box)',
|
|
|
|
castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'box', casttarget => 'circle', castfunc => 'circle(box)',
|
|
|
|
castcontext => 'e', castmethod => 'f' },
|
|
|
|
{ castsource => 'polygon', casttarget => 'point', castfunc => 'point(polygon)',
|
|
|
|
castcontext => 'e', castmethod => 'f' },
|
|
|
|
{ castsource => 'polygon', casttarget => 'path', castfunc => 'path',
|
|
|
|
castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'polygon', casttarget => 'box', castfunc => 'box(polygon)',
|
|
|
|
castcontext => 'e', castmethod => 'f' },
|
|
|
|
{ castsource => 'polygon', casttarget => 'circle',
|
|
|
|
castfunc => 'circle(polygon)', castcontext => 'e', castmethod => 'f' },
|
|
|
|
{ castsource => 'circle', casttarget => 'point', castfunc => 'point(circle)',
|
|
|
|
castcontext => 'e', castmethod => 'f' },
|
|
|
|
{ castsource => 'circle', casttarget => 'box', castfunc => 'box(circle)',
|
|
|
|
castcontext => 'e', castmethod => 'f' },
|
|
|
|
{ castsource => 'circle', casttarget => 'polygon',
|
|
|
|
castfunc => 'polygon(circle)', castcontext => 'e', castmethod => 'f' },
|
|
|
|
|
|
|
|
# MAC address category
|
|
|
|
{ castsource => 'macaddr', casttarget => 'macaddr8', castfunc => 'macaddr8',
|
|
|
|
castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'macaddr8', casttarget => 'macaddr', castfunc => 'macaddr',
|
|
|
|
castcontext => 'i', castmethod => 'f' },
|
|
|
|
|
|
|
|
# INET category
|
|
|
|
{ castsource => 'cidr', casttarget => 'inet', castfunc => '0',
|
|
|
|
castcontext => 'i', castmethod => 'b' },
|
|
|
|
{ castsource => 'inet', casttarget => 'cidr', castfunc => 'cidr',
|
|
|
|
castcontext => 'a', castmethod => 'f' },
|
|
|
|
|
|
|
|
# BitString category
|
|
|
|
{ castsource => 'bit', casttarget => 'varbit', castfunc => '0',
|
|
|
|
castcontext => 'i', castmethod => 'b' },
|
|
|
|
{ castsource => 'varbit', casttarget => 'bit', castfunc => '0',
|
|
|
|
castcontext => 'i', castmethod => 'b' },
|
|
|
|
|
|
|
|
# Cross-category casts between bit and int4, int8
|
|
|
|
{ castsource => 'int8', casttarget => 'bit', castfunc => 'bit(int8,int4)',
|
|
|
|
castcontext => 'e', castmethod => 'f' },
|
|
|
|
{ castsource => 'int4', casttarget => 'bit', castfunc => 'bit(int4,int4)',
|
|
|
|
castcontext => 'e', castmethod => 'f' },
|
|
|
|
{ castsource => 'bit', casttarget => 'int8', castfunc => 'int8(bit)',
|
|
|
|
castcontext => 'e', castmethod => 'f' },
|
|
|
|
{ castsource => 'bit', casttarget => 'int4', castfunc => 'int4(bit)',
|
|
|
|
castcontext => 'e', castmethod => 'f' },
|
|
|
|
|
|
|
|
# Cross-category casts to and from TEXT
|
|
|
|
# We need entries here only for a few specialized cases where the behavior
|
|
|
|
# of the cast function differs from the datatype's I/O functions. Otherwise,
|
|
|
|
# parse_coerce.c will generate CoerceViaIO operations without any prompting.
|
|
|
|
# Note that the castcontext values specified here should be no stronger than
|
|
|
|
# parse_coerce.c's automatic casts ('a' to text, 'e' from text) else odd
|
|
|
|
# behavior will ensue when the automatic cast is applied instead of the
|
|
|
|
# pg_cast entry!
|
|
|
|
{ castsource => 'cidr', casttarget => 'text', castfunc => 'text(inet)',
|
|
|
|
castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'inet', casttarget => 'text', castfunc => 'text(inet)',
|
|
|
|
castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'bool', casttarget => 'text', castfunc => 'text(bool)',
|
|
|
|
castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'xml', casttarget => 'text', castfunc => '0',
|
|
|
|
castcontext => 'a', castmethod => 'b' },
|
|
|
|
{ castsource => 'text', casttarget => 'xml', castfunc => 'xml',
|
|
|
|
castcontext => 'e', castmethod => 'f' },
|
|
|
|
|
|
|
|
# Cross-category casts to and from VARCHAR
|
|
|
|
# We support all the same casts as for TEXT.
|
|
|
|
{ castsource => 'cidr', casttarget => 'varchar', castfunc => 'text(inet)',
|
|
|
|
castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'inet', casttarget => 'varchar', castfunc => 'text(inet)',
|
|
|
|
castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'bool', casttarget => 'varchar', castfunc => 'text(bool)',
|
|
|
|
castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'xml', casttarget => 'varchar', castfunc => '0',
|
|
|
|
castcontext => 'a', castmethod => 'b' },
|
|
|
|
{ castsource => 'varchar', casttarget => 'xml', castfunc => 'xml',
|
|
|
|
castcontext => 'e', castmethod => 'f' },
|
|
|
|
|
|
|
|
# Cross-category casts to and from BPCHAR
|
|
|
|
# We support all the same casts as for TEXT.
|
|
|
|
{ castsource => 'cidr', casttarget => 'bpchar', castfunc => 'text(inet)',
|
|
|
|
castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'inet', casttarget => 'bpchar', castfunc => 'text(inet)',
|
|
|
|
castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'bool', casttarget => 'bpchar', castfunc => 'text(bool)',
|
|
|
|
castcontext => 'a', castmethod => 'f' },
|
|
|
|
{ castsource => 'xml', casttarget => 'bpchar', castfunc => '0',
|
|
|
|
castcontext => 'a', castmethod => 'b' },
|
|
|
|
{ castsource => 'bpchar', casttarget => 'xml', castfunc => 'xml',
|
|
|
|
castcontext => 'e', castmethod => 'f' },
|
|
|
|
|
|
|
|
# Length-coercion functions
|
|
|
|
{ castsource => 'bpchar', casttarget => 'bpchar',
|
|
|
|
castfunc => 'bpchar(bpchar,int4,bool)', castcontext => 'i',
|
|
|
|
castmethod => 'f' },
|
|
|
|
{ castsource => 'varchar', casttarget => 'varchar',
|
|
|
|
castfunc => 'varchar(varchar,int4,bool)', castcontext => 'i',
|
|
|
|
castmethod => 'f' },
|
|
|
|
{ castsource => 'time', casttarget => 'time', castfunc => 'time(time,int4)',
|
|
|
|
castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'timestamp', casttarget => 'timestamp',
|
|
|
|
castfunc => 'timestamp(timestamp,int4)', castcontext => 'i',
|
|
|
|
castmethod => 'f' },
|
|
|
|
{ castsource => 'timestamptz', casttarget => 'timestamptz',
|
|
|
|
castfunc => 'timestamptz(timestamptz,int4)', castcontext => 'i',
|
|
|
|
castmethod => 'f' },
|
|
|
|
{ castsource => 'interval', casttarget => 'interval',
|
|
|
|
castfunc => 'interval(interval,int4)', castcontext => 'i',
|
|
|
|
castmethod => 'f' },
|
|
|
|
{ castsource => 'timetz', casttarget => 'timetz',
|
|
|
|
castfunc => 'timetz(timetz,int4)', castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'bit', casttarget => 'bit', castfunc => 'bit(bit,int4,bool)',
|
|
|
|
castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'varbit', casttarget => 'varbit', castfunc => 'varbit',
|
|
|
|
castcontext => 'i', castmethod => 'f' },
|
|
|
|
{ castsource => 'numeric', casttarget => 'numeric',
|
|
|
|
castfunc => 'numeric(numeric,int4)', castcontext => 'i', castmethod => 'f' },
|
|
|
|
|
|
|
|
# json to/from jsonb
|
|
|
|
{ castsource => 'json', casttarget => 'jsonb', castfunc => '0',
|
|
|
|
castcontext => 'a', castmethod => 'i' },
|
|
|
|
{ castsource => 'jsonb', casttarget => 'json', castfunc => '0',
|
|
|
|
castcontext => 'a', castmethod => 'i' },
|
|
|
|
|
|
|
|
# jsonb to numeric and bool types
|
|
|
|
{ castsource => 'jsonb', casttarget => 'bool', castfunc => 'bool(jsonb)',
|
|
|
|
castcontext => 'e', castmethod => 'f' },
|
|
|
|
{ castsource => 'jsonb', casttarget => 'numeric', castfunc => 'numeric(jsonb)',
|
|
|
|
castcontext => 'e', castmethod => 'f' },
|
|
|
|
{ castsource => 'jsonb', casttarget => 'int2', castfunc => 'int2(jsonb)',
|
|
|
|
castcontext => 'e', castmethod => 'f' },
|
|
|
|
{ castsource => 'jsonb', casttarget => 'int4', castfunc => 'int4(jsonb)',
|
|
|
|
castcontext => 'e', castmethod => 'f' },
|
|
|
|
{ castsource => 'jsonb', casttarget => 'int8', castfunc => 'int8(jsonb)',
|
|
|
|
castcontext => 'e', castmethod => 'f' },
|
|
|
|
{ castsource => 'jsonb', casttarget => 'float4', castfunc => 'float4(jsonb)',
|
|
|
|
castcontext => 'e', castmethod => 'f' },
|
|
|
|
{ castsource => 'jsonb', casttarget => 'float8', castfunc => 'float8(jsonb)',
|
|
|
|
castcontext => 'e', castmethod => 'f' },
|
|
|
|
|
|
|
|
]
|