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