Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "postgres.h"
00015
00016 #include "access/gin.h"
00017 #include "access/skey.h"
00018 #include "utils/array.h"
00019 #include "utils/builtins.h"
00020 #include "utils/lsyscache.h"
00021
00022
00023 #define GinOverlapStrategy 1
00024 #define GinContainsStrategy 2
00025 #define GinContainedStrategy 3
00026 #define GinEqualStrategy 4
00027
00028
00029
00030
00031
00032 Datum
00033 ginarrayextract(PG_FUNCTION_ARGS)
00034 {
00035
00036 ArrayType *array = PG_GETARG_ARRAYTYPE_P_COPY(0);
00037 int32 *nkeys = (int32 *) PG_GETARG_POINTER(1);
00038 bool **nullFlags = (bool **) PG_GETARG_POINTER(2);
00039 int16 elmlen;
00040 bool elmbyval;
00041 char elmalign;
00042 Datum *elems;
00043 bool *nulls;
00044 int nelems;
00045
00046 get_typlenbyvalalign(ARR_ELEMTYPE(array),
00047 &elmlen, &elmbyval, &elmalign);
00048
00049 deconstruct_array(array,
00050 ARR_ELEMTYPE(array),
00051 elmlen, elmbyval, elmalign,
00052 &elems, &nulls, &nelems);
00053
00054 *nkeys = nelems;
00055 *nullFlags = nulls;
00056
00057
00058 PG_RETURN_POINTER(elems);
00059 }
00060
00061
00062
00063
00064
00065
00066
00067 Datum
00068 ginarrayextract_2args(PG_FUNCTION_ARGS)
00069 {
00070 if (PG_NARGS() < 3)
00071 elog(ERROR, "ginarrayextract requires three arguments");
00072 return ginarrayextract(fcinfo);
00073 }
00074
00075
00076
00077
00078 Datum
00079 ginqueryarrayextract(PG_FUNCTION_ARGS)
00080 {
00081
00082 ArrayType *array = PG_GETARG_ARRAYTYPE_P_COPY(0);
00083 int32 *nkeys = (int32 *) PG_GETARG_POINTER(1);
00084 StrategyNumber strategy = PG_GETARG_UINT16(2);
00085
00086
00087
00088 bool **nullFlags = (bool **) PG_GETARG_POINTER(5);
00089 int32 *searchMode = (int32 *) PG_GETARG_POINTER(6);
00090 int16 elmlen;
00091 bool elmbyval;
00092 char elmalign;
00093 Datum *elems;
00094 bool *nulls;
00095 int nelems;
00096
00097 get_typlenbyvalalign(ARR_ELEMTYPE(array),
00098 &elmlen, &elmbyval, &elmalign);
00099
00100 deconstruct_array(array,
00101 ARR_ELEMTYPE(array),
00102 elmlen, elmbyval, elmalign,
00103 &elems, &nulls, &nelems);
00104
00105 *nkeys = nelems;
00106 *nullFlags = nulls;
00107
00108 switch (strategy)
00109 {
00110 case GinOverlapStrategy:
00111 *searchMode = GIN_SEARCH_MODE_DEFAULT;
00112 break;
00113 case GinContainsStrategy:
00114 if (nelems > 0)
00115 *searchMode = GIN_SEARCH_MODE_DEFAULT;
00116 else
00117 *searchMode = GIN_SEARCH_MODE_ALL;
00118 break;
00119 case GinContainedStrategy:
00120
00121 *searchMode = GIN_SEARCH_MODE_INCLUDE_EMPTY;
00122 break;
00123 case GinEqualStrategy:
00124 if (nelems > 0)
00125 *searchMode = GIN_SEARCH_MODE_DEFAULT;
00126 else
00127 *searchMode = GIN_SEARCH_MODE_INCLUDE_EMPTY;
00128 break;
00129 default:
00130 elog(ERROR, "ginqueryarrayextract: unknown strategy number: %d",
00131 strategy);
00132 }
00133
00134
00135 PG_RETURN_POINTER(elems);
00136 }
00137
00138
00139
00140
00141 Datum
00142 ginarrayconsistent(PG_FUNCTION_ARGS)
00143 {
00144 bool *check = (bool *) PG_GETARG_POINTER(0);
00145 StrategyNumber strategy = PG_GETARG_UINT16(1);
00146
00147
00148 int32 nkeys = PG_GETARG_INT32(3);
00149
00150
00151 bool *recheck = (bool *) PG_GETARG_POINTER(5);
00152
00153
00154 bool *nullFlags = (bool *) PG_GETARG_POINTER(7);
00155 bool res;
00156 int32 i;
00157
00158 switch (strategy)
00159 {
00160 case GinOverlapStrategy:
00161
00162 *recheck = false;
00163
00164 res = false;
00165 for (i = 0; i < nkeys; i++)
00166 {
00167 if (check[i] && !nullFlags[i])
00168 {
00169 res = true;
00170 break;
00171 }
00172 }
00173 break;
00174 case GinContainsStrategy:
00175
00176 *recheck = false;
00177
00178 res = true;
00179 for (i = 0; i < nkeys; i++)
00180 {
00181 if (!check[i] || nullFlags[i])
00182 {
00183 res = false;
00184 break;
00185 }
00186 }
00187 break;
00188 case GinContainedStrategy:
00189
00190 *recheck = true;
00191
00192 res = true;
00193 break;
00194 case GinEqualStrategy:
00195
00196 *recheck = true;
00197
00198
00199
00200
00201
00202
00203 res = true;
00204 for (i = 0; i < nkeys; i++)
00205 {
00206 if (!check[i])
00207 {
00208 res = false;
00209 break;
00210 }
00211 }
00212 break;
00213 default:
00214 elog(ERROR, "ginarrayconsistent: unknown strategy number: %d",
00215 strategy);
00216 res = false;
00217 }
00218
00219 PG_RETURN_BOOL(res);
00220 }