diff --git a/contrib/ltree/expected/ltree.out b/contrib/ltree/expected/ltree.out index 8226930905..b1878a99b3 100644 --- a/contrib/ltree/expected/ltree.out +++ b/contrib/ltree/expected/ltree.out @@ -676,7 +676,7 @@ SELECT 'a.b.c.d.e'::ltree ~ '*.a.*.d.*'; SELECT 'a.b.c.d.e'::ltree ~ '*.!d.*'; ?column? ---------- - f + t (1 row) SELECT 'a.b.c.d.e'::ltree ~ '*.!d'; @@ -706,7 +706,7 @@ SELECT 'a.b.c.d.e'::ltree ~ '*.!e'; SELECT 'a.b.c.d.e'::ltree ~ '*.!e.*'; ?column? ---------- - f + t (1 row) SELECT 'a.b.c.d.e'::ltree ~ 'a.*.!e'; @@ -724,7 +724,7 @@ SELECT 'a.b.c.d.e'::ltree ~ 'a.*.!d'; SELECT 'a.b.c.d.e'::ltree ~ 'a.*.!d.*'; ?column? ---------- - f + t (1 row) SELECT 'a.b.c.d.e'::ltree ~ 'a.*.!f.*'; @@ -742,7 +742,7 @@ SELECT 'a.b.c.d.e'::ltree ~ '*.a.*.!f.*'; SELECT 'a.b.c.d.e'::ltree ~ '*.a.*.!d.*'; ?column? ---------- - f + t (1 row) SELECT 'a.b.c.d.e'::ltree ~ '*.a.!d.*'; @@ -766,13 +766,13 @@ SELECT 'a.b.c.d.e'::ltree ~ 'a.!d.*'; SELECT 'a.b.c.d.e'::ltree ~ '*.a.*.!d.*'; ?column? ---------- - f + t (1 row) SELECT 'a.b.c.d.e'::ltree ~ '*.!b.*'; ?column? ---------- - f + t (1 row) SELECT 'a.b.c.d.e'::ltree ~ '*.!b.c.*'; @@ -784,7 +784,7 @@ SELECT 'a.b.c.d.e'::ltree ~ '*.!b.c.*'; SELECT 'a.b.c.d.e'::ltree ~ '*.!b.*.c.*'; ?column? ---------- - f + t (1 row) SELECT 'a.b.c.d.e'::ltree ~ '!b.*.c.*'; @@ -832,31 +832,31 @@ SELECT 'a.b.c.d.e'::ltree ~ '*{1}.!b.*.!c.*.e'; SELECT 'a.b.c.d.e'::ltree ~ '*{1}.!b.*{1}.!c.*.e'; ?column? ---------- - t + f (1 row) SELECT 'a.b.c.d.e'::ltree ~ 'a.!b.*{1}.!c.*.e'; ?column? ---------- - t + f (1 row) SELECT 'a.b.c.d.e'::ltree ~ '!b.*{1}.!c.*.e'; ?column? ---------- - t + f (1 row) SELECT 'a.b.c.d.e'::ltree ~ '*.!b.*{1}.!c.*.e'; ?column? ---------- - t + f (1 row) SELECT 'a.b.c.d.e'::ltree ~ '*.!b.*.!c.*.e'; ?column? ---------- - f + t (1 row) SELECT 'a.b.c.d.e'::ltree ~ '!b.!c.*'; @@ -886,19 +886,19 @@ SELECT 'a.b.c.d.e'::ltree ~ '*{1}.!b.*.!c.*'; SELECT 'a.b.c.d.e'::ltree ~ '*{1}.!b.*{1}.!c.*'; ?column? ---------- - t + f (1 row) SELECT 'a.b.c.d.e'::ltree ~ 'a.!b.*{1}.!c.*'; ?column? ---------- - t + f (1 row) SELECT 'a.b.c.d.e'::ltree ~ '!b.*{1}.!c.*'; ?column? ---------- - t + f (1 row) SELECT 'a.b.c.d.e'::ltree ~ '*.!b.*{1}.!c.*'; @@ -909,6 +909,18 @@ SELECT 'a.b.c.d.e'::ltree ~ '*.!b.*{1}.!c.*'; SELECT 'a.b.c.d.e'::ltree ~ '*.!b.*.!c.*'; ?column? +---------- + t +(1 row) + +SELECT '5.0.1.0'::ltree ~ '5.!0.!0.0'; + ?column? +---------- + f +(1 row) + +SELECT 'a.b'::ltree ~ '!a.!a'; + ?column? ---------- f (1 row) diff --git a/contrib/ltree/lquery_op.c b/contrib/ltree/lquery_op.c index b6d2deb1af..392c193fd8 100644 --- a/contrib/ltree/lquery_op.c +++ b/contrib/ltree/lquery_op.c @@ -19,16 +19,6 @@ PG_FUNCTION_INFO_V1(lt_q_rregex); #define NEXTVAL(x) ( (lquery*)( (char*)(x) + INTALIGN( VARSIZE(x) ) ) ) -typedef struct -{ - lquery_level *q; - int nq; - ltree_level *t; - int nt; - int posq; - int post; -} FieldNot; - static char * getlexeme(char *start, char *end, int *len) { @@ -50,7 +40,7 @@ getlexeme(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; @@ -108,6 +98,9 @@ checkLevel(lquery_level *curq, ltree_level *curt) int (*cmpptr) (const char *, const char *, size_t); lquery_variant *curvar = LQL_FIRST(curq); int i; + bool success; + + success = (curq->flag & LQL_NOT) ? false : true; for (i = 0; i < curq->numvar; i++) { @@ -115,8 +108,9 @@ checkLevel(lquery_level *curq, ltree_level *curt) if (curvar->flag & LVAR_SUBLEXEME) { - if (compare_subnode(curt, curvar->name, curvar->len, cmpptr, (curvar->flag & LVAR_ANYEND))) - return true; + if (compare_subnode(curt, curvar->name, curvar->len, cmpptr, + (curvar->flag & LVAR_ANYEND))) + return success; } else if ( ( @@ -126,22 +120,12 @@ checkLevel(lquery_level *curq, ltree_level *curt) (*cmpptr) (curvar->name, curt->name, curvar->len) == 0) { - return true; + return success; } curvar = LVAR_NEXT(curvar); } - return false; -} - -/* -void -printFieldNot(FieldNot *fn ) { - while(fn->q) { - elog(NOTICE,"posQ:%d lenQ:%d posT:%d lenT:%d", fn->posq,fn->nq,fn->post,fn->nt); - fn++; - } + return !success; } -*/ static struct { @@ -154,7 +138,7 @@ static struct }; static bool -checkCond(lquery_level *curq, int query_numlevel, ltree_level *curt, int tree_numlevel, FieldNot *ptr) +checkCond(lquery_level *curq, int query_numlevel, ltree_level *curt, int tree_numlevel) { uint32 low_pos = 0, high_pos = 0, @@ -163,7 +147,6 @@ checkCond(lquery_level *curq, int query_numlevel, ltree_level *curt, int tree_nu qlen = query_numlevel; int isok; lquery_level *prevq = NULL; - ltree_level *prevt = NULL; if (SomeStack.muse) { @@ -178,7 +161,6 @@ checkCond(lquery_level *curq, int query_numlevel, ltree_level *curt, int tree_nu { if (curq->numvar) { - prevt = curt; while (cur_tpos < low_pos) { curt = LEVEL_NEXT(curt); @@ -186,83 +168,33 @@ checkCond(lquery_level *curq, int query_numlevel, ltree_level *curt, int tree_nu cur_tpos++; if (tlen == 0) return false; - if (ptr && ptr->q) - ptr->nt++; } - if (ptr && curq->flag & LQL_NOT) + isok = false; + while (cur_tpos <= high_pos && tlen > 0 && !isok) { - if (!(prevq && prevq->numvar == 0)) - prevq = curq; - if (ptr->q == NULL) - { - ptr->t = prevt; - ptr->q = prevq; - ptr->nt = 1; - ptr->nq = 1 + ((prevq == curq) ? 0 : 1); - ptr->posq = query_numlevel - qlen - ((prevq == curq) ? 0 : 1); - ptr->post = cur_tpos; - } - else - { - ptr->nt++; - ptr->nq++; - } - - if (qlen == 1 && ptr->q->numvar == 0) - ptr->nt = tree_numlevel - ptr->post; + isok = checkLevel(curq, curt); curt = LEVEL_NEXT(curt); tlen--; cur_tpos++; - if (high_pos < cur_tpos) - high_pos++; - } - else - { - isok = false; - while (cur_tpos <= high_pos && tlen > 0 && !isok) - { - isok = checkLevel(curq, curt); - 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++; - } - if (!isok) - return false; - - if (ptr && ptr->q) + if (isok && prevq && prevq->numvar == 0 && tlen > 0 && cur_tpos <= high_pos) { - if (checkCond(ptr->q, ptr->nq, ptr->t, ptr->nt, NULL)) - return false; - ptr->q = NULL; + SomeStack.high_pos = high_pos - cur_tpos; + SomeStack.muse = true; + if (checkCond(prevq, qlen + 1, curt, tlen)) + return true; } - low_pos = cur_tpos; - high_pos = cur_tpos; } + if (!isok) + return false; + + low_pos = cur_tpos; + high_pos = cur_tpos; } else { low_pos = cur_tpos + curq->low; high_pos = cur_tpos + curq->high; - if (ptr && ptr->q) - { - ptr->nq++; - if (qlen == 1) - ptr->nt = tree_numlevel - ptr->post; - } } prevq = curq; @@ -293,9 +225,6 @@ checkCond(lquery_level *curq, int query_numlevel, ltree_level *curt, int tree_nu if (low_pos > tree_numlevel || tree_numlevel > high_pos) return false; - if (ptr && ptr->q && checkCond(ptr->q, ptr->nq, ptr->t, ptr->nt, NULL)) - return false; - return true; } @@ -306,20 +235,8 @@ ltq_regex(PG_FUNCTION_ARGS) lquery *query = PG_GETARG_LQUERY_P(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); - } + res = checkCond(LQUERY_FIRST(query), query->numlevel, + LTREE_FIRST(tree), tree->numlevel); PG_FREE_IF_COPY(tree, 0); PG_FREE_IF_COPY(query, 1); diff --git a/contrib/ltree/ltree.h b/contrib/ltree/ltree.h index e4b8c84fa6..f3c6501309 100644 --- a/contrib/ltree/ltree.h +++ b/contrib/ltree/ltree.h @@ -78,8 +78,6 @@ typedef struct #define LQUERY_HDRSIZE MAXALIGN( offsetof(lquery, data) ) #define LQUERY_FIRST(x) ( (lquery_level*)( ((char*)(x))+LQUERY_HDRSIZE ) ) -#define LQUERY_HASNOT 0x01 - #define ISALNUM(x) ( t_isalpha(x) || t_isdigit(x) || ( pg_mblen(x) == 1 && t_iseq((x), '_') ) ) /* full text query */ diff --git a/contrib/ltree/ltree_io.c b/contrib/ltree/ltree_io.c index f54f037443..2e95e8a1e0 100644 --- a/contrib/ltree/ltree_io.c +++ b/contrib/ltree/ltree_io.c @@ -205,7 +205,6 @@ lquery_in(PG_FUNCTION_ARGS) *curqlevel, *tmpql; lquery_variant *lrptr = NULL; - bool hasnot = false; bool wasbad = false; int charlen; int pos = 0; @@ -254,7 +253,6 @@ lquery_in(PG_FUNCTION_ARGS) state = LQPRS_WAITDELIM; curqlevel->numvar = 1; curqlevel->flag |= LQL_NOT; - hasnot = true; } else if (charlen == 1 && t_iseq(ptr, '*')) state = LQPRS_WAITOPEN; @@ -480,8 +478,6 @@ lquery_in(PG_FUNCTION_ARGS) result->numlevel = num; result->firstgood = 0; result->flag = 0; - if (hasnot) - result->flag |= LQUERY_HASNOT; cur = LQUERY_FIRST(result); curqlevel = tmpql; while ((char *) curqlevel - (char *) tmpql < num * ITEMSIZE) diff --git a/contrib/ltree/sql/ltree.sql b/contrib/ltree/sql/ltree.sql index 846b04e48e..4f734953e2 100644 --- a/contrib/ltree/sql/ltree.sql +++ b/contrib/ltree/sql/ltree.sql @@ -168,7 +168,8 @@ SELECT 'a.b.c.d.e'::ltree ~ 'a.!b.*{1}.!c.*'; SELECT 'a.b.c.d.e'::ltree ~ '!b.*{1}.!c.*'; SELECT 'a.b.c.d.e'::ltree ~ '*.!b.*{1}.!c.*'; SELECT 'a.b.c.d.e'::ltree ~ '*.!b.*.!c.*'; - +SELECT '5.0.1.0'::ltree ~ '5.!0.!0.0'; +SELECT 'a.b'::ltree ~ '!a.!a'; SELECT 'QWER_TY'::ltree ~ 'q%@*'; SELECT 'QWER_TY'::ltree ~ 'Q_t%@*'; diff --git a/doc/src/sgml/ltree.sgml b/doc/src/sgml/ltree.sgml index 3ddd335b8c..df8b4b042f 100644 --- a/doc/src/sgml/ltree.sgml +++ b/doc/src/sgml/ltree.sgml @@ -598,7 +598,7 @@ ltreetest=> SELECT path FROM test WHERE path ~ '*.Astronomy.*'; Top.Collections.Pictures.Astronomy.Astronauts (7 rows) -ltreetest=> SELECT path FROM test WHERE path ~ '*.!pictures@.*.Astronomy.*'; +ltreetest=> SELECT path FROM test WHERE path ~ '*.!pictures@.Astronomy.*'; path ------------------------------------ Top.Science.Astronomy