Commits

Andrew Dunstan  committed a896c62

Merge Binary Upgradeability.

  • Participants
  • Parent commits 37f3664
  • Branches master

Comments (0)

Files changed (14)

 TESTS        = $(wildcard test/sql/*.sql)
 REGRESS      = $(patsubst test/sql/%.sql,%,$(TESTS))
 REGRESS_OPTS = --inputdir=test --load-language=plpgsql
-MODULES      = $(patsubst %.c,%,$(wildcard src/*.c))
+MODULES = $(patsubst %.c,%,$(wildcard src/*.c))
 PG_CONFIG    = pg_config
 PG91         = $(shell $(PG_CONFIG) --version | grep -qE " 8\.| 9\.0" && echo no || echo yes)
 

File Makefile.noextn

+
+DATA         = sql/json_noextn.sql
+TESTS        = test/sql/base_noext.sql test/sql/json91.sql
+REGRESS      = $(patsubst test/sql/%.sql,%,$(TESTS))
+REGRESS_OPTS = --inputdir=test --load-language=plpgsql
+MODULES = $(patsubst %.c,%,$(wildcard src/*.c))
+PG_CONFIG    = pg_config
+
+PGXS := $(shell $(PG_CONFIG) --pgxs)
+include $(PGXS)
 json for PostgreSQL 9.1
 =======================
 
-A long description
-
-To build it, just do this:
+To build it as an extension (but see below for binary upgradability), 
+just do this:
 
     make
     make installcheck
 
    CREATE EXTENSION json WITH SCHEMA pg_catalog;
 
+Binary Upgrade-ability
+----------------------
+
+To install for binary upgrade-ability, you need to do things a bit differently.
+The reason is that in 9.2 and later this is NOT an extension, and we don't
+want pg_upgrade trying to install an unnecessary extension.
+
+First, you need to build with a different makefile, and install NOT as an
+extension:
+
+    make -f Makefile.noext
+    make -f Makefile.noext install
+
+The to install in a database, do:
+
+    psql -f /path/to/sharedir/contrib/json_noext.sql yourdb
+
+This uses some magic imported from the pg_upgrade utility to make the json type
+and its array type use the same type oids as are used in Release 9.2 so that
+pg_upgrade will "just work" (almost). To do that it loads some routines
+in a library called json_binup.so. After you have installed json, if you are
+worried about superusers being able to load this library you can remove it - it
+is only needed while you are installing json into a database.
+
+When it comes time to upgrade the database to a new release, there is one more
+thing you need to do. pg_upgrade will see that the catalog uses a library called
+"$libdir/json" and if it can't load it will come screeching to a halt. It's
+not needed, and pg_upgrade doesn't do anything with it. So you'll need to fool
+pg_upgrade in your 9.2 or later installation by building and installing such a
+module. There is one provided in the upgrade_dummy_module directory.
+
+Change to that directory, and with your PATH pointing to the new installation
+do
+        make
+        make install
+
+After the upgrade, in the same directory and with the same path, do
+
+        make uninstall
+
 Dependencies
 ------------
 The `json` data type has no dependencies other than PostgreSQL.

File sql/json.sql

  *
  */ 
 
+
+DO 
+$$
+  BEGIN
+      PERFORM 1 FROM pg_namespace WHERE nspname = 'binoid';
+      IF NOT found THEN RETURN; END IF;
+      PERFORM binoid.set_next_pg_type_oid(114);
+      PERFORM binoid.set_next_array_pg_type_oid(199);
+  END;
+$$ language PLPGSQL;
+
 CREATE TYPE json;
 
 CREATE FUNCTION json_in(cstring)
 RETURNS json
 AS 'MODULE_PATHNAME','row_to_json_pretty'
 LANGUAGE C STRICT IMMUTABLE;
+
+DO $$
+  BEGIN
+      PERFORM 1 FROM pg_namespace WHERE nspname = 'binoid';
+      IF NOT found THEN RETURN; END IF;
+      DROP SCHEMA binoid CASCADE;
+      ALTER TYPE json SET SCHEMA pg_catalog;
+  END;
+$$ language PLPGSQL;
+

File sql/json_noextn.sql

+CREATE SCHEMA binoid;
+
+CREATE FUNCTION binoid.set_next_pg_type_oid(OID)
+   RETURNS VOID
+   AS '$libdir/json_binup'
+   LANGUAGE C STRICT;
+
+CREATE FUNCTION binoid.set_next_array_pg_type_oid(OID)
+   RETURNS VOID
+   AS '$libdir/json_binup'
+   LANGUAGE C STRICT;
+
+
+SELECT binoid.set_next_pg_type_oid(114);
+SELECT binoid.set_next_array_pg_type_oid(199);
+
+SET search_path = 'pg_catalog';
+
+CREATE TYPE json;
+
+CREATE FUNCTION json_in(cstring)
+RETURNS json
+AS '$libdir/json'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION json_out(json)
+RETURNS cstring
+AS '$libdir/json'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION json_recv(internal)
+RETURNS json
+AS '$libdir/json'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION json_send(json)
+RETURNS bytea
+AS '$libdir/json'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE TYPE json (
+        INTERNALLENGTH = -1,
+        INPUT = json_in,
+        OUTPUT = json_out,
+        RECEIVE = json_recv,
+        SEND = json_send,
+        STORAGE = extended
+);
+
+CREATE FUNCTION array_to_json(anyarray)
+RETURNS json
+AS '$libdir/json','array_to_json'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION array_to_json(anyarray, bool)
+RETURNS json
+AS '$libdir/json','array_to_json_pretty'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION row_to_json(record)
+RETURNS json
+AS '$libdir/json','row_to_json'
+LANGUAGE C STRICT IMMUTABLE;
+
+CREATE FUNCTION row_to_json(record, bool)
+RETURNS json
+AS '$libdir/json','row_to_json_pretty'
+LANGUAGE C STRICT IMMUTABLE;
+
+DROP SCHEMA binoid CASCADE;
+
+
+

File src/json_binup.c

+/*
+ *  json_binup.c
+ *
+ *  extracted from 
+ *	  pg_upgrade_support.c
+ *
+ *  used to set the oid of the json type and its array so that they will
+ *  work with pg_upgrade to postgres >= 9.2
+ *
+ *	Copyright (c) 2010-2011, PostgreSQL Global Development Group
+ *	contrib/pg_upgrade_support/pg_upgrade_support.c
+ */
+
+#include "postgres.h"
+
+#include "fmgr.h"
+#include "catalog/dependency.h"
+#include "catalog/namespace.h"
+#include "catalog/pg_class.h"
+#include "catalog/pg_type.h"
+#include "commands/extension.h"
+#include "miscadmin.h"
+#include "utils/array.h"
+#include "utils/builtins.h"
+
+
+#ifdef PG_MODULE_MAGIC
+PG_MODULE_MAGIC;
+#endif
+
+extern PGDLLIMPORT Oid binary_upgrade_next_pg_type_oid;
+extern PGDLLIMPORT Oid binary_upgrade_next_array_pg_type_oid;
+
+extern PGDLLIMPORT bool IsBinaryUpgrade;
+
+Datum		set_next_pg_type_oid(PG_FUNCTION_ARGS);
+Datum		set_next_array_pg_type_oid(PG_FUNCTION_ARGS);
+
+PG_FUNCTION_INFO_V1(set_next_pg_type_oid);
+PG_FUNCTION_INFO_V1(set_next_array_pg_type_oid);
+
+Datum
+set_next_pg_type_oid(PG_FUNCTION_ARGS)
+{
+	Oid			typoid = PG_GETARG_OID(0);
+
+	IsBinaryUpgrade = true;
+	binary_upgrade_next_pg_type_oid = typoid;
+
+	PG_RETURN_VOID();
+}
+
+Datum
+set_next_array_pg_type_oid(PG_FUNCTION_ARGS)
+{
+	Oid			typoid = PG_GETARG_OID(0);
+
+	binary_upgrade_next_array_pg_type_oid = typoid;
+
+	PG_RETURN_VOID();
+}
+

File test/expected/base.out

 \set ECHO 0
-ROLLBACK;

File test/expected/base_noext.out

+\i sql/json_noextn.sql
+CREATE SCHEMA binoid;
+CREATE FUNCTION binoid.set_next_pg_type_oid(OID)
+   RETURNS VOID
+   AS '$libdir/json_binup'
+   LANGUAGE C STRICT;
+CREATE FUNCTION binoid.set_next_array_pg_type_oid(OID)
+   RETURNS VOID
+   AS '$libdir/json_binup'
+   LANGUAGE C STRICT;
+SELECT binoid.set_next_pg_type_oid(114);
+ set_next_pg_type_oid 
+----------------------
+ 
+(1 row)
+
+SELECT binoid.set_next_array_pg_type_oid(199);
+ set_next_array_pg_type_oid 
+----------------------------
+ 
+(1 row)
+
+SET search_path = 'pg_catalog';
+CREATE TYPE json;
+CREATE FUNCTION json_in(cstring)
+RETURNS json
+AS '$libdir/json'
+LANGUAGE C STRICT IMMUTABLE;
+psql:sql/json_noextn.sql:24: NOTICE:  return type json is only a shell
+CREATE FUNCTION json_out(json)
+RETURNS cstring
+AS '$libdir/json'
+LANGUAGE C STRICT IMMUTABLE;
+psql:sql/json_noextn.sql:29: NOTICE:  argument type json is only a shell
+CREATE FUNCTION json_recv(internal)
+RETURNS json
+AS '$libdir/json'
+LANGUAGE C STRICT IMMUTABLE;
+psql:sql/json_noextn.sql:34: NOTICE:  return type json is only a shell
+CREATE FUNCTION json_send(json)
+RETURNS bytea
+AS '$libdir/json'
+LANGUAGE C STRICT IMMUTABLE;
+psql:sql/json_noextn.sql:39: NOTICE:  argument type json is only a shell
+CREATE TYPE json (
+        INTERNALLENGTH = -1,
+        INPUT = json_in,
+        OUTPUT = json_out,
+        RECEIVE = json_recv,
+        SEND = json_send,
+        STORAGE = extended
+);
+CREATE FUNCTION array_to_json(anyarray)
+RETURNS json
+AS '$libdir/json','array_to_json'
+LANGUAGE C STRICT IMMUTABLE;
+CREATE FUNCTION array_to_json(anyarray, bool)
+RETURNS json
+AS '$libdir/json','array_to_json_pretty'
+LANGUAGE C STRICT IMMUTABLE;
+CREATE FUNCTION row_to_json(record)
+RETURNS json
+AS '$libdir/json','row_to_json'
+LANGUAGE C STRICT IMMUTABLE;
+CREATE FUNCTION row_to_json(record, bool)
+RETURNS json
+AS '$libdir/json','row_to_json_pretty'
+LANGUAGE C STRICT IMMUTABLE;
+DROP SCHEMA binoid CASCADE;
+psql:sql/json_noextn.sql:70: NOTICE:  drop cascades to 2 other objects
+DETAIL:  drop cascades to function binoid.set_next_pg_type_oid(oid)
+drop cascades to function binoid.set_next_array_pg_type_oid(oid)

File test/expected/json91.out

-create extension json;
 -- Strings.
 SELECT '""'::json;				-- OK.
  json 

File test/sql/base.sql

 \set ECHO 0
-BEGIN;
 create extension json;
 \set ECHO all
-
-
-ROLLBACK;

File test/sql/base_noext.sql

+\i sql/json_noextn.sql
+

File test/sql/json91.sql

 
-create extension json;
-
 -- Strings.
 SELECT '""'::json;				-- OK.
 SELECT $$''$$::json;			-- ERROR, single quotes are not allowed

File upgrade_dummy_module/Makefile

+
+MODULES = json
+
+PG_CONFIG = pg_config
+PGXS := $(shell $(PG_CONFIG) --pgxs)
+
+include $(PGXS)
+

File upgrade_dummy_module/json.c

+/*
+ * json.c  
+ *
+ */
+
+#include "postgres.h"
+#include "fmgr.h"
+
+PG_MODULE_MAGIC;
+
+/*
+ * this is a dummy module whose only purpose is to fool
+ * pg_upgrade which thinks that the old json module we
+ * used in the 9.1 backport is required. It isn't, but
+ * pg_upgrade fails without it.
+ *
+*/
+