Skip to content

Commit 1523b2d

Browse files
authored
Add operator class between int and numeric to support index scan (#3764)
Earlier, index scan would not be chosen by the optimizer when filtering between int and numeric types if the index was created on a numeric column. While index scans worked when the index was on an integer column (due to existing operator class as part of int operator family), the reverse case wasn't supported. This commit fixes this issue by adding a new operator class as part of the numeric operator family which allows the optimizer to utilize indexes on numeric columns when filtering with integer values, improving query performance in these scenarios. This changes also requires engine changes (babelfish-for-postgresql/postgresql_modified_for_babelfish#578) in order to dump these Babelfish defined operator class correctly during pg_upgrade. Task: BABEL-5648 Signed-off-by: Sumit Jaiswal <[email protected]>
1 parent c339d07 commit 1523b2d

23 files changed

+10410
-0
lines changed

contrib/babelfishpg_common/sql/integer.sql

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,26 @@ CREATE OPERATOR CLASS sys.numeric_int FOR TYPE int4
210210
OPERATOR 5 sys.> (numeric, int4),
211211
FUNCTION 1 sys.numeric_int4_cmp(numeric, int4);
212212

213+
-- Operator class for numeric_ops to incorporate various operator between numeric and int4 for Index scan
214+
CREATE OPERATOR CLASS sys.numeric_int4_ops FOR TYPE numeric
215+
USING btree FAMILY numeric_ops AS
216+
OPERATOR 1 sys.< (numeric, int4),
217+
OPERATOR 2 sys.<= (numeric, int4),
218+
OPERATOR 3 sys.= (numeric, int4),
219+
OPERATOR 4 sys.>= (numeric, int4),
220+
OPERATOR 5 sys.> (numeric, int4),
221+
FUNCTION 1 sys.numeric_int4_cmp(numeric, int4);
222+
223+
-- Operator class for numeric_ops to incorporate various operator between int4 and numeric for Index scan
224+
CREATE OPERATOR CLASS sys.int4_numeric_ops FOR TYPE numeric
225+
USING btree FAMILY numeric_ops AS
226+
OPERATOR 1 sys.< (int4, numeric),
227+
OPERATOR 2 sys.<= (int4, numeric),
228+
OPERATOR 3 sys.= (int4, numeric),
229+
OPERATOR 4 sys.>= (int4, numeric),
230+
OPERATOR 5 sys.> (int4, numeric),
231+
FUNCTION 1 sys.int4_numeric_cmp(int4, numeric);
232+
213233
-- create support function for int2 and numeric comparison
214234
CREATE FUNCTION sys.int2_numeric_cmp (int2, numeric)
215235
RETURNS int
@@ -422,6 +442,26 @@ CREATE OPERATOR CLASS sys.numeric_int2 FOR TYPE int2
422442
OPERATOR 5 sys.> (numeric, int2),
423443
FUNCTION 1 sys.numeric_int2_cmp(numeric, int2);
424444

445+
-- Operator class for numeric_ops to incorporate various operator between numeric and int2 for Index scan
446+
CREATE OPERATOR CLASS sys.numeric_int2_ops FOR TYPE numeric
447+
USING btree FAMILY numeric_ops AS
448+
OPERATOR 1 sys.< (numeric, int2),
449+
OPERATOR 2 sys.<= (numeric, int2),
450+
OPERATOR 3 sys.= (numeric, int2),
451+
OPERATOR 4 sys.>= (numeric, int2),
452+
OPERATOR 5 sys.> (numeric, int2),
453+
FUNCTION 1 sys.numeric_int2_cmp(numeric, int2);
454+
455+
-- Operator class for numeric_ops to incorporate various operator between int2 and numeric for Index scan
456+
CREATE OPERATOR CLASS sys.int2_numeric_ops FOR TYPE numeric
457+
USING btree FAMILY numeric_ops AS
458+
OPERATOR 1 sys.< (int2, numeric),
459+
OPERATOR 2 sys.<= (int2, numeric),
460+
OPERATOR 3 sys.= (int2, numeric),
461+
OPERATOR 4 sys.>= (int2, numeric),
462+
OPERATOR 5 sys.> (int2, numeric),
463+
FUNCTION 1 sys.int2_numeric_cmp(int2, numeric);
464+
425465
-- create support function for int8 and numeric comparison
426466
CREATE FUNCTION sys.int8_numeric_cmp (int8, numeric)
427467
RETURNS int
@@ -633,3 +673,23 @@ CREATE OPERATOR CLASS sys.numeric_int8 FOR TYPE int8
633673
OPERATOR 4 sys.>= (numeric, int8),
634674
OPERATOR 5 sys.> (numeric, int8),
635675
FUNCTION 1 sys.numeric_int8_cmp(numeric, int8);
676+
677+
-- Operator class for numeric_ops to incorporate various operator between int8 and numeric for Index scan
678+
CREATE OPERATOR CLASS sys.int8_numeric_ops FOR TYPE numeric
679+
USING btree FAMILY numeric_ops AS
680+
OPERATOR 1 sys.< (int8, numeric),
681+
OPERATOR 2 sys.<= (int8, numeric),
682+
OPERATOR 3 sys.= (int8, numeric),
683+
OPERATOR 4 sys.>= (int8, numeric),
684+
OPERATOR 5 sys.> (int8, numeric),
685+
FUNCTION 1 sys.int8_numeric_cmp(int8, numeric);
686+
687+
-- Operator class for numeric_ops to incorporate various operator between numeric and int8 for Index scan
688+
CREATE OPERATOR CLASS sys.numeric_int8_ops FOR TYPE numeric
689+
USING btree FAMILY numeric_ops AS
690+
OPERATOR 1 sys.< (numeric, int8),
691+
OPERATOR 2 sys.<= (numeric, int8),
692+
OPERATOR 3 sys.= (numeric, int8),
693+
OPERATOR 4 sys.>= (numeric, int8),
694+
OPERATOR 5 sys.> (numeric, int8),
695+
FUNCTION 1 sys.numeric_int8_cmp(numeric, int8);

contrib/babelfishpg_common/sql/upgrades/babelfish_common_helper--4.6.0--4.7.0.sql

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,116 @@
44

55
-- complain if script is sourced in psql, rather than via ALTER EXTENSION
66
\echo Use "ALTER EXTENSION ""babelfishpg_common"" UPDATE TO '4.7.0'" to load this file. \quit
7+
8+
SELECT set_config('search_path', 'sys, '||current_setting('search_path'), false);
9+
10+
-- Operator class for numeric_ops to incorporate various operator between numeric and int4 for Index scan
11+
DO $$
12+
BEGIN
13+
IF NOT EXISTS(SELECT 1 FROM pg_opclass opc JOIN pg_opfamily opf ON opc.opcfamily = opf.oid
14+
WHERE opc.opcname = 'numeric_int4_ops' AND opc.opcnamespace = 'sys'::regnamespace
15+
AND opf.opfname = 'numeric_ops') THEN
16+
17+
CREATE OPERATOR CLASS sys.numeric_int4_ops FOR TYPE numeric
18+
USING btree FAMILY numeric_ops AS
19+
OPERATOR 1 sys.< (numeric, int4),
20+
OPERATOR 2 sys.<= (numeric, int4),
21+
OPERATOR 3 sys.= (numeric, int4),
22+
OPERATOR 4 sys.>= (numeric, int4),
23+
OPERATOR 5 sys.> (numeric, int4),
24+
FUNCTION 1 sys.numeric_int4_cmp(numeric, int4);
25+
END IF;
26+
END $$;
27+
28+
-- Operator class for numeric_ops to incorporate various operator between int4 and numeric for Index scan
29+
DO $$
30+
BEGIN
31+
IF NOT EXISTS(SELECT 1 FROM pg_opclass opc JOIN pg_opfamily opf ON opc.opcfamily = opf.oid
32+
WHERE opc.opcname = 'int4_numeric_ops' AND opc.opcnamespace = 'sys'::regnamespace
33+
AND opf.opfname = 'numeric_ops') THEN
34+
35+
CREATE OPERATOR CLASS sys.int4_numeric_ops FOR TYPE numeric
36+
USING btree FAMILY numeric_ops AS
37+
OPERATOR 1 sys.< (int4, numeric),
38+
OPERATOR 2 sys.<= (int4, numeric),
39+
OPERATOR 3 sys.= (int4, numeric),
40+
OPERATOR 4 sys.>= (int4, numeric),
41+
OPERATOR 5 sys.> (int4, numeric),
42+
FUNCTION 1 sys.int4_numeric_cmp(int4, numeric);
43+
END IF;
44+
END $$;
45+
46+
-- Operator class for numeric_ops to incorporate various operator between numeric and int2 for Index scan
47+
DO $$
48+
BEGIN
49+
IF NOT EXISTS(SELECT 1 FROM pg_opclass opc JOIN pg_opfamily opf ON opc.opcfamily = opf.oid
50+
WHERE opc.opcname = 'numeric_int2_ops' AND opc.opcnamespace = 'sys'::regnamespace
51+
AND opf.opfname = 'numeric_ops') THEN
52+
53+
CREATE OPERATOR CLASS sys.numeric_int2_ops FOR TYPE numeric
54+
USING btree FAMILY numeric_ops AS
55+
OPERATOR 1 sys.< (numeric, int2),
56+
OPERATOR 2 sys.<= (numeric, int2),
57+
OPERATOR 3 sys.= (numeric, int2),
58+
OPERATOR 4 sys.>= (numeric, int2),
59+
OPERATOR 5 sys.> (numeric, int2),
60+
FUNCTION 1 sys.numeric_int2_cmp(numeric, int2);
61+
END IF;
62+
END $$;
63+
64+
-- Operator class for numeric_ops to incorporate various operator between int2 and numeric for Index scan
65+
DO $$
66+
BEGIN
67+
IF NOT EXISTS(SELECT 1 FROM pg_opclass opc JOIN pg_opfamily opf ON opc.opcfamily = opf.oid
68+
WHERE opc.opcname = 'int2_numeric_ops' AND opc.opcnamespace = 'sys'::regnamespace
69+
AND opf.opfname = 'numeric_ops') THEN
70+
71+
CREATE OPERATOR CLASS sys.int2_numeric_ops FOR TYPE numeric
72+
USING btree FAMILY numeric_ops AS
73+
OPERATOR 1 sys.< (int2, numeric),
74+
OPERATOR 2 sys.<= (int2, numeric),
75+
OPERATOR 3 sys.= (int2, numeric),
76+
OPERATOR 4 sys.>= (int2, numeric),
77+
OPERATOR 5 sys.> (int2, numeric),
78+
FUNCTION 1 sys.int2_numeric_cmp(int2, numeric);
79+
END IF;
80+
END $$;
81+
82+
-- Operator class for numeric_ops to incorporate various operator int8 and numeric for Index scan
83+
DO $$
84+
BEGIN
85+
IF NOT EXISTS(SELECT 1 FROM pg_opclass opc JOIN pg_opfamily opf ON opc.opcfamily = opf.oid
86+
WHERE opc.opcname = 'int8_numeric_ops' AND opc.opcnamespace = 'sys'::regnamespace
87+
AND opf.opfname = 'numeric_ops') THEN
88+
89+
CREATE OPERATOR CLASS sys.int8_numeric_ops FOR TYPE numeric
90+
USING btree FAMILY numeric_ops AS
91+
OPERATOR 1 sys.< (int8, numeric),
92+
OPERATOR 2 sys.<= (int8, numeric),
93+
OPERATOR 3 sys.= (int8, numeric),
94+
OPERATOR 4 sys.>= (int8, numeric),
95+
OPERATOR 5 sys.> (int8, numeric),
96+
FUNCTION 1 sys.int8_numeric_cmp(int8, numeric);
97+
END IF;
98+
END $$;
99+
100+
-- Operator class for numeric_ops to incorporate various operator between numeric and int8 for Index scan
101+
DO $$
102+
BEGIN
103+
IF NOT EXISTS(SELECT 1 FROM pg_opclass opc JOIN pg_opfamily opf ON opc.opcfamily = opf.oid
104+
WHERE opc.opcname = 'numeric_int8_ops' AND opc.opcnamespace = 'sys'::regnamespace
105+
AND opf.opfname = 'numeric_ops') THEN
106+
107+
CREATE OPERATOR CLASS sys.numeric_int8_ops FOR TYPE numeric
108+
USING btree FAMILY numeric_ops AS
109+
OPERATOR 1 sys.< (numeric, int8),
110+
OPERATOR 2 sys.<= (numeric, int8),
111+
OPERATOR 3 sys.= (numeric, int8),
112+
OPERATOR 4 sys.>= (numeric, int8),
113+
OPERATOR 5 sys.> (numeric, int8),
114+
FUNCTION 1 sys.numeric_int8_cmp(numeric, int8);
115+
END IF;
116+
END $$;
117+
118+
-- Reset search_path to not affect any subsequent scripts
119+
SELECT set_config('search_path', trim(leading 'sys, ' from current_setting('search_path')), false);
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
-- complain if script is sourced in psql, rather than via ALTER EXTENSION
2+
\echo Use "ALTER EXTENSION ""babelfishpg_common"" UPDATE TO '4.0.0'" to load this file. \quit

0 commit comments

Comments
 (0)