From 3a20b0e7b6dae48cd6be1257e9017663f1402b91 Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas Date: Sat, 28 Mar 2015 15:11:53 +0200 Subject: [PATCH] Add index-only scan support to inet GiST opclass. Andreas Karlsson --- src/backend/utils/adt/network_gist.c | 27 +++++++++++++++++++++++++++ src/include/catalog/catversion.h | 2 +- src/include/catalog/pg_amproc.h | 1 + src/include/catalog/pg_proc.h | 2 ++ src/include/utils/inet.h | 1 + src/test/regress/expected/inet.out | 19 +++++++++++++++++++ src/test/regress/sql/inet.sql | 6 ++++++ 7 files changed, 57 insertions(+), 1 deletion(-) diff --git a/src/backend/utils/adt/network_gist.c b/src/backend/utils/adt/network_gist.c index 14dd62b771..cd2b8b19a7 100644 --- a/src/backend/utils/adt/network_gist.c +++ b/src/backend/utils/adt/network_gist.c @@ -587,6 +587,33 @@ inet_gist_decompress(PG_FUNCTION_ARGS) PG_RETURN_POINTER(entry); } +/* + * The GiST fetch function + * + * Reconstruct the original inet datum from a GistInetKey. + */ +Datum +inet_gist_fetch(PG_FUNCTION_ARGS) +{ + GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); + GistInetKey *key = DatumGetInetKeyP(entry->key); + GISTENTRY *retval; + inet *dst; + + dst = (inet *) palloc0(sizeof(inet)); + + ip_family(dst) = gk_ip_family(key); + ip_bits(dst) = gk_ip_minbits(key); + memcpy(ip_addr(dst), gk_ip_addr(key), ip_addrsize(dst)); + SET_INET_VARSIZE(dst); + + retval = palloc(sizeof(GISTENTRY)); + gistentryinit(*retval, InetPGetDatum(dst), entry->rel, entry->page, + entry->offset, FALSE); + + PG_RETURN_POINTER(retval); +} + /* * The GiST page split penalty function * diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 3d50f70402..f3f148a8c5 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 201503261 +#define CATALOG_VERSION_NO 201503281 #endif diff --git a/src/include/catalog/pg_amproc.h b/src/include/catalog/pg_amproc.h index 612a9d242e..037684c3f2 100644 --- a/src/include/catalog/pg_amproc.h +++ b/src/include/catalog/pg_amproc.h @@ -411,6 +411,7 @@ DATA(insert ( 3550 869 869 4 3556 )); DATA(insert ( 3550 869 869 5 3557 )); DATA(insert ( 3550 869 869 6 3558 )); DATA(insert ( 3550 869 869 7 3559 )); +DATA(insert ( 3550 869 869 9 3573 )); /* sp-gist */ DATA(insert ( 3474 3831 3831 1 3469 )); diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index 77b77176a3..a96d3695df 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -2240,6 +2240,8 @@ DATA(insert OID = 3555 ( inet_gist_compress PGNSP PGUID 12 1 0 0 0 f f f f t f DESCR("GiST support"); DATA(insert OID = 3556 ( inet_gist_decompress PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 2281 "2281" _null_ _null_ _null_ _null_ inet_gist_decompress _null_ _null_ _null_ )); DESCR("GiST support"); +DATA(insert OID = 3573 ( inet_gist_fetch PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 2281 "2281" _null_ _null_ _null_ _null_ inet_gist_fetch _null_ _null_ _null_ )); +DESCR("GiST support"); DATA(insert OID = 3557 ( inet_gist_penalty PGNSP PGUID 12 1 0 0 0 f f f f t f i 3 0 2281 "2281 2281 2281" _null_ _null_ _null_ _null_ inet_gist_penalty _null_ _null_ _null_ )); DESCR("GiST support"); DATA(insert OID = 3558 ( inet_gist_picksplit PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 2281 "2281 2281" _null_ _null_ _null_ _null_ inet_gist_picksplit _null_ _null_ _null_ )); diff --git a/src/include/utils/inet.h b/src/include/utils/inet.h index 66946886c7..2d2bae4cbe 100644 --- a/src/include/utils/inet.h +++ b/src/include/utils/inet.h @@ -123,6 +123,7 @@ extern int bitncommon(const unsigned char *l, const unsigned char *r, int n); /* * GiST support functions in network_gist.c */ +extern Datum inet_gist_fetch(PG_FUNCTION_ARGS); extern Datum inet_gist_consistent(PG_FUNCTION_ARGS); extern Datum inet_gist_union(PG_FUNCTION_ARGS); extern Datum inet_gist_compress(PG_FUNCTION_ARGS); diff --git a/src/test/regress/expected/inet.out b/src/test/regress/expected/inet.out index d58bf017b6..d25e5e42a7 100644 --- a/src/test/regress/expected/inet.out +++ b/src/test/regress/expected/inet.out @@ -390,6 +390,25 @@ SELECT * FROM inet_tbl WHERE i <> '192.168.1.0/24'::cidr ORDER BY i; 10:23::8000/113 | 10:23::ffff (16 rows) +-- test index-only scans +EXPLAIN (COSTS OFF) +SELECT i FROM inet_tbl WHERE i << '192.168.1.0/24'::cidr ORDER BY i; + QUERY PLAN +--------------------------------------------------- + Sort + Sort Key: i + -> Index Only Scan using inet_idx2 on inet_tbl + Index Cond: (i << '192.168.1.0/24'::inet) +(4 rows) + +SELECT i FROM inet_tbl WHERE i << '192.168.1.0/24'::cidr ORDER BY i; + i +------------------ + 192.168.1.0/25 + 192.168.1.255/25 + 192.168.1.226 +(3 rows) + SET enable_seqscan TO on; DROP INDEX inet_idx2; -- simple tests of inet boolean and arithmetic operators diff --git a/src/test/regress/sql/inet.sql b/src/test/regress/sql/inet.sql index c9792b7120..2034d3e86f 100644 --- a/src/test/regress/sql/inet.sql +++ b/src/test/regress/sql/inet.sql @@ -84,6 +84,12 @@ SELECT * FROM inet_tbl WHERE i = '192.168.1.0/24'::cidr ORDER BY i; SELECT * FROM inet_tbl WHERE i >= '192.168.1.0/24'::cidr ORDER BY i; SELECT * FROM inet_tbl WHERE i > '192.168.1.0/24'::cidr ORDER BY i; SELECT * FROM inet_tbl WHERE i <> '192.168.1.0/24'::cidr ORDER BY i; + +-- test index-only scans +EXPLAIN (COSTS OFF) +SELECT i FROM inet_tbl WHERE i << '192.168.1.0/24'::cidr ORDER BY i; +SELECT i FROM inet_tbl WHERE i << '192.168.1.0/24'::cidr ORDER BY i; + SET enable_seqscan TO on; DROP INDEX inet_idx2; -- 2.40.0