Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
533020d
Fix minor issues in psql's new \dAc and related commands.
tglsfdc Aug 2, 2020
63e9aa6
Correct comment in simplehash.h.
macdice Aug 3, 2020
f44b9b6
Fix rare failure in LDAP tests.
macdice Aug 3, 2020
b8fdee7
Add %P to log_line_prefix for parallel group leader
michaelpq Aug 3, 2020
5f28b21
Fix behavior of ecpg's "EXEC SQL elif name".
tglsfdc Aug 3, 2020
eeb01e3
Doc: fix obsolete info about allowed range of TZ offsets in timetz.
tglsfdc Aug 3, 2020
9e49676
Remove unnecessary "DISTINCT" in psql's queries for \dAc and \dAf.
tglsfdc Aug 3, 2020
a451b7d
Add nbtree page deletion assertion.
petergeoghegan Aug 3, 2020
9a9db08
Fix replica backward scan race condition.
petergeoghegan Aug 3, 2020
dd87799
Make new SSL TAP test for channel_binding more robust
michaelpq Aug 4, 2020
0f76294
Increase hard-wired timeout values in ecpg regression tests.
tglsfdc Aug 4, 2020
f47b5e1
Remove btree page items after page unlink
akorotkov Aug 4, 2020
7a980df
Fix matching of sub-partitions when a partitioned plan is stale.
tglsfdc Aug 5, 2020
a677535
doc: clarify "state" table reference in tutorial
bmomjian Aug 5, 2020
bab1500
Register llvm_shutdown using on_proc_exit, not before_shmem_exit.
robertmhaas Aug 6, 2020
d5e9652
Fix bogus EXPLAIN output for Hash Aggregate
david-rowley Aug 6, 2020
c254d8d
amcheck: Sanitize metapage's allequalimage field.
petergeoghegan Aug 6, 2020
3a3be80
Remove obsolete amcheck comment.
petergeoghegan Aug 6, 2020
199cec9
Fix yet another issue with step generation in partition pruning.
Aug 7, 2020
3df92bb
Rename nbtree split REDO routine variables.
petergeoghegan Aug 7, 2020
6f0b632
Support testing of cases where table schemas change after planning.
tglsfdc Aug 7, 2020
cea3d55
Remove PROC_IN_ANALYZE and derived flags
alvherre Aug 7, 2020
0a7d771
Make nbtree split REDO locking match original execution.
petergeoghegan Aug 7, 2020
7259736
Implement streaming mode in ReorderBuffer.
Aug 8, 2020
a13421c
Add some const decorations
petere Aug 8, 2020
82a0ba7
Fix the logical streaming test.
Aug 8, 2020
470687b
walsnd: Don't set waiting_for_ping_response spuriously
alvherre Aug 8, 2020
39132b7
Teach amcheck to verify sibling links in all cases.
petergeoghegan Aug 8, 2020
20e7e1f
Remove <@ from contrib/intarray's GiST operator classes.
tglsfdc Aug 8, 2020
1c164ef
Remove useless Assert.
tglsfdc Aug 9, 2020
1b9cde5
Check for fseeko() failure in pg_dump's _tarAddFile().
tglsfdc Aug 9, 2020
d129c07
Correct nbtree page split lock coupling comment.
petergeoghegan Aug 9, 2020
7eeb1d9
Make contrib modules' installation scripts more secure.
tglsfdc Aug 10, 2020
e078fb5
Move connect.h from fe_utils to src/include/common.
nmisch Aug 10, 2020
11da970
Empty search_path in logical replication apply worker and walsender.
nmisch Aug 10, 2020
cec57b1
Document clashes between logical replication and untrusted users.
nmisch Aug 10, 2020
1784f27
Replace remaining StrNCpy() by strlcpy()
petere Aug 10, 2020
1f75b45
Improve tab completion of REINDEX in psql
michaelpq Aug 11, 2020
fea10a6
Rename VariableCacheData.nextFullXid to nextXid.
anarazel Aug 11, 2020
3bd7f99
Track latest completed xid as a FullTransactionId.
anarazel Aug 12, 2020
3546cf8
Improve comments for postmaster.c's BackendList.
tglsfdc Aug 12, 2020
1f42d35
BRIN: Handle concurrent desummarization properly
alvherre Aug 12, 2020
dc7420c
snapshot scalability: Don't compute global horizons while building sn…
anarazel Aug 12, 2020
b8443ea
Fix out-of-date version reference, grammar.
anarazel Aug 13, 2020
a811ea5
Handle new HOT chains in index-build table scans
alvherre Aug 13, 2020
1f51c17
snapshot scalability: Move PGXACT->xmin back to PGPROC.
anarazel Aug 13, 2020
a9306f1
Doc: improve examples for json_populate_record() and related functions.
tglsfdc Aug 14, 2020
1f32136
Fix compilation warnings with libselinux 3.1 in contrib/sepgsql/
michaelpq Aug 14, 2020
5bdf694
Fix typo in test comment.
hlinnaka Aug 14, 2020
0038f94
Fix postmaster's behavior during smart shutdown.
tglsfdc Aug 14, 2020
914140e
Fix obsolete comment in xlogutils.c.
petergeoghegan Aug 14, 2020
2ba5b2d
pg_dump: fix dependencies on FKs to partitioned tables
alvherre Aug 14, 2020
941697c
snapshot scalability: Introduce dense array of in-progress xids.
anarazel Aug 14, 2020
5788e25
snapshot scalability: Move PGXACT->vacuumFlags to ProcGlobal->vacuumF…
anarazel Jul 15, 2020
73487a6
snapshot scalability: Move subxact info to ProcGlobal, remove PGXACT.
anarazel Aug 14, 2020
1e7629d
Be more careful about the shape of hashable subplan clauses.
tglsfdc Aug 15, 2020
b48cac3
Mark a few logical decoding related variables with PGDLLIMPORT.
Aug 15, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
203 changes: 169 additions & 34 deletions contrib/amcheck/verify_nbtree.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,9 @@ static void bt_check_every_level(Relation rel, Relation heaprel,
bool rootdescend);
static BtreeLevel bt_check_level_from_leftmost(BtreeCheckState *state,
BtreeLevel level);
static void bt_recheck_sibling_links(BtreeCheckState *state,
BlockNumber btpo_prev_from_target,
BlockNumber leftcurrent);
static void bt_target_page_check(BtreeCheckState *state);
static BTScanInsert bt_right_page_check_scankey(BtreeCheckState *state);
static void bt_child_check(BtreeCheckState *state, BTScanInsert targetkey,
Expand Down Expand Up @@ -305,8 +308,20 @@ bt_index_check_internal(Oid indrelid, bool parentcheck, bool heapallindexed,
errmsg("index \"%s\" lacks a main relation fork",
RelationGetRelationName(indrel))));

