1--  citus--8.3-1--9.0-1
2
3SET search_path = 'pg_catalog';
4
5-- We swapped the groupid and nodeid sequences when creating pg_dist_node
6ALTER TABLE pg_dist_node ALTER COLUMN groupid SET DEFAULT nextval ('pg_dist_groupid_seq');
7ALTER TABLE pg_dist_node ALTER COLUMN nodeid SET DEFAULT nextval('pg_dist_node_nodeid_seq');
8
9CREATE SCHEMA IF NOT EXISTS citus_internal;
10
11-- move citus internal functions to citus_internal to make space in the citus schema for
12-- our public interface
13ALTER FUNCTION citus.find_groupid_for_node SET SCHEMA citus_internal;
14ALTER FUNCTION citus.pg_dist_node_trigger_func SET SCHEMA citus_internal;
15ALTER FUNCTION citus.pg_dist_shard_placement_trigger_func SET SCHEMA citus_internal;
16ALTER FUNCTION citus.refresh_isolation_tester_prepared_statement SET SCHEMA citus_internal;
17ALTER FUNCTION citus.replace_isolation_tester_func SET SCHEMA citus_internal;
18ALTER FUNCTION citus.restore_isolation_tester_func SET SCHEMA citus_internal;
19
20-- we can now safely grant usage on the citus schema to use types
21GRANT USAGE ON SCHEMA citus TO public;
22
23#include "udfs/pg_dist_shard_placement_trigger_func/9.0-1.sql"
24
25CREATE OR REPLACE FUNCTION pg_catalog.worker_create_or_replace_object(statement text)
26  RETURNS bool
27  LANGUAGE C STRICT
28  AS 'MODULE_PATHNAME', $$worker_create_or_replace_object$$;
29COMMENT ON FUNCTION pg_catalog.worker_create_or_replace_object(statement text)
30    IS 'takes a sql CREATE statement, before executing the create it will check if an object with that name already exists and safely replaces that named object with the new object';
31
32CREATE OR REPLACE FUNCTION pg_catalog.master_unmark_object_distributed(classid oid, objid oid, objsubid int)
33    RETURNS void
34    LANGUAGE C STRICT
35    AS 'MODULE_PATHNAME', $$master_unmark_object_distributed$$;
36COMMENT ON FUNCTION pg_catalog.master_unmark_object_distributed(classid oid, objid oid, objsubid int)
37    IS 'remove an object address from citus.pg_dist_object once the object has been deleted';
38
39CREATE TABLE citus.pg_dist_object (
40	-- fields used for composite primary key
41    classid oid NOT NULL,
42    objid oid NOT NULL,
43    objsubid integer NOT NULL,
44
45    -- fields used for upgrades
46    type text DEFAULT NULL,
47    object_names text[] DEFAULT NULL,
48    object_args text[] DEFAULT NULL,
49
50    -- fields that are only valid for distributed
51    -- functions/procedures
52    distribution_argument_index int,
53    colocationid int,
54
55    CONSTRAINT pg_dist_object_pkey PRIMARY KEY (classid, objid, objsubid)
56);
57
58CREATE FUNCTION master_dist_object_cache_invalidate()
59    RETURNS trigger
60    LANGUAGE C
61    AS 'MODULE_PATHNAME', $$master_dist_object_cache_invalidate$$;
62COMMENT ON FUNCTION master_dist_object_cache_invalidate()
63    IS 'register relcache invalidation for changed rows';
64CREATE TRIGGER dist_object_cache_invalidate
65    AFTER INSERT OR UPDATE OR DELETE
66    ON citus.pg_dist_object
67    FOR EACH ROW EXECUTE PROCEDURE master_dist_object_cache_invalidate();
68
69#include "udfs/create_distributed_function/9.0-1.sql"
70
71#include "udfs/citus_drop_trigger/9.0-1.sql"
72#include "udfs/citus_prepare_pg_upgrade/9.0-1.sql"
73#include "udfs/citus_finish_pg_upgrade/9.0-1.sql"
74
75-- We truncate pg_dist_node during metadata syncing, but we do not want
76-- this to cascade to pg_dist_poolinfo, which is generally maintained
77-- by the operator.
78ALTER TABLE pg_dist_poolinfo DROP CONSTRAINT pg_dist_poolinfo_nodeid_fkey;
79
80--  if the rebalancer extension is still around, drop it before creating Citus functions
81DROP EXTENSION IF EXISTS shard_rebalancer;
82
83#include "udfs/get_rebalance_table_shards_plan/9.0-1.sql"
84#include "udfs/replicate_table_shards/9.0-1.sql"
85#include "udfs/rebalance_table_shards/9.0-1.sql"
86#include "udfs/get_rebalance_progress/9.0-1.sql"
87
88DROP FUNCTION master_add_node(text, integer, integer, noderole, name);
89CREATE FUNCTION master_add_node(nodename text,
90                                nodeport integer,
91                                groupid integer default 0,
92                                noderole noderole default 'primary',
93                                nodecluster name default 'default')
94  RETURNS INTEGER
95  LANGUAGE C STRICT
96  AS 'MODULE_PATHNAME', $$master_add_node$$;
97COMMENT ON FUNCTION master_add_node(nodename text, nodeport integer,
98                                    groupid integer, noderole noderole, nodecluster name)
99  IS 'add node to the cluster';
100
101DROP FUNCTION master_add_inactive_node(text, integer, integer, noderole, name);
102CREATE FUNCTION master_add_inactive_node(nodename text,
103                                         nodeport integer,
104                                         groupid integer default 0,
105                                         noderole noderole default 'primary',
106                                         nodecluster name default 'default')
107  RETURNS INTEGER
108  LANGUAGE C STRICT
109  AS 'MODULE_PATHNAME',$$master_add_inactive_node$$;
110COMMENT ON FUNCTION master_add_inactive_node(nodename text,nodeport integer,
111                                             groupid integer, noderole noderole,
112                                             nodecluster name)
113  IS 'prepare node by adding it to pg_dist_node';
114
115DROP FUNCTION master_activate_node(text, integer);
116CREATE FUNCTION master_activate_node(nodename text,
117                                     nodeport integer)
118    RETURNS INTEGER
119    LANGUAGE C STRICT
120    AS 'MODULE_PATHNAME',$$master_activate_node$$;
121COMMENT ON FUNCTION master_activate_node(nodename text, nodeport integer)
122    IS 'activate a node which is in the cluster';
123
124DROP FUNCTION master_add_secondary_node(text, integer, text, integer, name);
125CREATE FUNCTION master_add_secondary_node(nodename text,
126                                          nodeport integer,
127                                          primaryname text,
128                                          primaryport integer,
129                                          nodecluster name default 'default')
130  RETURNS INTEGER
131  LANGUAGE C STRICT
132  AS 'MODULE_PATHNAME', $$master_add_secondary_node$$;
133COMMENT ON FUNCTION master_add_secondary_node(nodename text, nodeport integer,
134                                              primaryname text, primaryport integer,
135                                              nodecluster name)
136  IS 'add a secondary node to the cluster';
137
138
139REVOKE ALL ON FUNCTION master_activate_node(text,int) FROM PUBLIC;
140REVOKE ALL ON FUNCTION master_add_inactive_node(text,int,int,noderole,name) FROM PUBLIC;
141REVOKE ALL ON FUNCTION master_add_node(text,int,int,noderole,name) FROM PUBLIC;
142REVOKE ALL ON FUNCTION master_add_secondary_node(text,int,text,int,name) FROM PUBLIC;
143
144ALTER TABLE pg_dist_node ADD COLUMN metadatasynced BOOLEAN DEFAULT FALSE;
145COMMENT ON COLUMN pg_dist_node.metadatasynced IS
146    'indicates whether the node has the most recent metadata';
147
148CREATE FUNCTION worker_apply_sequence_command(create_sequence_command text,
149                                              sequence_type_id regtype DEFAULT 'bigint'::regtype)
150    RETURNS VOID
151    LANGUAGE C STRICT
152    AS 'MODULE_PATHNAME', $$worker_apply_sequence_command$$;
153COMMENT ON FUNCTION worker_apply_sequence_command(text,regtype)
154    IS 'create a sequence which produces globally unique values';
155
156#include "udfs/citus_isolation_test_session_is_blocked/9.0-1.sql"
157
158
159CREATE FUNCTION ensure_truncate_trigger_is_after()
160    RETURNS void
161    LANGUAGE plpgsql
162    SET search_path = pg_catalog
163    AS $$
164DECLARE
165    table_name regclass;
166    command text;
167    trigger_name text;
168BEGIN
169    --
170    -- register triggers
171    --
172    FOR table_name, trigger_name IN SELECT tgrelid::regclass, tgname
173      FROM pg_dist_partition
174      JOIN pg_trigger ON tgrelid=logicalrelid
175      JOIN pg_class ON pg_class.oid=logicalrelid
176      WHERE
177        tgname LIKE 'truncate_trigger_%' AND tgfoid = 'citus_truncate_trigger'::regproc
178    LOOP
179        command := 'drop trigger ' || trigger_name || ' on ' || table_name;
180        EXECUTE command;
181        command := 'create trigger ' || trigger_name || ' after truncate on ' || table_name || ' execute procedure pg_catalog.citus_truncate_trigger()';
182        EXECUTE command;
183        command := 'update pg_trigger set tgisinternal = true where tgname = ' || quote_literal(trigger_name);
184        EXECUTE command;
185    END LOOP;
186END;
187$$;
188
189SELECT ensure_truncate_trigger_is_after();
190DROP FUNCTION ensure_truncate_trigger_is_after;
191
192-- This sequence is unused
193DROP SEQUENCE pg_catalog.pg_dist_jobid_seq;
194
195RESET search_path;
196