On Fri, May 9, 2014 at 9:30 PM, Tom Lane <t...@sss.pgh.pa.us> wrote:
>
> =?UTF-8?Q?Fabr=C3=ADzio_de_Royes_Mello?= <fabriziome...@gmail.com> writes:
> > On Fri, May 9, 2014 at 8:42 PM, Tom Lane <t...@sss.pgh.pa.us> wrote:
> >> I think it's really too late for this for 9.4.  At this point it's
> >> less than 48 hours until beta1 wraps, and we do not have the bandwidth
> >> to do anything but worry about stabilizing the features we've already
> >> got.
>
> > But it's a very small change with many benefits, and Michael acted very
> > proactive to make this happens.
>
> [ shrug... ]  "proactive" would have been doing this a month ago.
> If we're going to ship a release, we have to stop taking new features
> at some point, and we are really past that point for 9.4.
>
> And, to be blunt, this is not important enough to hold up the release
> for, nor to take any stability risks for.  It should go into the next
> commitfest cycle where it can get a non-rushed review.
>

I agree with you that is too late to add *new features*.

But I agree with Andres when he said this is a regression introcuced in the
pg_lsn patch.

So we'll release a version that break a simple query like that:

fabrizio=# SELECT DISTINCT (g.i||'/0')::pg_lsn f FROM generate_series(1,
100) g(i), generate_series(1, 5);
ERROR:  could not identify an equality operator for type pg_lsn
LINE 1: SELECT DISTINCT (g.i||'/0')::pg_lsn f FROM generate_series(1...
                         ^

I attached the last version of this fix with the Andres and Fujii
suggestions.


Regards,

--
Fabrízio de Royes Mello
Consultoria/Coaching PostgreSQL
>> Timbira: http://www.timbira.com.br
>> Blog sobre TI: http://fabriziomello.blogspot.com
>> Perfil Linkedin: http://br.linkedin.com/in/fabriziomello
>> Twitter: http://twitter.com/fabriziomello
diff --git a/src/backend/utils/adt/pg_lsn.c b/src/backend/utils/adt/pg_lsn.c
index d1448ae..c021a1e 100644
--- a/src/backend/utils/adt/pg_lsn.c
+++ b/src/backend/utils/adt/pg_lsn.c
@@ -14,6 +14,7 @@
 #include "postgres.h"
 
 #include "funcapi.h"
+#include "access/hash.h"
 #include "libpq/pqformat.h"
 #include "utils/builtins.h"
 #include "utils/pg_lsn.h"
@@ -153,6 +154,27 @@ pg_lsn_ge(PG_FUNCTION_ARGS)
 	PG_RETURN_BOOL(lsn1 >= lsn2);
 }
 
+/* handler for btree index operator */
+Datum
+pg_lsn_cmp(PG_FUNCTION_ARGS)
+{
+	XLogRecPtr a = PG_GETARG_LSN(0);
+	XLogRecPtr b = PG_GETARG_LSN(1);
+
+	if (a > b)
+		PG_RETURN_INT32(1);
+	else if (a == b)
+		PG_RETURN_INT32(0);
+	else
+		PG_RETURN_INT32(-1);
+}
+
+/* hash index support */
+Datum
+pg_lsn_hash(PG_FUNCTION_ARGS)
+{
+	return DirectFunctionCall1(hashint8, PG_GETARG_LSN(0));
+}
 
 /*----------------------------------------------------------
  *	Arithmetic operators on PostgreSQL LSNs.
diff --git a/src/include/catalog/pg_amop.h b/src/include/catalog/pg_amop.h
index 8efd3be..35fd17e 100644
--- a/src/include/catalog/pg_amop.h
+++ b/src/include/catalog/pg_amop.h
@@ -513,6 +513,16 @@ DATA(insert (	2968  2950 2950 4 s 2977	403 0 ));
 DATA(insert (	2968  2950 2950 5 s 2975	403 0 ));
 
 /*
+ * btree pg_lsn_ops
+ */
+
+DATA(insert (	3260  3220 3220 1 s 3224	403 0 ));
+DATA(insert (	3260  3220 3220 2 s 3226	403 0 ));
+DATA(insert (	3260  3220 3220 3 s 3222	403 0 ));
+DATA(insert (	3260  3220 3220 4 s 3227	403 0 ));
+DATA(insert (	3260  3220 3220 5 s 3225	403 0 ));
+
+/*
  *	hash index _ops
  */
 
@@ -581,6 +591,8 @@ DATA(insert (	2231   1042 1042 1 s 1054 405 0 ));
 DATA(insert (	2235   1033 1033 1 s  974 405 0 ));
 /* uuid_ops */
 DATA(insert (	2969   2950 2950 1 s 2972 405 0 ));
+/* pg_lsn_ops */
+DATA(insert (	3261   3220 3220 1 s 3222 405 0 ));
 /* numeric_ops */
 DATA(insert (	1998   1700 1700 1 s 1752 405 0 ));
 /* array_ops */
diff --git a/src/include/catalog/pg_amproc.h b/src/include/catalog/pg_amproc.h
index 198b126..369adb9 100644
--- a/src/include/catalog/pg_amproc.h
+++ b/src/include/catalog/pg_amproc.h
@@ -134,6 +134,7 @@ DATA(insert (	2789   27 27 1 2794 ));
 DATA(insert (	2968   2950 2950 1 2960 ));
 DATA(insert (	2994   2249 2249 1 2987 ));
 DATA(insert (	3194   2249 2249 1 3187 ));
+DATA(insert (	3260   3220 3220 1 3263 ));
 DATA(insert (	3522   3500 3500 1 3514 ));
 DATA(insert (	3626   3614 3614 1 3622 ));
 DATA(insert (	3683   3615 3615 1 3668 ));
@@ -174,6 +175,7 @@ DATA(insert (	2229   25 25 1 400 ));
 DATA(insert (	2231   1042 1042 1 1080 ));
 DATA(insert (	2235   1033 1033 1 329 ));
 DATA(insert (	2969   2950 2950 1 2963 ));
+DATA(insert (	3261   3220 3220 1 3262 ));
 DATA(insert (	3523   3500 3500 1 3515 ));
 DATA(insert (	3903   3831 3831 1 3902 ));
 DATA(insert (	4034   3802 3802 1 4045 ));
diff --git a/src/include/catalog/pg_opclass.h b/src/include/catalog/pg_opclass.h
index ecf7063..2298a83 100644
--- a/src/include/catalog/pg_opclass.h
+++ b/src/include/catalog/pg_opclass.h
@@ -215,6 +215,8 @@ DATA(insert (	2742	_reltime_ops		PGNSP PGUID 2745  1024 t 703 ));
 DATA(insert (	2742	_tinterval_ops		PGNSP PGUID 2745  1025 t 704 ));
 DATA(insert (	403		uuid_ops			PGNSP PGUID 2968  2950 t 0 ));
 DATA(insert (	405		uuid_ops			PGNSP PGUID 2969  2950 t 0 ));
+DATA(insert (	403		pg_lsn_ops			PGNSP PGUID 3260  3220 t 0 ));
+DATA(insert (	405		pg_lsn_ops			PGNSP PGUID 3261  3220 t 0 ));
 DATA(insert (	403		enum_ops			PGNSP PGUID 3522  3500 t 0 ));
 DATA(insert (	405		enum_ops			PGNSP PGUID 3523  3500 t 0 ));
 DATA(insert (	403		tsvector_ops		PGNSP PGUID 3626  3614 t 0 ));
