Re: [HACKERS] GSoC 2017: Foreign Key Arrays - Mailing list pgsql-hackers
From | Mark Rofail |
---|---|
Subject | Re: [HACKERS] GSoC 2017: Foreign Key Arrays |
Date | |
Msg-id | CAJvoCus-eACvA4-eHqrG4ft38z6wd6QLpu0Vfzu3J2xFfEotCg@mail.gmail.com Whole thread Raw |
In response to | Re: [HACKERS] GSoC 2017: Foreign Key Arrays (Alexander Korotkov <aekorotkov@gmail.com>) |
Responses |
Re: [HACKERS] GSoC 2017: Foreign Key Arrays
|
List | pgsql-hackers |
src/include/catalog/pg_amop.hsrc/include/catalog/pg_amproc.h src/include/catalog/pg_opclass.h src/include/catalog/pg_opfamily.h
I am going to post the steps I took to locate the procedure, the following is the trail of tables I followed.
pg_opfamily | pg_opfamily defines operator families. { opfmethod; /* index access method opfamily is for */ opfname; /* name of this opfamily */ opfnamespace; /* namespace of this opfamily */ opfowner; /* opfamily owner */ }
gin=# select oid, * from pg_opfamily where opfmethod = 2742; oid | opfmethod | opfname | opfnamespace | opfowner ------+-----------+----------- 2745 | 2742 | array_ops | 11 | 10 3659 | 2742 | tsvector_ops | 11 | 10 4036 | 2742 | jsonb_ops | 11 | 10 4037 | 2742 | jsonb_path_ops | 11 | 10 (4 rows)
|
pg_opclass | pg_opclass defines index access method operator classes. { gin=# select * from pg_opclass where opcfamily = 2745; opcmethod | opcname | opcnamespace | opcowner | opcfamily | opcintype | opcdefault | opckeytype -----------+-----------+------ 2742 | array_ops | 11 | 10 | 2745 | 2277 | t | 2283 (1 row)
|
pg_amproc | pg_amproc stores information about support procedures associated with access method operator families. { amprocfamily; /* the index opfamily this entry is for */ amproclefttype; /* procedure's left input data type */ amprocrighttype; /* procedure's right input data type */ amprocnum[1]; /* support procedure index */ amproc; /* OID of the proc */ } gin=# select * from pg_amproc where amprocfamily = 2745; amprocfamily | amproclefttype | amprocrighttype | amprocnum | amproc ------------------+----------- 2745 | 2277 | 2277 | 2 | pg_catalog.ginarrayextract 2745 | 2277 | 2277 | 3 | ginqueryarrayextract 2745 | 2277 | 2277 | 4 | ginarrayconsistent 2745 | 2277 | 2277 | 6 | ginarraytriconsistent (4 rows)
[1]amprocnum refers to this table |
pg_amop | pg_amop stores information about operators associated with access method operator families. { amopfamily; /* the index opfamily this entry is for */ amoplefttype; /* operator's left input data type */ amoprighttype; /* operator's right input data type */ amopstrategy; /* operator strategy number */ amoppurpose; /* is operator for 's'earch or 'o'rdering? */ amopopr; /* the operator's pg_operator OID */ amopmethod; /* the index access method this entry is for amopsortfamily; /* ordering opfamily OID, or 0 if search op }
=# select * from pg_amop where amopfamily = 2745; amopfamily | amoplefttype | amoprighttype | amopstrategy | amoppurpose | amopopr | amopmethod | amopsortfamily ------------+--------------+-- 2745 | 2277 | 2277 | 1 | s | 2750 | 2742 | 0 2745 | 2277 | 2277 | 2 | s | 2751 | 2742 | 0 2745 | 2277 | 2277 | 3 | s | 2752 | 2742 | 0 2745 | 2277 | 2277 | 4 | s | 1070 | 2742 | 0 (4 rows) |
I will need to add a record of my new operator to this table by appending this line to src/include/catalog/pg_amop.h
DATA(insert (2745 2277 2277 1 s 2750 2742 0 ));
This will result in the following entry
=# select * from pg_amop where amopfamily = 2745;
amopfamily | amoplefttype | amoprighttype | amopstrategy | amoppurpose | amopopr | amopmethod | amopsortfamily
------------+--------------+--
2745 | 2277 | 2283 | 1 | s | 2750 | 2742 | 0
this led me to pg_operator
pg_operator | pg_operator stores information about operators. {
postgres=# select * from pg_operator where oid = 2751; oprname | oprnamespace | oprowner | oprkind | oprcanmerge | oprcanhash | oprleft | oprright | oprresult | oprcom | oprnegate | oprcode | oprrest | oprjoin ---------+--------------+----- @> | 11 | 10 | b | f | f | 2277 | 2277 | 16 | 2752 | 0 | arraycontains | arraycontsel | arraycontjoinsel (1 row)
|
I will need to add a record of my new operator to this table by appending this line to src/include/catalog/pg_
However, as this is dependent on the procedure I have yet to create there are still uknown values
DATA(insert OID = <uniqueProcId> ( "@>" PGNSP PGUID b f f 2277 2283 16 2752 0 arraycontainselem ???? ???? ));
DESCR("contains");
#define OID_ARRAY_CONTAINS_OP <uniqueProcId>
This will lead to this entry
oprname | oprnamespace | oprowner | oprkind | oprcanmerge | oprcanhash | oprleft | oprright | oprresult | oprcom | oprnegate | oprcode | oprrest | oprjoin
---------+--------------+-----
@> | 11 | 10 | b | f | f | 2277 | 2283 | 16 | 2752 | 0 | arraycontainselem | ???? | ????
(1 row)
this led me to pg_proc
pg_proc | pg_proc stores information about functions (or procedures) { proname; /* procedure name */ pronamespace; /* OID of namespace containing this proc */ proowner; /* procedure owner */ prolang; /* OID of pg_language entry */ procost; /* estimated execution cost */ prorows; /* estimated # of rows out (if proretset) */ provariadic; /* element type of variadic array, or 0 */ protransform; /* transforms calls to it during planning */ proisagg; /* is it an aggregate? */ proiswindow; /* is it a window function? */ prosecdef; /* security definer */ proleakproof; /* is it a leak-proof function? */ proisstrict; /* strict with respect to NULLs? */ proretset; /* returns a set? */ provolatile; /* see PROVOLATILE_ categories below */ proparallel; /* see PROPARALLEL_ categories below */ pronargs; /* number of arguments */ pronargdefaults; /* number of arguments with defaults */ prorettype; /* OID of result type */ proargtypes; /* parameter types (excludes OUT params) */ proallargtypes[1]; /* all param types (NULL if IN only) */ proargmodes[1]; /* parameter modes (NULL if IN only) */ proargnames[1]; /* parameter names (NULL if no names) */ proargdefaults; /* list of expression trees for argument protrftypes[1]; /* types for which to apply transforms */ prosrc; /* procedure source text */ probin; /* secondary procedure info (can be NULL) */ proconfig[1]; /* procedure-local GUC settings */ proacl[1]; /* access permissions */ }
postgres=# select * from pg_proc where oid = 2748; proname | pronamespace | proowner | prolang | procost | prorows | provariadic | protransform | proisagg | proiswindow | prosecdef | proleakproof | proisstrict | proretset | provolatile | proparallel | pron args | pronargdefaults | prorettype | proargtypes | proallargtypes | proargmodes | proargnames | proargdefaults | protrftypes | prosrc | probin | proconfig | proacl ---------------+-------------- -----+-----------------+------ arraycontains | 11 | 10 | 12 | 1 | 0 | 0 | - | f | f | f | f | t | f | i | s | 2 | 0 | 16 | 2277 2277 | | | | | | arraycontains | | | (1 row) |
Datum
arraycontains(PG_FUNCTION_
{
AnyArrayType *array1 = PG_GETARG_ANY_ARRAY(0);
AnyArrayType *array2 = PG_GETARG_ANY_ARRAY(1);
Oid collation = PG_GET_COLLATION();
bool result;
result = array_contain_compare(array2, array1, collation, true,
&fcinfo->flinfo->fn_extra);
/* Avoid leaking memory when handed toasted input. */
AARR_FREE_IF_COPY(array1, 0);
AARR_FREE_IF_COPY(array2, 1);
PG_RETURN_BOOL(result);
}
Studying the syntax will help me produce a function that follows the postgres style rules.
pgsql-hackers by date: