Compare commits

..

No commits in common. "58054de2d0847c09ef091956f72ae5e9fb9a176e" and "e0477837ce49d73c9f21a5e00143b741ce6e1f89" have entirely different histories.

22 changed files with 110 additions and 153 deletions

View File

@ -52,12 +52,6 @@ SELECT pg_get_functiondef('pg_stat_statements_reset'::regproc);
(1 row) (1 row)
SELECT pg_stat_statements_reset();
pg_stat_statements_reset
--------------------------
(1 row)
\d pg_stat_statements \d pg_stat_statements
View "public.pg_stat_statements" View "public.pg_stat_statements"
Column | Type | Collation | Nullable | Default Column | Type | Collation | Nullable | Default
@ -94,17 +88,6 @@ SELECT count(*) > 0 AS has_data FROM pg_stat_statements;
-- New functions and views for pg_stat_statements in 1.8 -- New functions and views for pg_stat_statements in 1.8
AlTER EXTENSION pg_stat_statements UPDATE TO '1.8'; AlTER EXTENSION pg_stat_statements UPDATE TO '1.8';
SELECT pg_get_functiondef('pg_stat_statements_reset'::regproc);
pg_get_functiondef
--------------------------------------------------------------------------------------------------------------------------------
CREATE OR REPLACE FUNCTION public.pg_stat_statements_reset(userid oid DEFAULT 0, dbid oid DEFAULT 0, queryid bigint DEFAULT 0)+
RETURNS void +
LANGUAGE c +
PARALLEL SAFE STRICT +
AS '$libdir/pg_stat_statements', $function$pg_stat_statements_reset_1_7$function$ +
(1 row)
\d pg_stat_statements \d pg_stat_statements
View "public.pg_stat_statements" View "public.pg_stat_statements"
Column | Type | Collation | Nullable | Default Column | Type | Collation | Nullable | Default
@ -142,10 +125,15 @@ SELECT pg_get_functiondef('pg_stat_statements_reset'::regproc);
wal_fpi | bigint | | | wal_fpi | bigint | | |
wal_bytes | numeric | | | wal_bytes | numeric | | |
SELECT count(*) > 0 AS has_data FROM pg_stat_statements; SELECT pg_get_functiondef('pg_stat_statements_reset'::regproc);
has_data pg_get_functiondef
---------- --------------------------------------------------------------------------------------------------------------------------------
t CREATE OR REPLACE FUNCTION public.pg_stat_statements_reset(userid oid DEFAULT 0, dbid oid DEFAULT 0, queryid bigint DEFAULT 0)+
RETURNS void +
LANGUAGE c +
PARALLEL SAFE STRICT +
AS '$libdir/pg_stat_statements', $function$pg_stat_statements_reset_1_7$function$ +
(1 row) (1 row)
-- New function pg_stat_statement_info, and new function -- New function pg_stat_statement_info, and new function
@ -336,10 +324,4 @@ SELECT pg_get_functiondef('pg_stat_statements_reset'::regproc);
(1 row) (1 row)
SELECT pg_stat_statements_reset() IS NOT NULL AS t;
t
---
t
(1 row)
DROP EXTENSION pg_stat_statements; DROP EXTENSION pg_stat_statements;

View File

@ -28,15 +28,13 @@ SET SESSION AUTHORIZATION pg_read_all_stats;
SELECT pg_stat_statements_reset(); SELECT pg_stat_statements_reset();
RESET SESSION AUTHORIZATION; RESET SESSION AUTHORIZATION;
SELECT pg_get_functiondef('pg_stat_statements_reset'::regproc); SELECT pg_get_functiondef('pg_stat_statements_reset'::regproc);
SELECT pg_stat_statements_reset();
\d pg_stat_statements \d pg_stat_statements
SELECT count(*) > 0 AS has_data FROM pg_stat_statements; SELECT count(*) > 0 AS has_data FROM pg_stat_statements;
-- New functions and views for pg_stat_statements in 1.8 -- New functions and views for pg_stat_statements in 1.8
AlTER EXTENSION pg_stat_statements UPDATE TO '1.8'; AlTER EXTENSION pg_stat_statements UPDATE TO '1.8';
SELECT pg_get_functiondef('pg_stat_statements_reset'::regproc);
\d pg_stat_statements \d pg_stat_statements
SELECT count(*) > 0 AS has_data FROM pg_stat_statements; SELECT pg_get_functiondef('pg_stat_statements_reset'::regproc);
-- New function pg_stat_statement_info, and new function -- New function pg_stat_statement_info, and new function
-- and view for pg_stat_statements introduced in 1.9 -- and view for pg_stat_statements introduced in 1.9
@ -56,6 +54,5 @@ AlTER EXTENSION pg_stat_statements UPDATE TO '1.11';
SELECT count(*) > 0 AS has_data FROM pg_stat_statements; SELECT count(*) > 0 AS has_data FROM pg_stat_statements;
-- New parameter minmax_only of pg_stat_statements_reset function -- New parameter minmax_only of pg_stat_statements_reset function
SELECT pg_get_functiondef('pg_stat_statements_reset'::regproc); SELECT pg_get_functiondef('pg_stat_statements_reset'::regproc);
SELECT pg_stat_statements_reset() IS NOT NULL AS t;
DROP EXTENSION pg_stat_statements; DROP EXTENSION pg_stat_statements;

