Skip to content

Commit 5f257e0

Browse files
committed
Merge branch 'REL9_6_STABLE' into PGPRO9_6
2 parents b5f506f + 91ba77c commit 5f257e0

File tree

42 files changed

+973
-390
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+973
-390
lines changed

contrib/pageinspect/ginfuncs.c

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,31 @@ PG_FUNCTION_INFO_V1(gin_metapage_info);
2828
PG_FUNCTION_INFO_V1(gin_page_opaque_info);
2929
PG_FUNCTION_INFO_V1(gin_leafpage_items);
3030

31+
32+
static Page
33+
get_page_from_raw(bytea *raw_page)
34+
{
35+
int raw_page_size;
36+
Page page;
37+
38+
raw_page_size = VARSIZE(raw_page) - VARHDRSZ;
39+
if (raw_page_size < BLCKSZ)
40+
ereport(ERROR,
41+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
42+
errmsg("input page too small (%d bytes)", raw_page_size)));
43+
44+
/* make a copy so that the page is properly aligned for struct access */
45+
page = palloc(raw_page_size);
46+
memcpy(page, VARDATA(raw_page), raw_page_size);
47+
48+
return page;
49+
}
50+
51+
3152
Datum
3253
gin_metapage_info(PG_FUNCTION_ARGS)
3354
{
3455
bytea *raw_page = PG_GETARG_BYTEA_P(0);
35-
int raw_page_size;
3656
TupleDesc tupdesc;
3757
Page page;
3858
GinPageOpaque opaq;
@@ -46,12 +66,7 @@ gin_metapage_info(PG_FUNCTION_ARGS)
4666
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
4767
(errmsg("must be superuser to use raw page functions"))));
4868

49-
raw_page_size = VARSIZE(raw_page) - VARHDRSZ;
50-
if (raw_page_size < BLCKSZ)
51-
ereport(ERROR,
52-
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
53-
errmsg("input page too small (%d bytes)", raw_page_size)));
54-
page = VARDATA(raw_page);
69+
page = get_page_from_raw(raw_page);
5570

5671
opaq = (GinPageOpaque) PageGetSpecialPointer(page);
5772
if (opaq->flags != GIN_META)
@@ -94,13 +109,12 @@ Datum
94109
gin_page_opaque_info(PG_FUNCTION_ARGS)
95110
{
96111
bytea *raw_page = PG_GETARG_BYTEA_P(0);
97-
int raw_page_size;
98112
TupleDesc tupdesc;
99113
Page page;
100114
GinPageOpaque opaq;
101115
HeapTuple resultTuple;
102116
Datum values[3];
103-
bool nulls[10];
117+
bool nulls[3];
104118
Datum flags[16];
105119
int nflags = 0;
106120
uint16 flagbits;
@@ -110,12 +124,7 @@ gin_page_opaque_info(PG_FUNCTION_ARGS)
110124
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
111125
(errmsg("must be superuser to use raw page functions"))));
112126

113-
raw_page_size = VARSIZE(raw_page) - VARHDRSZ;
114-
if (raw_page_size < BLCKSZ)
115-
ereport(ERROR,
116-
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
117-
errmsg("input page too small (%d bytes)", raw_page_size)));
118-
page = VARDATA(raw_page);
127+
page = get_page_from_raw(raw_page);
119128

120129
opaq = (GinPageOpaque) PageGetSpecialPointer(page);
121130

@@ -152,9 +161,9 @@ gin_page_opaque_info(PG_FUNCTION_ARGS)
152161
memset(nulls, 0, sizeof(nulls));
153162

154163
values[0] = Int64GetDatum(opaq->rightlink);
155-
values[1] = Int64GetDatum(opaq->maxoff);
156-
values[2] = PointerGetDatum(
157-
construct_array(flags, nflags, TEXTOID, -1, false, 'i'));
164+
values[1] = Int32GetDatum(opaq->maxoff);
165+
values[2] = PointerGetDatum(construct_array(flags, nflags,
166+
TEXTOID, -1, false, 'i'));
158167

159168
/* Build and return the result tuple. */
160169
resultTuple = heap_form_tuple(tupdesc, values, nulls);
@@ -173,7 +182,6 @@ Datum
173182
gin_leafpage_items(PG_FUNCTION_ARGS)
174183
{
175184
bytea *raw_page = PG_GETARG_BYTEA_P(0);
176-
int raw_page_size;
177185
FuncCallContext *fctx;
178186
gin_leafpage_items_state *inter_call_data;
179187

@@ -182,20 +190,17 @@ gin_leafpage_items(PG_FUNCTION_ARGS)
182190
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
183191
(errmsg("must be superuser to use raw page functions"))));
184192

185-
raw_page_size = VARSIZE(raw_page) - VARHDRSZ;
186-
187193
if (SRF_IS_FIRSTCALL())
188194
{
189195
TupleDesc tupdesc;
190196
MemoryContext mctx;
191197
Page page;
192198
GinPageOpaque opaq;
193199

194-
if (raw_page_size < BLCKSZ)
195-
ereport(ERROR,
196-
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
197-
errmsg("input page too small (%d bytes)", raw_page_size)));
198-
page = VARDATA(raw_page);
200+
fctx = SRF_FIRSTCALL_INIT();
201+
mctx = MemoryContextSwitchTo(fctx->multi_call_memory_ctx);
202+
203+
page = get_page_from_raw(raw_page);
199204

200205
if (PageGetSpecialSize(page) != MAXALIGN(sizeof(GinPageOpaqueData)))
201206
ereport(ERROR,
@@ -214,9 +219,6 @@ gin_leafpage_items(PG_FUNCTION_ARGS)
214219
opaq->flags,
215220
(GIN_DATA | GIN_LEAF | GIN_COMPRESSED))));
216221

217-
fctx = SRF_FIRSTCALL_INIT();
218-
mctx = MemoryContextSwitchTo(fctx->multi_call_memory_ctx);
219-
220222
inter_call_data = palloc(sizeof(gin_leafpage_items_state));
221223

222224
/* Build a tuple descriptor for our result type */

contrib/pageinspect/heapfuncs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ heap_page_items(PG_FUNCTION_ARGS)
279279
*
280280
* Split raw tuple data taken directly from a page into an array of bytea
281281
* elements. This routine does a lookup on NULL values and creates array
282-
* elements accordindly. This is a reimplementation of nocachegetattr()
282+
* elements accordingly. This is a reimplementation of nocachegetattr()
283283
* in heaptuple.c simplified for educational purposes.
284284
*/
285285
static Datum

doc/src/sgml/ddl.sgml

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2559,7 +2559,8 @@ VALUES ('Albany', NULL, NULL, 'NY');
25592559

25602560
<para>
25612561
All check constraints and not-null constraints on a parent table are
2562-
automatically inherited by its children. Other types of constraints
2562+
automatically inherited by its children, unless explicitly specified
2563+
otherwise with <literal>NO INHERIT</> clauses. Other types of constraints
25632564
(unique, primary key, and foreign key constraints) are not inherited.
25642565
</para>
25652566

@@ -2570,10 +2571,12 @@ VALUES ('Albany', NULL, NULL, 'NY');
25702571
same column name appears in multiple parent tables, or in both a parent
25712572
table and the child's definition, then these columns are <quote>merged</>
25722573
so that there is only one such column in the child table. To be merged,
2573-
columns must have the same data types, else an error is raised. The
2574-
merged column will have copies of all the check constraints coming from
2575-
any one of the column definitions it came from, and will be marked not-null
2576-
if any of them are.
2574+
columns must have the same data types, else an error is raised.
2575+
Inheritable check constraints and not-null constraints are merged in a
2576+
similar fashion. Thus, for example, a merged column will be marked
2577+
not-null if any one of the column definitions it came from is marked
2578+
not-null. Check constraints are merged if they have the same name,
2579+
and the merge will fail if their conditions are different.
25772580
</para>
25782581

25792582
<para>
@@ -2625,12 +2628,19 @@ VALUES ('Albany', NULL, NULL, 'NY');
26252628
</para>
26262629

26272630
<para>
2628-
Note how table access permissions are handled. Querying a parent
2629-
table can automatically access data in child tables without further
2630-
access privilege checking. This preserves the appearance that the
2631-
data is (also) in the parent table. Accessing the child tables
2632-
directly is, however, not automatically allowed and would require
2633-
further privileges to be granted.
2631+
Inherited queries perform access permission checks on the parent table
2632+
only. Thus, for example, granting <literal>UPDATE</> permission on
2633+
the <structname>cities</> table implies permission to update rows in
2634+
the <structname>capitals</structname> table as well, when they are
2635+
accessed through <structname>cities</>. This preserves the appearance
2636+
that the data is (also) in the parent table. But
2637+
the <structname>capitals</structname> table could not be updated directly
2638+
without an additional grant. In a similar way, the parent table's row
2639+
security policies (see <xref linkend="ddl-rowsecurity">) are applied to
2640+
rows coming from child tables during an inherited query. A child table's
2641+
policies, if any, are applied only when it is the table explicitly named
2642+
in the query; and in that case, any policies attached to its parent(s) are
2643+
ignored.
26342644
</para>
26352645

26362646
<para>

doc/src/sgml/pltcl.sgml

Lines changed: 35 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -296,36 +296,38 @@ $$ LANGUAGE pltcl;
296296
If the command is a <command>SELECT</> statement, the values of the
297297
result columns are placed into Tcl variables named after the columns.
298298
If the <literal>-array</> option is given, the column values are
299-
instead stored into the named associative array, with the
300-
column names used as array indexes.
299+
instead stored into elements of the named associative array, with the
300+
column names used as array indexes. In addition, the current row
301+
number within the result (counting from zero) is stored into the array
302+
element named <quote><literal>.tupno</></quote>, unless that name is
303+
in use as a column name in the result.
301304
</para>
302305
<para>
303306
If the command is a <command>SELECT</> statement and no <replaceable>loop-body</>
304307
script is given, then only the first row of results are stored into
305-
Tcl variables; remaining rows, if any, are ignored. No storing occurs
306-
if the
307-
query returns no rows. (This case can be detected by checking the
308-
result of <function>spi_exec</function>.) For example:
308+
Tcl variables or array elements; remaining rows, if any, are ignored.
309+
No storing occurs if the query returns no rows. (This case can be
310+
detected by checking the result of <function>spi_exec</function>.)
311+
For example:
309312
<programlisting>
310313
spi_exec "SELECT count(*) AS cnt FROM pg_proc"
311314
</programlisting>
312-
313315
will set the Tcl variable <literal>$cnt</> to the number of rows in
314316
the <structname>pg_proc</> system catalog.
315317
</para>
316318
<para>
317319
If the optional <replaceable>loop-body</> argument is given, it is
318320
a piece of Tcl script that is executed once for each row in the
319321
query result. (<replaceable>loop-body</> is ignored if the given
320-
command is not a <command>SELECT</>.) The values of the current row's columns
321-
are stored into Tcl variables before each iteration. For example:
322-
322+
command is not a <command>SELECT</>.)
323+
The values of the current row's columns
324+
are stored into Tcl variables or array elements before each iteration.
325+
For example:
323326
<programlisting>
324327
spi_exec -array C "SELECT * FROM pg_class" {
325328
elog DEBUG "have table $C(relname)"
326329
}
327330
</programlisting>
328-
329331
will print a log message for every row of <literal>pg_class</>. This
330332
feature works similarly to other Tcl looping constructs; in
331333
particular <literal>continue</> and <literal>break</> work in the
@@ -667,21 +669,35 @@ SELECT 'doesn''t' AS ret
667669

668670
<para>
669671
The return value from a trigger procedure can be one of the strings
670-
<literal>OK</> or <literal>SKIP</>, or a list as returned by the
671-
<literal>array get</> Tcl command. If the return value is <literal>OK</>,
672-
the operation (<command>INSERT</>/<command>UPDATE</>/<command>DELETE</>) that fired the trigger will proceed
672+
<literal>OK</> or <literal>SKIP</>, or a list of column name/value pairs.
673+
If the return value is <literal>OK</>,
674+
the operation (<command>INSERT</>/<command>UPDATE</>/<command>DELETE</>)
675+
that fired the trigger will proceed
673676
normally. <literal>SKIP</> tells the trigger manager to silently suppress
674677
the operation for this row. If a list is returned, it tells PL/Tcl to
675-
return a modified row to the trigger manager. This is only meaningful
678+
return a modified row to the trigger manager; the contents of the
679+
modified row are specified by the column names and values in the list.
680+
Any columns not mentioned in the list are set to null.
681+
Returning a modified row is only meaningful
676682
for row-level <literal>BEFORE</> <command>INSERT</> or <command>UPDATE</>
677-
triggers for which the modified row will be inserted instead of the one
683+
triggers, for which the modified row will be inserted instead of the one
678684
given in <varname>$NEW</>; or for row-level <literal>INSTEAD OF</>
679685
<command>INSERT</> or <command>UPDATE</> triggers where the returned row
680-
is used to support <command>INSERT RETURNING</> and
681-
<command>UPDATE RETURNING</> commands. The return value is ignored for
682-
other types of triggers.
686+
is used as the source data for <command>INSERT RETURNING</> or
687+
<command>UPDATE RETURNING</> clauses.
688+
In row-level <literal>BEFORE</> <command>DELETE</> or <literal>INSTEAD
689+
OF</> <command>DELETE</> triggers, returning a modified row has the same
690+
effect as returning <literal>OK</>, that is the operation proceeds.
691+
The trigger return value is ignored for all other types of triggers.
683692
</para>
684693

694+
<tip>
695+
<para>
696+
The result list can be made from an array representation of the
697+
modified tuple with the <literal>array get</> Tcl command.
698+
</para>
699+
</tip>
700+
685701
<para>
686702
Here's a little example trigger procedure that forces an integer value
687703
in a table to keep track of the number of updates that are performed on the

doc/src/sgml/sources.sgml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -898,7 +898,7 @@ BETTER: unrecognized node type: 42
898898
expressions of various types need to be passed to the macro.
899899
</para>
900900
<para>
901-
When the definition an inline function references symbols
901+
When the definition of an inline function references symbols
902902
(i.e. variables, functions) that are only available as part of the
903903
backend, the function may not be visible when included from frontend
904904
code.

doc/src/sgml/xaggr.sgml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -626,14 +626,28 @@ if (AggCheckCallContext(fcinfo, NULL))
626626
function, the first input
627627
must be a temporary state value and can therefore safely be modified
628628
in-place rather than allocating a new copy.
629-
See <literal>int8inc()</> for an example.
629+
See <function>int8inc()</> for an example.
630630
(This is the <emphasis>only</>
631631
case where it is safe for a function to modify a pass-by-reference input.
632632
In particular, final functions for normal aggregates must not
633633
modify their inputs in any case, because in some cases they will be
634634
re-executed on the same final state value.)
635635
</para>
636636

637+
<para>
638+
The second argument of <function>AggCheckCallContext</> can be used to
639+
retrieve the memory context in which aggregate state values are being kept.
640+
This is useful for transition functions that wish to use <quote>expanded</>
641+
objects (see <xref linkend="xtypes-toast">) as their state values.
642+
On first call, the transition function should return an expanded object
643+
whose memory context is a child of the aggregate state context, and then
644+
keep returning the same expanded object on subsequent calls. See
645+
<function>array_append()</> for an example. (<function>array_append()</>
646+
is not the transition function of any built-in aggregate, but it is written
647+
to behave efficiently when used as transition function of a custom
648+
aggregate.)
649+
</para>
650+
637651
<para>
638652
Another support routine available to aggregate functions written in C
639653
is <function>AggGetAggref</>, which returns the <literal>Aggref</>