/* Check index, possibly against table it is an index on */
/* Extract metadata from metapage, and sanitize it in passing */
_bt_metaversion(indrel, &heapkeyspace, &allequalimage);
if (allequalimage && !heapkeyspace)
ereport(ERROR,
(errcode(ERRCODE_INDEX_CORRUPTED),
errmsg("index \"%s\" metapage has equalimage field set on unsupported nbtree version",
RelationGetRelationName(indrel))));
if (allequalimage && !_bt_allequalimage(indrel, false))
ereport(ERROR,
(errcode(ERRCODE_INDEX_CORRUPTED),
errmsg("index \"%s\" metapage incorrectly indicates that deduplication is safe",
RelationGetRelationName(indrel))));

/* Check index, possibly against table it is an index on */
bt_check_every_level(indrel, heaprel, heapkeyspace, parentcheck,
heapallindexed, rootdescend);
}
Expand Down Expand Up @@ -419,10 +434,10 @@ bt_check_every_level(Relation rel, Relation heaprel, bool heapkeyspace,
RelationGetRelationName(rel));

/*
* RecentGlobalXmin assertion matches index_getnext_tid(). See note on
* RecentGlobalXmin/B-Tree page deletion.
* This assertion matches the one in index_getnext_tid(). See page
* recycling/"visible to everyone" notes in nbtree README.
*/
Assert(TransactionIdIsValid(RecentGlobalXmin));
Assert(TransactionIdIsValid(RecentXmin));

/*
* Initialize state for entire verification operation
Expand Down Expand Up @@ -775,17 +790,9 @@ bt_check_level_from_leftmost(BtreeCheckState *state, BtreeLevel level)
*/
}

/*
* readonly mode can only ever land on live pages and half-dead pages,
* so sibling pointers should always be in mutual agreement
*/
if (state->readonly && opaque->btpo_prev != leftcurrent)
ereport(ERROR,
(errcode(ERRCODE_INDEX_CORRUPTED),
errmsg("left link/right link pair in index \"%s\" not in agreement",
RelationGetRelationName(state->rel)),
errdetail_internal("Block=%u left block=%u left link from block=%u.",
current, leftcurrent, opaque->btpo_prev)));
/* Sibling links should be in mutual agreement */
if (opaque->btpo_prev != leftcurrent)
bt_recheck_sibling_links(state, opaque->btpo_prev, leftcurrent);

