On Fri, May 9, 2014 at 10:49 PM, Fujii Masao <[email protected]> wrote:
> On Fri, May 9, 2014 at 10:03 PM, Andres Freund <[email protected]> wrote:
>> You plan to commit it?
>
> Yes unless many people object the commit.
>
> Michael, you're now modifying the patch?
OK, I have been able to put my head into that earlier than I thought
as it would be better to get that done before the beta, finishing with
the attached. When hacking that, I noticed that some tests were
missing for some of the operators. I am including them in this patch
as well, with more tests for unique index creation, ordering, and
hash/btree index creation. The test suite looks cleaner with all that.
--
Michael
From 13513f3392085edb0b3a75af12ef9d08334bdb2e Mon Sep 17 00:00:00 2001
From: Michael Paquier <[email protected]>
Date: Sat, 10 May 2014 14:34:04 +0900
Subject: [PATCH] Add hash/btree operators for pg_lsn
At the same time, regression tests are completed with some tests for
operators that were missing and of course new tests for the new btree
and hash operators.
---
src/backend/utils/adt/pg_lsn.c | 21 ++++++++
src/include/catalog/pg_amop.h | 12 +++++
src/include/catalog/pg_amproc.h | 2 +
src/include/catalog/pg_opclass.h | 2 +
src/include/catalog/pg_operator.h | 2 +-
src/include/catalog/pg_opfamily.h | 2 +
src/include/catalog/pg_proc.h | 4 ++
src/include/utils/pg_lsn.h | 2 +
src/test/regress/expected/pg_lsn.out | 96 ++++++++++++++++++++++++++++++------
src/test/regress/sql/pg_lsn.sql | 46 +++++++++++++----
10 files changed, 165 insertions(+), 24 deletions(-)
diff --git a/src/backend/utils/adt/pg_lsn.c b/src/backend/utils/adt/pg_lsn.c
index d1448ae..b779907 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,26 @@ 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(1);
+ PG_RETURN_INT32(0);
+}
+
+/* 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..1a77ba8 100644
--- a/src/test/regress/expected/pg_lsn.out
+++ b/src/test/regress/expected/pg_lsn.out
@@ -1,32 +1,81 @@
--
-- PG_LSN
--
-CREATE TABLE PG_LSN_TBL (f1 pg_lsn);
+CREATE TABLE pg_lsn_tbl (f1 pg_lsn);
+-- Some data
+INSERT INTO pg_lsn_tbl VALUES ('0/16AE7F8');
+INSERT INTO pg_lsn_tbl VALUES ('0/16AE7F7');
+INSERT INTO pg_lsn_tbl VALUES ('16/16AE7F8');
+INSERT INTO pg_lsn_tbl VALUES ('16/16AE7F7');
+INSERT INTO pg_lsn_tbl VALUES ('FF/16AE7F8');
+INSERT INTO pg_lsn_tbl VALUES ('FF/16AE7F7');
-- 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;
+-- ordering test
+SELECT f1 FROM pg_lsn_tbl ORDER BY f1 ASC;
+ f1
+-------------------
+ 0/0
+ 0/16AE7F7
+ 0/16AE7F8
+ 16/16AE7F7
+ 16/16AE7F8
+ FF/16AE7F7
+ FF/16AE7F8
+ FFFFFFFF/FFFFFFFF
+(8 rows)
+
+SELECT f1 FROM pg_lsn_tbl ORDER BY f1 DESC;
+ f1
+-------------------
+ FFFFFFFF/FFFFFFFF
+ FF/16AE7F8
+ FF/16AE7F7
+ 16/16AE7F8
+ 16/16AE7F7
+ 0/16AE7F8
+ 0/16AE7F7
+ 0/0
+(8 rows)
+
+-- btree and hash index creation test
+CREATE INDEX pg_lsn_btree ON pg_lsn_tbl USING BTREE (f1);
+CREATE INDEX pg_lsn_hash ON pg_lsn_tbl USING HASH (f1);
+-- unique index test
+CREATE UNIQUE INDEX pg_lsn_unique_btree ON pg_lsn_tbl USING BTREE (f1);
+-- this will fail
+INSERT INTO pg_lsn_tbl VALUES ('16/16AE7F7');
+ERROR: duplicate key value violates unique constraint "pg_lsn_unique_btree"
+DETAIL: Key (f1)=(16/16AE7F7) already exists.
+-- check to see whether the new indexes are actually there
+SELECT count(*) FROM pg_class WHERE relkind='i' AND relname LIKE 'pg_lsn%';
+ count
+-------
+ 3
+(1 row)
+
-- Operators
SELECT '0/16AE7F8' = '0/16AE7F8'::pg_lsn;
?column?
@@ -34,6 +83,12 @@ SELECT '0/16AE7F8' = '0/16AE7F8'::pg_lsn;
t
(1 row)
+SELECT '0/16AE7F8' <> '0/16AE7F8'::pg_lsn;
+ ?column?
+----------
+ f
+(1 row)
+
SELECT '0/16AE7F8'::pg_lsn != '0/16AE7F7';
?column?
----------
@@ -46,12 +101,24 @@ SELECT '0/16AE7F7' < '0/16AE7F8'::pg_lsn;
t
(1 row)
+SELECT '0/16AE7F7' <= '0/16AE7F8'::pg_lsn;
+ ?column?
+----------
+ t
+(1 row)
+
SELECT '0/16AE7F8' > pg_lsn '0/16AE7F7';
?column?
----------
t
(1 row)
+SELECT '0/16AE7F8' >= pg_lsn '0/16AE7F7';
+ ?column?
+----------
+ t
+(1 row)
+
SELECT '0/16AE7F7'::pg_lsn - '0/16AE7F8'::pg_lsn;
?column?
----------
@@ -64,3 +131,4 @@ SELECT '0/16AE7F8'::pg_lsn - '0/16AE7F7'::pg_lsn;
1
(1 row)
+DROP TABLE pg_lsn_tbl;
diff --git a/src/test/regress/sql/pg_lsn.sql b/src/test/regress/sql/pg_lsn.sql
index 1634d37..c42e03c 100644
--- a/src/test/regress/sql/pg_lsn.sql
+++ b/src/test/regress/sql/pg_lsn.sql
@@ -2,24 +2,52 @@
-- PG_LSN
--
-CREATE TABLE PG_LSN_TBL (f1 pg_lsn);
+CREATE TABLE pg_lsn_tbl (f1 pg_lsn);
+
+-- Some data
+INSERT INTO pg_lsn_tbl VALUES ('0/16AE7F8');
+INSERT INTO pg_lsn_tbl VALUES ('0/16AE7F7');
+INSERT INTO pg_lsn_tbl VALUES ('16/16AE7F8');
+INSERT INTO pg_lsn_tbl VALUES ('16/16AE7F7');
+INSERT INTO pg_lsn_tbl VALUES ('FF/16AE7F8');
+INSERT INTO pg_lsn_tbl VALUES ('FF/16AE7F7');
-- 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');
+
+-- ordering test
+SELECT f1 FROM pg_lsn_tbl ORDER BY f1 ASC;
+SELECT f1 FROM pg_lsn_tbl ORDER BY f1 DESC;
+
+-- btree and hash index creation test
+CREATE INDEX pg_lsn_btree ON pg_lsn_tbl USING BTREE (f1);
+CREATE INDEX pg_lsn_hash ON pg_lsn_tbl USING HASH (f1);
+
+-- unique index test
+CREATE UNIQUE INDEX pg_lsn_unique_btree ON pg_lsn_tbl USING BTREE (f1);
+-- this will fail
+INSERT INTO pg_lsn_tbl VALUES ('16/16AE7F7');
+
+-- check to see whether the new indexes are actually there
+SELECT count(*) FROM pg_class WHERE relkind='i' AND relname LIKE 'pg_lsn%';
-- Operators
SELECT '0/16AE7F8' = '0/16AE7F8'::pg_lsn;
+SELECT '0/16AE7F8' <> '0/16AE7F8'::pg_lsn;
SELECT '0/16AE7F8'::pg_lsn != '0/16AE7F7';
SELECT '0/16AE7F7' < '0/16AE7F8'::pg_lsn;
+SELECT '0/16AE7F7' <= '0/16AE7F8'::pg_lsn;
SELECT '0/16AE7F8' > pg_lsn '0/16AE7F7';
+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;
+
+DROP TABLE pg_lsn_tbl;
--
1.9.2
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers