/* * In all cases, GIN_TRUE is at least as favorable to inclusion as * GIN_MAYBE. If no better option is available, simply treat * GIN_MAYBE as if it were GIN_TRUE and apply the same test as the binary * consistent function. */ Datum gin_trgm_triconsistent(PG_FUNCTION_ARGS) { GinTernaryValue *check = (GinTernaryValue *) PG_GETARG_POINTER(0); StrategyNumber strategy = PG_GETARG_UINT16(1); /* text *query = PG_GETARG_TEXT_P(2); */ int32 nkeys = PG_GETARG_INT32(3); Pointer *extra_data = (Pointer *) PG_GETARG_POINTER(4); GinTernaryValue res = GIN_MAYBE; int32 i, ntrue; bool *boolcheck; switch (strategy) { case SimilarityStrategyNumber: /* Count the matches */ ntrue = 0; for (i = 0; i < nkeys; i++) { if (check[i] != GIN_FALSE) ntrue++; } /* * See comment in gin_trgm_consistent() about * upper bound formula */ res = (nkeys == 0) ? GIN_FALSE : (((((float4) ntrue) / ((float4) nkeys)) >= trgm_limit) ? GIN_MAYBE : GIN_FALSE); break; case ILikeStrategyNumber: #ifndef IGNORECASE elog(ERROR, "cannot handle ~~* with case-sensitive trigrams"); #endif /* FALL THRU */ case LikeStrategyNumber: /* Check if all extracted trigrams are presented. */ res = GIN_MAYBE; for (i = 0; i < nkeys; i++) { if (check[i] == GIN_FALSE) { res = GIN_FALSE; break; } } break; case RegExpICaseStrategyNumber: #ifndef IGNORECASE elog(ERROR, "cannot handle ~* with case-sensitive trigrams"); #endif /* FALL THRU */ case RegExpStrategyNumber: if (nkeys < 1) { /* Regex processing gave no result: do full index scan */ res = GIN_MAYBE; } else { /* * As trigramsMatchGraph implements a montonic boolean function, * promoting all GIN_MAYBE keys to GIN_TRUE will give a * conservative result. */ boolcheck = (bool *) palloc(sizeof(bool) * nkeys); for (i = 0; i < nkeys; i++) boolcheck[i] = (check[i] != GIN_FALSE); if (!trigramsMatchGraph((TrgmPackedGraph *) extra_data[0], boolcheck)) res = GIN_FALSE; pfree(boolcheck); } break; default: elog(ERROR, "unrecognized strategy number: %d", strategy); res = GIN_FALSE; /* keep compiler quiet */ break; } /* All cases served by this function are inexact */ Assert(res != GIN_TRUE); PG_RETURN_GIN_TERNARY_VALUE(res); }
Datum gin_trgm_consistent(PG_FUNCTION_ARGS) { bool *check = (bool *) PG_GETARG_POINTER(0); StrategyNumber strategy = PG_GETARG_UINT16(1); /* text *query = PG_GETARG_TEXT_P(2); */ int32 nkeys = PG_GETARG_INT32(3); Pointer *extra_data = (Pointer *) PG_GETARG_POINTER(4); bool *recheck = (bool *) PG_GETARG_POINTER(5); bool res; int32 i, ntrue; /* All cases served by this function are inexact */ *recheck = true; switch (strategy) { case SimilarityStrategyNumber: /* Count the matches */ ntrue = 0; for (i = 0; i < nkeys; i++) { if (check[i]) ntrue++; } #ifdef DIVUNION res = (nkeys == ntrue) ? true : ((((((float4) ntrue) / ((float4) (nkeys - ntrue)))) >= trgm_limit) ? true : false); #else res = (nkeys == 0) ? false : ((((((float4) ntrue) / ((float4) nkeys))) >= trgm_limit) ? true : false); #endif break; case ILikeStrategyNumber: #ifndef IGNORECASE elog(ERROR, "cannot handle ~~* with case-sensitive trigrams"); #endif /* FALL THRU */ case LikeStrategyNumber: /* Check if all extracted trigrams are presented. */ res = true; for (i = 0; i < nkeys; i++) { if (!check[i]) { res = false; break; } } break; case RegExpICaseStrategyNumber: #ifndef IGNORECASE elog(ERROR, "cannot handle ~* with case-sensitive trigrams"); #endif /* FALL THRU */ case RegExpStrategyNumber: if (nkeys < 1) { /* Regex processing gave no result: do full index scan */ res = true; } else res = trigramsMatchGraph((TrgmPackedGraph *) extra_data[0], check); break; default: elog(ERROR, "unrecognized strategy number: %d", strategy); res = false; /* keep compiler quiet */ break; } PG_RETURN_BOOL(res); }
Datum gin_trgm_consistent(PG_FUNCTION_ARGS) { bool *check = (bool *) PG_GETARG_POINTER(0); StrategyNumber strategy = PG_GETARG_UINT16(1); /* text *query = PG_GETARG_TEXT_P(2); */ int32 nkeys = PG_GETARG_INT32(3); Pointer *extra_data = (Pointer *) PG_GETARG_POINTER(4); bool *recheck = (bool *) PG_GETARG_POINTER(5); bool res; int32 i, ntrue; /* All cases served by this function are inexact */ *recheck = true; switch (strategy) { case SimilarityStrategyNumber: /* Count the matches */ ntrue = 0; for (i = 0; i < nkeys; i++) { if (check[i]) ntrue++; } /*-------------------- * If DIVUNION is defined then similarity formula is: * c / (len1 + len2 - c) * where c is number of common trigrams and it stands as ntrue in * this code. Here we don't know value of len2 but we can assume * that c (ntrue) is a lower bound of len2, so upper bound of * similarity is: * c / (len1 + c - c) => c / len1 * If DIVUNION is not defined then similarity formula is: * c / max(len1, len2) * And again, c (ntrue) is a lower bound of len2, but c <= len1 * just by definition and, consequently, upper bound of * similarity is just c / len1. * So, independly on DIVUNION the upper bound formula is the same. */ res = (nkeys == 0) ? false : ((((((float4) ntrue) / ((float4) nkeys))) >= trgm_limit) ? true : false); break; case ILikeStrategyNumber: #ifndef IGNORECASE elog(ERROR, "cannot handle ~~* with case-sensitive trigrams"); #endif /* FALL THRU */ case LikeStrategyNumber: /* Check if all extracted trigrams are presented. */ res = true; for (i = 0; i < nkeys; i++) { if (!check[i]) { res = false; break; } } break; case RegExpICaseStrategyNumber: #ifndef IGNORECASE elog(ERROR, "cannot handle ~* with case-sensitive trigrams"); #endif /* FALL THRU */ case RegExpStrategyNumber: if (nkeys < 1) { /* Regex processing gave no result: do full index scan */ res = true; } else res = trigramsMatchGraph((TrgmPackedGraph *) extra_data[0], check); break; default: elog(ERROR, "unrecognized strategy number: %d", strategy); res = false; /* keep compiler quiet */ break; } PG_RETURN_BOOL(res); }