/* Check level, which must be valid for non-ignorable page */
if (level.level != opaque->btpo.level)
Expand Down Expand Up @@ -865,6 +872,140 @@ bt_check_level_from_leftmost(BtreeCheckState *state, BtreeLevel level)
return nextleveldown;
}

/*
* Raise an error when target page's left link does not point back to the
* previous target page, called leftcurrent here. The leftcurrent page's
* right link was followed to get to the current target page, and we expect
* mutual agreement among leftcurrent and the current target page. Make sure
* that this condition has definitely been violated in the !readonly case,
* where concurrent page splits are something that we need to deal with.
*
* Cross-page inconsistencies involving pages that don't agree about being
* siblings are known to be a particularly good indicator of corruption
* involving partial writes/lost updates. The bt_right_page_check_scankey
* check also provides a way of detecting cross-page inconsistencies for
* !readonly callers, but it can only detect sibling pages that have an
* out-of-order keyspace, which can't catch many of the problems that we
* expect to catch here.
*
* The classic example of the kind of inconsistency that we can only catch
* with this check (when in !readonly mode) involves three sibling pages that
* were affected by a faulty page split at some point in the past. The
* effects of the split are reflected in the original page and its new right
* sibling page, with a lack of any accompanying changes for the _original_
* right sibling page. The original right sibling page's left link fails to
* point to the new right sibling page (its left link still points to the
* original page), even though the first phase of a page split is supposed to
* work as a single atomic action. This subtle inconsistency will probably
* only break backwards scans in practice.
*
* Note that this is the only place where amcheck will "couple" buffer locks
* (and only for !readonly callers). In general we prefer to avoid more
* thorough cross-page checks in !readonly mode, but it seems worth the
* complexity here. Also, the performance overhead of performing lock
* coupling here is negligible in practice. Control only reaches here with a
* non-corrupt index when there is a concurrent page split at the instant
* caller crossed over to target page from leftcurrent page.
*/
static void
bt_recheck_sibling_links(BtreeCheckState *state,
BlockNumber btpo_prev_from_target,
BlockNumber leftcurrent)
{
if (!state->readonly)
{
Buffer lbuf;
Buffer newtargetbuf;
Page page;
BTPageOpaque opaque;
BlockNumber newtargetblock;

/* Couple locks in the usual order for nbtree: Left to right */
lbuf = ReadBufferExtended(state->rel, MAIN_FORKNUM, leftcurrent,
RBM_NORMAL, state->checkstrategy);
LockBuffer(lbuf, BT_READ);
_bt_checkpage(state->rel, lbuf);
page = BufferGetPage(lbuf);
opaque = (BTPageOpaque) PageGetSpecialPointer(page);
if (P_ISDELETED(opaque))
{
/*
* Cannot reason about concurrently deleted page -- the left link
* in the page to the right is expected to point to some other
* page to the left (not leftcurrent page).
*
* Note that we deliberately don't give up with a half-dead page.
*/
UnlockReleaseBuffer(lbuf);
return;
}

newtargetblock = opaque->btpo_next;
/* Avoid self-deadlock when newtargetblock == leftcurrent */
if (newtargetblock != leftcurrent)
{
newtargetbuf = ReadBufferExtended(state->rel, MAIN_FORKNUM,
newtargetblock, RBM_NORMAL,
state->checkstrategy);
LockBuffer(newtargetbuf, BT_READ);
_bt_checkpage(state->rel, newtargetbuf);
page = BufferGetPage(newtargetbuf);
opaque = (BTPageOpaque) PageGetSpecialPointer(page);
/* btpo_prev_from_target may have changed; update it */
btpo_prev_from_target = opaque->btpo_prev;
}
else
{
/*
* leftcurrent right sibling points back to leftcurrent block.
* Index is corrupt. Easiest way to handle this is to pretend
* that we actually read from a distinct page that has an invalid
* block number in its btpo_prev.
*/
newtargetbuf = InvalidBuffer;
btpo_prev_from_target = InvalidBlockNumber;
}

/*
* No need to check P_ISDELETED here, since new target block cannot be
* marked deleted as long as we hold a lock on lbuf
*/
if (BufferIsValid(newtargetbuf))
UnlockReleaseBuffer(newtargetbuf);
UnlockReleaseBuffer(lbuf);

if (btpo_prev_from_target == leftcurrent)
{
/* Report split in left sibling, not target (or new target) */
ereport(DEBUG1,
(errcode(ERRCODE_INTERNAL_ERROR),
errmsg("harmless concurrent page split detected in index \"%s\"",
RelationGetRelationName(state->rel)),
errdetail_internal("Block=%u new right sibling=%u original right sibling=%u.",
leftcurrent, newtargetblock,
state->targetblock)));
return;
}

/*
* Index is corrupt. Make sure that we report correct target page.
*
* This could have changed in cases where there was a concurrent page
* split, as well as index corruption (at least in theory). Note that
* btpo_prev_from_target was already updated above.
*/
state->targetblock = newtargetblock;
}

ereport(ERROR,
(errcode(ERRCODE_INDEX_CORRUPTED),
errmsg("left link/right link pair in index \"%s\" not in agreement",
RelationGetRelationName(state->rel)),
errdetail_internal("Block=%u left block=%u left link from block=%u.",
state->targetblock, leftcurrent,
btpo_prev_from_target)));
}

