• After finding the arraycontains function, I implemented arraycontainselem that corresponds to the operator @<(anyarray, anyelem) ◦ Please read the attached patch file to view my progress.
• In addition to src/backend/utils/adt/arrayfuncs.c where I implemented arraycontainselem. ◦ I also edited pg_amop (src/include/catalog/pg_amop.h) since it stores information about operators associated with access method operator families. +DATA(insert ( 2745 2277 2283 2 s 2753 2742 0 )); { 2745: Oid amopfamily; (denotes gin array_ops) 277: Oid amoplefttype; (denotes anyaray) 2283: Oid amoprighttype; (denotes anyelem) 5: int16 amopstrategy; /* operator strategy number */ (denotes the new startegy that is yet to be created) 's': char amoppurpose; (denotes 's' for search) 2753: Oid amopopr; (denotes the new operator Oid) 2742: Oid amopmethod;(denotes gin) 0: Oid amopsortfamily; (0 since search operator) } ◦ And pg_operator (src/include/catalog/pg_operator.h) since it stores information about operators. +DATA(insert OID = 2753 ( "@>" PGNSP PGUID b f f 2277 2283 16 0 0 arraycontainselem 0 0 )); { "@>": NameData oprname; /* name of operator */ Oid oprnamespace; /* OID of namespace containing this oper */ Oid oprowner; /* operator owner */ 'b': char oprkind; /* 'l', 'r', or 'b' */ (denotes infix) 'f': bool oprcanmerge; /* can be used in merge join? */ 'f': bool oprcanhash; /* can be used in hash join? */ 277: Oid oprleft; (denotes anyaray) 2283: Oid oprright; (denotes anyelem) 16: Oid oprresult; (denotes boolean) 0: Oid oprcom; /* OID of commutator oper, or 0 if none */ (needs to be revisited) 0: Oid oprnegate; /* OID of negator oper, or 0 if none */ (needs to be revisited) arraycontainselem: regproc oprcode; /* OID of underlying function */ 0: regproc oprrest; /* OID of restriction estimator, or 0 */ 0: regproc oprjoin; /* OID of join estimator, or 0 */ }
diff --git a/src/backend/access/gin/ginarrayproc.c b/src/backend/access/gin/ginarrayproc.c index cc7435e030..14fedc8066 100644 --- a/src/backend/access/gin/ginarrayproc.c +++ b/src/backend/access/gin/ginarrayproc.c @@ -24,6 +24,7 @@ #define GinContainsStrategy 2 #define GinContainedStrategy 3 #define GinEqualStrategy 4 +#define GinContainsElemStrategy 5 /* @@ -110,7 +111,8 @@ ginqueryarrayextract(PG_FUNCTION_ARGS) case GinOverlapStrategy: *searchMode = GIN_SEARCH_MODE_DEFAULT; break; + case GinContainsElemStrategy: case GinContainsStrategy: if (nelems > 0) *searchMode = GIN_SEARCH_MODE_DEFAULT; else /* everything contains the empty set */ @@ -171,6 +173,7 @@ ginarrayconsistent(PG_FUNCTION_ARGS) } } break; + case GinContainsElemStrategy: case GinContainsStrategy: /* result is not lossy */ *recheck = false; @@ -258,7 +261,8 @@ ginarraytriconsistent(PG_FUNCTION_ARGS) } } break; - case GinContainsStrategy: + case GinContainsElemStrategy: case GinContainsStrategy: /* must have all elements in check[] true, and no nulls */ res = GIN_TRUE; for (i = 0; i < nkeys; i++) diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c index d9c8aa569c..e1ff6d33b5 100644 --- a/src/backend/utils/adt/arrayfuncs.c +++ b/src/backend/utils/adt/arrayfuncs.c @@ -4215,6 +4215,40 @@ arraycontains(PG_FUNCTION_ARGS) } Datum +arraycontainselem(PG_FUNCTION_ARGS) +{ + Datum *elem = PG_GETARG_DATUM(0); + AnyArrayType *array1; + AnyArrayType *array2 = PG_GETARG_ANY_ARRAY(1); + Oid collation = PG_GET_COLLATION(); + bool result; + + int16 typlen; + bool typbyval; + char typalign; + int nelems; + + /* we have one element */ + nelems= 1; + + /* get required info about the element type */ + get_typlenbyvalalign(ARR_ELEMTYPE(array), + &typlen, &typbyval, &typalign); + + /* now build the array */ + array1 = construct_array(&elem, nelems,collation, &typlen, &typbyval, &typalign); + + result = array_contain_compare(array2, array1, collation, true, + &fcinfo->flinfo->fn_extra); + + /* Avoid leaking memory when handed toasted input. */ + PG_FREE_IF_COPY(elem,0); + AARR_FREE_IF_COPY(array, 1); + + PG_RETURN_BOOL(result); +} + +Datum arraycontained(PG_FUNCTION_ARGS) { AnyArrayType *array1 = PG_GETARG_ANY_ARRAY(0); diff --git a/src/include/catalog/pg_amop.h b/src/include/catalog/pg_amop.h index da0228de6b..2da9002577 100644 --- a/src/include/catalog/pg_amop.h +++ b/src/include/catalog/pg_amop.h @@ -687,6 +687,8 @@ DATA(insert ( 2595 718 600 15 o 3291 783 1970 )); */ DATA(insert ( 2745 2277 2277 1 s 2750 2742 0 )); DATA(insert ( 2745 2277 2277 2 s 2751 2742 0 )); +//TODO link the operator's pg_operator OID +DATA(insert ( 2745 2277 2283 5 s 2753 2742 0 )); DATA(insert ( 2745 2277 2277 3 s 2752 2742 0 )); DATA(insert ( 2745 2277 2277 4 s 1070 2742 0 )); diff --git a/src/include/catalog/pg_operator.h b/src/include/catalog/pg_operator.h index ccbb17efec..626a0b1c49 100644 --- a/src/include/catalog/pg_operator.h +++ b/src/include/catalog/pg_operator.h @@ -1567,6 +1567,9 @@ DESCR("overlaps"); DATA(insert OID = 2751 ( "@>" PGNSP PGUID b f f 2277 2277 16 2752 0 arraycontains arraycontsel arraycontjoinsel )); DESCR("contains"); #define OID_ARRAY_CONTAINS_OP 2751 +DATA(insert OID = 2753 ( "@>" PGNSP PGUID b f f 2277 2283 16 2753 0 arraycontainselem 0 0 )); +DESCR("containselem"); +#define OID_ARRAY_CONTAINS_ELEM_OP 2753 DATA(insert OID = 2752 ( "<@" PGNSP PGUID b f f 2277 2277 16 2751 0 arraycontained arraycontsel arraycontjoinsel )); DESCR("is contained by"); #define OID_ARRAY_CONTAINED_OP 2752
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers