+/* triConsistent function is available only in 9.4 or later */
+#if PG_VERSION_NUM >= 90400
+Datum
+gin_bigm_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;
+
+ switch (strategy)
+ {
+ case LikeStrategyNumber:
+ /*
+ * Don't recheck the heap tuple against the query if either
+ * pg_bigm.enable_recheck is disabled or the search word is the
+ * special one so that the index can return the exact result.
+ */
+ res = (bigm_enable_recheck &&
+ (*((bool *) extra_data) || (nkeys != 1))) ?
+ GIN_MAYBE : GIN_TRUE;
+
+ /* Check if all extracted bigrams are presented. */
+ for (i = 0; i < nkeys; i++)
+ {
+ if (check[i] == GIN_FALSE)
+ {
+ res = GIN_FALSE;
+ break;
+ }
+ }
+ break;
+ case SimilarityStrategyNumber:
+ /* Count the matches */
+ ntrue = 0;
+ for (i = 0; i < nkeys; i++)
+ {
+ if (check[i] != GIN_FALSE)
+ ntrue++;
+ }
+
+ /*
+ * See comment in gin_bigm_consistent() about upper bound formula
+ */
+ res = (nkeys == 0) ? GIN_FALSE :
+ (((((float4) ntrue) / ((float4) nkeys)) >=
+ (float4) bigm_similarity_limit) ? GIN_MAYBE : GIN_FALSE);
+
+ if (res != GIN_FALSE && !bigm_enable_recheck)
+ res = GIN_TRUE;
+ break;
+ default:
+ elog(ERROR, "unrecognized strategy number: %d", strategy);
+ res = GIN_FALSE; /* keep compiler quiet */
+ break;
+ }
+
+ PG_RETURN_GIN_TERNARY_VALUE(res);
+}
+#endif /* PG_VERSION_NUM >= 90400 */
+