示例#1
0
/*
 * citextcmp()
 * Internal comparison function for citext strings.
 * Returns int32 negative, zero, or positive.
 */
static int32
citextcmp(text *left, text *right, Oid collid)
{
	char	   *lcstr,
			   *rcstr;
	int32		result;

	/*
	 * We must do our str_tolower calls with DEFAULT_COLLATION_OID, not the
	 * input collation as you might expect.  This is so that the behavior of
	 * citext's equality and hashing functions is not collation-dependent.  We
	 * should change this once the core infrastructure is able to cope with
	 * collation-dependent equality and hashing functions.
	 */

	lcstr = str_tolower(VARDATA_ANY(left), VARSIZE_ANY_EXHDR(left), DEFAULT_COLLATION_OID);
	rcstr = str_tolower(VARDATA_ANY(right), VARSIZE_ANY_EXHDR(right), DEFAULT_COLLATION_OID);

	result = varstr_cmp(lcstr, strlen(lcstr),
						rcstr, strlen(rcstr),
						collid);

	pfree(lcstr);
	pfree(rcstr);

	return result;
}
示例#2
0
Datum
gin_compare_jsonb(PG_FUNCTION_ARGS)
{
	text	   *arg1 = PG_GETARG_TEXT_PP(0);
	text	   *arg2 = PG_GETARG_TEXT_PP(1);
	int32		result;
	char	   *a1p,
			   *a2p;
	int			len1,
				len2;

	a1p = VARDATA_ANY(arg1);
	a2p = VARDATA_ANY(arg2);

	len1 = VARSIZE_ANY_EXHDR(arg1);
	len2 = VARSIZE_ANY_EXHDR(arg2);

	/* Compare text as bttextcmp does, but always using C collation */
	result = varstr_cmp(a1p, len1, a2p, len2, C_COLLATION_OID);

	PG_FREE_IF_COPY(arg1, 0);
	PG_FREE_IF_COPY(arg2, 1);

	PG_RETURN_INT32(result);
}
示例#3
0
/*
 *		nameeq	- returns 1 iff arguments are equal
 *		namene	- returns 1 iff arguments are not equal
 *		namelt	- returns 1 iff a < b
 *		namele	- returns 1 iff a <= b
 *		namegt	- returns 1 iff a > b
 *		namege	- returns 1 iff a >= b
 *
 * Note that the use of strncmp with NAMEDATALEN limit is mostly historical;
 * strcmp would do as well, because we do not allow NAME values that don't
 * have a '\0' terminator.  Whatever might be past the terminator is not
 * considered relevant to comparisons.
 */
static int
namecmp(Name arg1, Name arg2, Oid collid)
{
	/* Fast path for common case used in system catalogs */
	if (collid == C_COLLATION_OID)
		return strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN);

	/* Else rely on the varstr infrastructure */
	return varstr_cmp(NameStr(*arg1), strlen(NameStr(*arg1)),
					  NameStr(*arg2), strlen(NameStr(*arg2)),
					  collid);
}
示例#4
0
/* text_cmp()
 * Internal comparison function for text strings.
 * Returns -1, 0 or 1
 */
static int
text_cmp(text *arg1, text *arg2, Oid collid)
{
	char	   *a1p,
			   *a2p;
	int			len1,
				len2;

	a1p = VARDATA_ANY(arg1);
	a2p = VARDATA_ANY(arg2);

	len1 = VARSIZE_ANY_EXHDR(arg1);
	len2 = VARSIZE_ANY_EXHDR(arg2);

	return varstr_cmp(a1p, len1, a2p, len2, collid);
}
示例#5
0
Datum
bpchar_smaller(PG_FUNCTION_ARGS)
{
	BpChar	   *arg1 = PG_GETARG_BPCHAR_P(0);
	BpChar	   *arg2 = PG_GETARG_BPCHAR_P(1);
	int			len1,
				len2;
	int			cmp;

	len1 = bcTruelen(arg1);
	len2 = bcTruelen(arg2);

	cmp = varstr_cmp(VARDATA(arg1), len1, VARDATA(arg2), len2);

	PG_RETURN_BPCHAR_P((cmp <= 0) ? arg1 : arg2);
}
示例#6
0
/*
 * citextcmp()
 * Internal comparison function for citext strings.
 * Returns int32 negative, zero, or positive.
 */
static int32
citextcmp(text *left, text *right)
{
	char	   *lcstr,
			   *rcstr;
	int32		result;

	lcstr = str_tolower(VARDATA_ANY(left), VARSIZE_ANY_EXHDR(left));
	rcstr = str_tolower(VARDATA_ANY(right), VARSIZE_ANY_EXHDR(right));

	result = varstr_cmp(lcstr, strlen(lcstr),
						rcstr, strlen(rcstr));

	pfree(lcstr);
	pfree(rcstr);

	return result;
}
示例#7
0
Datum
bpcharcmp(PG_FUNCTION_ARGS)
{
	BpChar	   *arg1 = PG_GETARG_BPCHAR_P(0);
	BpChar	   *arg2 = PG_GETARG_BPCHAR_P(1);
	int			len1,
				len2;
	int			cmp;

	len1 = bcTruelen(arg1);
	len2 = bcTruelen(arg2);

	cmp = varstr_cmp(VARDATA(arg1), len1, VARDATA(arg2), len2);

	PG_FREE_IF_COPY(arg1, 0);
	PG_FREE_IF_COPY(arg2, 1);

	PG_RETURN_INT32(cmp);
}
示例#8
0
/*
 * returns true, if query matches prefix ( common prefix )
*/
static bool
gbt_bytea_pf_match(const bytea *pf, const bytea *query, const gbtree_vinfo *tinfo)
{

	bool		out = FALSE;
	int32		k = 0;
	int32		qlen = VARSIZE(query) - VARHDRSZ;
	int32		nlen = VARSIZE(pf) - VARHDRSZ;

	if (nlen <= qlen)
	{
		char	   *q = VARDATA(query);
		char	   *n = VARDATA(pf);

		if (tinfo->eml > 1)
		{
			out = (varstr_cmp(q, nlen, n, nlen) == 0);
		}
		else
		{
			out = TRUE;
			for (k = 0; k < nlen; k++)
			{
				if (*n != *q)
				{
					out = FALSE;
					break;
				}
				if (k < (nlen - 1))
				{
					q++;
					n++;
				}
			}
		}
	}

	return out;
}
示例#9
0
Datum
bpcharne(PG_FUNCTION_ARGS)
{
	BpChar	   *arg1 = PG_GETARG_BPCHAR_P(0);
	BpChar	   *arg2 = PG_GETARG_BPCHAR_P(1);
	int			len1,
				len2;
	bool		result;

	len1 = bcTruelen(arg1);
	len2 = bcTruelen(arg2);

	/* fast path for different-length inputs */
	if (len1 != len2)
		result = true;
	else
		result = (varstr_cmp(VARDATA(arg1), len1, VARDATA(arg2), len2) != 0);

	PG_FREE_IF_COPY(arg1, 0);
	PG_FREE_IF_COPY(arg2, 1);

	PG_RETURN_BOOL(result);
}
示例#10
0
Datum
spg_text_leaf_consistent(PG_FUNCTION_ARGS)
{
    spgLeafConsistentIn *in = (spgLeafConsistentIn *) PG_GETARG_POINTER(0);
    spgLeafConsistentOut *out = (spgLeafConsistentOut *) PG_GETARG_POINTER(1);
    StrategyNumber strategy = in->strategy;
    text	   *query = DatumGetTextPP(in->query);
    int			level = in->level;
    text	   *leafValue,
               *reconstrValue = NULL;
    char	   *fullValue;
    int			fullLen;
    int			queryLen;
    int			r;
    bool		res;

    /* all tests are exact */
    out->recheck = false;

    leafValue = DatumGetTextPP(in->leafDatum);

    if (DatumGetPointer(in->reconstructedValue))
        reconstrValue = DatumGetTextP(in->reconstructedValue);

    Assert(level == 0 ? reconstrValue == NULL :
           VARSIZE_ANY_EXHDR(reconstrValue) == level);

    fullLen = level + VARSIZE_ANY_EXHDR(leafValue);

    queryLen = VARSIZE_ANY_EXHDR(query);

    /*
     * For an equality check, we needn't reconstruct fullValue if not same
     * length; it can't match
     */
    if (strategy == BTEqualStrategyNumber && queryLen != fullLen)
        PG_RETURN_BOOL(false);

    /* Else, reconstruct the full string represented by this leaf tuple */
    if (VARSIZE_ANY_EXHDR(leafValue) == 0 && level > 0)
    {
        fullValue = VARDATA(reconstrValue);
        out->leafValue = PointerGetDatum(reconstrValue);
    }
    else
    {
        text   *fullText = palloc(VARHDRSZ + fullLen);

        SET_VARSIZE(fullText, VARHDRSZ + fullLen);
        fullValue = VARDATA(fullText);
        if (level)
            memcpy(fullValue, VARDATA(reconstrValue), level);
        if (VARSIZE_ANY_EXHDR(leafValue) > 0)
            memcpy(fullValue + level, VARDATA_ANY(leafValue),
                   VARSIZE_ANY_EXHDR(leafValue));
        out->leafValue = PointerGetDatum(fullText);
    }

    /* Run the appropriate type of comparison */
    if (strategy > 10)
    {
        /* Collation-aware comparison */
        strategy -= 10;

        /* If asserts are enabled, verify encoding of reconstructed string */
        Assert(pg_verifymbstr(fullValue, fullLen, false));

        r = varstr_cmp(fullValue, Min(queryLen, fullLen),
                       VARDATA_ANY(query), Min(queryLen, fullLen),
                       PG_GET_COLLATION());
    }
    else
    {
        /* Non-collation-aware comparison */
        r = memcmp(fullValue, VARDATA_ANY(query), Min(queryLen, fullLen));
    }

    if (r == 0)
    {
        if (queryLen > fullLen)
            r = -1;
        else if (queryLen < fullLen)
            r = 1;
    }

    switch (strategy)
    {
    case BTLessStrategyNumber:
        res = (r < 0);
        break;
    case BTLessEqualStrategyNumber:
        res = (r <= 0);
        break;
    case BTEqualStrategyNumber:
        res = (r == 0);
        break;
    case BTGreaterEqualStrategyNumber:
        res = (r >= 0);
        break;
    case BTGreaterStrategyNumber:
        res = (r > 0);
        break;
    default:
        elog(ERROR, "unrecognized strategy number: %d", in->strategy);
        res = false;
        break;
    }

    PG_RETURN_BOOL(res);
}
示例#11
0
Datum
spg_text_leaf_consistent(PG_FUNCTION_ARGS)
{
	spgLeafConsistentIn *in = (spgLeafConsistentIn *) PG_GETARG_POINTER(0);
	spgLeafConsistentOut *out = (spgLeafConsistentOut *) PG_GETARG_POINTER(1);
	int			level = in->level;
	text	   *leafValue,
			   *reconstrValue = NULL;
	char	   *fullValue;
	int			fullLen;
	bool		res;
	int			j;

	/* all tests are exact */
	out->recheck = false;

	leafValue = DatumGetTextPP(in->leafDatum);

	if (DatumGetPointer(in->reconstructedValue))
		reconstrValue = DatumGetTextP(in->reconstructedValue);

	Assert(level == 0 ? reconstrValue == NULL :
		   VARSIZE_ANY_EXHDR(reconstrValue) == level);

	/* Reconstruct the full string represented by this leaf tuple */
	fullLen = level + VARSIZE_ANY_EXHDR(leafValue);
	if (VARSIZE_ANY_EXHDR(leafValue) == 0 && level > 0)
	{
		fullValue = VARDATA(reconstrValue);
		out->leafValue = PointerGetDatum(reconstrValue);
	}
	else
	{
		text	   *fullText = palloc(VARHDRSZ + fullLen);

		SET_VARSIZE(fullText, VARHDRSZ + fullLen);
		fullValue = VARDATA(fullText);
		if (level)
			memcpy(fullValue, VARDATA(reconstrValue), level);
		if (VARSIZE_ANY_EXHDR(leafValue) > 0)
			memcpy(fullValue + level, VARDATA_ANY(leafValue),
				   VARSIZE_ANY_EXHDR(leafValue));
		out->leafValue = PointerGetDatum(fullText);
	}

	/* Perform the required comparison(s) */
	res = true;
	for (j = 0; j < in->nkeys; j++)
	{
		StrategyNumber strategy = in->scankeys[j].sk_strategy;
		text	   *query = DatumGetTextPP(in->scankeys[j].sk_argument);
		int			queryLen = VARSIZE_ANY_EXHDR(query);
		int			r;

		if (strategy > 10)
		{
			/* Collation-aware comparison */
			strategy -= 10;

			/* If asserts enabled, verify encoding of reconstructed string */
			Assert(pg_verifymbstr(fullValue, fullLen, false));

			r = varstr_cmp(fullValue, Min(queryLen, fullLen),
						   VARDATA_ANY(query), Min(queryLen, fullLen),
						   PG_GET_COLLATION());
		}
		else
		{
			/* Non-collation-aware comparison */
			r = memcmp(fullValue, VARDATA_ANY(query), Min(queryLen, fullLen));
		}

		if (r == 0)
		{
			if (queryLen > fullLen)
				r = -1;
			else if (queryLen < fullLen)
				r = 1;
		}

		switch (strategy)
		{
			case BTLessStrategyNumber:
				res = (r < 0);
				break;
			case BTLessEqualStrategyNumber:
				res = (r <= 0);
				break;
			case BTEqualStrategyNumber:
				res = (r == 0);
				break;
			case BTGreaterEqualStrategyNumber:
				res = (r >= 0);
				break;
			case BTGreaterStrategyNumber:
				res = (r > 0);
				break;
			default:
				elog(ERROR, "unrecognized strategy number: %d",
					 in->scankeys[j].sk_strategy);
				res = false;
				break;
		}

		if (!res)
			break;				/* no need to consider remaining conditions */
	}

	PG_RETURN_BOOL(res);
}