/* * is there value 'val' in array or not ? */ static bool checkcondition_str(void *checkval, QueryOperand *val) { CHKVAL *chkval = (CHKVAL *) checkval; WordEntry *StopLow = chkval->arrb; WordEntry *StopHigh = chkval->arre; WordEntry *StopMiddle = StopHigh; int difference = -1; bool res = false; /* Loop invariant: StopLow <= val < StopHigh */ while (StopLow < StopHigh) { StopMiddle = StopLow + (StopHigh - StopLow) / 2; difference = tsCompareString(chkval->operand + val->distance, val->length, chkval->values + StopMiddle->pos, StopMiddle->len, false); if (difference == 0) { res = (val->weight && StopMiddle->haspos) ? checkclass_str(chkval, StopMiddle, val) : true; break; } else if (difference > 0) StopLow = StopMiddle + 1; else StopHigh = StopMiddle; } if (!res && val->prefix) { /* * there was a failed exact search, so we should scan further to find * a prefix match. */ if (StopLow >= StopHigh) StopMiddle = StopHigh; while (res == false && StopMiddle < chkval->arre && tsCompareString(chkval->operand + val->distance, val->length, chkval->values + StopMiddle->pos, StopMiddle->len, true) == 0) { res = (val->weight && StopMiddle->haspos) ? checkclass_str(chkval, StopMiddle, val) : true; StopMiddle++; } } return res; }
static void hlfinditem(HeadlineParsedText *prs, TSQuery query, char *buf, int buflen) { int i; QueryItem *item = GETQUERY(query); HeadlineWordEntry *word; while (prs->curwords + query->size >= prs->lenwords) { prs->lenwords *= 2; prs->words = (HeadlineWordEntry *) repalloc((void *) prs->words, prs->lenwords * sizeof(HeadlineWordEntry)); } word = &(prs->words[prs->curwords - 1]); for (i = 0; i < query->size; i++) { if (item->type == QI_VAL && tsCompareString(GETOPERAND(query) + item->qoperand.distance, item->qoperand.length, buf, buflen, item->qoperand.prefix) == 0) { if (word->item) { memcpy(&(prs->words[prs->curwords]), word, sizeof(HeadlineWordEntry)); prs->words[prs->curwords].item = &item->qoperand; prs->words[prs->curwords].repeated = 1; prs->curwords++; } else word->item = &item->qoperand; } item++; } }
/* * Order: haspos, len, word, for all positions (pos, weight) */ static int silly_cmp_tsvector(const TSVector a, const TSVector b) { if (VARSIZE(a) < VARSIZE(b)) return -1; else if (VARSIZE(a) > VARSIZE(b)) return 1; else if (a->size < b->size) return -1; else if (a->size > b->size) return 1; else { WordEntry *aptr = ARRPTR(a); WordEntry *bptr = ARRPTR(b); int i = 0; int res; for (i = 0; i < a->size; i++) { if (aptr->haspos != bptr->haspos) { return (aptr->haspos > bptr->haspos) ? -1 : 1; } else if ((res = tsCompareString(STRPTR(a) + aptr->pos, aptr->len, STRPTR(b) + bptr->pos, bptr->len, false)) != 0) { return res; } else if (aptr->haspos) { WordEntryPos *ap = POSDATAPTR(a, aptr); WordEntryPos *bp = POSDATAPTR(b, bptr); int j; if (POSDATALEN(a, aptr) != POSDATALEN(b, bptr)) return (POSDATALEN(a, aptr) > POSDATALEN(b, bptr)) ? -1 : 1; for (j = 0; j < POSDATALEN(a, aptr); j++) { if (WEP_GETPOS(*ap) != WEP_GETPOS(*bp)) { return (WEP_GETPOS(*ap) > WEP_GETPOS(*bp)) ? -1 : 1; } else if (WEP_GETWEIGHT(*ap) != WEP_GETWEIGHT(*bp)) { return (WEP_GETWEIGHT(*ap) > WEP_GETWEIGHT(*bp)) ? -1 : 1; } ap++, bp++; } } aptr++; bptr++; } } return 0; }
/* * sort QueryOperands by (length, word) */ static int compareQueryOperand(const void *a, const void *b, void *arg) { char *operand = (char *) arg; QueryOperand *qa = (*(QueryOperand *const *) a); QueryOperand *qb = (*(QueryOperand *const *) b); return tsCompareString(operand + qa->distance, qa->length, operand + qb->distance, qb->length, false); }
/* Compare two WordEntryIN values for qsort */ static int compareentry(const void *va, const void *vb, void *arg) { const WordEntryIN *a = (const WordEntryIN *) va; const WordEntryIN *b = (const WordEntryIN *) vb; char *BufferStr = (char *) arg; return tsCompareString(&BufferStr[a->entry.pos], a->entry.len, &BufferStr[b->entry.pos], b->entry.len, false); }
/* * Sort comparator for QTNodes. * * The sort order is somewhat arbitrary. */ int QTNodeCompare(QTNode *an, QTNode *bn) { /* since this function recurses, it could be driven to stack overflow. */ check_stack_depth(); if (an->valnode->type != bn->valnode->type) return (an->valnode->type > bn->valnode->type) ? -1 : 1; if (an->valnode->type == QI_OPR) { QueryOperator *ao = &an->valnode->qoperator; QueryOperator *bo = &bn->valnode->qoperator; if (ao->oper != bo->oper) return (ao->oper > bo->oper) ? -1 : 1; if (an->nchild != bn->nchild) return (an->nchild > bn->nchild) ? -1 : 1; { int i, res; for (i = 0; i < an->nchild; i++) if ((res = QTNodeCompare(an->child[i], bn->child[i])) != 0) return res; } if (ao->oper == OP_PHRASE && ao->distance != bo->distance) return (ao->distance > bo->distance) ? -1 : 1; return 0; } else if (an->valnode->type == QI_VAL) { QueryOperand *ao = &an->valnode->qoperand; QueryOperand *bo = &bn->valnode->qoperand; if (ao->valcrc != bo->valcrc) { return (ao->valcrc > bo->valcrc) ? -1 : 1; } return tsCompareString(an->word, ao->length, bn->word, bo->length, false); } else { elog(ERROR, "unrecognized QueryItem type: %d", an->valnode->type); return 0; /* keep compiler quiet */ } }
datum_t gin_cmp_tslexeme(PG_FUNC_ARGS) { text* a = ARG_TEXT_PP(0); text* b = ARG_TEXT_PP(1); int cmp; cmp = tsCompareString(VLA_DATA_ANY(a), VLA_SZ_ANY_EXHDR(a), VLA_DATA_ANY(b), VLA_SZ_ANY_EXHDR(b), false); PG_FREE_IF_COPY(a, 0); PG_FREE_IF_COPY(b, 1); RET_INT32(cmp); }
Datum gin_cmp_tslexeme(PG_FUNCTION_ARGS) { text *a = PG_GETARG_TEXT_PP(0); text *b = PG_GETARG_TEXT_PP(1); int cmp; cmp = tsCompareString(VARDATA_ANY(a), VARSIZE_ANY_EXHDR(a), VARDATA_ANY(b), VARSIZE_ANY_EXHDR(b), false); PG_FREE_IF_COPY(a, 0); PG_FREE_IF_COPY(b, 1); PG_RETURN_INT32(cmp); }
int QTNodeCompare(QTNode *an, QTNode *bn) { /* since this function recurses, it could be driven to stack overflow. */ check_stack_depth(); if (an->valnode->type != bn->valnode->type) return (an->valnode->type > bn->valnode->type) ? -1 : 1; if (an->valnode->type == QI_OPR) { QueryOperator *ao = &an->valnode->qoperator; QueryOperator *bo = &bn->valnode->qoperator; if (ao->oper != bo->oper) return (ao->oper > bo->oper) ? -1 : 1; if (an->nchild != bn->nchild) return (an->nchild > bn->nchild) ? -1 : 1; { int i, res; for (i = 0; i < an->nchild; i++) if ((res = QTNodeCompare(an->child[i], bn->child[i])) != 0) return res; } return 0; } else { QueryOperand *ao = &an->valnode->qoperand; QueryOperand *bo = &bn->valnode->qoperand; Assert(an->valnode->type == QI_VAL); if (ao->valcrc != bo->valcrc) { return (ao->valcrc > bo->valcrc) ? -1 : 1; } return tsCompareString(an->word, ao->length, bn->word, bo->length, false); } }
/* * to_tsvector */ static int compareWORD(const void *a, const void *b) { int res; res = tsCompareString( ((const ParsedWord *) a)->word, ((const ParsedWord *) a)->len, ((const ParsedWord *) b)->word, ((const ParsedWord *) b)->len, false); if (res == 0) { if (((const ParsedWord *) a)->pos.pos == ((const ParsedWord *) b)->pos.pos) return 0; res = (((const ParsedWord *) a)->pos.pos > ((const ParsedWord *) b)->pos.pos) ? 1 : -1; } return res; }
datum_t gin_cmp_prefix(PG_FUNC_ARGS) { text *a = ARG_TEXT_PP(0); text *b = ARG_TEXT_PP(1); #ifdef NOT_USED strat_nr_t strategy = ARG_UINT16(2); pointer_p extra_data = ARG_POINTER(3); #endif int cmp; cmp = tsCompareString(VLA_DATA_ANY(a), VLA_SZ_ANY_EXHDR(a), VLA_DATA_ANY(b), VLA_SZ_ANY_EXHDR(b), true); if (cmp < 0) cmp = 1; /* prevent continue scan */ PG_FREE_IF_COPY(a, 0); PG_FREE_IF_COPY(b, 1); RET_INT32(cmp); }
Datum gin_cmp_prefix(PG_FUNCTION_ARGS) { text *a = PG_GETARG_TEXT_PP(0); text *b = PG_GETARG_TEXT_PP(1); #ifdef NOT_USED StrategyNumber strategy = PG_GETARG_UINT16(2); Pointer extra_data = PG_GETARG_POINTER(3); #endif int cmp; cmp = tsCompareString(VARDATA_ANY(a), VARSIZE_ANY_EXHDR(a), VARDATA_ANY(b), VARSIZE_ANY_EXHDR(b), true); if (cmp < 0) cmp = 1; /* prevent continue scan */ PG_FREE_IF_COPY(a, 0); PG_FREE_IF_COPY(b, 1); PG_RETURN_INT32(cmp); }