mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-10-01 03:01:16 +02: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:
parent
a286f73210
commit
71e1f531d3
@ -110,6 +110,9 @@ ltree <@ ltree
|
|||||||
equal).
|
equal).
|
||||||
ltree ~ lquery, lquery ~ ltree
|
ltree ~ lquery, lquery ~ ltree
|
||||||
- return TRUE if node represented by ltree satisfies lquery.
|
- return TRUE if node represented by ltree satisfies lquery.
|
||||||
|
ltree ? lquery[], lquery ? ltree[]
|
||||||
|
- return TRUE if node represented by ltree satisfies at least one lquery
|
||||||
|
from array.
|
||||||
ltree @ ltxtquery, ltxtquery @ ltree
|
ltree @ ltxtquery, ltxtquery @ ltree
|
||||||
- return TRUE if node represented by ltree satisfies ltxtquery.
|
- return TRUE if node represented by ltree satisfies ltxtquery.
|
||||||
ltree || ltree, ltree || text, text || ltree
|
ltree || ltree, ltree || text, text || ltree
|
||||||
@ -123,6 +126,9 @@ ltree @> ltree[], ltree[] <@ ltree
|
|||||||
- returns TRUE if array ltree[] contains a descendant of ltree.
|
- returns TRUE if array ltree[] contains a descendant of ltree.
|
||||||
ltree[] ~ lquery, lquery ~ ltree[]
|
ltree[] ~ lquery, lquery ~ ltree[]
|
||||||
- returns TRUE if array ltree[] contains label paths matched lquery.
|
- returns TRUE if array ltree[] contains label paths matched lquery.
|
||||||
|
ltree[] ? lquery[], lquery[] ? ltree[]
|
||||||
|
- returns TRUE if array ltree[] contains label paths matched atleaset one
|
||||||
|
lquery from array.
|
||||||
ltree[] @ ltxtquery, ltxtquery @ ltree[]
|
ltree[] @ ltxtquery, ltxtquery @ ltree[]
|
||||||
- returns TRUE if array ltree[] contains label paths matched ltxtquery
|
- returns TRUE if array ltree[] contains label paths matched ltxtquery
|
||||||
(full text search).
|
(full text search).
|
||||||
@ -142,11 +148,11 @@ Various indices could be created to speed up execution of operations:
|
|||||||
* B-tree index over ltree:
|
* B-tree index over ltree:
|
||||||
<, <=, =, =>, >
|
<, <=, =, =>, >
|
||||||
* GiST index over ltree:
|
* GiST index over ltree:
|
||||||
<, <=, =, =>, >, @>, <@, @, ~
|
<, <=, =, =>, >, @>, <@, @, ~, ?
|
||||||
Example:
|
Example:
|
||||||
create index path_gist_idx on test using gist (path);
|
create index path_gist_idx on test using gist (path);
|
||||||
* GiST index over ltree[]:
|
* GiST index over ltree[]:
|
||||||
ltree[]<@ ltree, ltree @> ltree[], @, ~.
|
ltree[]<@ ltree, ltree @> ltree[], @, ~, ?.
|
||||||
Example:
|
Example:
|
||||||
create index path_gist_idx on test using gist (array_path);
|
create index path_gist_idx on test using gist (array_path);
|
||||||
Notices: This index is lossy.
|
Notices: This index is lossy.
|
||||||
@ -426,6 +432,10 @@ appreciate your input. So far, below some (rather obvious) results:
|
|||||||
|
|
||||||
CHANGES
|
CHANGES
|
||||||
|
|
||||||
|
Feb 7, 2003
|
||||||
|
Add ? operation
|
||||||
|
Fix ~ operation bug: eg '1.1.1' ~ '*.1'
|
||||||
|
Optimize index storage
|
||||||
Aug 9, 2002
|
Aug 9, 2002
|
||||||
Fixed very stupid but important bug :-)
|
Fixed very stupid but important bug :-)
|
||||||
July 31, 2002
|
July 31, 2002
|
||||||
|
@ -96,7 +96,7 @@ _ltree_compress(PG_FUNCTION_ARGS)
|
|||||||
entry->rel, entry->page,
|
entry->rel, entry->page,
|
||||||
entry->offset, key->len, FALSE);
|
entry->offset, key->len, FALSE);
|
||||||
}
|
}
|
||||||
else
|
else if ( !LTG_ISALLTRUE(entry->key) )
|
||||||
{
|
{
|
||||||
int4 i,
|
int4 i,
|
||||||
len;
|
len;
|
||||||
@ -105,10 +105,9 @@ _ltree_compress(PG_FUNCTION_ARGS)
|
|||||||
BITVECP sign = LTG_SIGN(DatumGetPointer(entry->key));
|
BITVECP sign = LTG_SIGN(DatumGetPointer(entry->key));
|
||||||
|
|
||||||
ALOOPBYTE(
|
ALOOPBYTE(
|
||||||
if (sign[i] != 0xff)
|
if ((sign[i]&0xff) != 0xff)
|
||||||
PG_RETURN_POINTER(retval);
|
PG_RETURN_POINTER(retval);
|
||||||
);
|
);
|
||||||
|
|
||||||
len = LTG_HDRSIZE;
|
len = LTG_HDRSIZE;
|
||||||
key = (ltree_gist *) palloc(len);
|
key = (ltree_gist *) palloc(len);
|
||||||
key->len = len;
|
key->len = len;
|
||||||
@ -222,7 +221,7 @@ _ltree_penalty(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
if (LTG_ISALLTRUE(origval))
|
if (LTG_ISALLTRUE(origval))
|
||||||
{
|
{
|
||||||
*penalty = 0.0;
|
*penalty = 0.1;
|
||||||
PG_RETURN_POINTER(penalty);
|
PG_RETURN_POINTER(penalty);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -489,7 +488,7 @@ _ltree_picksplit(PG_FUNCTION_ARGS)
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size_alpha - size_l < size_beta - size_r + WISH_F(v->spl_nleft, v->spl_nright, 0.1))
|
if (size_alpha - size_l < size_beta - size_r + WISH_F(v->spl_nleft, v->spl_nright, 0.00001))
|
||||||
{
|
{
|
||||||
if (!LTG_ISALLTRUE(datum_l))
|
if (!LTG_ISALLTRUE(datum_l))
|
||||||
{
|
{
|
||||||
@ -613,6 +612,22 @@ gist_qe(ltree_gist * key, lquery * query)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
_arrq_cons(ltree_gist *key, ArrayType *_query) {
|
||||||
|
lquery *query = (lquery *) ARR_DATA_PTR(_query);
|
||||||
|
int num = ArrayGetNItems(ARR_NDIM(_query), ARR_DIMS(_query));
|
||||||
|
|
||||||
|
if (ARR_NDIM(_query) != 1)
|
||||||
|
elog(ERROR, "Dimension of array != 1");
|
||||||
|
|
||||||
|
while (num > 0) {
|
||||||
|
if ( gist_qe(key, query) )
|
||||||
|
return true;
|
||||||
|
num--;
|
||||||
|
query = (lquery*)NEXTVAL(query);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
_ltree_consistent(PG_FUNCTION_ARGS)
|
_ltree_consistent(PG_FUNCTION_ARGS)
|
||||||
@ -641,6 +656,10 @@ _ltree_consistent(PG_FUNCTION_ARGS)
|
|||||||
case 15:
|
case 15:
|
||||||
res = gist_qtxt(key, (ltxtquery *) query);
|
res = gist_qtxt(key, (ltxtquery *) query);
|
||||||
break;
|
break;
|
||||||
|
case 16:
|
||||||
|
case 17:
|
||||||
|
res = _arrq_cons(key, (ArrayType *) query);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
elog(ERROR, "Unknown StrategyNumber: %d", strategy);
|
elog(ERROR, "Unknown StrategyNumber: %d", strategy);
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,8 @@ PG_FUNCTION_INFO_V1(_ltree_risparent);
|
|||||||
PG_FUNCTION_INFO_V1(_ltree_r_risparent);
|
PG_FUNCTION_INFO_V1(_ltree_r_risparent);
|
||||||
PG_FUNCTION_INFO_V1(_ltq_regex);
|
PG_FUNCTION_INFO_V1(_ltq_regex);
|
||||||
PG_FUNCTION_INFO_V1(_ltq_rregex);
|
PG_FUNCTION_INFO_V1(_ltq_rregex);
|
||||||
|
PG_FUNCTION_INFO_V1(_lt_q_regex);
|
||||||
|
PG_FUNCTION_INFO_V1(_lt_q_rregex);
|
||||||
PG_FUNCTION_INFO_V1(_ltxtq_exec);
|
PG_FUNCTION_INFO_V1(_ltxtq_exec);
|
||||||
PG_FUNCTION_INFO_V1(_ltxtq_rexec);
|
PG_FUNCTION_INFO_V1(_ltxtq_rexec);
|
||||||
|
|
||||||
@ -126,6 +128,42 @@ _ltq_rregex(PG_FUNCTION_ARGS)
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Datum
|
||||||
|
_lt_q_regex(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
ArrayType *_tree = PG_GETARG_ARRAYTYPE_P(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 ( array_iterator(_tree, ltq_regex, (void*)query, NULL) ) {
|
||||||
|
res = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
num--;
|
||||||
|
query = (lquery*)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)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
_ltxtq_exec(PG_FUNCTION_ARGS)
|
_ltxtq_exec(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
|
@ -3,10 +3,10 @@ psql:ltree.sql:9: NOTICE: ProcedureCreate: type ltree is not yet defined
|
|||||||
psql:ltree.sql:14: NOTICE: Argument type "ltree" is only a shell
|
psql:ltree.sql:14: NOTICE: Argument type "ltree" is only a shell
|
||||||
psql:ltree.sql:281: NOTICE: ProcedureCreate: type lquery is not yet defined
|
psql:ltree.sql:281: NOTICE: ProcedureCreate: type lquery is not yet defined
|
||||||
psql:ltree.sql:286: NOTICE: Argument type "lquery" is only a shell
|
psql:ltree.sql:286: NOTICE: Argument type "lquery" is only a shell
|
||||||
psql:ltree.sql:345: NOTICE: ProcedureCreate: type ltxtquery is not yet defined
|
psql:ltree.sql:392: NOTICE: ProcedureCreate: type ltxtquery is not yet defined
|
||||||
psql:ltree.sql:350: NOTICE: Argument type "ltxtquery" is only a shell
|
psql:ltree.sql:397: NOTICE: Argument type "ltxtquery" is only a shell
|
||||||
psql:ltree.sql:412: NOTICE: ProcedureCreate: type ltree_gist is not yet defined
|
psql:ltree.sql:459: NOTICE: ProcedureCreate: type ltree_gist is not yet defined
|
||||||
psql:ltree.sql:417: NOTICE: Argument type "ltree_gist" is only a shell
|
psql:ltree.sql:464: NOTICE: Argument type "ltree_gist" is only a shell
|
||||||
SELECT ''::ltree;
|
SELECT ''::ltree;
|
||||||
ltree
|
ltree
|
||||||
-------
|
-------
|
||||||
@ -963,6 +963,36 @@ SELECT '{j.k.l.m, g.b.c.d.e}'::ltree[] ~ 'A*@|g.b.c.d.e';
|
|||||||
t
|
t
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
|
SELECT 'a.b.c.d.e'::ltree ? '{A.b.c.d.e}';
|
||||||
|
?column?
|
||||||
|
----------
|
||||||
|
f
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT 'a.b.c.d.e'::ltree ? '{a.b.c.d.e}';
|
||||||
|
?column?
|
||||||
|
----------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT 'a.b.c.d.e'::ltree ? '{A.b.c.d.e, a.*}';
|
||||||
|
?column?
|
||||||
|
----------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT '{a.b.c.d.e,B.df}'::ltree[] ? '{A.b.c.d.e}';
|
||||||
|
?column?
|
||||||
|
----------
|
||||||
|
f
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT '{a.b.c.d.e,B.df}'::ltree[] ? '{A.b.c.d.e,*.df}';
|
||||||
|
?column?
|
||||||
|
----------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
--exractors
|
--exractors
|
||||||
SELECT ('{3456,1.2.3.34}'::ltree[] ?@> '1.2.3.4') is null;
|
SELECT ('{3456,1.2.3.34}'::ltree[] ?@> '1.2.3.4') is null;
|
||||||
?column?
|
?column?
|
||||||
@ -3058,58 +3088,6 @@ SELECT * FROM ltreetest WHERE t <@ '1.1.1' order by t asc;
|
|||||||
1.1.1.2.1
|
1.1.1.2.1
|
||||||
(4 rows)
|
(4 rows)
|
||||||
|
|
||||||
SELECT * FROM ltreetest WHERE t ~ '1.1.1.*' order by t asc;
|
|
||||||
t
|
|
||||||
-----------
|
|
||||||
1.1.1
|
|
||||||
1.1.1.1
|
|
||||||
1.1.1.2
|
|
||||||
1.1.1.2.1
|
|
||||||
(4 rows)
|
|
||||||
|
|
||||||
SELECT * FROM ltreetest WHERE t ~ '*.1' order by t asc;
|
|
||||||
t
|
|
||||||
--------------------------------
|
|
||||||
1
|
|
||||||
10.22.1
|
|
||||||
10.26.30.15.1
|
|
||||||
11.1
|
|
||||||
17.25.2.13.10.27.13.1
|
|
||||||
18.13.6.12.26.26.26.29.18.20.1
|
|
||||||
19.20.25.7.27.28.27.17.9.3.1
|
|
||||||
19.9.32.23.13.24.1
|
|
||||||
20.17.18.21.1
|
|
||||||
20.4.27.31.1
|
|
||||||
21.18.2.1
|
|
||||||
21.23.17.8.23.11.8.1
|
|
||||||
22.30.31.24.23.22.5.20.28.1
|
|
||||||
23.28.1
|
|
||||||
23.3.32.21.5.14.10.17.1
|
|
||||||
25.6.12.16.1
|
|
||||||
29.1
|
|
||||||
29.15.29.8.31.26.1
|
|
||||||
32.31.11.22.1
|
|
||||||
4.7.1
|
|
||||||
6.27.29.14.8.12.26.3.21.4.1
|
|
||||||
8.13.1
|
|
||||||
8.2.18.23.5.16.17.1
|
|
||||||
8.32.30.1
|
|
||||||
9.21.20.29.1
|
|
||||||
(25 rows)
|
|
||||||
|
|
||||||
SELECT * FROM ltreetest WHERE t ~ '23.*.1' order by t asc;
|
|
||||||
t
|
|
||||||
-------------------------
|
|
||||||
23.28.1
|
|
||||||
23.3.32.21.5.14.10.17.1
|
|
||||||
(2 rows)
|
|
||||||
|
|
||||||
SELECT * FROM ltreetest WHERE t ~ '23.*{1}.1' order by t asc;
|
|
||||||
t
|
|
||||||
---------
|
|
||||||
23.28.1
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
SELECT * FROM ltreetest WHERE t @ '23 & 1' order by t asc;
|
SELECT * FROM ltreetest WHERE t @ '23 & 1' order by t asc;
|
||||||
t
|
t
|
||||||
--------------------------------
|
--------------------------------
|
||||||
@ -3154,6 +3132,83 @@ SELECT * FROM ltreetest WHERE t @ '23 & 1' order by t asc;
|
|||||||
9.5.9.3.23.9.25.14.1.29.28
|
9.5.9.3.23.9.25.14.1.29.28
|
||||||
(39 rows)
|
(39 rows)
|
||||||
|
|
||||||
|
SELECT * FROM ltreetest WHERE t ~ '1.1.1.*' order by t asc;
|
||||||
|
t
|
||||||
|
-----------
|
||||||
|
1.1.1
|
||||||
|
1.1.1.1
|
||||||
|
1.1.1.2
|
||||||
|
1.1.1.2.1
|
||||||
|
(4 rows)
|
||||||
|
|
||||||
|
SELECT * FROM ltreetest WHERE t ~ '*.1' order by t asc;
|
||||||
|
t
|
||||||
|
--------------------------------
|
||||||
|
1
|
||||||
|
1.1
|
||||||
|
1.1.1
|
||||||
|
1.1.1.1
|
||||||
|
1.1.1.2.1
|
||||||
|
1.1.2.1
|
||||||
|
1.26.15.23.5.31.29.11.19.28.1
|
||||||
|
10.13.22.1.8.30.9.24.1.2.1
|
||||||
|
10.22.1
|
||||||
|
10.26.30.15.1
|
||||||
|
11.1
|
||||||
|
12.1.1
|
||||||
|
17.25.2.13.10.27.13.1
|
||||||
|
18.13.6.12.26.26.26.29.18.20.1
|
||||||
|
19.20.25.7.27.28.27.17.9.3.1
|
||||||
|
19.9.32.23.13.24.1
|
||||||
|
20.17.18.21.1
|
||||||
|
20.4.27.31.1
|
||||||
|
21.18.2.1
|
||||||
|
21.23.17.8.23.11.8.1
|
||||||
|
22.30.31.24.23.22.5.20.28.1
|
||||||
|
23.17.22.1.23.4.29.32.4.1
|
||||||
|
23.28.1
|
||||||
|
23.3.32.21.5.14.10.17.1
|
||||||
|
25.6.12.16.1
|
||||||
|
29.1
|
||||||
|
29.15.29.8.31.26.1
|
||||||
|
32.31.11.22.1
|
||||||
|
4.7.1
|
||||||
|
6.27.29.14.8.12.26.3.21.4.1
|
||||||
|
8.13.1
|
||||||
|
8.2.18.23.5.16.17.1
|
||||||
|
8.32.30.1
|
||||||
|
9.21.20.29.1
|
||||||
|
(34 rows)
|
||||||
|
|
||||||
|
SELECT * FROM ltreetest WHERE t ~ '23.*{1}.1' order by t asc;
|
||||||
|
t
|
||||||
|
---------
|
||||||
|
23.28.1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT * FROM ltreetest WHERE t ~ '23.*.1' order by t asc;
|
||||||
|
t
|
||||||
|
---------------------------
|
||||||
|
23.17.22.1.23.4.29.32.4.1
|
||||||
|
23.28.1
|
||||||
|
23.3.32.21.5.14.10.17.1
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT * FROM ltreetest WHERE t ~ '23.*.2' order by t asc;
|
||||||
|
t
|
||||||
|
------------------
|
||||||
|
23.20.12.16.15.2
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT * FROM ltreetest WHERE t ? '{23.*.1,23.*.2}' order by t asc;
|
||||||
|
t
|
||||||
|
---------------------------
|
||||||
|
23.17.22.1.23.4.29.32.4.1
|
||||||
|
23.20.12.16.15.2
|
||||||
|
23.28.1
|
||||||
|
23.3.32.21.5.14.10.17.1
|
||||||
|
(4 rows)
|
||||||
|
|
||||||
create unique index tstidx on ltreetest (t);
|
create unique index tstidx on ltreetest (t);
|
||||||
set enable_seqscan=off;
|
set enable_seqscan=off;
|
||||||
SELECT * FROM ltreetest WHERE t < '12.3' order by t asc;
|
SELECT * FROM ltreetest WHERE t < '12.3' order by t asc;
|
||||||
@ -7253,58 +7308,6 @@ SELECT * FROM ltreetest WHERE t <@ '1.1.1' order by t asc;
|
|||||||
1.1.1.2.1
|
1.1.1.2.1
|
||||||
(4 rows)
|
(4 rows)
|
||||||
|
|
||||||
SELECT * FROM ltreetest WHERE t ~ '1.1.1.*' order by t asc;
|
|
||||||
t
|
|
||||||
-----------
|
|
||||||
1.1.1
|
|
||||||
1.1.1.1
|
|
||||||
1.1.1.2
|
|
||||||
1.1.1.2.1
|
|
||||||
(4 rows)
|
|
||||||
|
|
||||||
SELECT * FROM ltreetest WHERE t ~ '*.1' order by t asc;
|
|
||||||
t
|
|
||||||
--------------------------------
|
|
||||||
1
|
|
||||||
10.22.1
|
|
||||||
10.26.30.15.1
|
|
||||||
11.1
|
|
||||||
17.25.2.13.10.27.13.1
|
|
||||||
18.13.6.12.26.26.26.29.18.20.1
|
|
||||||
19.20.25.7.27.28.27.17.9.3.1
|
|
||||||
19.9.32.23.13.24.1
|
|
||||||
20.17.18.21.1
|
|
||||||
20.4.27.31.1
|
|
||||||
21.18.2.1
|
|
||||||
21.23.17.8.23.11.8.1
|
|
||||||
22.30.31.24.23.22.5.20.28.1
|
|
||||||
23.28.1
|
|
||||||
23.3.32.21.5.14.10.17.1
|
|
||||||
25.6.12.16.1
|
|
||||||
29.1
|
|
||||||
29.15.29.8.31.26.1
|
|
||||||
32.31.11.22.1
|
|
||||||
4.7.1
|
|
||||||
6.27.29.14.8.12.26.3.21.4.1
|
|
||||||
8.13.1
|
|
||||||
8.2.18.23.5.16.17.1
|
|
||||||
8.32.30.1
|
|
||||||
9.21.20.29.1
|
|
||||||
(25 rows)
|
|
||||||
|
|
||||||
SELECT * FROM ltreetest WHERE t ~ '23.*.1' order by t asc;
|
|
||||||
t
|
|
||||||
-------------------------
|
|
||||||
23.28.1
|
|
||||||
23.3.32.21.5.14.10.17.1
|
|
||||||
(2 rows)
|
|
||||||
|
|
||||||
SELECT * FROM ltreetest WHERE t ~ '23.*{1}.1' order by t asc;
|
|
||||||
t
|
|
||||||
---------
|
|
||||||
23.28.1
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
SELECT * FROM ltreetest WHERE t @ '23 & 1' order by t asc;
|
SELECT * FROM ltreetest WHERE t @ '23 & 1' order by t asc;
|
||||||
t
|
t
|
||||||
--------------------------------
|
--------------------------------
|
||||||
@ -7349,6 +7352,83 @@ SELECT * FROM ltreetest WHERE t @ '23 & 1' order by t asc;
|
|||||||
9.5.9.3.23.9.25.14.1.29.28
|
9.5.9.3.23.9.25.14.1.29.28
|
||||||
(39 rows)
|
(39 rows)
|
||||||
|
|
||||||
|
SELECT * FROM ltreetest WHERE t ~ '1.1.1.*' order by t asc;
|
||||||
|
t
|
||||||
|
-----------
|
||||||
|
1.1.1
|
||||||
|
1.1.1.1
|
||||||
|
1.1.1.2
|
||||||
|
1.1.1.2.1
|
||||||
|
(4 rows)
|
||||||
|
|
||||||
|
SELECT * FROM ltreetest WHERE t ~ '*.1' order by t asc;
|
||||||
|
t
|
||||||
|
--------------------------------
|
||||||
|
1
|
||||||
|
1.1
|
||||||
|
1.1.1
|
||||||
|
1.1.1.1
|
||||||
|
1.1.1.2.1
|
||||||
|
1.1.2.1
|
||||||
|
1.26.15.23.5.31.29.11.19.28.1
|
||||||
|
10.13.22.1.8.30.9.24.1.2.1
|
||||||
|
10.22.1
|
||||||
|
10.26.30.15.1
|
||||||
|
11.1
|
||||||
|
12.1.1
|
||||||
|
17.25.2.13.10.27.13.1
|
||||||
|
18.13.6.12.26.26.26.29.18.20.1
|
||||||
|
19.20.25.7.27.28.27.17.9.3.1
|
||||||
|
19.9.32.23.13.24.1
|
||||||
|
20.17.18.21.1
|
||||||
|
20.4.27.31.1
|
||||||
|
21.18.2.1
|
||||||
|
21.23.17.8.23.11.8.1
|
||||||
|
22.30.31.24.23.22.5.20.28.1
|
||||||
|
23.17.22.1.23.4.29.32.4.1
|
||||||
|
23.28.1
|
||||||
|
23.3.32.21.5.14.10.17.1
|
||||||
|
25.6.12.16.1
|
||||||
|
29.1
|
||||||
|
29.15.29.8.31.26.1
|
||||||
|
32.31.11.22.1
|
||||||
|
4.7.1
|
||||||
|
6.27.29.14.8.12.26.3.21.4.1
|
||||||
|
8.13.1
|
||||||
|
8.2.18.23.5.16.17.1
|
||||||
|
8.32.30.1
|
||||||
|
9.21.20.29.1
|
||||||
|
(34 rows)
|
||||||
|
|
||||||
|
SELECT * FROM ltreetest WHERE t ~ '23.*{1}.1' order by t asc;
|
||||||
|
t
|
||||||
|
---------
|
||||||
|
23.28.1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT * FROM ltreetest WHERE t ~ '23.*.1' order by t asc;
|
||||||
|
t
|
||||||
|
---------------------------
|
||||||
|
23.17.22.1.23.4.29.32.4.1
|
||||||
|
23.28.1
|
||||||
|
23.3.32.21.5.14.10.17.1
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT * FROM ltreetest WHERE t ~ '23.*.2' order by t asc;
|
||||||
|
t
|
||||||
|
------------------
|
||||||
|
23.20.12.16.15.2
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT * FROM ltreetest WHERE t ? '{23.*.1,23.*.2}' order by t asc;
|
||||||
|
t
|
||||||
|
---------------------------
|
||||||
|
23.17.22.1.23.4.29.32.4.1
|
||||||
|
23.20.12.16.15.2
|
||||||
|
23.28.1
|
||||||
|
23.3.32.21.5.14.10.17.1
|
||||||
|
(4 rows)
|
||||||
|
|
||||||
create table _ltreetest (t ltree[]);
|
create table _ltreetest (t ltree[]);
|
||||||
\copy _ltreetest FROM 'data/_ltree.data'
|
\copy _ltreetest FROM 'data/_ltree.data'
|
||||||
SELECT count(*) FROM _ltreetest WHERE t @> '1.1.1' ;
|
SELECT count(*) FROM _ltreetest WHERE t @> '1.1.1' ;
|
||||||
@ -7363,6 +7443,12 @@ SELECT count(*) FROM _ltreetest WHERE t <@ '1.1.1' ;
|
|||||||
19
|
19
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
|
SELECT count(*) FROM _ltreetest WHERE t @ '23 & 1' ;
|
||||||
|
count
|
||||||
|
-------
|
||||||
|
147
|
||||||
|
(1 row)
|
||||||
|
|
||||||
SELECT count(*) FROM _ltreetest WHERE t ~ '1.1.1.*' ;
|
SELECT count(*) FROM _ltreetest WHERE t ~ '1.1.1.*' ;
|
||||||
count
|
count
|
||||||
-------
|
-------
|
||||||
@ -7372,13 +7458,7 @@ SELECT count(*) FROM _ltreetest WHERE t ~ '1.1.1.*' ;
|
|||||||
SELECT count(*) FROM _ltreetest WHERE t ~ '*.1' ;
|
SELECT count(*) FROM _ltreetest WHERE t ~ '*.1' ;
|
||||||
count
|
count
|
||||||
-------
|
-------
|
||||||
83
|
109
|
||||||
(1 row)
|
|
||||||
|
|
||||||
SELECT count(*) FROM _ltreetest WHERE t ~ '23.*.1' ;
|
|
||||||
count
|
|
||||||
-------
|
|
||||||
10
|
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
SELECT count(*) FROM _ltreetest WHERE t ~ '23.*{1}.1' ;
|
SELECT count(*) FROM _ltreetest WHERE t ~ '23.*{1}.1' ;
|
||||||
@ -7387,10 +7467,22 @@ SELECT count(*) FROM _ltreetest WHERE t ~ '23.*{1}.1' ;
|
|||||||
5
|
5
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
SELECT count(*) FROM _ltreetest WHERE t @ '23 & 1' ;
|
SELECT count(*) FROM _ltreetest WHERE t ~ '23.*.1' ;
|
||||||
count
|
count
|
||||||
-------
|
-------
|
||||||
147
|
11
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT count(*) FROM _ltreetest WHERE t ~ '23.*.2' ;
|
||||||
|
count
|
||||||
|
-------
|
||||||
|
5
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT count(*) FROM _ltreetest WHERE t ? '{23.*.1,23.*.2}' ;
|
||||||
|
count
|
||||||
|
-------
|
||||||
|
15
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
create index _tstidx on _ltreetest using gist (t);
|
create index _tstidx on _ltreetest using gist (t);
|
||||||
@ -7407,6 +7499,12 @@ SELECT count(*) FROM _ltreetest WHERE t <@ '1.1.1' ;
|
|||||||
19
|
19
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
|
SELECT count(*) FROM _ltreetest WHERE t @ '23 & 1' ;
|
||||||
|
count
|
||||||
|
-------
|
||||||
|
147
|
||||||
|
(1 row)
|
||||||
|
|
||||||
SELECT count(*) FROM _ltreetest WHERE t ~ '1.1.1.*' ;
|
SELECT count(*) FROM _ltreetest WHERE t ~ '1.1.1.*' ;
|
||||||
count
|
count
|
||||||
-------
|
-------
|
||||||
@ -7416,13 +7514,7 @@ SELECT count(*) FROM _ltreetest WHERE t ~ '1.1.1.*' ;
|
|||||||
SELECT count(*) FROM _ltreetest WHERE t ~ '*.1' ;
|
SELECT count(*) FROM _ltreetest WHERE t ~ '*.1' ;
|
||||||
count
|
count
|
||||||
-------
|
-------
|
||||||
83
|
109
|
||||||
(1 row)
|
|
||||||
|
|
||||||
SELECT count(*) FROM _ltreetest WHERE t ~ '23.*.1' ;
|
|
||||||
count
|
|
||||||
-------
|
|
||||||
10
|
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
SELECT count(*) FROM _ltreetest WHERE t ~ '23.*{1}.1' ;
|
SELECT count(*) FROM _ltreetest WHERE t ~ '23.*{1}.1' ;
|
||||||
@ -7431,9 +7523,21 @@ SELECT count(*) FROM _ltreetest WHERE t ~ '23.*{1}.1' ;
|
|||||||
5
|
5
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
SELECT count(*) FROM _ltreetest WHERE t @ '23 & 1' ;
|
SELECT count(*) FROM _ltreetest WHERE t ~ '23.*.1' ;
|
||||||
count
|
count
|
||||||
-------
|
-------
|
||||||
147
|
11
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT count(*) FROM _ltreetest WHERE t ~ '23.*.2' ;
|
||||||
|
count
|
||||||
|
-------
|
||||||
|
5
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT count(*) FROM _ltreetest WHERE t ? '{23.*.1,23.*.2}' ;
|
||||||
|
count
|
||||||
|
-------
|
||||||
|
15
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
|
@ -5,10 +5,16 @@
|
|||||||
|
|
||||||
#include "ltree.h"
|
#include "ltree.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include "utils/array.h"
|
||||||
|
|
||||||
PG_FUNCTION_INFO_V1(ltq_regex);
|
PG_FUNCTION_INFO_V1(ltq_regex);
|
||||||
PG_FUNCTION_INFO_V1(ltq_rregex);
|
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
|
typedef struct
|
||||||
{
|
{
|
||||||
lquery_level *q;
|
lquery_level *q;
|
||||||
@ -39,7 +45,7 @@ getlexem(char *start, char *end, int *len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
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 *endt = t->name + t->len;
|
||||||
char *endq = qn + len;
|
char *endq = qn + len;
|
||||||
@ -117,6 +123,11 @@ printFieldNot(FieldNot *fn ) {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
bool muse;
|
||||||
|
uint32 high_pos;
|
||||||
|
} SomeStack = {false,0,};
|
||||||
|
|
||||||
static bool
|
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, FieldNot * ptr)
|
||||||
{
|
{
|
||||||
@ -129,6 +140,14 @@ checkCond(lquery_level * curq, int query_numlevel, ltree_level * curt, int tree_
|
|||||||
lquery_level *prevq = NULL;
|
lquery_level *prevq = NULL;
|
||||||
ltree_level *prevt = 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)
|
while (tlen > 0 && qlen > 0)
|
||||||
{
|
{
|
||||||
if (curq->numvar)
|
if (curq->numvar)
|
||||||
@ -181,6 +200,15 @@ checkCond(lquery_level * curq, int query_numlevel, ltree_level * curt, int tree_
|
|||||||
curt = LEVEL_NEXT(curt);
|
curt = LEVEL_NEXT(curt);
|
||||||
tlen--;
|
tlen--;
|
||||||
cur_tpos++;
|
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)
|
if (!isok && ptr)
|
||||||
ptr->nt++;
|
ptr->nt++;
|
||||||
}
|
}
|
||||||
@ -278,3 +306,42 @@ ltq_rregex(PG_FUNCTION_ARGS)
|
|||||||
PG_GETARG_DATUM(0)
|
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)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -140,10 +140,14 @@ Datum ltree_isparent(PG_FUNCTION_ARGS);
|
|||||||
Datum ltree_risparent(PG_FUNCTION_ARGS);
|
Datum ltree_risparent(PG_FUNCTION_ARGS);
|
||||||
Datum ltq_regex(PG_FUNCTION_ARGS);
|
Datum ltq_regex(PG_FUNCTION_ARGS);
|
||||||
Datum ltq_rregex(PG_FUNCTION_ARGS);
|
Datum ltq_rregex(PG_FUNCTION_ARGS);
|
||||||
|
Datum lt_q_regex(PG_FUNCTION_ARGS);
|
||||||
|
Datum lt_q_rregex(PG_FUNCTION_ARGS);
|
||||||
Datum ltxtq_exec(PG_FUNCTION_ARGS);
|
Datum ltxtq_exec(PG_FUNCTION_ARGS);
|
||||||
Datum ltxtq_rexec(PG_FUNCTION_ARGS);
|
Datum ltxtq_rexec(PG_FUNCTION_ARGS);
|
||||||
Datum _ltq_regex(PG_FUNCTION_ARGS);
|
Datum _ltq_regex(PG_FUNCTION_ARGS);
|
||||||
Datum _ltq_rregex(PG_FUNCTION_ARGS);
|
Datum _ltq_rregex(PG_FUNCTION_ARGS);
|
||||||
|
Datum _lt_q_regex(PG_FUNCTION_ARGS);
|
||||||
|
Datum _lt_q_rregex(PG_FUNCTION_ARGS);
|
||||||
Datum _ltxtq_exec(PG_FUNCTION_ARGS);
|
Datum _ltxtq_exec(PG_FUNCTION_ARGS);
|
||||||
Datum _ltxtq_rexec(PG_FUNCTION_ARGS);
|
Datum _ltxtq_rexec(PG_FUNCTION_ARGS);
|
||||||
Datum _ltree_isparent(PG_FUNCTION_ARGS);
|
Datum _ltree_isparent(PG_FUNCTION_ARGS);
|
||||||
@ -173,7 +177,7 @@ ltree *lca_inner(ltree ** a, int len);
|
|||||||
/* GiST support for ltree */
|
/* GiST support for ltree */
|
||||||
|
|
||||||
#define BITBYTE 8
|
#define BITBYTE 8
|
||||||
#define SIGLENINT 8
|
#define SIGLENINT 2
|
||||||
#define SIGLEN ( sizeof(int4)*SIGLENINT )
|
#define SIGLEN ( sizeof(int4)*SIGLENINT )
|
||||||
#define SIGLENBIT (SIGLEN*BITBYTE)
|
#define SIGLENBIT (SIGLEN*BITBYTE)
|
||||||
typedef unsigned char BITVEC[SIGLEN];
|
typedef unsigned char BITVEC[SIGLEN];
|
||||||
|
@ -339,6 +339,53 @@ CREATE OPERATOR ^~ (
|
|||||||
JOIN = contjoinsel
|
JOIN = contjoinsel
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE FUNCTION lt_q_regex(ltree,_lquery)
|
||||||
|
RETURNS bool
|
||||||
|
AS 'MODULE_PATHNAME'
|
||||||
|
LANGUAGE 'C' WITH (isstrict,iscachable);
|
||||||
|
|
||||||
|
CREATE FUNCTION lt_q_rregex(_lquery,ltree)
|
||||||
|
RETURNS bool
|
||||||
|
AS 'MODULE_PATHNAME'
|
||||||
|
LANGUAGE 'C' WITH (isstrict,iscachable);
|
||||||
|
|
||||||
|
CREATE OPERATOR ? (
|
||||||
|
LEFTARG = ltree,
|
||||||
|
RIGHTARG = _lquery,
|
||||||
|
PROCEDURE = lt_q_regex,
|
||||||
|
COMMUTATOR = '?',
|
||||||
|
RESTRICT = contsel,
|
||||||
|
JOIN = contjoinsel
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE OPERATOR ? (
|
||||||
|
LEFTARG = _lquery,
|
||||||
|
RIGHTARG = ltree,
|
||||||
|
PROCEDURE = lt_q_rregex,
|
||||||
|
COMMUTATOR = '?',
|
||||||
|
RESTRICT = contsel,
|
||||||
|
JOIN = contjoinsel
|
||||||
|
);
|
||||||
|
|
||||||
|
--not-indexed
|
||||||
|
CREATE OPERATOR ^? (
|
||||||
|
LEFTARG = ltree,
|
||||||
|
RIGHTARG = _lquery,
|
||||||
|
PROCEDURE = lt_q_regex,
|
||||||
|
COMMUTATOR = '^?',
|
||||||
|
RESTRICT = contsel,
|
||||||
|
JOIN = contjoinsel
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE OPERATOR ^? (
|
||||||
|
LEFTARG = _lquery,
|
||||||
|
RIGHTARG = ltree,
|
||||||
|
PROCEDURE = lt_q_rregex,
|
||||||
|
COMMUTATOR = '^?',
|
||||||
|
RESTRICT = contsel,
|
||||||
|
JOIN = contjoinsel
|
||||||
|
);
|
||||||
|
|
||||||
CREATE FUNCTION ltxtq_in(cstring)
|
CREATE FUNCTION ltxtq_in(cstring)
|
||||||
RETURNS ltxtquery
|
RETURNS ltxtquery
|
||||||
AS 'MODULE_PATHNAME'
|
AS 'MODULE_PATHNAME'
|
||||||
@ -452,6 +499,8 @@ CREATE OPERATOR CLASS gist_ltree_ops
|
|||||||
OPERATOR 13 ~ (lquery, ltree) ,
|
OPERATOR 13 ~ (lquery, ltree) ,
|
||||||
OPERATOR 14 @ (ltree, ltxtquery) ,
|
OPERATOR 14 @ (ltree, ltxtquery) ,
|
||||||
OPERATOR 15 @ (ltxtquery, ltree) ,
|
OPERATOR 15 @ (ltxtquery, ltree) ,
|
||||||
|
OPERATOR 16 ? (ltree, _lquery) ,
|
||||||
|
OPERATOR 17 ? (_lquery, ltree) ,
|
||||||
FUNCTION 1 ltree_consistent (internal, internal, int2),
|
FUNCTION 1 ltree_consistent (internal, internal, int2),
|
||||||
FUNCTION 2 ltree_union (bytea, internal),
|
FUNCTION 2 ltree_union (bytea, internal),
|
||||||
FUNCTION 3 ltree_compress (internal),
|
FUNCTION 3 ltree_compress (internal),
|
||||||
@ -494,6 +543,16 @@ RETURNS bool
|
|||||||
AS 'MODULE_PATHNAME'
|
AS 'MODULE_PATHNAME'
|
||||||
LANGUAGE 'C' WITH (isstrict,iscachable);
|
LANGUAGE 'C' WITH (isstrict,iscachable);
|
||||||
|
|
||||||
|
CREATE FUNCTION _lt_q_regex(_ltree,_lquery)
|
||||||
|
RETURNS bool
|
||||||
|
AS 'MODULE_PATHNAME'
|
||||||
|
LANGUAGE 'C' WITH (isstrict,iscachable);
|
||||||
|
|
||||||
|
CREATE FUNCTION _lt_q_rregex(_lquery,_ltree)
|
||||||
|
RETURNS bool
|
||||||
|
AS 'MODULE_PATHNAME'
|
||||||
|
LANGUAGE 'C' WITH (isstrict,iscachable);
|
||||||
|
|
||||||
CREATE FUNCTION _ltxtq_exec(_ltree, ltxtquery)
|
CREATE FUNCTION _ltxtq_exec(_ltree, ltxtquery)
|
||||||
RETURNS bool
|
RETURNS bool
|
||||||
AS 'MODULE_PATHNAME'
|
AS 'MODULE_PATHNAME'
|
||||||
@ -558,6 +617,24 @@ CREATE OPERATOR ~ (
|
|||||||
JOIN = contjoinsel
|
JOIN = contjoinsel
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE OPERATOR ? (
|
||||||
|
LEFTARG = _ltree,
|
||||||
|
RIGHTARG = _lquery,
|
||||||
|
PROCEDURE = _lt_q_regex,
|
||||||
|
COMMUTATOR = '?',
|
||||||
|
RESTRICT = contsel,
|
||||||
|
JOIN = contjoinsel
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE OPERATOR ? (
|
||||||
|
LEFTARG = _lquery,
|
||||||
|
RIGHTARG = _ltree,
|
||||||
|
PROCEDURE = _lt_q_rregex,
|
||||||
|
COMMUTATOR = '?',
|
||||||
|
RESTRICT = contsel,
|
||||||
|
JOIN = contjoinsel
|
||||||
|
);
|
||||||
|
|
||||||
CREATE OPERATOR @ (
|
CREATE OPERATOR @ (
|
||||||
LEFTARG = _ltree,
|
LEFTARG = _ltree,
|
||||||
RIGHTARG = ltxtquery,
|
RIGHTARG = ltxtquery,
|
||||||
@ -632,6 +709,24 @@ CREATE OPERATOR ^~ (
|
|||||||
JOIN = contjoinsel
|
JOIN = contjoinsel
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE OPERATOR ^? (
|
||||||
|
LEFTARG = _ltree,
|
||||||
|
RIGHTARG = _lquery,
|
||||||
|
PROCEDURE = _lt_q_regex,
|
||||||
|
COMMUTATOR = '^?',
|
||||||
|
RESTRICT = contsel,
|
||||||
|
JOIN = contjoinsel
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE OPERATOR ^? (
|
||||||
|
LEFTARG = _lquery,
|
||||||
|
RIGHTARG = _ltree,
|
||||||
|
PROCEDURE = _lt_q_rregex,
|
||||||
|
COMMUTATOR = '^?',
|
||||||
|
RESTRICT = contsel,
|
||||||
|
JOIN = contjoinsel
|
||||||
|
);
|
||||||
|
|
||||||
CREATE OPERATOR ^@ (
|
CREATE OPERATOR ^@ (
|
||||||
LEFTARG = _ltree,
|
LEFTARG = _ltree,
|
||||||
RIGHTARG = ltxtquery,
|
RIGHTARG = ltxtquery,
|
||||||
@ -729,6 +824,8 @@ CREATE OPERATOR CLASS gist__ltree_ops
|
|||||||
OPERATOR 13 ~ (lquery, _ltree) RECHECK ,
|
OPERATOR 13 ~ (lquery, _ltree) RECHECK ,
|
||||||
OPERATOR 14 @ (_ltree, ltxtquery) RECHECK ,
|
OPERATOR 14 @ (_ltree, ltxtquery) RECHECK ,
|
||||||
OPERATOR 15 @ (ltxtquery, _ltree) RECHECK ,
|
OPERATOR 15 @ (ltxtquery, _ltree) RECHECK ,
|
||||||
|
OPERATOR 16 ? (_ltree, _lquery) RECHECK ,
|
||||||
|
OPERATOR 17 ? (_lquery, _ltree) RECHECK ,
|
||||||
FUNCTION 1 _ltree_consistent (internal, internal, int2),
|
FUNCTION 1 _ltree_consistent (internal, internal, int2),
|
||||||
FUNCTION 2 _ltree_union (bytea, internal),
|
FUNCTION 2 _ltree_union (bytea, internal),
|
||||||
FUNCTION 3 _ltree_compress (internal),
|
FUNCTION 3 _ltree_compress (internal),
|
||||||
|
@ -7,9 +7,11 @@
|
|||||||
#include "access/gist.h"
|
#include "access/gist.h"
|
||||||
#include "access/rtree.h"
|
#include "access/rtree.h"
|
||||||
#include "access/nbtree.h"
|
#include "access/nbtree.h"
|
||||||
|
#include "utils/array.h"
|
||||||
#include "crc32.h"
|
#include "crc32.h"
|
||||||
|
|
||||||
|
#define NEXTVAL(x) ( (lquery*)( (char*)(x) + INTALIGN( VARSIZE(x) ) ) )
|
||||||
|
|
||||||
PG_FUNCTION_INFO_V1(ltree_gist_in);
|
PG_FUNCTION_INFO_V1(ltree_gist_in);
|
||||||
Datum ltree_gist_in(PG_FUNCTION_ARGS);
|
Datum ltree_gist_in(PG_FUNCTION_ARGS);
|
||||||
|
|
||||||
@ -596,6 +598,22 @@ gist_qtxt(ltree_gist * key, ltxtquery * query)
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
arrq_cons(ltree_gist *key, ArrayType *_query) {
|
||||||
|
lquery *query = (lquery *) ARR_DATA_PTR(_query);
|
||||||
|
int num = ArrayGetNItems(ARR_NDIM(_query), ARR_DIMS(_query));
|
||||||
|
|
||||||
|
if (ARR_NDIM(_query) != 1)
|
||||||
|
elog(ERROR, "Dimension of array != 1");
|
||||||
|
|
||||||
|
while (num > 0) {
|
||||||
|
if ( gist_qe(key, query) && gist_between(key, query) )
|
||||||
|
return true;
|
||||||
|
num--;
|
||||||
|
query = NEXTVAL(query);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
ltree_consistent(PG_FUNCTION_ARGS)
|
ltree_consistent(PG_FUNCTION_ARGS)
|
||||||
@ -672,6 +690,16 @@ ltree_consistent(PG_FUNCTION_ARGS)
|
|||||||
else
|
else
|
||||||
res = gist_qtxt(key, (ltxtquery *) query);
|
res = gist_qtxt(key, (ltxtquery *) query);
|
||||||
break;
|
break;
|
||||||
|
case 16:
|
||||||
|
case 17:
|
||||||
|
if (GIST_LEAF(entry))
|
||||||
|
res = DatumGetBool(DirectFunctionCall2(lt_q_regex,
|
||||||
|
PointerGetDatum(LTG_NODE(key)),
|
||||||
|
PointerGetDatum((ArrayType *) query)
|
||||||
|
));
|
||||||
|
else
|
||||||
|
res = arrq_cons(key, (ArrayType *) query);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
elog(ERROR, "Unknown StrategyNumber: %d", strategy);
|
elog(ERROR, "Unknown StrategyNumber: %d", strategy);
|
||||||
}
|
}
|
||||||
|
@ -139,6 +139,7 @@ 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.*{1}.!c.*';
|
||||||
SELECT 'a.b.c.d.e'::ltree ~ '*.!b.*.!c.*';
|
SELECT 'a.b.c.d.e'::ltree ~ '*.!b.*.!c.*';
|
||||||
|
|
||||||
|
|
||||||
SELECT 'QWER_TY'::ltree ~ 'q%@*';
|
SELECT 'QWER_TY'::ltree ~ 'q%@*';
|
||||||
SELECT 'QWER_TY'::ltree ~ 'Q_t%@*';
|
SELECT 'QWER_TY'::ltree ~ 'Q_t%@*';
|
||||||
SELECT 'QWER_GY'::ltree ~ 'q_t%@*';
|
SELECT 'QWER_GY'::ltree ~ 'q_t%@*';
|
||||||
@ -175,6 +176,11 @@ SELECT '{1.2.3.4.5, 7.12.asd}'::ltree[] @> '1.2.3.4';
|
|||||||
SELECT '{1.3.3, 7.12.asd}'::ltree[] @> '1.2.3.4';
|
SELECT '{1.3.3, 7.12.asd}'::ltree[] @> '1.2.3.4';
|
||||||
SELECT '{ltree.asd, tree.awdfg}'::ltree[] @ 'tree & aWdfg@'::ltxtquery;
|
SELECT '{ltree.asd, tree.awdfg}'::ltree[] @ 'tree & aWdfg@'::ltxtquery;
|
||||||
SELECT '{j.k.l.m, g.b.c.d.e}'::ltree[] ~ 'A*@|g.b.c.d.e';
|
SELECT '{j.k.l.m, g.b.c.d.e}'::ltree[] ~ 'A*@|g.b.c.d.e';
|
||||||
|
SELECT 'a.b.c.d.e'::ltree ? '{A.b.c.d.e}';
|
||||||
|
SELECT 'a.b.c.d.e'::ltree ? '{a.b.c.d.e}';
|
||||||
|
SELECT 'a.b.c.d.e'::ltree ? '{A.b.c.d.e, a.*}';
|
||||||
|
SELECT '{a.b.c.d.e,B.df}'::ltree[] ? '{A.b.c.d.e}';
|
||||||
|
SELECT '{a.b.c.d.e,B.df}'::ltree[] ? '{A.b.c.d.e,*.df}';
|
||||||
|
|
||||||
--exractors
|
--exractors
|
||||||
SELECT ('{3456,1.2.3.34}'::ltree[] ?@> '1.2.3.4') is null;
|
SELECT ('{3456,1.2.3.34}'::ltree[] ?@> '1.2.3.4') is null;
|
||||||
@ -194,11 +200,13 @@ SELECT * FROM ltreetest WHERE t >= '12.3' order by t asc;
|
|||||||
SELECT * FROM ltreetest WHERE t > '12.3' order by t asc;
|
SELECT * FROM ltreetest WHERE t > '12.3' order by t asc;
|
||||||
SELECT * FROM ltreetest WHERE t @> '1.1.1' order by t asc;
|
SELECT * FROM ltreetest WHERE t @> '1.1.1' order by t asc;
|
||||||
SELECT * FROM ltreetest WHERE t <@ '1.1.1' order by t asc;
|
SELECT * FROM ltreetest WHERE t <@ '1.1.1' order by t asc;
|
||||||
|
SELECT * FROM ltreetest WHERE t @ '23 & 1' order by t asc;
|
||||||
SELECT * FROM ltreetest WHERE t ~ '1.1.1.*' order by t asc;
|
SELECT * FROM ltreetest WHERE t ~ '1.1.1.*' order by t asc;
|
||||||
SELECT * FROM ltreetest WHERE t ~ '*.1' order by t asc;
|
SELECT * FROM ltreetest WHERE t ~ '*.1' order by t asc;
|
||||||
SELECT * FROM ltreetest WHERE t ~ '23.*.1' order by t asc;
|
|
||||||
SELECT * FROM ltreetest WHERE t ~ '23.*{1}.1' order by t asc;
|
SELECT * FROM ltreetest WHERE t ~ '23.*{1}.1' order by t asc;
|
||||||
SELECT * FROM ltreetest WHERE t @ '23 & 1' order by t asc;
|
SELECT * FROM ltreetest WHERE t ~ '23.*.1' order by t asc;
|
||||||
|
SELECT * FROM ltreetest WHERE t ~ '23.*.2' order by t asc;
|
||||||
|
SELECT * FROM ltreetest WHERE t ? '{23.*.1,23.*.2}' order by t asc;
|
||||||
|
|
||||||
create unique index tstidx on ltreetest (t);
|
create unique index tstidx on ltreetest (t);
|
||||||
set enable_seqscan=off;
|
set enable_seqscan=off;
|
||||||
@ -220,31 +228,37 @@ SELECT * FROM ltreetest WHERE t >= '12.3' order by t asc;
|
|||||||
SELECT * FROM ltreetest WHERE t > '12.3' order by t asc;
|
SELECT * FROM ltreetest WHERE t > '12.3' order by t asc;
|
||||||
SELECT * FROM ltreetest WHERE t @> '1.1.1' order by t asc;
|
SELECT * FROM ltreetest WHERE t @> '1.1.1' order by t asc;
|
||||||
SELECT * FROM ltreetest WHERE t <@ '1.1.1' order by t asc;
|
SELECT * FROM ltreetest WHERE t <@ '1.1.1' order by t asc;
|
||||||
|
SELECT * FROM ltreetest WHERE t @ '23 & 1' order by t asc;
|
||||||
SELECT * FROM ltreetest WHERE t ~ '1.1.1.*' order by t asc;
|
SELECT * FROM ltreetest WHERE t ~ '1.1.1.*' order by t asc;
|
||||||
SELECT * FROM ltreetest WHERE t ~ '*.1' order by t asc;
|
SELECT * FROM ltreetest WHERE t ~ '*.1' order by t asc;
|
||||||
SELECT * FROM ltreetest WHERE t ~ '23.*.1' order by t asc;
|
|
||||||
SELECT * FROM ltreetest WHERE t ~ '23.*{1}.1' order by t asc;
|
SELECT * FROM ltreetest WHERE t ~ '23.*{1}.1' order by t asc;
|
||||||
SELECT * FROM ltreetest WHERE t @ '23 & 1' order by t asc;
|
SELECT * FROM ltreetest WHERE t ~ '23.*.1' order by t asc;
|
||||||
|
SELECT * FROM ltreetest WHERE t ~ '23.*.2' order by t asc;
|
||||||
|
SELECT * FROM ltreetest WHERE t ? '{23.*.1,23.*.2}' order by t asc;
|
||||||
|
|
||||||
create table _ltreetest (t ltree[]);
|
create table _ltreetest (t ltree[]);
|
||||||
\copy _ltreetest FROM 'data/_ltree.data'
|
\copy _ltreetest FROM 'data/_ltree.data'
|
||||||
|
|
||||||
SELECT count(*) FROM _ltreetest WHERE t @> '1.1.1' ;
|
SELECT count(*) FROM _ltreetest WHERE t @> '1.1.1' ;
|
||||||
SELECT count(*) FROM _ltreetest WHERE t <@ '1.1.1' ;
|
SELECT count(*) FROM _ltreetest WHERE t <@ '1.1.1' ;
|
||||||
|
SELECT count(*) FROM _ltreetest WHERE t @ '23 & 1' ;
|
||||||
SELECT count(*) FROM _ltreetest WHERE t ~ '1.1.1.*' ;
|
SELECT count(*) FROM _ltreetest WHERE t ~ '1.1.1.*' ;
|
||||||
SELECT count(*) FROM _ltreetest WHERE t ~ '*.1' ;
|
SELECT count(*) FROM _ltreetest WHERE t ~ '*.1' ;
|
||||||
SELECT count(*) FROM _ltreetest WHERE t ~ '23.*.1' ;
|
|
||||||
SELECT count(*) FROM _ltreetest WHERE t ~ '23.*{1}.1' ;
|
SELECT count(*) FROM _ltreetest WHERE t ~ '23.*{1}.1' ;
|
||||||
SELECT count(*) FROM _ltreetest WHERE t @ '23 & 1' ;
|
SELECT count(*) FROM _ltreetest WHERE t ~ '23.*.1' ;
|
||||||
|
SELECT count(*) FROM _ltreetest WHERE t ~ '23.*.2' ;
|
||||||
|
SELECT count(*) FROM _ltreetest WHERE t ? '{23.*.1,23.*.2}' ;
|
||||||
|
|
||||||
create index _tstidx on _ltreetest using gist (t);
|
create index _tstidx on _ltreetest using gist (t);
|
||||||
set enable_seqscan=off;
|
set enable_seqscan=off;
|
||||||
|
|
||||||
SELECT count(*) FROM _ltreetest WHERE t @> '1.1.1' ;
|
SELECT count(*) FROM _ltreetest WHERE t @> '1.1.1' ;
|
||||||
SELECT count(*) FROM _ltreetest WHERE t <@ '1.1.1' ;
|
SELECT count(*) FROM _ltreetest WHERE t <@ '1.1.1' ;
|
||||||
|
SELECT count(*) FROM _ltreetest WHERE t @ '23 & 1' ;
|
||||||
SELECT count(*) FROM _ltreetest WHERE t ~ '1.1.1.*' ;
|
SELECT count(*) FROM _ltreetest WHERE t ~ '1.1.1.*' ;
|
||||||
SELECT count(*) FROM _ltreetest WHERE t ~ '*.1' ;
|
SELECT count(*) FROM _ltreetest WHERE t ~ '*.1' ;
|
||||||
SELECT count(*) FROM _ltreetest WHERE t ~ '23.*.1' ;
|
|
||||||
SELECT count(*) FROM _ltreetest WHERE t ~ '23.*{1}.1' ;
|
SELECT count(*) FROM _ltreetest WHERE t ~ '23.*{1}.1' ;
|
||||||
SELECT count(*) FROM _ltreetest WHERE t @ '23 & 1' ;
|
SELECT count(*) FROM _ltreetest WHERE t ~ '23.*.1' ;
|
||||||
|
SELECT count(*) FROM _ltreetest WHERE t ~ '23.*.2' ;
|
||||||
|
SELECT count(*) FROM _ltreetest WHERE t ? '{23.*.1,23.*.2}' ;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user