Пример #1
0
Datum
ltree_index(PG_FUNCTION_ARGS)
{
    ltree	   *a = PG_GETARG_LTREE(0);
    ltree	   *b = PG_GETARG_LTREE(1);
    int			start = (fcinfo->nargs == 3) ? PG_GETARG_INT32(2) : 0;
    int			i,
                j;
    ltree_level *startptr,
                *aptr,
                *bptr;
    bool		found = false;

    if (start < 0)
    {
        if (-start >= a->numlevel)
            start = 0;
        else
            start = (int) (a->numlevel) + start;
    }

    if (a->numlevel - start < b->numlevel || a->numlevel == 0 || b->numlevel == 0)
    {
        PG_FREE_IF_COPY(a, 0);
        PG_FREE_IF_COPY(b, 1);
        PG_RETURN_INT32(-1);
    }

    startptr = LTREE_FIRST(a);
    for (i = 0; i <= a->numlevel - b->numlevel; i++)
    {
        if (i >= start)
        {
            aptr = startptr;
            bptr = LTREE_FIRST(b);
            for (j = 0; j < b->numlevel; j++)
            {
                if (!(aptr->len == bptr->len && strncmp(aptr->name, bptr->name, aptr->len) == 0))
                    break;
                aptr = LEVEL_NEXT(aptr);
                bptr = LEVEL_NEXT(bptr);
            }

            if (j == b->numlevel)
            {
                found = true;
                break;
            }
        }
        startptr = LEVEL_NEXT(startptr);
    }

    if (!found)
        i = -1;

    PG_FREE_IF_COPY(a, 0);
    PG_FREE_IF_COPY(b, 1);
    PG_RETURN_INT32(i);
}
Пример #2
0
Datum
ltree_risparent(PG_FUNCTION_ARGS)
{
    ltree	   *c = PG_GETARG_LTREE(0);
    ltree	   *p = PG_GETARG_LTREE(1);
    bool		res = inner_isparent(c, p);

    PG_FREE_IF_COPY(c, 0);
    PG_FREE_IF_COPY(p, 1);
    PG_RETURN_BOOL(res);
}
Пример #3
0
Datum
ltree_addltree(PG_FUNCTION_ARGS)
{
    ltree	   *a = PG_GETARG_LTREE(0);
    ltree	   *b = PG_GETARG_LTREE(1);
    ltree	   *r;

    r = ltree_concat(a, b);
    PG_FREE_IF_COPY(a, 0);
    PG_FREE_IF_COPY(b, 1);
    PG_RETURN_POINTER(r);
}
Пример #4
0
Datum
ltree2text(PG_FUNCTION_ARGS)
{
    ltree	   *in = PG_GETARG_LTREE(0);
    char	   *ptr;
    int			i;
    ltree_level *curlevel;
    text	   *out;

    out = (text *) palloc(VARSIZE(in) + VARHDRSZ);
    ptr = VARDATA(out);
    curlevel = LTREE_FIRST(in);
    for (i = 0; i < in->numlevel; i++)
    {
        if (i != 0)
        {
            *ptr = '.';
            ptr++;
        }
        memcpy(ptr, curlevel->name, curlevel->len);
        ptr += curlevel->len;
        curlevel = LEVEL_NEXT(curlevel);
    }

    SET_VARSIZE(out, ptr - ((char *) out));
    PG_FREE_IF_COPY(in, 0);

    PG_RETURN_POINTER(out);
}
Пример #5
0
Datum
subpath(PG_FUNCTION_ARGS)
{
    ltree	   *t = PG_GETARG_LTREE(0);
    int4		start = PG_GETARG_INT32(1);
    int4		len = (fcinfo->nargs == 3) ? PG_GETARG_INT32(2) : 0;
    int4		end;
    ltree	   *res;

    end = start + len;

    if (start < 0)
    {
        start = t->numlevel + start;
        end = start + len;
    }
    if (start < 0)
    {   /* start > t->numlevel */
        start = t->numlevel + start;
        end = start + len;
    }

    if (len < 0)
        end = t->numlevel + len;
    else if (len == 0)
        end = (fcinfo->nargs == 3) ? start : 0xffff;

    res = inner_subltree(t, start, end);

    PG_FREE_IF_COPY(t, 0);
    PG_RETURN_POINTER(res);
}
Пример #6
0
Datum
ltree_textadd(PG_FUNCTION_ARGS)
{
	ltree	   *a = PG_GETARG_LTREE(1);
	text	   *b = PG_GETARG_TEXT_P(0);
	char	   *s;
	ltree	   *r,
			   *tmp;

	s = (char *) palloc(VARSIZE(b) - VARHDRSZ + 1);
	memcpy(s, VARDATA(b), VARSIZE(b) - VARHDRSZ);
	s[VARSIZE(b) - VARHDRSZ] = '\0';

	tmp = (ltree *) DatumGetPointer(DirectFunctionCall1(
														ltree_in,
														PointerGetDatum(s)
														));

	pfree(s);

	r = ltree_concat(tmp, a);

	pfree(tmp);

	PG_FREE_IF_COPY(a, 1);
	PG_FREE_IF_COPY(b, 0);
	PG_RETURN_POINTER(r);
}
Datum
ltree_out(PG_FUNCTION_ARGS)
{
	ltree	   *in = PG_GETARG_LTREE(0);
	char	   *buf,
			   *ptr;
	int			i;
	ltree_level *curlevel;

	ptr = buf = (char *) palloc(VARSIZE(in));
	curlevel = LTREE_FIRST(in);
	for (i = 0; i < in->numlevel; i++)
	{
		if (i != 0)
		{
			*ptr = '.';
			ptr++;
		}
		memcpy(ptr, curlevel->name, curlevel->len);
		ptr += curlevel->len;
		curlevel = LEVEL_NEXT(curlevel);
	}

	*ptr = '\0';
	PG_FREE_IF_COPY(in, 0);

	PG_RETURN_POINTER(buf);
}
Пример #8
0
Datum
lt_q_regex(PG_FUNCTION_ARGS)
{
	ltree	   *tree = PG_GETARG_LTREE(0);
	ArrayType  *_query = PG_GETARG_ARRAYTYPE_P(1);
	lquery	   *query = (lquery *) ARR_DATA_PTR(_query);
	bool		res = false;
	int			num = ArrayGetNItems(ARR_NDIM(_query), ARR_DIMS(_query));

	if (ARR_NDIM(_query) != 1)
		ereport(ERROR,
				(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
				 errmsg("array must be one-dimensional")));

	while (num > 0)
	{
		if (DatumGetBool(DirectFunctionCall2(ltq_regex,
						 PointerGetDatum(tree), PointerGetDatum(query))))
		{

			res = true;
			break;
		}
		num--;
		query = NEXTVAL(query);
	}

	PG_FREE_IF_COPY(tree, 0);
	PG_FREE_IF_COPY(_query, 1);
	PG_RETURN_BOOL(res);
}
Пример #9
0
Datum
ltq_regex(PG_FUNCTION_ARGS)
{
	ltree	   *tree = PG_GETARG_LTREE(0);
	lquery	   *query = PG_GETARG_LQUERY(1);
	bool		res = false;

	if (query->flag & LQUERY_HASNOT)
	{
		FieldNot	fn;

		fn.q = NULL;

		res = checkCond(LQUERY_FIRST(query), query->numlevel,
						LTREE_FIRST(tree), tree->numlevel, &fn);
	}
	else
	{
		res = checkCond(LQUERY_FIRST(query), query->numlevel,
						LTREE_FIRST(tree), tree->numlevel, NULL);
	}

	PG_FREE_IF_COPY(tree, 0);
	PG_FREE_IF_COPY(query, 1);
	PG_RETURN_BOOL(res);
}
Пример #10
0
Datum
subltree(PG_FUNCTION_ARGS)
{
    ltree	   *t = PG_GETARG_LTREE(0);
    ltree	   *res = inner_subltree(t, PG_GETARG_INT32(1), PG_GETARG_INT32(2));

    PG_FREE_IF_COPY(t, 0);
    PG_RETURN_POINTER(res);
}
Пример #11
0
Datum
nlevel(PG_FUNCTION_ARGS)
{
    ltree	   *a = PG_GETARG_LTREE(0);
    int			res = a->numlevel;

    PG_FREE_IF_COPY(a, 0);
    PG_RETURN_INT32(res);
}
Пример #12
0
Datum
_ltree_risparent(PG_FUNCTION_ARGS)
{
	ArrayType  *la = PG_GETARG_ARRAYTYPE_P(0);
	ltree	   *query = PG_GETARG_LTREE(1);
	bool		res = array_iterator(la, ltree_risparent, (void *) query, NULL);

	PG_FREE_IF_COPY(la, 0);
	PG_FREE_IF_COPY(query, 1);
	PG_RETURN_BOOL(res);
}
Пример #13
0
Datum
lca(PG_FUNCTION_ARGS)
{
    int			i;
    ltree	  **a,
              *res;

    a = (ltree **) palloc(sizeof(ltree *) * fcinfo->nargs);
    for (i = 0; i < fcinfo->nargs; i++)
        a[i] = PG_GETARG_LTREE(i);
    res = lca_inner(a, (int) fcinfo->nargs);
    for (i = 0; i < fcinfo->nargs; i++)
        PG_FREE_IF_COPY(a[i], i);
    pfree(a);

    if (res)
        PG_RETURN_POINTER(res);
    else
        PG_RETURN_NULL();
}
Datum
ltxtq_exec(PG_FUNCTION_ARGS)
{
	ltree	   *val = PG_GETARG_LTREE(0);
	ltxtquery  *query = PG_GETARG_LTXTQUERY(1);
	CHKVAL		chkval;
	bool		result;

	chkval.node = val;
	chkval.operand = GETOPERAND(query);

	result = ltree_execute(
						   GETQUERY(query),
						   &chkval,
						   true,
						   checkcondition_str
		);

	PG_FREE_IF_COPY(val, 0);
	PG_FREE_IF_COPY(query, 1);
	PG_RETURN_BOOL(result);
}
Пример #15
0
Datum
_ltree_extract_risparent(PG_FUNCTION_ARGS)
{
	ArrayType  *la = PG_GETARG_ARRAYTYPE_P(0);
	ltree	   *query = PG_GETARG_LTREE(1);
	ltree	   *found,
			   *item;

	if (!array_iterator(la, ltree_risparent, (void *) query, &found))
	{
		PG_FREE_IF_COPY(la, 0);
		PG_FREE_IF_COPY(query, 1);
		PG_RETURN_NULL();
	}

	item = (ltree *) palloc(VARSIZE(found));
	memcpy(item, found, VARSIZE(found));

	PG_FREE_IF_COPY(la, 0);
	PG_FREE_IF_COPY(query, 1);
	PG_RETURN_POINTER(item);
}
Пример #16
0
Datum
ltree_textadd(PG_FUNCTION_ARGS)
{
    ltree	   *a = PG_GETARG_LTREE(1);
    text	   *b = PG_GETARG_TEXT_PP(0);
    char	   *s;
    ltree	   *r,
               *tmp;

    s = text_to_cstring(b);

    tmp = (ltree *) DatumGetPointer(DirectFunctionCall1(ltree_in,
                                    PointerGetDatum(s)));

    pfree(s);

    r = ltree_concat(tmp, a);

    pfree(tmp);

    PG_FREE_IF_COPY(a, 1);
    PG_FREE_IF_COPY(b, 0);
    PG_RETURN_POINTER(r);
}