Datum querytree(PG_FUNCTION_ARGS) { QUERYTYPE *query = (QUERYTYPE *) PG_GETARG_QUERYTYPE_P_COPY(0); INFIX nrm; text *res; ITEM *q; int4 len; if (query->size == 0) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("empty query"))); q = (ITEM *) palloc(sizeof(ITEM) * query->size); memcpy((void *) q, GETQUERY(query), sizeof(ITEM) * query->size); len = shorterquery(q, query->size); PG_FREE_IF_COPY(query, 0); if (len == 0) { res = (text *) palloc(1 + VARHDRSZ); SET_VARSIZE(res, 1 + VARHDRSZ); *((char *) VARDATA(res)) = 'T'; } else { nrm.curpol = q + len - 1; nrm.buflen = 32; nrm.cur = nrm.buf = (char *) palloc(sizeof(char) * nrm.buflen); *(nrm.cur) = '\0'; infix(&nrm, true); res = (text *) palloc(nrm.cur - nrm.buf + VARHDRSZ); SET_VARSIZE(res, nrm.cur - nrm.buf + VARHDRSZ); memcpy(VARDATA(res), nrm.buf, nrm.cur - nrm.buf); } pfree(q); PG_RETURN_POINTER(res); }
Datum querytree(PG_FUNCTION_ARGS) { QUERYTYPE *query = (QUERYTYPE *) PG_DETOAST_DATUM(PG_GETARG_POINTER(0)); INFIX nrm; text *res; ITEM *q; int4 len; if (query->size == 0) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("empty query"))); q = (ITEM *) palloc(sizeof(ITEM) * query->size); memcpy((void *) q, GETQUERY(query), sizeof(ITEM) * query->size); len = shorterquery(q, query->size); PG_FREE_IF_COPY(query, 0); if (len == 0) { res = cstring_to_text("T"); } else { nrm.curpol = q + len - 1; nrm.buflen = 32; nrm.cur = nrm.buf = (char *) palloc(sizeof(char) * nrm.buflen); *(nrm.cur) = '\0'; infix(&nrm, true); res = cstring_to_text_with_len(nrm.buf, nrm.cur - nrm.buf); } pfree(q); PG_RETURN_TEXT_P(res); }
Datum ginint4_queryextract(PG_FUNCTION_ARGS) { int32 *nentries = (int32 *) PG_GETARG_POINTER(1); StrategyNumber strategy = PG_GETARG_UINT16(2); Datum *res = NULL; *nentries = 0; if (strategy == BooleanSearchStrategy) { QUERYTYPE *query = (QUERYTYPE *) PG_DETOAST_DATUM_COPY(PG_GETARG_POINTER(0)); ITEM *items = GETQUERY(query); int i; if (query->size == 0) PG_RETURN_POINTER(NULL); if (shorterquery(items, query->size) == 0) elog(ERROR, "Query requires full scan, GIN doesn't support it"); pfree(query); query = (QUERYTYPE *) PG_DETOAST_DATUM(PG_GETARG_POINTER(0)); items = GETQUERY(query); res = (Datum *) palloc(sizeof(Datum) * query->size); *nentries = 0; for (i = 0; i < query->size; i++) if (items[i].type == VAL) { res[*nentries] = Int32GetDatum(items[i].val); (*nentries)++; } } else { ArrayType *query = PG_GETARG_ARRAYTYPE_P(0); int4 *arr; uint32 i; CHECKARRVALID(query); *nentries = ARRNELEMS(query); if (*nentries > 0) { res = (Datum *) palloc(sizeof(Datum) * (*nentries)); arr = ARRPTR(query); for (i = 0; i < *nentries; i++) res[i] = Int32GetDatum(arr[i]); } } if (*nentries == 0) { switch (strategy) { case BooleanSearchStrategy: case RTOverlapStrategyNumber: *nentries = -1; /* nobody can be found */ break; default: /* require fullscan: GIN can't find void * arrays */ break; } } PG_RETURN_POINTER(res); }