/*
* Function performs the following checks on target page, or pages ancillary to
* target page:
Expand All @@ -891,7 +1032,6 @@ bt_check_level_from_leftmost(BtreeCheckState *state, BtreeLevel level)
* tuple.
*
* - That downlink to block was encountered in parent where that's expected.
* (Limited to readonly callers.)
*
* - That high keys of child pages matches corresponding pivot keys in parent.
*
Expand Down Expand Up @@ -1441,7 +1581,7 @@ bt_right_page_check_scankey(BtreeCheckState *state)
* does not occur until no possible index scan could land on the page.
* Index scans can follow links with nothing more than their snapshot as
* an interlock and be sure of at least that much. (See page
* recycling/RecentGlobalXmin notes in nbtree README.)
* recycling/"visible to everyone" notes in nbtree README.)
*
* Furthermore, it's okay if we follow a rightlink and find a half-dead or
* dead (ignorable) page one or more times. There will either be a
Expand Down Expand Up @@ -1954,18 +2094,14 @@ bt_child_check(BtreeCheckState *state, BTScanInsert targetkey,
* downlink, which was concurrently physically removed in target/parent as
* part of deletion's first phase.)
*
* Note that while the cross-page-same-level last item check uses a trick
* that allows it to perform verification for !readonly callers, a similar
* trick seems difficult here. The trick that that other check uses is,
* in essence, to lock down race conditions to those that occur due to
* concurrent page deletion of the target; that's a race that can be
* reliably detected before actually reporting corruption.
*
* On the other hand, we'd need to lock down race conditions involving
* deletion of child's left page, for long enough to read the child page
* into memory (in other words, a scheme with concurrently held buffer
* locks on both child and left-of-child pages). That's unacceptable for
* amcheck functions on general principle, though.
* While we use various techniques elsewhere to perform cross-page
* verification for !readonly callers, a similar trick seems difficult
* here. The tricks used by bt_recheck_sibling_links and by
* bt_right_page_check_scankey both involve verification of a same-level,
* cross-sibling invariant. Cross-level invariants are far more squishy,
* though. The nbtree REDO routines do not actually couple buffer locks
* across levels during page splits, so making any cross-level check work
* reliably in !readonly mode may be impossible.
*/
Assert(state->readonly);

Expand Down Expand Up @@ -2774,6 +2910,8 @@ invariant_l_nontarget_offset(BtreeCheckState *state, BTScanInsert key,
* There is never an attempt to get a consistent view of multiple pages using
* multiple concurrent buffer locks; in general, we only acquire a single pin
* and buffer lock at a time, which is often all that the nbtree code requires.
* (Actually, bt_recheck_sibling_links couples buffer locks, which is the only
* exception to this general rule.)
*
* Operating on a copy of the page is useful because it prevents control
* getting stuck in an uninterruptible state when an underlying operator class
Expand Down Expand Up @@ -2864,11 +3002,8 @@ palloc_btree_page(BtreeCheckState *state, BlockNumber blocknum)
* As noted at the beginning of _bt_binsrch(), an internal page must have
* children, since there must always be a negative infinity downlink
* (there may also be a highkey). In the case of non-rightmost leaf
* pages, there must be at least a highkey. Deleted pages on replica
* might contain no items, because page unlink re-initializes
* page-to-be-deleted. Deleted pages with no items might be on primary
* too due to preceding recovery, but on primary new deletions can't
* happen concurrently to amcheck.
* pages, there must be at least a highkey. The exceptions are deleted
* pages, which contain no items.
*
* This is correct when pages are half-dead, since internal pages are
* never half-dead, and leaf pages must have a high key when half-dead
Expand Down
56 changes: 36 additions & 20 deletions contrib/btree_gist/btree_gist--1.1--1.2.sql
Original file line number Diff line number Diff line change
Expand Up @@ -8,56 +8,72 @@
-- wherein the signatures have been updated already. In that case to_regprocedure() will
-- return NULL and no updates will happen.

DO LANGUAGE plpgsql
$$
DECLARE
my_schema pg_catalog.text := pg_catalog.quote_ident(pg_catalog.current_schema());
old_path pg_catalog.text := pg_catalog.current_setting('search_path');
BEGIN
-- for safety, transiently set search_path to just pg_catalog+pg_temp
PERFORM pg_catalog.set_config('search_path', 'pg_catalog, pg_temp', true);

UPDATE pg_catalog.pg_proc SET
proargtypes = pg_catalog.array_to_string(newtypes::pg_catalog.oid[], ' ')::pg_catalog.oidvector,
pronargs = pg_catalog.array_length(newtypes, 1)
FROM (VALUES
(NULL::pg_catalog.text, NULL::pg_catalog.regtype[]), -- establish column types
(NULL::pg_catalog.text, NULL::pg_catalog.text[]), -- establish column types
('gbt_oid_distance(internal,oid,int2,oid)', '{internal,oid,int2,oid,internal}'),
('gbt_oid_union(bytea,internal)', '{internal,internal}'),
('gbt_oid_same(internal,internal,internal)', '{gbtreekey8,gbtreekey8,internal}'),
('gbt_oid_same(internal,internal,internal)', '{SCH.gbtreekey8,SCH.gbtreekey8,internal}'),
('gbt_int2_distance(internal,int2,int2,oid)', '{internal,int2,int2,oid,internal}'),
('gbt_int2_union(bytea,internal)', '{internal,internal}'),
('gbt_int2_same(internal,internal,internal)', '{gbtreekey4,gbtreekey4,internal}'),
('gbt_int2_same(internal,internal,internal)', '{SCH.gbtreekey4,SCH.gbtreekey4,internal}'),
('gbt_int4_distance(internal,int4,int2,oid)', '{internal,int4,int2,oid,internal}'),
('gbt_int4_union(bytea,internal)', '{internal,internal}'),
('gbt_int4_same(internal,internal,internal)', '{gbtreekey8,gbtreekey8,internal}'),
('gbt_int4_same(internal,internal,internal)', '{SCH.gbtreekey8,SCH.gbtreekey8,internal}'),
('gbt_int8_distance(internal,int8,int2,oid)', '{internal,int8,int2,oid,internal}'),
('gbt_int8_union(bytea,internal)', '{internal,internal}'),
('gbt_int8_same(internal,internal,internal)', '{gbtreekey16,gbtreekey16,internal}'),
('gbt_int8_same(internal,internal,internal)', '{SCH.gbtreekey16,SCH.gbtreekey16,internal}'),
('gbt_float4_distance(internal,float4,int2,oid)', '{internal,float4,int2,oid,internal}'),
('gbt_float4_union(bytea,internal)', '{internal,internal}'),
('gbt_float4_same(internal,internal,internal)', '{gbtreekey8,gbtreekey8,internal}'),
('gbt_float4_same(internal,internal,internal)', '{SCH.gbtreekey8,SCH.gbtreekey8,internal}'),
('gbt_float8_distance(internal,float8,int2,oid)', '{internal,float8,int2,oid,internal}'),
('gbt_float8_union(bytea,internal)', '{internal,internal}'),
('gbt_float8_same(internal,internal,internal)', '{gbtreekey16,gbtreekey16,internal}'),
('gbt_float8_same(internal,internal,internal)', '{SCH.gbtreekey16,SCH.gbtreekey16,internal}'),
('gbt_ts_distance(internal,timestamp,int2,oid)', '{internal,timestamp,int2,oid,internal}'),
('gbt_tstz_distance(internal,timestamptz,int2,oid)', '{internal,timestamptz,int2,oid,internal}'),
('gbt_ts_union(bytea,internal)', '{internal,internal}'),
('gbt_ts_same(internal,internal,internal)', '{gbtreekey16,gbtreekey16,internal}'),
('gbt_ts_same(internal,internal,internal)', '{SCH.gbtreekey16,SCH.gbtreekey16,internal}'),
('gbt_time_distance(internal,time,int2,oid)', '{internal,time,int2,oid,internal}'),
('gbt_time_union(bytea,internal)', '{internal,internal}'),
('gbt_time_same(internal,internal,internal)', '{gbtreekey16,gbtreekey16,internal}'),
('gbt_time_same(internal,internal,internal)', '{SCH.gbtreekey16,SCH.gbtreekey16,internal}'),
('gbt_date_distance(internal,date,int2,oid)', '{internal,date,int2,oid,internal}'),
('gbt_date_union(bytea,internal)', '{internal,internal}'),
('gbt_date_same(internal,internal,internal)', '{gbtreekey8,gbtreekey8,internal}'),
('gbt_date_same(internal,internal,internal)', '{SCH.gbtreekey8,SCH.gbtreekey8,internal}'),
('gbt_intv_distance(internal,interval,int2,oid)', '{internal,interval,int2,oid,internal}'),
('gbt_intv_union(bytea,internal)', '{internal,internal}'),
('gbt_intv_same(internal,internal,internal)', '{gbtreekey32,gbtreekey32,internal}'),
('gbt_intv_same(internal,internal,internal)', '{SCH.gbtreekey32,SCH.gbtreekey32,internal}'),
('gbt_cash_distance(internal,money,int2,oid)', '{internal,money,int2,oid,internal}'),
('gbt_cash_union(bytea,internal)', '{internal,internal}'),
('gbt_cash_same(internal,internal,internal)', '{gbtreekey16,gbtreekey16,internal}'),
('gbt_cash_same(internal,internal,internal)', '{SCH.gbtreekey16,SCH.gbtreekey16,internal}'),
('gbt_macad_union(bytea,internal)', '{internal,internal}'),
('gbt_macad_same(internal,internal,internal)', '{gbtreekey16,gbtreekey16,internal}'),
('gbt_macad_same(internal,internal,internal)', '{SCH.gbtreekey16,SCH.gbtreekey16,internal}'),
('gbt_text_union(bytea,internal)', '{internal,internal}'),
('gbt_text_same(internal,internal,internal)', '{gbtreekey_var,gbtreekey_var,internal}'),
('gbt_text_same(internal,internal,internal)', '{SCH.gbtreekey_var,SCH.gbtreekey_var,internal}'),
('gbt_bytea_union(bytea,internal)', '{internal,internal}'),
('gbt_bytea_same(internal,internal,internal)', '{gbtreekey_var,gbtreekey_var,internal}'),
('gbt_bytea_same(internal,internal,internal)', '{SCH.gbtreekey_var,SCH.gbtreekey_var,internal}'),
('gbt_numeric_union(bytea,internal)', '{internal,internal}'),
('gbt_numeric_same(internal,internal,internal)', '{gbtreekey_var,gbtreekey_var,internal}'),
('gbt_numeric_same(internal,internal,internal)', '{SCH.gbtreekey_var,SCH.gbtreekey_var,internal}'),
('gbt_bit_union(bytea,internal)', '{internal,internal}'),
('gbt_bit_same(internal,internal,internal)', '{gbtreekey_var,gbtreekey_var,internal}'),
('gbt_bit_same(internal,internal,internal)', '{SCH.gbtreekey_var,SCH.gbtreekey_var,internal}'),
('gbt_inet_union(bytea,internal)', '{internal,internal}'),
('gbt_inet_same(internal,internal,internal)', '{gbtreekey16,gbtreekey16,internal}')
) AS update_data (oldproc, newtypes)
WHERE oid = pg_catalog.to_regprocedure(oldproc);
('gbt_inet_same(internal,internal,internal)', '{SCH.gbtreekey16,SCH.gbtreekey16,internal}')
) AS update_data (oldproc, newtypestext),
LATERAL (
SELECT array_agg(replace(typ, 'SCH', my_schema)::regtype) as newtypes FROM unnest(newtypestext) typ
) ls
WHERE oid = to_regprocedure(my_schema || '.' || replace(oldproc, 'SCH', my_schema));

PERFORM pg_catalog.set_config('search_path', old_path, true);
END
$$;
Loading