View File

@ -2318,16 +2318,9 @@ REVOKE ALL ON accounts FROM PUBLIC;
<primary><type>aclitem</type></primary> <primary><type>aclitem</type></primary>
</indexterm> </indexterm>
The privileges that have been granted for a particular object are The privileges that have been granted for a particular object are
displayed as a list of <type>aclitem</type> entries, each having the displayed as a list of <type>aclitem</type> entries, where each
format: <type>aclitem</type> describes the permissions of one grantee that
<synopsis> have been granted by a particular grantor. For example,
<replaceable>grantee</replaceable><literal>=</literal><replaceable>privilege-abbreviation</replaceable><optional><literal>*</literal></optional>...<literal>/</literal><replaceable>grantor</replaceable>
</synopsis>
Each <type>aclitem</type> lists all the permissions of one grantee that
have been granted by a particular grantor. Specific privileges are
represented by one-letter abbreviations from
<xref linkend="privilege-abbrevs-table"/>, with <literal>*</literal>
appended if the privilege was granted with grant option. For example,
<literal>calvin=r*w/hobbes</literal> specifies that the role <literal>calvin=r*w/hobbes</literal> specifies that the role
<literal>calvin</literal> has the privilege <literal>calvin</literal> has the privilege
<literal>SELECT</literal> (<literal>r</literal>) with grant option <literal>SELECT</literal> (<literal>r</literal>) with grant option

View File