src/backend/access/transam/xlog.c

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -612,11 +612,14 @@ typedef struct XLogCtlData
612612

613613
/*
614614
* During recovery, we keep a copy of the latest checkpoint record here.
615-
* Used by the background writer when it wants to create a restartpoint.
615+
* lastCheckPointRecPtr points to start of checkpoint record and
616+
* lastCheckPointEndPtr points to end+1 of checkpoint record. Used by the
617+
* background writer when it wants to create a restartpoint.
616618
*
617619
* Protected by info_lck.
618620
*/
619621
XLogRecPtr lastCheckPointRecPtr;
622+
XLogRecPtr lastCheckPointEndPtr;
620623
CheckPoint lastCheckPoint;
621624

622625
/*
@@ -8703,6 +8706,7 @@ RecoveryRestartPoint(const CheckPoint *checkPoint)
87038706
*/
87048707
SpinLockAcquire(&XLogCtl->info_lck);
87058708
XLogCtl->lastCheckPointRecPtr = ReadRecPtr;
8709+
XLogCtl->lastCheckPointEndPtr = EndRecPtr;
87068710
XLogCtl->lastCheckPoint = *checkPoint;
87078711
SpinLockRelease(&XLogCtl->info_lck);
87088712
}
@@ -8722,6 +8726,7 @@ bool
87228726
CreateRestartPoint(int flags)
87238727
{
87248728
XLogRecPtr lastCheckPointRecPtr;
8729+
XLogRecPtr lastCheckPointEndPtr;
87258730
CheckPoint lastCheckPoint;
87268731
XLogRecPtr PriorRedoPtr;
87278732
TimestampTz xtime;
@@ -8735,6 +8740,7 @@ CreateRestartPoint(int flags)
87358740
/* Get a local copy of the last safe checkpoint record. */
87368741
SpinLockAcquire(&XLogCtl->info_lck);
87378742
lastCheckPointRecPtr = XLogCtl->lastCheckPointRecPtr;
8743+
lastCheckPointEndPtr = XLogCtl->lastCheckPointEndPtr;
87388744
lastCheckPoint = XLogCtl->lastCheckPoint;
87398745
SpinLockRelease(&XLogCtl->info_lck);
87408746

@@ -8838,6 +8844,27 @@ CreateRestartPoint(int flags)
88388844
ControlFile->checkPoint = lastCheckPointRecPtr;
88398845
ControlFile->checkPointCopy = lastCheckPoint;
88408846
ControlFile->time = (pg_time_t) time(NULL);
8847+
8848+
/*
8849+
* Ensure minRecoveryPoint is past the checkpoint record. Normally,
8850+
* this will have happened already while writing out dirty buffers,
8851+
* but not necessarily - e.g. because no buffers were dirtied. We do
8852+
* this because a non-exclusive base backup uses minRecoveryPoint to
8853+
* determine which WAL files must be included in the backup, and the
8854+
* file (or files) containing the checkpoint record must be included,
8855+
* at a minimum. Note that for an ordinary restart of recovery there's
8856+
* no value in having the minimum recovery point any earlier than this
8857+
* anyway, because redo will begin just after the checkpoint record.
8858+
*/
8859+
if (ControlFile->minRecoveryPoint < lastCheckPointEndPtr)
8860+
{
8861+
ControlFile->minRecoveryPoint = lastCheckPointEndPtr;
8862+
ControlFile->minRecoveryPointTLI = lastCheckPoint.ThisTimeLineID;
8863+
8864+
/* update local copy */
8865+
minRecoveryPoint = ControlFile->minRecoveryPoint;
8866+
minRecoveryPointTLI = ControlFile->minRecoveryPointTLI;
8867+
}
88418868
if (flags & CHECKPOINT_IS_SHUTDOWN)
88428869
ControlFile->state = DB_SHUTDOWNED_IN_RECOVERY;
88438870
UpdateControlFile();

0 commit comments

Comments
 (0)