diff --git a/src/include/catalog/pg_operator.h b/src/include/catalog/pg_operator.h
index f280af4..87ee4eb 100644
--- a/src/include/catalog/pg_operator.h
+++ b/src/include/catalog/pg_operator.h
@@ -1595,7 +1595,7 @@ DATA(insert OID = 2977 (  ">="	   PGNSP PGUID b f f 2950 2950 16 2976 2974 uuid_
 DESCR("greater than or equal");
 
 /* pg_lsn operators */
-DATA(insert OID = 3222 (  "="	   PGNSP PGUID b f f 3220 3220 16 3222 3223 pg_lsn_eq eqsel eqjoinsel ));
+DATA(insert OID = 3222 (  "="	   PGNSP PGUID b t t 3220 3220 16 3222 3223 pg_lsn_eq eqsel eqjoinsel ));
 DESCR("equal");
 DATA(insert OID = 3223 (  "<>"	   PGNSP PGUID b f f 3220 3220 16 3223 3222 pg_lsn_ne neqsel neqjoinsel ));
 DESCR("not equal");
diff --git a/src/include/catalog/pg_opfamily.h b/src/include/catalog/pg_opfamily.h
index 9e8f4ac..84f66ac 100644
--- a/src/include/catalog/pg_opfamily.h
+++ b/src/include/catalog/pg_opfamily.h
@@ -134,6 +134,8 @@ DATA(insert OID = 1029 (	783		point_ops		PGNSP PGUID ));
 DATA(insert OID = 2745 (	2742	array_ops		PGNSP PGUID ));
 DATA(insert OID = 2968 (	403		uuid_ops		PGNSP PGUID ));
 DATA(insert OID = 2969 (	405		uuid_ops		PGNSP PGUID ));
+DATA(insert OID = 3260 (	403		pg_lsn_ops		PGNSP PGUID ));
+DATA(insert OID = 3261 (	405		pg_lsn_ops		PGNSP PGUID ));
 DATA(insert OID = 3522 (	403		enum_ops		PGNSP PGUID ));
 DATA(insert OID = 3523 (	405		enum_ops		PGNSP PGUID ));
 DATA(insert OID = 3626 (	403		tsvector_ops	PGNSP PGUID ));
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index e601ccd..2fbc8f1 100644
--- a/src/include/catalog/pg_proc.h
+++ b/src/include/catalog/pg_proc.h
@@ -4293,6 +4293,10 @@ DATA(insert OID = 3238 (  pg_lsn_recv	PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 3
 DESCR("I/O");
 DATA(insert OID = 3239 (  pg_lsn_send	PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 17 "3220" _null_ _null_ _null_ _null_ pg_lsn_send _null_ _null_ _null_ ));
 DESCR("I/O");
+DATA(insert OID = 3262 (  pg_lsn_hash	PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 23 "3220" _null_ _null_ _null_ _null_ pg_lsn_hash _null_ _null_ _null_ ));
+DESCR("hash");
+DATA(insert OID = 3263 (  pg_lsn_cmp	PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 23 "3220 3220" _null_ _null_ _null_ _null_ pg_lsn_cmp _null_ _null_ _null_ ));
+DESCR("less-equal-greater");
 
 /* enum related procs */
 DATA(insert OID = 3504 (  anyenum_in	PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 3500 "2275" _null_ _null_ _null_ _null_ anyenum_in _null_ _null_ _null_ ));
diff --git a/src/include/utils/pg_lsn.h b/src/include/utils/pg_lsn.h
index 981fcd6..7dd932d 100644
--- a/src/include/utils/pg_lsn.h
+++ b/src/include/utils/pg_lsn.h
@@ -29,6 +29,8 @@ extern Datum pg_lsn_lt(PG_FUNCTION_ARGS);
 extern Datum pg_lsn_gt(PG_FUNCTION_ARGS);
 extern Datum pg_lsn_le(PG_FUNCTION_ARGS);
 extern Datum pg_lsn_ge(PG_FUNCTION_ARGS);
+extern Datum pg_lsn_cmp(PG_FUNCTION_ARGS);
+extern Datum pg_lsn_hash(PG_FUNCTION_ARGS);
 
 extern Datum pg_lsn_mi(PG_FUNCTION_ARGS);
 
diff --git a/src/test/regress/expected/pg_lsn.out b/src/test/regress/expected/pg_lsn.out
index 504768c..8421e15 100644
--- a/src/test/regress/expected/pg_lsn.out
+++ b/src/test/regress/expected/pg_lsn.out
@@ -1,32 +1,31 @@
 --
 -- PG_LSN
 --
-CREATE TABLE PG_LSN_TBL (f1 pg_lsn);
+CREATE TABLE pg_lsn_tbl (f1 pg_lsn);
 -- Largest and smallest input
-INSERT INTO PG_LSN_TBL VALUES ('0/0');
-INSERT INTO PG_LSN_TBL VALUES ('FFFFFFFF/FFFFFFFF');
+INSERT INTO pg_lsn_tbl VALUES ('0/0');
+INSERT INTO pg_lsn_tbl VALUES ('FFFFFFFF/FFFFFFFF');
 -- Incorrect input
-INSERT INTO PG_LSN_TBL VALUES ('G/0');
+INSERT INTO pg_lsn_tbl VALUES ('G/0');
 ERROR:  invalid input syntax for type pg_lsn: "G/0"
-LINE 1: INSERT INTO PG_LSN_TBL VALUES ('G/0');
+LINE 1: INSERT INTO pg_lsn_tbl VALUES ('G/0');
                                        ^
-INSERT INTO PG_LSN_TBL VALUES ('-1/0');
+INSERT INTO pg_lsn_tbl VALUES ('-1/0');
 ERROR:  invalid input syntax for type pg_lsn: "-1/0"
-LINE 1: INSERT INTO PG_LSN_TBL VALUES ('-1/0');
+LINE 1: INSERT INTO pg_lsn_tbl VALUES ('-1/0');
                                        ^
-INSERT INTO PG_LSN_TBL VALUES (' 0/12345678');
+INSERT INTO pg_lsn_tbl VALUES (' 0/12345678');
 ERROR:  invalid input syntax for type pg_lsn: " 0/12345678"
-LINE 1: INSERT INTO PG_LSN_TBL VALUES (' 0/12345678');
+LINE 1: INSERT INTO pg_lsn_tbl VALUES (' 0/12345678');
                                        ^
-INSERT INTO PG_LSN_TBL VALUES ('ABCD/');
+INSERT INTO pg_lsn_tbl VALUES ('ABCD/');
 ERROR:  invalid input syntax for type pg_lsn: "ABCD/"
-LINE 1: INSERT INTO PG_LSN_TBL VALUES ('ABCD/');
+LINE 1: INSERT INTO pg_lsn_tbl VALUES ('ABCD/');
                                        ^
-INSERT INTO PG_LSN_TBL VALUES ('/ABCD');
+INSERT INTO pg_lsn_tbl VALUES ('/ABCD');
 ERROR:  invalid input syntax for type pg_lsn: "/ABCD"
-LINE 1: INSERT INTO PG_LSN_TBL VALUES ('/ABCD');
+LINE 1: INSERT INTO pg_lsn_tbl VALUES ('/ABCD');
                                        ^
-DROP TABLE PG_LSN_TBL;
 -- Operators
 SELECT '0/16AE7F8' = '0/16AE7F8'::pg_lsn;
  ?column? 
@@ -64,3 +63,75 @@ SELECT '0/16AE7F8'::pg_lsn - '0/16AE7F7'::pg_lsn;
         1
 (1 row)
 
+-- Operator Class
+TRUNCATE pg_lsn_tbl;
+INSERT INTO pg_lsn_tbl SELECT DISTINCT (g.i||'/0')::pg_lsn f FROM generate_series(1, 5) g(i), generate_series(1, 5);
+SELECT * FROM pg_lsn_tbl ORDER BY 1;
+ f1  
+-----
+ 1/0
+ 2/0
+ 3/0
+ 4/0
+ 5/0
+(5 rows)
+
+CREATE INDEX pg_lsn_tbl_1 ON pg_lsn_tbl USING btree (f1);
+CREATE INDEX pg_lsn_tbl_2 ON pg_lsn_tbl USING hash (f1);
+SELECT indexdef FROM pg_indexes WHERE tablename = 'pg_lsn_tbl' ORDER BY 1;
+                         indexdef                         
+----------------------------------------------------------
+ CREATE INDEX pg_lsn_tbl_1 ON pg_lsn_tbl USING btree (f1)
+ CREATE INDEX pg_lsn_tbl_2 ON pg_lsn_tbl USING hash (f1)
+(2 rows)
+
+DROP TABLE pg_lsn_tbl;
+EXPLAIN (COSTS OFF) SELECT DISTINCT (g.i||'/0')::pg_lsn f FROM generate_series(1, 100) g(i), generate_series(1, 5);
+                     QUERY PLAN                     
+----------------------------------------------------
+ HashAggregate
+   Group Key: (((g.i)::text || '/0'::text))::pg_lsn
+   ->  Nested Loop
+         ->  Function Scan on generate_series g
+         ->  Function Scan on generate_series
+(5 rows)
+
+EXPLAIN (COSTS OFF) SELECT (g.i||'/0')::pg_lsn f FROM generate_series(1, 100) g(i) ORDER BY f;
+                    QUERY PLAN                     
+---------------------------------------------------
+ Sort
+   Sort Key: ((((i)::text || '/0'::text))::pg_lsn)
+   ->  Function Scan on generate_series g
+(3 rows)
+
+EXPLAIN (COSTS OFF) SELECT (g.i||'/0')::pg_lsn, count(*) FROM generate_series(1, 100) g(i), generate_series(1, 5) GROUP BY 1 ORDER BY 1;
+                        QUERY PLAN                        
+----------------------------------------------------------
+ Sort
+   Sort Key: ((((g.i)::text || '/0'::text))::pg_lsn)
+   ->  HashAggregate
+         Group Key: (((g.i)::text || '/0'::text))::pg_lsn
+         ->  Nested Loop
+               ->  Function Scan on generate_series g
+               ->  Function Scan on generate_series
+(7 rows)
+
+EXPLAIN (COSTS OFF) SELECT * FROM (SELECT (g.i||'/0')::pg_lsn lsn FROM generate_series(1, 10) g(i) ORDER BY g.i) a JOIN (SELECT (g.i||'/0')::pg_lsn lsn FROM generate_series(1, 10) g(i) ORDER BY g.i DESC) b ON (a.lsn = b.lsn );
+                          QUERY PLAN                          
+--------------------------------------------------------------
+ Merge Join
+   Merge Cond: (a.lsn = b.lsn)
+   ->  Sort
+         Sort Key: a.lsn
+         ->  Subquery Scan on a
+               ->  Sort
+                     Sort Key: g.i
+                     ->  Function Scan on generate_series g
+   ->  Sort
+         Sort Key: b.lsn
+         ->  Subquery Scan on b
+               ->  Sort
+                     Sort Key: g_1.i
+                     ->  Function Scan on generate_series g_1
+(14 rows)
+
diff --git a/src/test/regress/sql/pg_lsn.sql b/src/test/regress/sql/pg_lsn.sql
index 1634d37..8ff302e 100644
--- a/src/test/regress/sql/pg_lsn.sql
+++ b/src/test/regress/sql/pg_lsn.sql
@@ -2,19 +2,18 @@
 -- PG_LSN
 --
 
-CREATE TABLE PG_LSN_TBL (f1 pg_lsn);
+CREATE TABLE pg_lsn_tbl (f1 pg_lsn);
 
 -- Largest and smallest input
-INSERT INTO PG_LSN_TBL VALUES ('0/0');
-INSERT INTO PG_LSN_TBL VALUES ('FFFFFFFF/FFFFFFFF');
+INSERT INTO pg_lsn_tbl VALUES ('0/0');
+INSERT INTO pg_lsn_tbl VALUES ('FFFFFFFF/FFFFFFFF');
 
 -- Incorrect input
-INSERT INTO PG_LSN_TBL VALUES ('G/0');
-INSERT INTO PG_LSN_TBL VALUES ('-1/0');
-INSERT INTO PG_LSN_TBL VALUES (' 0/12345678');
-INSERT INTO PG_LSN_TBL VALUES ('ABCD/');
-INSERT INTO PG_LSN_TBL VALUES ('/ABCD');
-DROP TABLE PG_LSN_TBL;
+INSERT INTO pg_lsn_tbl VALUES ('G/0');
+INSERT INTO pg_lsn_tbl VALUES ('-1/0');
+INSERT INTO pg_lsn_tbl VALUES (' 0/12345678');
+INSERT INTO pg_lsn_tbl VALUES ('ABCD/');
+INSERT INTO pg_lsn_tbl VALUES ('/ABCD');
 
 -- Operators
 SELECT '0/16AE7F8' = '0/16AE7F8'::pg_lsn;
@@ -23,3 +22,16 @@ SELECT '0/16AE7F7' < '0/16AE7F8'::pg_lsn;
 SELECT '0/16AE7F8' > pg_lsn '0/16AE7F7';
 SELECT '0/16AE7F7'::pg_lsn - '0/16AE7F8'::pg_lsn;
 SELECT '0/16AE7F8'::pg_lsn - '0/16AE7F7'::pg_lsn;
+
+-- Operator Class
+TRUNCATE pg_lsn_tbl;
+INSERT INTO pg_lsn_tbl SELECT DISTINCT (g.i||'/0')::pg_lsn f FROM generate_series(1, 5) g(i), generate_series(1, 5);
+SELECT * FROM pg_lsn_tbl ORDER BY 1;
+CREATE INDEX pg_lsn_tbl_1 ON pg_lsn_tbl USING btree (f1);
+CREATE INDEX pg_lsn_tbl_2 ON pg_lsn_tbl USING hash (f1);
+SELECT indexdef FROM pg_indexes WHERE tablename = 'pg_lsn_tbl' ORDER BY 1;
+DROP TABLE pg_lsn_tbl;
+EXPLAIN (COSTS OFF) SELECT DISTINCT (g.i||'/0')::pg_lsn f FROM generate_series(1, 100) g(i), generate_series(1, 5);
+EXPLAIN (COSTS OFF) SELECT (g.i||'/0')::pg_lsn f FROM generate_series(1, 100) g(i) ORDER BY f;
+EXPLAIN (COSTS OFF) SELECT (g.i||'/0')::pg_lsn, count(*) FROM generate_series(1, 100) g(i), generate_series(1, 5) GROUP BY 1 ORDER BY 1;
+EXPLAIN (COSTS OFF) SELECT * FROM (SELECT (g.i||'/0')::pg_lsn lsn FROM generate_series(1, 10) g(i) ORDER BY g.i) a JOIN (SELECT (g.i||'/0')::pg_lsn lsn FROM generate_series(1, 10) g(i) ORDER BY g.i DESC) b ON (a.lsn = b.lsn );
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to