Go to the documentation of this file.00001
00002
00003
00004 #include "postgres.h"
00005
00006 #include "access/gin.h"
00007 #include "access/skey.h"
00008 #include "catalog/pg_type.h"
00009
00010 #include "hstore.h"
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #define KEYFLAG 'K'
00021 #define VALFLAG 'V'
00022 #define NULLFLAG 'N'
00023
00024 PG_FUNCTION_INFO_V1(gin_extract_hstore);
00025 Datum gin_extract_hstore(PG_FUNCTION_ARGS);
00026
00027
00028 static text *
00029 makeitem(char *str, int len, char flag)
00030 {
00031 text *item;
00032
00033 item = (text *) palloc(VARHDRSZ + len + 1);
00034 SET_VARSIZE(item, VARHDRSZ + len + 1);
00035
00036 *VARDATA(item) = flag;
00037
00038 if (str && len > 0)
00039 memcpy(VARDATA(item) + 1, str, len);
00040
00041 return item;
00042 }
00043
00044 Datum
00045 gin_extract_hstore(PG_FUNCTION_ARGS)
00046 {
00047 HStore *hs = PG_GETARG_HS(0);
00048 int32 *nentries = (int32 *) PG_GETARG_POINTER(1);
00049 Datum *entries = NULL;
00050 HEntry *hsent = ARRPTR(hs);
00051 char *ptr = STRPTR(hs);
00052 int count = HS_COUNT(hs);
00053 int i;
00054
00055 *nentries = 2 * count;
00056 if (count)
00057 entries = (Datum *) palloc(sizeof(Datum) * 2 * count);
00058
00059 for (i = 0; i < count; ++i)
00060 {
00061 text *item;
00062
00063 item = makeitem(HS_KEY(hsent, ptr, i), HS_KEYLEN(hsent, i),
00064 KEYFLAG);
00065 entries[2 * i] = PointerGetDatum(item);
00066
00067 if (HS_VALISNULL(hsent, i))
00068 item = makeitem(NULL, 0, NULLFLAG);
00069 else
00070 item = makeitem(HS_VAL(hsent, ptr, i), HS_VALLEN(hsent, i),
00071 VALFLAG);
00072 entries[2 * i + 1] = PointerGetDatum(item);
00073 }
00074
00075 PG_RETURN_POINTER(entries);
00076 }
00077
00078 PG_FUNCTION_INFO_V1(gin_extract_hstore_query);
00079 Datum gin_extract_hstore_query(PG_FUNCTION_ARGS);
00080
00081 Datum
00082 gin_extract_hstore_query(PG_FUNCTION_ARGS)
00083 {
00084 int32 *nentries = (int32 *) PG_GETARG_POINTER(1);
00085 StrategyNumber strategy = PG_GETARG_UINT16(2);
00086 int32 *searchMode = (int32 *) PG_GETARG_POINTER(6);
00087 Datum *entries;
00088
00089 if (strategy == HStoreContainsStrategyNumber)
00090 {
00091
00092 entries = (Datum *)
00093 DatumGetPointer(DirectFunctionCall2(gin_extract_hstore,
00094 PG_GETARG_DATUM(0),
00095 PointerGetDatum(nentries)));
00096
00097 if (entries == NULL)
00098 *searchMode = GIN_SEARCH_MODE_ALL;
00099 }
00100 else if (strategy == HStoreExistsStrategyNumber)
00101 {
00102 text *query = PG_GETARG_TEXT_PP(0);
00103 text *item;
00104
00105 *nentries = 1;
00106 entries = (Datum *) palloc(sizeof(Datum));
00107 item = makeitem(VARDATA_ANY(query), VARSIZE_ANY_EXHDR(query), KEYFLAG);
00108 entries[0] = PointerGetDatum(item);
00109 }
00110 else if (strategy == HStoreExistsAnyStrategyNumber ||
00111 strategy == HStoreExistsAllStrategyNumber)
00112 {
00113 ArrayType *query = PG_GETARG_ARRAYTYPE_P(0);
00114 Datum *key_datums;
00115 bool *key_nulls;
00116 int key_count;
00117 int i,
00118 j;
00119 text *item;
00120
00121 deconstruct_array(query,
00122 TEXTOID, -1, false, 'i',
00123 &key_datums, &key_nulls, &key_count);
00124
00125 entries = (Datum *) palloc(sizeof(Datum) * key_count);
00126
00127 for (i = 0, j = 0; i < key_count; ++i)
00128 {
00129
00130 if (key_nulls[i])
00131 continue;
00132 item = makeitem(VARDATA(key_datums[i]), VARSIZE(key_datums[i]) - VARHDRSZ, KEYFLAG);
00133 entries[j++] = PointerGetDatum(item);
00134 }
00135
00136 *nentries = j;
00137
00138 if (j == 0 && strategy == HStoreExistsAllStrategyNumber)
00139 *searchMode = GIN_SEARCH_MODE_ALL;
00140 }
00141 else
00142 {
00143 elog(ERROR, "unrecognized strategy number: %d", strategy);
00144 entries = NULL;
00145 }
00146
00147 PG_RETURN_POINTER(entries);
00148 }
00149
00150 PG_FUNCTION_INFO_V1(gin_consistent_hstore);
00151 Datum gin_consistent_hstore(PG_FUNCTION_ARGS);
00152
00153 Datum
00154 gin_consistent_hstore(PG_FUNCTION_ARGS)
00155 {
00156 bool *check = (bool *) PG_GETARG_POINTER(0);
00157 StrategyNumber strategy = PG_GETARG_UINT16(1);
00158
00159
00160 int32 nkeys = PG_GETARG_INT32(3);
00161
00162
00163 bool *recheck = (bool *) PG_GETARG_POINTER(5);
00164 bool res = true;
00165 int32 i;
00166
00167 if (strategy == HStoreContainsStrategyNumber)
00168 {
00169
00170
00171
00172
00173
00174 *recheck = true;
00175 for (i = 0; i < nkeys; i++)
00176 {
00177 if (!check[i])
00178 {
00179 res = false;
00180 break;
00181 }
00182 }
00183 }
00184 else if (strategy == HStoreExistsStrategyNumber)
00185 {
00186
00187 *recheck = false;
00188 res = true;
00189 }
00190 else if (strategy == HStoreExistsAnyStrategyNumber)
00191 {
00192
00193 *recheck = false;
00194 res = true;
00195 }
00196 else if (strategy == HStoreExistsAllStrategyNumber)
00197 {
00198
00199 *recheck = false;
00200 for (i = 0; i < nkeys; i++)
00201 {
00202 if (!check[i])
00203 {
00204 res = false;
00205 break;
00206 }
00207 }
00208 }
00209 else
00210 elog(ERROR, "unrecognized strategy number: %d", strategy);
00211
00212 PG_RETURN_BOOL(res);
00213 }