From 2d8d1d1e8c39d8d4f00eb18eba3535c90c30cb31 Mon Sep 17 00:00:00 2001
From: Andrey Borodin <amborodin@acm.org>
Date: Sun, 29 Oct 2017 13:32:21 +0500
Subject: [PATCH] Enable Index Only Scan in cube

---
 contrib/cube/Makefile           |  2 +-
 contrib/cube/cube--1.3--1.4.sql | 36 ++++++++++++++++++++++++++++++++++++
 contrib/cube/cube.control       |  2 +-
 contrib/cube/expected/cube.out  | 19 +++++++++++++++++++
 contrib/cube/sql/cube.sql       |  6 ++++++
 5 files changed, 63 insertions(+), 2 deletions(-)
 create mode 100644 contrib/cube/cube--1.3--1.4.sql

diff --git a/contrib/cube/Makefile b/contrib/cube/Makefile
index 244c1d9bbf..accb7d28a3 100644
--- a/contrib/cube/Makefile
+++ b/contrib/cube/Makefile
@@ -4,7 +4,7 @@ MODULE_big = cube
 OBJS= cube.o cubeparse.o $(WIN32RES)
 
 EXTENSION = cube
-DATA = cube--1.2.sql cube--1.2--1.3.sql \
+DATA = cube--1.2.sql cube--1.2--1.3.sql cube--1.3--1.4.sql \
 	cube--1.1--1.2.sql cube--1.0--1.1.sql \
 	cube--unpackaged--1.0.sql
 PGFILEDESC = "cube - multidimensional cube data type"
diff --git a/contrib/cube/cube--1.3--1.4.sql b/contrib/cube/cube--1.3--1.4.sql
new file mode 100644
index 0000000000..a73bd36eab
--- /dev/null
+++ b/contrib/cube/cube--1.3--1.4.sql
@@ -0,0 +1,36 @@
+/* contrib/cube/cube--1.3--1.4.sql */
+
+-- complain if script is sourced in psql, rather than via ALTER EXTENSION
+\echo Use "ALTER EXTENSION cube UPDATE TO '1.4'" to load this file. \quit
+
+UPDATE "pg_catalog"."pg_depend"
+SET deptype = 'a'
+WHERE classid = 'pg_amproc'::regclass
+  AND objid =
+    (SELECT objid
+     FROM "pg_catalog"."pg_depend"
+     WHERE classid = 'pg_amproc'::regclass
+       AND refclassid = 'pg_proc'::regclass
+       AND (refobjid = 'g_cube_compress(internal)'::regprocedure))
+  AND refclassid = 'pg_opclass'::regclass
+  AND deptype = 'i';
+  
+ALTER OPERATOR FAMILY gist_cube_ops USING gist drop function 3 (cube);
+ALTER EXTENSION cube DROP function g_cube_compress(internal);
+DROP FUNCTION g_cube_compress(internal);
+
+UPDATE "pg_catalog"."pg_depend"
+SET deptype = 'a'
+WHERE classid = 'pg_amproc'::regclass
+  AND objid =
+    (SELECT objid
+     FROM "pg_catalog"."pg_depend"
+     WHERE classid = 'pg_amproc'::regclass
+       AND refclassid = 'pg_proc'::regclass
+       AND (refobjid = 'g_cube_decompress(internal)'::regprocedure))
+  AND refclassid = 'pg_opclass'::regclass
+  AND deptype = 'i';
+  
+ALTER OPERATOR FAMILY gist_cube_ops USING gist drop function 4 (cube);
+ALTER EXTENSION cube DROP function g_cube_decompress(internal);
+DROP FUNCTION g_cube_decompress(internal);
\ No newline at end of file
diff --git a/contrib/cube/cube.control b/contrib/cube/cube.control
index af062d4843..f39a838e3f 100644
--- a/contrib/cube/cube.control
+++ b/contrib/cube/cube.control
@@ -1,5 +1,5 @@
 # cube extension
 comment = 'data type for multidimensional cubes'
-default_version = '1.3'
+default_version = '1.4'
 module_pathname = '$libdir/cube'
 relocatable = true
diff --git a/contrib/cube/expected/cube.out b/contrib/cube/expected/cube.out
index 328b3b5f5d..52d65c0339 100644
--- a/contrib/cube/expected/cube.out
+++ b/contrib/cube/expected/cube.out
@@ -1701,6 +1701,25 @@ SELECT * FROM test_cube ORDER BY c~>4 DESC LIMIT 15; -- descending by 2nd coordi
  (46151, 49848),(46058, 49830)
 (15 rows)
 
+-- Test Index Only Scans
+SET ENABLE_BITMAPSCAN = FALSE;
+EXPLAIN (COSTS OFF) SELECT c FROM test_cube WHERE c <@ '(3000,1000),(0,0)';
+                    QUERY PLAN                    
+--------------------------------------------------
+ Index Only Scan using test_cube_ix on test_cube
+   Index Cond: (c <@ '(3000, 1000),(0, 0)'::cube)
+(2 rows)
+
+SELECT c FROM test_cube WHERE c <@ '(3000,1000),(0,0)';
+            c            
+-------------------------
+ (2424, 160),(2424, 81)
+ (759, 187),(662, 163)
+ (1444, 403),(1346, 344)
+ (337, 455),(240, 359)
+(4 rows)
+
+SET ENABLE_BITMAPSCAN = TRUE;
 -- same thing for index with points
 CREATE TABLE test_point(c cube);
 INSERT INTO test_point(SELECT cube(array[c->1,c->2,c->3,c->4]) FROM test_cube);
diff --git a/contrib/cube/sql/cube.sql b/contrib/cube/sql/cube.sql
index 58ea3ad811..277a81a03e 100644
--- a/contrib/cube/sql/cube.sql
+++ b/contrib/cube/sql/cube.sql
@@ -393,6 +393,12 @@ SELECT * FROM test_cube ORDER BY c~>4 LIMIT 15; -- ascending by 2nd coordinate o
 SELECT * FROM test_cube ORDER BY c~>1 DESC LIMIT 15; -- descending by 1st coordinate of lower left corner
 SELECT * FROM test_cube ORDER BY c~>4 DESC LIMIT 15; -- descending by 2nd coordinate or upper right corner
 
+-- Test Index Only Scans
+SET ENABLE_BITMAPSCAN = FALSE;
+EXPLAIN (COSTS OFF) SELECT c FROM test_cube WHERE c <@ '(3000,1000),(0,0)';
+SELECT c FROM test_cube WHERE c <@ '(3000,1000),(0,0)';
+SET ENABLE_BITMAPSCAN = TRUE;
+
 -- same thing for index with points
 CREATE TABLE test_point(c cube);
 INSERT INTO test_point(SELECT cube(array[c->1,c->2,c->3,c->4]) FROM test_cube);
-- 
2.13.5 (Apple Git-94)

