/* * This function is used for morph parsing. * * The value is passed to parsetext which will call the right dictionary to * lexize the word. If it turns out to be a stopword, we push a QI_VALSTOP * to the stack. * * All words belonging to the same variant are pushed as an ANDed list, * and different variants are ORred together. */ static void pushval_morph(Datum opaque, TSQueryParserState state, char *strval, int lenval, int2 weight, bool prefix) { int4 count = 0; ParsedText prs; uint32 variant, pos, cntvar = 0, cntpos = 0, cnt = 0; Oid cfg_id = DatumGetObjectId(opaque); /* the input is actually * an Oid, not a pointer */ prs.lenwords = 4; prs.curwords = 0; prs.pos = 0; prs.words = (ParsedWord *) palloc(sizeof(ParsedWord) * prs.lenwords); parsetext(cfg_id, &prs, strval, lenval); if (prs.curwords > 0) { while (count < prs.curwords) { pos = prs.words[count].pos.pos; cntvar = 0; while (count < prs.curwords && pos == prs.words[count].pos.pos) { variant = prs.words[count].nvariant; cnt = 0; while (count < prs.curwords && pos == prs.words[count].pos.pos && variant == prs.words[count].nvariant) { pushValue(state, prs.words[count].word, prs.words[count].len, weight, ((prs.words[count].flags & TSL_PREFIX) || prefix) ? true : false); pfree(prs.words[count].word); if (cnt) pushOperator(state, OP_AND); cnt++; count++; } if (cntvar) pushOperator(state, OP_OR); cntvar++; } if (cntpos) pushOperator(state, OP_AND); cntpos++; } pfree(prs.words); } else pushStop(state); }
/* * This function is used for morph parsing. * * The value is passed to parsetext which will call the right dictionary to * lexize the word. If it turns out to be a stopword, we push a QI_VALSTOP * to the stack. * * All words belonging to the same variant are pushed as an ANDed list, * and different variants are ORed together. */ static void pushval_morph(Datum opaque, TSQueryParserState state, char *strval, int lenval, int16 weight, bool prefix) { int32 count = 0; ParsedText prs; uint32 variant, pos = 0, cntvar = 0, cntpos = 0, cnt = 0; MorphOpaque *data = (MorphOpaque *) DatumGetPointer(opaque); prs.lenwords = 4; prs.curwords = 0; prs.pos = 0; prs.words = (ParsedWord *) palloc(sizeof(ParsedWord) * prs.lenwords); parsetext(data->cfg_id, &prs, strval, lenval); if (prs.curwords > 0) { while (count < prs.curwords) { /* * Were any stop words removed? If so, fill empty positions with * placeholders linked by an appropriate operator. */ if (pos > 0 && pos + 1 < prs.words[count].pos.pos) { while (pos + 1 < prs.words[count].pos.pos) { /* put placeholders for each missing stop word */ pushStop(state); if (cntpos) pushOperator(state, data->qoperator, 1); cntpos++; pos++; } } /* save current word's position */ pos = prs.words[count].pos.pos; /* Go through all variants obtained from this token */ cntvar = 0; while (count < prs.curwords && pos == prs.words[count].pos.pos) { variant = prs.words[count].nvariant; /* Push all words belonging to the same variant */ cnt = 0; while (count < prs.curwords && pos == prs.words[count].pos.pos && variant == prs.words[count].nvariant) { pushValue(state, prs.words[count].word, prs.words[count].len, weight, ((prs.words[count].flags & TSL_PREFIX) || prefix)); pfree(prs.words[count].word); if (cnt) pushOperator(state, OP_AND, 0); cnt++; count++; } if (cntvar) pushOperator(state, OP_OR, 0); cntvar++; } if (cntpos) { /* distance may be useful */ pushOperator(state, data->qoperator, 1); } cntpos++; } pfree(prs.words); } else pushStop(state); }