mirror of
https://github.com/postgres/postgres.git
synced 2025-07-28 23:42:10 +03:00
Please apply patches for contrib/ltree.
ltree_73.patch.gz - for 7.3 : Fix ~ operation bug: eg '1.1.1' ~ '*.1' ltree_74.patch.gz - for current CVS Fix ~ operation bug: eg '1.1.1' ~ '*.1' Add ? operation Optimize index storage Last change needs drop/create all ltree indexes, so only for 7.4 Teodor Sigaev
This commit is contained in:
@ -5,10 +5,16 @@
|
||||
|
||||
#include "ltree.h"
|
||||
#include <ctype.h>
|
||||
#include "utils/array.h"
|
||||
|
||||
PG_FUNCTION_INFO_V1(ltq_regex);
|
||||
PG_FUNCTION_INFO_V1(ltq_rregex);
|
||||
|
||||
PG_FUNCTION_INFO_V1(lt_q_regex);
|
||||
PG_FUNCTION_INFO_V1(lt_q_rregex);
|
||||
|
||||
#define NEXTVAL(x) ( (lquery*)( (char*)(x) + INTALIGN( VARSIZE(x) ) ) )
|
||||
|
||||
typedef struct
|
||||
{
|
||||
lquery_level *q;
|
||||
@ -39,7 +45,7 @@ getlexem(char *start, char *end, int *len)
|
||||
}
|
||||
|
||||
bool
|
||||
compare_subnode(ltree_level * t, char *qn, int len, int (*cmpptr) (const char *, const char *, size_t), bool anyend)
|
||||
compare_subnode(ltree_level * t, char *qn, int len, int (*cmpptr) (const char *, const char *, size_t), bool anyend)
|
||||
{
|
||||
char *endt = t->name + t->len;
|
||||
char *endq = qn + len;
|
||||
@ -117,6 +123,11 @@ printFieldNot(FieldNot *fn ) {
|
||||
}
|
||||
*/
|
||||
|
||||
static struct {
|
||||
bool muse;
|
||||
uint32 high_pos;
|
||||
} SomeStack = {false,0,};
|
||||
|
||||
static bool
|
||||
checkCond(lquery_level * curq, int query_numlevel, ltree_level * curt, int tree_numlevel, FieldNot * ptr)
|
||||
{
|
||||
@ -129,6 +140,14 @@ checkCond(lquery_level * curq, int query_numlevel, ltree_level * curt, int tree_
|
||||
lquery_level *prevq = NULL;
|
||||
ltree_level *prevt = NULL;
|
||||
|
||||
if ( SomeStack.muse ) {
|
||||
high_pos = SomeStack.high_pos;
|
||||
qlen--;
|
||||
prevq = curq;
|
||||
curq = LQL_NEXT(curq);
|
||||
SomeStack.muse = false;
|
||||
}
|
||||
|
||||
while (tlen > 0 && qlen > 0)
|
||||
{
|
||||
if (curq->numvar)
|
||||
@ -181,6 +200,15 @@ checkCond(lquery_level * curq, int query_numlevel, ltree_level * curt, int tree_
|
||||
curt = LEVEL_NEXT(curt);
|
||||
tlen--;
|
||||
cur_tpos++;
|
||||
if ( isok && prevq && prevq->numvar==0 && tlen>0 && cur_tpos <= high_pos ) {
|
||||
FieldNot tmpptr;
|
||||
if ( ptr )
|
||||
memcpy(&tmpptr,ptr,sizeof(FieldNot));
|
||||
SomeStack.high_pos = high_pos-cur_tpos;
|
||||
SomeStack.muse = true;
|
||||
if ( checkCond(prevq, qlen+1, curt, tlen, (ptr) ? &tmpptr : NULL) )
|
||||
return true;
|
||||
}
|
||||
if (!isok && ptr)
|
||||
ptr->nt++;
|
||||
}
|
||||
@ -278,3 +306,42 @@ ltq_rregex(PG_FUNCTION_ARGS)
|
||||
PG_GETARG_DATUM(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)
|
||||
elog(ERROR, "Dimension of array != 1");
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
Datum
|
||||
lt_q_rregex(PG_FUNCTION_ARGS)
|
||||
{
|
||||
PG_RETURN_DATUM(DirectFunctionCall2(lt_q_regex,
|
||||
PG_GETARG_DATUM(1),
|
||||
PG_GETARG_DATUM(0)
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user