@ -409,6 +409,7 @@ btrescan(IndexScanDesc scan, ScanKey scankey, int nscankeys,
so->markItemIndex = -1; so->markItemIndex = -1;
so->arrayKeyCount = 0; so->arrayKeyCount = 0;
so->firstPage = false;
BTScanPosUnpinIfPinned(so->markPos); BTScanPosUnpinIfPinned(so->markPos);
BTScanPosInvalidate(so->markPos); BTScanPosInvalidate(so->markPos);

View File

@ -30,7 +30,7 @@ static OffsetNumber _bt_binsrch(Relation rel, BTScanInsert key, Buffer buf);
static int _bt_binsrch_posting(BTScanInsert key, Page page, static int _bt_binsrch_posting(BTScanInsert key, Page page,
OffsetNumber offnum); OffsetNumber offnum);
static bool _bt_readpage(IndexScanDesc scan, ScanDirection dir, static bool _bt_readpage(IndexScanDesc scan, ScanDirection dir,
OffsetNumber offnum, bool firstPage); OffsetNumber offnum);
static void _bt_saveitem(BTScanOpaque so, int itemIndex, static void _bt_saveitem(BTScanOpaque so, int itemIndex,
OffsetNumber offnum, IndexTuple itup); OffsetNumber offnum, IndexTuple itup);
static int _bt_setuppostingitems(BTScanOpaque so, int itemIndex, static int _bt_setuppostingitems(BTScanOpaque so, int itemIndex,
@ -1395,6 +1395,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
offnum = _bt_binsrch(rel, &inskey, buf); offnum = _bt_binsrch(rel, &inskey, buf);
Assert(!BTScanPosIsValid(so->currPos)); Assert(!BTScanPosIsValid(so->currPos));
so->currPos.buf = buf; so->currPos.buf = buf;
so->firstPage = true;
/* /*
* Now load data from the first page of the scan. * Now load data from the first page of the scan.
@ -1415,7 +1416,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
* for the page. For example, when inskey is both < the leaf page's high * for the page. For example, when inskey is both < the leaf page's high
* key and > all of its non-pivot tuples, offnum will be "maxoff + 1". * key and > all of its non-pivot tuples, offnum will be "maxoff + 1".
*/ */
if (!_bt_readpage(scan, dir, offnum, true)) if (!_bt_readpage(scan, dir, offnum))
{ {
/* /*
* There's no actually-matching data on this page. Try to advance to * There's no actually-matching data on this page. Try to advance to
@ -1519,8 +1520,7 @@ _bt_next(IndexScanDesc scan, ScanDirection dir)
* Returns true if any matching items found on the page, false if none. * Returns true if any matching items found on the page, false if none.
*/ */
static bool static bool
_bt_readpage(IndexScanDesc scan, ScanDirection dir, OffsetNumber offnum, _bt_readpage(IndexScanDesc scan, ScanDirection dir, OffsetNumber offnum)
bool firstPage)
{ {
BTScanOpaque so = (BTScanOpaque) scan->opaque; BTScanOpaque so = (BTScanOpaque) scan->opaque;
Page page; Page page;
@ -1530,8 +1530,7 @@ _bt_readpage(IndexScanDesc scan, ScanDirection dir, OffsetNumber offnum,
int itemIndex; int itemIndex;
bool continuescan; bool continuescan;
int indnatts; int indnatts;
bool continuescanPrechecked; bool requiredMatchedByPrecheck;
bool haveFirstMatch = false;
/* /*
* We must have the buffer pinned and locked, but the usual macro can't be * We must have the buffer pinned and locked, but the usual macro can't be
@ -1586,11 +1585,12 @@ _bt_readpage(IndexScanDesc scan, ScanDirection dir, OffsetNumber offnum,
Assert(BTScanPosIsPinned(so->currPos)); Assert(BTScanPosIsPinned(so->currPos));
/* /*
* Prechecking the value of the continuescan flag for the last item on the * Prechecking the page with scan keys required for direction scan. We
* page (for backwards scan it will be the first item on a page). If we * check these keys with the last item on the page (according to our scan
* observe it to be true, then it should be true for all other items. This * direction). If these keys are matched, we can skip checking them with
* allows us to do significant optimizations in the _bt_checkkeys() * every item on the page. Scan keys for our scan direction would
* function for all the items on the page. * necessarily match the previous items. Scan keys required for opposite
* direction scan are already matched by the _bt_first() call.
* *
* With the forward scan, we do this check for the last item on the page * With the forward scan, we do this check for the last item on the page
* instead of the high key. It's relatively likely that the most * instead of the high key. It's relatively likely that the most
@ -1601,7 +1601,7 @@ _bt_readpage(IndexScanDesc scan, ScanDirection dir, OffsetNumber offnum,
* We skip this for the first page in the scan to evade the possible * We skip this for the first page in the scan to evade the possible
* slowdown of the point queries. * slowdown of the point queries.
*/ */
if (!firstPage && minoff < maxoff) if (!so->firstPage && minoff < maxoff)
{ {
ItemId iid; ItemId iid;
IndexTuple itup; IndexTuple itup;
@ -1610,17 +1610,18 @@ _bt_readpage(IndexScanDesc scan, ScanDirection dir, OffsetNumber offnum,
itup = (IndexTuple) PageGetItem(page, iid); itup = (IndexTuple) PageGetItem(page, iid);
/* /*
* Do the precheck. Note that we pass the pointer to the * Do the precheck. Note that we pass the pointer to
* 'continuescanPrechecked' to the 'continuescan' argument. That will * 'requiredMatchedByPrecheck' to 'continuescan' argument. That will
* set flag to true if all required keys are satisfied and false * set flag to true if all required keys are satisfied and false
* otherwise. * otherwise.
*/ */
(void) _bt_checkkeys(scan, itup, indnatts, dir, (void) _bt_checkkeys(scan, itup, indnatts, dir,
&continuescanPrechecked, false, false); &requiredMatchedByPrecheck, false);
} }
else else
{ {
continuescanPrechecked = false; so->firstPage = false;
requiredMatchedByPrecheck = false;
} }
if (ScanDirectionIsForward(dir)) if (ScanDirectionIsForward(dir))
@ -1650,22 +1651,19 @@ _bt_readpage(IndexScanDesc scan, ScanDirection dir, OffsetNumber offnum,
Assert(!BTreeTupleIsPivot(itup)); Assert(!BTreeTupleIsPivot(itup));
passes_quals = _bt_checkkeys(scan, itup, indnatts, dir, passes_quals = _bt_checkkeys(scan, itup, indnatts, dir,
&continuescan, &continuescan, requiredMatchedByPrecheck);
continuescanPrechecked,
haveFirstMatch);
/* /*
* If the result of prechecking required keys was true, then in * If the result of prechecking required keys was true, then in
* assert-enabled builds we also recheck that the _bt_checkkeys() * assert-enabled builds we also recheck that the _bt_checkkeys()
* result is the same. * result is the same.
*/ */
Assert((!continuescanPrechecked && haveFirstMatch) || Assert(!requiredMatchedByPrecheck ||
passes_quals == _bt_checkkeys(scan, itup, indnatts, dir, passes_quals == _bt_checkkeys(scan, itup, indnatts, dir,
&continuescan, false, false)); &continuescan, false));
if (passes_quals) if (passes_quals)
{ {
/* tuple passes all scan key conditions */ /* tuple passes all scan key conditions */
haveFirstMatch = true;
if (!BTreeTupleIsPosting(itup)) if (!BTreeTupleIsPosting(itup))
{ {
/* Remember it */ /* Remember it */
@ -1720,7 +1718,7 @@ _bt_readpage(IndexScanDesc scan, ScanDirection dir, OffsetNumber offnum,
int truncatt; int truncatt;
truncatt = BTreeTupleGetNAtts(itup, scan->indexRelation); truncatt = BTreeTupleGetNAtts(itup, scan->indexRelation);
_bt_checkkeys(scan, itup, truncatt, dir, &continuescan, false, false); _bt_checkkeys(scan, itup, truncatt, dir, &continuescan, false);
} }
if (!continuescan) if (!continuescan)
@ -1773,22 +1771,19 @@ _bt_readpage(IndexScanDesc scan, ScanDirection dir, OffsetNumber offnum,
Assert(!BTreeTupleIsPivot(itup)); Assert(!BTreeTupleIsPivot(itup));
passes_quals = _bt_checkkeys(scan, itup, indnatts, dir, passes_quals = _bt_checkkeys(scan, itup, indnatts, dir,
&continuescan, &continuescan, requiredMatchedByPrecheck);
continuescanPrechecked,
haveFirstMatch);
/* /*
* If the result of prechecking required keys was true, then in * If the result of prechecking required keys was true, then in
* assert-enabled builds we also recheck that the _bt_checkkeys() * assert-enabled builds we also recheck that the _bt_checkkeys()
* result is the same. * result is the same.
*/ */
Assert((!continuescanPrechecked && !haveFirstMatch) || Assert(!requiredMatchedByPrecheck ||
passes_quals == _bt_checkkeys(scan, itup, indnatts, dir, passes_quals == _bt_checkkeys(scan, itup, indnatts, dir,
&continuescan, false, false)); &continuescan, false));
if (passes_quals && tuple_alive) if (passes_quals && tuple_alive)
{ {
/* tuple passes all scan key conditions */ /* tuple passes all scan key conditions */
haveFirstMatch = true;
if (!BTreeTupleIsPosting(itup)) if (!BTreeTupleIsPosting(itup))
{ {
/* Remember it */ /* Remember it */
@ -2084,7 +2079,7 @@ _bt_readnextpage(IndexScanDesc scan, BlockNumber blkno, ScanDirection dir)
PredicateLockPage(rel, blkno, scan->xs_snapshot); PredicateLockPage(rel, blkno, scan->xs_snapshot);
/* see if there are any matches on this page */ /* see if there are any matches on this page */
/* note that this will clear moreRight if we can stop */ /* note that this will clear moreRight if we can stop */
if (_bt_readpage(scan, dir, P_FIRSTDATAKEY(opaque), false)) if (_bt_readpage(scan, dir, P_FIRSTDATAKEY(opaque)))
break; break;
} }
else if (scan->parallel_scan != NULL) else if (scan->parallel_scan != NULL)
@ -2175,7 +2170,7 @@ _bt_readnextpage(IndexScanDesc scan, BlockNumber blkno, ScanDirection dir)
PredicateLockPage(rel, BufferGetBlockNumber(so->currPos.buf), scan->xs_snapshot); PredicateLockPage(rel, BufferGetBlockNumber(so->currPos.buf), scan->xs_snapshot);
/* see if there are any matches on this page */ /* see if there are any matches on this page */
/* note that this will clear moreLeft if we can stop */ /* note that this will clear moreLeft if we can stop */
if (_bt_readpage(scan, dir, PageGetMaxOffsetNumber(page), false)) if (_bt_readpage(scan, dir, PageGetMaxOffsetNumber(page)))
break; break;
} }
else if (scan->parallel_scan != NULL) else if (scan->parallel_scan != NULL)
@ -2492,13 +2487,14 @@ _bt_endpoint(IndexScanDesc scan, ScanDirection dir)
/* remember which buffer we have pinned */ /* remember which buffer we have pinned */
so->currPos.buf = buf; so->currPos.buf = buf;
so->firstPage = true;
_bt_initialize_more_data(so, dir); _bt_initialize_more_data(so, dir);
/* /*
* Now load data from the first page of the scan. * Now load data from the first page of the scan.
*/ */
if (!_bt_readpage(scan, dir, start, false)) if (!_bt_readpage(scan, dir, start))
{ {
/* /*
* There's no actually-matching data on this page. Try to advance to * There's no actually-matching data on this page. Try to advance to

View File

@ -1364,15 +1364,13 @@ _bt_mark_scankey_required(ScanKey skey)
* tupnatts: number of attributes in tupnatts (high key may be truncated) * tupnatts: number of attributes in tupnatts (high key may be truncated)
* dir: direction we are scanning in * dir: direction we are scanning in
* continuescan: output parameter (will be set correctly in all cases) * continuescan: output parameter (will be set correctly in all cases)
* continuescanPrechecked: indicates that *continuescan flag is known to * requiredMatchedByPrecheck: indicates that scan keys required for
* be true for the last item on the page * direction scan are already matched
* haveFirstMatch: indicates that we already have at least one match
* in the current page
*/ */
bool bool
_bt_checkkeys(IndexScanDesc scan, IndexTuple tuple, int tupnatts, _bt_checkkeys(IndexScanDesc scan, IndexTuple tuple, int tupnatts,
ScanDirection dir, bool *continuescan, ScanDirection dir, bool *continuescan,
bool continuescanPrechecked, bool haveFirstMatch) bool requiredMatchedByPrecheck)
{ {
TupleDesc tupdesc; TupleDesc tupdesc;
BTScanOpaque so; BTScanOpaque so;
@ -1408,23 +1406,13 @@ _bt_checkkeys(IndexScanDesc scan, IndexTuple tuple, int tupnatts,
requiredOppositeDir = true; requiredOppositeDir = true;
/* /*
* If the caller told us the *continuescan flag is known to be true * Is the key required for scanning for either forward or backward
* for the last item on the page, then we know the keys required for * direction? If so and caller told us that these types of keys are
* the current direction scan should be matched. Otherwise, the * known to be matched, skip the check. Except for the row keys,
* *continuescan flag would be set for the current item and * where NULLs could be found in the middle of matching values.
* subsequently the last item on the page accordingly.
*
* If the key is required for the opposite direction scan, we can skip
* the check if the caller tells us there was already at least one
* matching item on the page. Also, we require the *continuescan flag
* to be true for the last item on the page to know there are no
* NULLs.
*
* Both cases above work except for the row keys, where NULLs could be
* found in the middle of matching values.
*/ */
if ((requiredSameDir || (requiredOppositeDir && haveFirstMatch)) && if ((requiredSameDir || requiredOppositeDir) &&
!(key->sk_flags & SK_ROW_HEADER) && continuescanPrechecked) !(key->sk_flags & SK_ROW_HEADER) && requiredMatchedByPrecheck)
continue; continue;
if (key->sk_attno > tupnatts) if (key->sk_attno > tupnatts)
@ -1525,12 +1513,12 @@ _bt_checkkeys(IndexScanDesc scan, IndexTuple tuple, int tupnatts,
} }
/* /*
* Apply the key-checking function. When the key is required for the * Apply the key checking function. When the key is required for
* opposite direction scan, it must be already satisfied as soon as * opposite direction scan, it must be already satisfied by
* there is already match on the page. Except for the NULLs checking, * _bt_first() except for the NULLs checking, which have already done
* which have already done above. * above.
*/ */
if (!(requiredOppositeDir && haveFirstMatch)) if (!requiredOppositeDir)
{ {
test = FunctionCall2Coll(&key->sk_func, key->sk_collation, test = FunctionCall2Coll(&key->sk_func, key->sk_collation,
datum, key->sk_argument); datum, key->sk_argument);

View File

@ -2280,7 +2280,7 @@ XLogWrite(XLogwrtRqst WriteRqst, TimeLineID tli, bool flexible)
char *from; char *from;
Size nbytes; Size nbytes;
Size nleft; Size nleft;
ssize_t written; int written;
instr_time start; instr_time start;
/* OK to write the page(s) */ /* OK to write the page(s) */

View File

@ -117,8 +117,8 @@ static void perform_base_backup(basebackup_options *opt, bbsink *sink,
IncrementalBackupInfo *ib); IncrementalBackupInfo *ib);
static void parse_basebackup_options(List *options, basebackup_options *opt); static void parse_basebackup_options(List *options, basebackup_options *opt);
static int compareWalFileNames(const ListCell *a, const ListCell *b); static int compareWalFileNames(const ListCell *a, const ListCell *b);
static ssize_t basebackup_read_file(int fd, char *buf, size_t nbytes, off_t offset, static int basebackup_read_file(int fd, char *buf, size_t nbytes, off_t offset,
const char *filename, bool partial_read_ok); const char *filename, bool partial_read_ok);
/* Was the backup currently in-progress initiated in recovery mode? */ /* Was the backup currently in-progress initiated in recovery mode? */
static bool backup_started_in_recovery = false; static bool backup_started_in_recovery = false;
@ -525,7 +525,7 @@ perform_base_backup(basebackup_options *opt, bbsink *sink,
{ {
char *walFileName = (char *) lfirst(lc); char *walFileName = (char *) lfirst(lc);
int fd; int fd;
ssize_t cnt; size_t cnt;
pgoff_t len = 0; pgoff_t len = 0;
snprintf(pathbuf, MAXPGPATH, XLOGDIR "/%s", walFileName); snprintf(pathbuf, MAXPGPATH, XLOGDIR "/%s", walFileName);
@ -2079,11 +2079,11 @@ convert_link_to_directory(const char *pathbuf, struct stat *statbuf)
* *
* Returns the number of bytes read. * Returns the number of bytes read.
*/ */
static ssize_t static int
basebackup_read_file(int fd, char *buf, size_t nbytes, off_t offset, basebackup_read_file(int fd, char *buf, size_t nbytes, off_t offset,
const char *filename, bool partial_read_ok) const char *filename, bool partial_read_ok)
{ {
ssize_t rc; int rc;
pgstat_report_wait_start(WAIT_EVENT_BASEBACKUP_READ); pgstat_report_wait_start(WAIT_EVENT_BASEBACKUP_READ);
rc = pg_pread(fd, buf, nbytes, offset); rc = pg_pread(fd, buf, nbytes, offset);
@ -2096,7 +2096,7 @@ basebackup_read_file(int fd, char *buf, size_t nbytes, off_t offset,
if (!partial_read_ok && rc > 0 && rc != nbytes) if (!partial_read_ok && rc > 0 && rc != nbytes)
ereport(ERROR, ereport(ERROR,
(errcode_for_file_access(), (errcode_for_file_access(),
errmsg("could not read file \"%s\": read %zd of %zu", errmsg("could not read file \"%s\": read %d of %zu",
filename, rc, nbytes))); filename, rc, nbytes)));
return rc; return rc;

View File

@ -575,7 +575,7 @@ PrepareForIncrementalBackup(IncrementalBackupInfo *ib,
tle->tli, tle->tli,
LSN_FORMAT_ARGS(tli_start_lsn), LSN_FORMAT_ARGS(tli_start_lsn),
LSN_FORMAT_ARGS(tli_end_lsn)), LSN_FORMAT_ARGS(tli_end_lsn)),
errdetail("The first unsummarized LSN in this range is %X/%X.", errdetail("The first unsummarized LSN is this range is %X/%X.",
LSN_FORMAT_ARGS(tli_missing_lsn)))); LSN_FORMAT_ARGS(tli_missing_lsn))));
} }

View File

@ -43,8 +43,11 @@ SET search_path TO information_schema;
CREATE FUNCTION _pg_expandarray(IN anyarray, OUT x anyelement, OUT n int) CREATE FUNCTION _pg_expandarray(IN anyarray, OUT x anyelement, OUT n int)
RETURNS SETOF RECORD RETURNS SETOF RECORD
LANGUAGE sql STRICT IMMUTABLE PARALLEL SAFE LANGUAGE sql STRICT IMMUTABLE PARALLEL SAFE
ROWS 100 SUPPORT pg_catalog.array_unnest_support AS 'select $1[s],
AS 'SELECT * FROM pg_catalog.unnest($1) WITH ORDINALITY'; s operator(pg_catalog.-) pg_catalog.array_lower($1,1) operator(pg_catalog.+) 1
from pg_catalog.generate_series(pg_catalog.array_lower($1,1),
pg_catalog.array_upper($1,1),
1) as g(s)';
/* Given an index's OID and an underlying-table column number, return the /* Given an index's OID and an underlying-table column number, return the
* column's position in the index (NULL if not there) */ * column's position in the index (NULL if not there) */

View File

@ -438,7 +438,7 @@ GetOldestUnsummarizedLSN(TimeLineID *tli, bool *lsn_is_exact,
LWLockMode mode = reset_pending_lsn ? LW_EXCLUSIVE : LW_SHARED; LWLockMode mode = reset_pending_lsn ? LW_EXCLUSIVE : LW_SHARED;
int n; int n;
List *tles; List *tles;
XLogRecPtr unsummarized_lsn = InvalidXLogRecPtr; XLogRecPtr unsummarized_lsn;
TimeLineID unsummarized_tli = 0; TimeLineID unsummarized_tli = 0;
bool should_make_exact = false; bool should_make_exact = false;
List *existing_summaries; List *existing_summaries;

View File

@ -416,7 +416,7 @@ SyncRepInitConfig(void)
SpinLockRelease(&MyWalSnd->mutex); SpinLockRelease(&MyWalSnd->mutex);
ereport(DEBUG1, ereport(DEBUG1,
(errmsg_internal("standby \"%s\" now has synchronous standby priority %d", (errmsg_internal("standby \"%s\" now has synchronous standby priority %u",
application_name, priority))); application_name, priority)));
} }
} }
@ -483,7 +483,7 @@ SyncRepReleaseWaiters(void)
if (SyncRepConfig->syncrep_method == SYNC_REP_PRIORITY) if (SyncRepConfig->syncrep_method == SYNC_REP_PRIORITY)
ereport(LOG, ereport(LOG,
(errmsg("standby \"%s\" is now a synchronous standby with priority %d", (errmsg("standby \"%s\" is now a synchronous standby with priority %u",
application_name, MyWalSnd->sync_standby_priority))); application_name, MyWalSnd->sync_standby_priority)));
else else
ereport(LOG, ereport(LOG,

View File

@ -6317,9 +6317,6 @@ array_unnest(PG_FUNCTION_ARGS)
/* /*
* Planner support function for array_unnest(anyarray) * Planner support function for array_unnest(anyarray)
*
* Note: this is now also used for information_schema._pg_expandarray(),
* which is simply a wrapper around array_unnest().
*/ */
Datum Datum
array_unnest_support(PG_FUNCTION_ARGS) array_unnest_support(PG_FUNCTION_ARGS)

View File

@ -538,7 +538,7 @@ check_control_files(int n_backups, char **backup_dirs)
/* Control file contents not meaningful if CRC is bad. */ /* Control file contents not meaningful if CRC is bad. */
if (!crc_ok) if (!crc_ok)
pg_fatal("%s: CRC is incorrect", controlpath); pg_fatal("%s: crc is incorrect", controlpath);
/* Can't interpret control file if not current version. */ /* Can't interpret control file if not current version. */
if (control_file->pg_control_version != PG_CONTROL_VERSION) if (control_file->pg_control_version != PG_CONTROL_VERSION)

View File

@ -504,7 +504,7 @@ make_rfile(char *filename, bool missing_ok)
static void static void
read_bytes(rfile *rf, void *buffer, unsigned length) read_bytes(rfile *rf, void *buffer, unsigned length)
{ {
int rb = read(rf->fd, buffer, length); unsigned rb = read(rf->fd, buffer, length);
if (rb != length) if (rb != length)
{ {
@ -512,7 +512,7 @@ read_bytes(rfile *rf, void *buffer, unsigned length)
pg_fatal("could not read file \"%s\": %m", rf->filename); pg_fatal("could not read file \"%s\": %m", rf->filename);
else else
pg_fatal("could not read file \"%s\": read only %d of %d bytes", pg_fatal("could not read file \"%s\": read only %d of %d bytes",
rf->filename, rb, length); rf->filename, (int) rb, length);
} }
} }
@ -614,7 +614,7 @@ write_reconstructed_file(char *input_filename,
{ {
uint8 buffer[BLCKSZ]; uint8 buffer[BLCKSZ];
rfile *s = sourcemap[i]; rfile *s = sourcemap[i];
int wb; unsigned wb;
/* Update accounting information. */ /* Update accounting information. */
if (s == NULL) if (s == NULL)
@ -641,7 +641,7 @@ write_reconstructed_file(char *input_filename,
} }
else else
{ {
int rb; unsigned rb;
/* Read the block from the correct source, except if dry-run. */ /* Read the block from the correct source, except if dry-run. */
rb = pg_pread(s->fd, buffer, BLCKSZ, offsetmap[i]); rb = pg_pread(s->fd, buffer, BLCKSZ, offsetmap[i]);
@ -650,9 +650,9 @@ write_reconstructed_file(char *input_filename,
if (rb < 0) if (rb < 0)
pg_fatal("could not read file \"%s\": %m", s->filename); pg_fatal("could not read file \"%s\": %m", s->filename);
else else
pg_fatal("could not read file \"%s\": read only %d of %d bytes at offset %llu", pg_fatal("could not read file \"%s\": read only %d of %d bytes at offset %u",
s->filename, rb, BLCKSZ, s->filename, (int) rb, BLCKSZ,
(unsigned long long) offsetmap[i]); (unsigned) offsetmap[i]);
} }
} }
@ -663,7 +663,7 @@ write_reconstructed_file(char *input_filename,
pg_fatal("could not write file \"%s\": %m", output_filename); pg_fatal("could not write file \"%s\": %m", output_filename);
else else
pg_fatal("could not write file \"%s\": wrote only %d of %d bytes", pg_fatal("could not write file \"%s\": wrote only %d of %d bytes",
output_filename, wb, BLCKSZ); output_filename, (int) wb, BLCKSZ);
} }
/* Update the checksum computation. */ /* Update the checksum computation. */

View File

@ -72,7 +72,7 @@ create_manifest_writer(char *directory)
*/ */
void void
add_file_to_manifest(manifest_writer *mwriter, const char *manifest_path, add_file_to_manifest(manifest_writer *mwriter, const char *manifest_path,
size_t size, time_t mtime, size_t size, pg_time_t mtime,
pg_checksum_type checksum_type, pg_checksum_type checksum_type,
int checksum_length, int checksum_length,
uint8 *checksum_payload) uint8 *checksum_payload)

View File

@ -13,6 +13,7 @@
#define WRITE_MANIFEST_H #define WRITE_MANIFEST_H
#include "common/checksum_helper.h" #include "common/checksum_helper.h"
#include "pgtime.h"
struct manifest_wal_range; struct manifest_wal_range;
@ -22,7 +23,7 @@ typedef struct manifest_writer manifest_writer;
extern manifest_writer *create_manifest_writer(char *directory); extern manifest_writer *create_manifest_writer(char *directory);
extern void add_file_to_manifest(manifest_writer *mwriter, extern void add_file_to_manifest(manifest_writer *mwriter,
const char *manifest_path, const char *manifest_path,
size_t size, time_t mtime, size_t size, pg_time_t mtime,
pg_checksum_type checksum_type, pg_checksum_type checksum_type,
int checksum_length, int checksum_length,
uint8 *checksum_payload); uint8 *checksum_payload);

View File

@ -1051,6 +1051,9 @@ typedef struct BTScanOpaqueData
int *killedItems; /* currPos.items indexes of killed items */ int *killedItems; /* currPos.items indexes of killed items */
int numKilled; /* number of currently stored items */ int numKilled; /* number of currently stored items */
/* flag indicating the first page in the scan */
bool firstPage;
/* /*
* If we are doing an index-only scan, these are the tuple storage * If we are doing an index-only scan, these are the tuple storage
* workspaces for the currPos and markPos respectively. Each is of size * workspaces for the currPos and markPos respectively. Each is of size
@ -1251,7 +1254,7 @@ extern void _bt_restore_array_keys(IndexScanDesc scan);
extern void _bt_preprocess_keys(IndexScanDesc scan); extern void _bt_preprocess_keys(IndexScanDesc scan);
extern bool _bt_checkkeys(IndexScanDesc scan, IndexTuple tuple, extern bool _bt_checkkeys(IndexScanDesc scan, IndexTuple tuple,
int tupnatts, ScanDirection dir, bool *continuescan, int tupnatts, ScanDirection dir, bool *continuescan,
bool requiredMatchedByPrecheck, bool haveFirstMatch); bool requiredMatchedByPrecheck);
extern void _bt_killitems(IndexScanDesc scan); extern void _bt_killitems(IndexScanDesc scan);
extern BTCycleId _bt_vacuum_cycleid(Relation rel); extern BTCycleId _bt_vacuum_cycleid(Relation rel);
extern BTCycleId _bt_start_vacuum(Relation rel); extern BTCycleId _bt_start_vacuum(Relation rel);

View File

@ -57,6 +57,6 @@
*/ */
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 202312271 #define CATALOG_VERSION_NO 202312251
#endif #endif

View File

@ -70,7 +70,7 @@ is(scalar(my @foobar = split /^/m, $result),
# If we immediately crash the server we might lose the progress we just made # If we immediately crash the server we might lose the progress we just made
# and replay the same changes again. But a clean shutdown should never repeat # and replay the same changes again. But a clean shutdown should never repeat
# the same changes when we use the SQL decoding interface. # the same changes when we use the SQL decoding interface.
$node_primary->restart; $node_primary->restart('fast');
# There are no new writes, so the result should be empty. # There are no new writes, so the result should be empty.
$result = $node_primary->safe_psql('postgres', $result = $node_primary->safe_psql('postgres',

View File

@ -5293,30 +5293,26 @@ comment on function psql_df_plpgsql () is 'some comment';
rollback; rollback;
drop role regress_psql_user; drop role regress_psql_user;
-- check \sf -- check \sf
\sf information_schema._pg_index_position \sf information_schema._pg_expandarray
CREATE OR REPLACE FUNCTION information_schema._pg_index_position(oid, smallint) CREATE OR REPLACE FUNCTION information_schema._pg_expandarray(anyarray, OUT x anyelement, OUT n integer)
RETURNS integer RETURNS SETOF record
LANGUAGE sql LANGUAGE sql
STABLE STRICT IMMUTABLE PARALLEL SAFE STRICT
BEGIN ATOMIC AS $function$select $1[s],
SELECT (ss.a).n AS n s operator(pg_catalog.-) pg_catalog.array_lower($1,1) operator(pg_catalog.+) 1
FROM ( SELECT information_schema._pg_expandarray(pg_index.indkey) AS a from pg_catalog.generate_series(pg_catalog.array_lower($1,1),
FROM pg_index pg_catalog.array_upper($1,1),
WHERE (pg_index.indexrelid = $1)) ss 1) as g(s)$function$
WHERE ((ss.a).x = $2); \sf+ information_schema._pg_expandarray
END CREATE OR REPLACE FUNCTION information_schema._pg_expandarray(anyarray, OUT x anyelement, OUT n integer)
\sf+ information_schema._pg_index_position RETURNS SETOF record
CREATE OR REPLACE FUNCTION information_schema._pg_index_position(oid, smallint)
RETURNS integer
LANGUAGE sql LANGUAGE sql
STABLE STRICT IMMUTABLE PARALLEL SAFE STRICT
1 BEGIN ATOMIC 1 AS $function$select $1[s],
2 SELECT (ss.a).n AS n 2 s operator(pg_catalog.-) pg_catalog.array_lower($1,1) operator(pg_catalog.+) 1
3 FROM ( SELECT information_schema._pg_expandarray(pg_index.indkey) AS a 3 from pg_catalog.generate_series(pg_catalog.array_lower($1,1),
4 FROM pg_index 4 pg_catalog.array_upper($1,1),
5 WHERE (pg_index.indexrelid = $1)) ss 5 1) as g(s)$function$
6 WHERE ((ss.a).x = $2);
7 END
\sf+ interval_pl_time \sf+ interval_pl_time
CREATE OR REPLACE FUNCTION pg_catalog.interval_pl_time(interval, time without time zone) CREATE OR REPLACE FUNCTION pg_catalog.interval_pl_time(interval, time without time zone)
RETURNS time without time zone RETURNS time without time zone

View File

@ -1312,8 +1312,8 @@ rollback;
drop role regress_psql_user; drop role regress_psql_user;
-- check \sf -- check \sf
\sf information_schema._pg_index_position \sf information_schema._pg_expandarray
\sf+ information_schema._pg_index_position \sf+ information_schema._pg_expandarray
\sf+ interval_pl_time \sf+ interval_pl_time
\sf ts_debug(text) \sf ts_debug(text)
\sf+ ts_debug(text) \sf+ ts_debug(text)