Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Postgres FD Implementation
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Abuhujair Javed
Postgres FD Implementation
Commits
5320c6cf
Commit
5320c6cf
authored
May 03, 2006
by
Teodor Sigaev
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Make GIN opclass worked with intarray extensions
parent
2a58f3bf
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
258 additions
and
16 deletions
+258
-16
contrib/intarray/Makefile
contrib/intarray/Makefile
+2
-2
contrib/intarray/_int.h
contrib/intarray/_int.h
+9
-2
contrib/intarray/_int.sql.in
contrib/intarray/_int.sql.in
+34
-0
contrib/intarray/_int_bool.c
contrib/intarray/_int_bool.c
+42
-8
contrib/intarray/_int_gin.c
contrib/intarray/_int_gin.c
+100
-0
contrib/intarray/expected/_int.out
contrib/intarray/expected/_int.out
+54
-4
contrib/intarray/sql/_int.sql
contrib/intarray/sql/_int.sql
+12
-0
contrib/intarray/uninstall__int.sql
contrib/intarray/uninstall__int.sql
+5
-0
No files found.
contrib/intarray/Makefile
View file @
5320c6cf
# $PostgreSQL: pgsql/contrib/intarray/Makefile,v 1.1
3 2006/02/27 12:54:39 petere
Exp $
# $PostgreSQL: pgsql/contrib/intarray/Makefile,v 1.1
4 2006/05/03 16:31:07 teodor
Exp $
MODULE_big
=
_int
OBJS
=
_int_bool.o _int_gist.o _int_op.o _int_tool.o _intbig_gist.o
OBJS
=
_int_bool.o _int_gist.o _int_op.o _int_tool.o _intbig_gist.o
_int_gin.o
DATA_built
=
_int.sql
DATA
=
uninstall__int.sql
DOCS
=
README.intarray
...
...
contrib/intarray/_int.h
View file @
5320c6cf
...
...
@@ -151,10 +151,17 @@ typedef struct
#define COMPUTESIZE(size) ( HDRSIZEQT + size * sizeof(ITEM) )
#define GETQUERY(x) (ITEM*)( (char*)(x)+HDRSIZEQT )
#define END 0
#define ERR 1
#define VAL 2
#define OPR 3
#define OPEN 4
#define CLOSE 5
bool
signconsistent
(
QUERYTYPE
*
query
,
BITVEC
sign
,
bool
calcnot
);
bool
execconsistent
(
QUERYTYPE
*
query
,
ArrayType
*
array
,
bool
calcnot
);
bool
ginconsistent
(
QUERYTYPE
*
query
,
bool
*
check
);
int4
shorterquery
(
ITEM
*
q
,
int4
len
);
int
compASC
(
const
void
*
a
,
const
void
*
b
);
...
...
contrib/intarray/_int.sql.in
View file @
5320c6cf
...
...
@@ -6,6 +6,8 @@
-- opclasses get created.
SET search_path = public;
BEGIN;
-- Query type
CREATE FUNCTION bqarr_in(cstring)
RETURNS query_int
...
...
@@ -431,3 +433,35 @@ AS
FUNCTION 6 g_intbig_picksplit (internal, internal),
FUNCTION 7 g_intbig_same (internal, internal, internal),
STORAGE intbig_gkey;
--GIN
--mark built-in gin's _int4_ops as non default
update pg_opclass set opcdefault = 'f' where
pg_opclass.opcamid = (select pg_am.oid from pg_am where amname='gin') and
opcname = '_int4_ops';
CREATE FUNCTION ginint4_queryextract(internal, internal, int2)
RETURNS internal
AS 'MODULE_PATHNAME'
LANGUAGE C;
CREATE FUNCTION ginint4_consistent(internal, int2, internal)
RETURNS internal
AS 'MODULE_PATHNAME'
LANGUAGE C;
CREATE OPERATOR CLASS gin__int_ops
DEFAULT FOR TYPE _int4 USING gin
AS
OPERATOR 3 &&,
OPERATOR 6 = (anyarray, anyarray) RECHECK,
OPERATOR 7 @,
OPERATOR 8 ~ RECHECK,
OPERATOR 20 @@ (_int4, query_int),
FUNCTION 1 btint4cmp (int4, int4),
FUNCTION 2 ginarrayextract (anyarray, internal),
FUNCTION 3 ginint4_queryextract (internal, internal, int2),
FUNCTION 4 ginint4_consistent (internal, int2, internal),
STORAGE int4;
COMMIT;
contrib/intarray/_int_bool.c
View file @
5320c6cf
...
...
@@ -232,7 +232,7 @@ typedef struct
* is there value 'val' in array or not ?
*/
static
bool
checkcondition_arr
(
void
*
checkval
,
int4
val
)
checkcondition_arr
(
void
*
checkval
,
ITEM
*
item
)
{
int4
*
StopLow
=
((
CHKVAL
*
)
checkval
)
->
arrb
;
int4
*
StopHigh
=
((
CHKVAL
*
)
checkval
)
->
arre
;
...
...
@@ -243,9 +243,9 @@ checkcondition_arr(void *checkval, int4 val)
while
(
StopLow
<
StopHigh
)
{
StopMiddle
=
StopLow
+
(
StopHigh
-
StopLow
)
/
2
;
if
(
*
StopMiddle
==
val
)
if
(
*
StopMiddle
==
item
->
val
)
return
(
true
);
else
if
(
*
StopMiddle
<
val
)
else
if
(
*
StopMiddle
<
item
->
val
)
StopLow
=
StopMiddle
+
1
;
else
StopHigh
=
StopMiddle
;
...
...
@@ -254,20 +254,20 @@ checkcondition_arr(void *checkval, int4 val)
}
static
bool
checkcondition_bit
(
void
*
checkval
,
int4
val
)
checkcondition_bit
(
void
*
checkval
,
ITEM
*
item
)
{
return
GETBIT
(
checkval
,
HASHVAL
(
val
));
return
GETBIT
(
checkval
,
HASHVAL
(
item
->
val
));
}
/*
* check for boolean condition
*/
static
bool
execute
(
ITEM
*
curitem
,
void
*
checkval
,
bool
calcnot
,
bool
(
*
chkcond
)
(
void
*
checkval
,
int4
val
))
execute
(
ITEM
*
curitem
,
void
*
checkval
,
bool
calcnot
,
bool
(
*
chkcond
)
(
void
*
checkval
,
ITEM
*
item
))
{
if
(
curitem
->
type
==
VAL
)
return
(
*
chkcond
)
(
checkval
,
curitem
->
val
);
return
(
*
chkcond
)
(
checkval
,
curitem
);
else
if
(
curitem
->
val
==
(
int4
)
'!'
)
{
return
(
calcnot
)
?
...
...
@@ -319,6 +319,40 @@ execconsistent(QUERYTYPE * query, ArrayType *array, bool calcnot)
);
}
typedef
struct
{
ITEM
*
first
;
bool
*
mapped_check
;
}
GinChkVal
;
static
bool
checkcondition_gin
(
void
*
checkval
,
ITEM
*
item
)
{
GinChkVal
*
gcv
=
(
GinChkVal
*
)
checkval
;
return
gcv
->
mapped_check
[
item
-
gcv
->
first
];
}
bool
ginconsistent
(
QUERYTYPE
*
query
,
bool
*
check
)
{
GinChkVal
gcv
;
ITEM
*
items
=
GETQUERY
(
query
);
int
i
,
j
=
0
;
if
(
query
->
size
<
0
)
return
FALSE
;
gcv
.
first
=
items
;
gcv
.
mapped_check
=
(
bool
*
)
palloc
(
sizeof
(
bool
)
*
query
->
size
);
for
(
i
=
0
;
i
<
query
->
size
;
i
++
)
if
(
items
[
i
].
type
==
VAL
)
gcv
.
mapped_check
[
i
]
=
check
[
j
++
];
return
execute
(
GETQUERY
(
query
)
+
query
->
size
-
1
,
(
void
*
)
&
gcv
,
true
,
checkcondition_gin
);
}
/*
* boolean operations
*/
...
...
@@ -588,7 +622,7 @@ countdroptree(ITEM * q, int4 pos)
* result of all '!' will be = 'true', so
* we can modify query tree for clearing
*/
static
int4
int4
shorterquery
(
ITEM
*
q
,
int4
len
)
{
int4
index
,
...
...
contrib/intarray/_int_gin.c
0 → 100644
View file @
5320c6cf
#include "_int.h"
PG_FUNCTION_INFO_V1
(
ginint4_queryextract
);
Datum
ginint4_queryextract
(
PG_FUNCTION_ARGS
);
Datum
ginint4_queryextract
(
PG_FUNCTION_ARGS
)
{
uint32
*
nentries
=
(
uint32
*
)
PG_GETARG_POINTER
(
1
);
StrategyNumber
strategy
=
PG_GETARG_UINT16
(
2
);
Datum
*
res
=
NULL
;
*
nentries
=
0
;
if
(
strategy
==
BooleanSearchStrategy
)
{
QUERYTYPE
*
query
=
(
QUERYTYPE
*
)
PG_DETOAST_DATUM_COPY
(
PG_GETARG_POINTER
(
0
));
ITEM
*
items
=
GETQUERY
(
query
);
int
i
;
if
(
query
->
size
==
0
)
PG_RETURN_POINTER
(
NULL
);
if
(
shorterquery
(
items
,
query
->
size
)
==
0
)
elog
(
ERROR
,
"Query requires full scan, GIN doesn't support it"
);
pfree
(
query
);
query
=
(
QUERYTYPE
*
)
PG_DETOAST_DATUM
(
PG_GETARG_POINTER
(
0
));
items
=
GETQUERY
(
query
);
res
=
(
Datum
*
)
palloc
(
sizeof
(
Datum
)
*
query
->
size
);
*
nentries
=
0
;
for
(
i
=
0
;
i
<
query
->
size
;
i
++
)
if
(
items
[
i
].
type
==
VAL
)
{
res
[
*
nentries
]
=
Int32GetDatum
(
items
[
i
].
val
);
(
*
nentries
)
++
;
}
}
else
{
ArrayType
*
query
=
PG_GETARG_ARRAYTYPE_P
(
0
);
int4
*
arr
;
uint32
i
;
CHECKARRVALID
(
query
);
*
nentries
=
ARRNELEMS
(
query
);
if
(
*
nentries
>
0
)
{
res
=
(
Datum
*
)
palloc
(
sizeof
(
Datum
)
*
(
*
nentries
));
arr
=
ARRPTR
(
query
);
for
(
i
=
0
;
i
<*
nentries
;
i
++
)
res
[
i
]
=
Int32GetDatum
(
arr
[
i
]
);
}
}
PG_RETURN_POINTER
(
res
);
}
PG_FUNCTION_INFO_V1
(
ginint4_consistent
);
Datum
ginint4_consistent
(
PG_FUNCTION_ARGS
);
Datum
ginint4_consistent
(
PG_FUNCTION_ARGS
)
{
bool
*
check
=
(
bool
*
)
PG_GETARG_POINTER
(
0
);
StrategyNumber
strategy
=
PG_GETARG_UINT16
(
1
);
int
res
=
FALSE
;
/* we can do not check array carefully, it's done by previous ginarrayextract call */
switch
(
strategy
)
{
case
RTOverlapStrategyNumber
:
case
RTContainedByStrategyNumber
:
/* at least one element in check[] is true, so result = true */
res
=
TRUE
;
break
;
case
RTSameStrategyNumber
:
case
RTContainsStrategyNumber
:
res
=
TRUE
;
do
{
ArrayType
*
query
=
PG_GETARG_ARRAYTYPE_P
(
2
);
int
i
,
nentries
=
ARRNELEMS
(
query
);
for
(
i
=
0
;
i
<
nentries
;
i
++
)
if
(
!
check
[
i
]
)
{
res
=
FALSE
;
break
;
}
}
while
(
0
);
break
;
case
BooleanSearchStrategy
:
do
{
QUERYTYPE
*
query
=
(
QUERYTYPE
*
)
PG_DETOAST_DATUM
(
PG_GETARG_POINTER
(
2
));
res
=
ginconsistent
(
query
,
check
);
}
while
(
0
);
break
;
default:
elog
(
ERROR
,
"ginint4_consistent: unknown strategy number: %d"
,
strategy
);
}
PG_RETURN_BOOL
(
res
);
}
contrib/intarray/expected/_int.out
View file @
5320c6cf
...
...
@@ -3,12 +3,12 @@
-- does not depend on contents of _int.sql.
--
\set ECHO none
psql:_int.sql:1
3
: NOTICE: type "query_int" is not yet defined
psql:_int.sql:1
5
: NOTICE: type "query_int" is not yet defined
DETAIL: Creating a shell type definition.
psql:_int.sql:
18
: NOTICE: argument type query_int is only a shell
psql:_int.sql:3
68
: NOTICE: type "intbig_gkey" is not yet defined
psql:_int.sql:
20
: NOTICE: argument type query_int is only a shell
psql:_int.sql:3
70
: NOTICE: type "intbig_gkey" is not yet defined
DETAIL: Creating a shell type definition.
psql:_int.sql:37
3
: NOTICE: argument type intbig_gkey is only a shell
psql:_int.sql:37
5
: NOTICE: argument type intbig_gkey is only a shell
SELECT intset(1234);
intset
--------
...
...
@@ -519,3 +519,53 @@ SELECT count(*) from test__int WHERE a @@ '(20&23)|(50&68)';
21
(1 row)
DROP INDEX text_idx;
CREATE INDEX text_idx on test__int using gin ( a );
SELECT count(*) from test__int WHERE a && '{23,50}';
count
-------
403
(1 row)
SELECT count(*) from test__int WHERE a @@ '23|50';
count
-------
403
(1 row)
SELECT count(*) from test__int WHERE a @ '{23,50}';
count
-------
12
(1 row)
SELECT count(*) from test__int WHERE a @@ '23&50';
count
-------
12
(1 row)
SELECT count(*) from test__int WHERE a @ '{20,23}';
count
-------
12
(1 row)
SELECT count(*) from test__int WHERE a @@ '50&68';
count
-------
9
(1 row)
SELECT count(*) from test__int WHERE a @ '{20,23}' or a @ '{50,68}';
count
-------
21
(1 row)
SELECT count(*) from test__int WHERE a @@ '(20&23)|(50&68)';
count
-------
21
(1 row)
contrib/intarray/sql/_int.sql
View file @
5320c6cf
...
...
@@ -107,3 +107,15 @@ SELECT count(*) from test__int WHERE a @ '{20,23}';
SELECT
count
(
*
)
from
test__int
WHERE
a
@@
'50&68'
;
SELECT
count
(
*
)
from
test__int
WHERE
a
@
'{20,23}'
or
a
@
'{50,68}'
;
SELECT
count
(
*
)
from
test__int
WHERE
a
@@
'(20&23)|(50&68)'
;
DROP
INDEX
text_idx
;
CREATE
INDEX
text_idx
on
test__int
using
gin
(
a
);
SELECT
count
(
*
)
from
test__int
WHERE
a
&&
'{23,50}'
;
SELECT
count
(
*
)
from
test__int
WHERE
a
@@
'23|50'
;
SELECT
count
(
*
)
from
test__int
WHERE
a
@
'{23,50}'
;
SELECT
count
(
*
)
from
test__int
WHERE
a
@@
'23&50'
;
SELECT
count
(
*
)
from
test__int
WHERE
a
@
'{20,23}'
;
SELECT
count
(
*
)
from
test__int
WHERE
a
@@
'50&68'
;
SELECT
count
(
*
)
from
test__int
WHERE
a
@
'{20,23}'
or
a
@
'{50,68}'
;
SELECT
count
(
*
)
from
test__int
WHERE
a
@@
'(20&23)|(50&68)'
;
contrib/intarray/uninstall__int.sql
View file @
5320c6cf
...
...
@@ -113,3 +113,8 @@ DROP FUNCTION boolop(_int4, query_int);
DROP
FUNCTION
querytree
(
query_int
);
DROP
TYPE
query_int
CASCADE
;
update
pg_opclass
set
opcdefault
=
't'
where
pg_opclass
.
opcamid
=
(
select
pg_am
.
oid
from
pg_am
where
amname
=
'gin'
)
and
opcname
=
'_int4_ops'
;
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment