↑↓ select ↵ open ⌫ change scope Open full search

PG.CENTER connects PostgreSQL documentation, reference, and ecosystem knowledge. Maintained by Pigsty.

Wiki / Plan Nodes / Combination

Append

Append

Visits its child plans and combines their rows.

Reading PostgreSQL 18.6.

Description

Visits its child plans and combines their rows.

Core node tag
T_Append
Structured EXPLAIN Node Type
Append
Inputs
Multiple child plans
Output
Combined tuples
Executor initializer
ExecInitAppend
Memory mechanism
unclassified

EXPLAIN names and attributes

Structured formats use the Node Type above. Text-format spellings can also include operation, strategy, join type, scan direction or aggregation-stage attributes.

Text names recorded by this source: Append.

Parallel-aware and parallel-safe are different plan properties. A node running inside a parallel worker is not necessarily a parallel-aware node.

Memory and temporary storage

This extraction does not assign a universal memory limit or spill policy to this node. Inspect the same-build implementation and its expressions or provider.

Parallel execution and instrumentation

The source callbacks below can coordinate execution or collect worker instrumentation. Their presence is not a blanket claim that this node supports a shared parallel scan or shared state.

Callbacks in this build: ExecAppendEstimate, ExecAppendInitializeDSM, ExecAppendInitializeWorker, ExecAppendReInitializeDSM.

Same-version manual discussion

Normally, EXPLAIN will display every plan node created by the planner. However, there are cases where the executor can determine that certain nodes need not be executed because they cannot produce any rows, based on parameter values that were not available at planning time. (Currently this can only happen for child nodes of an Append or MergeAppend node that is scanning a partitioned table.) When this happens, those plan nodes are omitted from the EXPLAIN output and a Subplans Removed: N annotation appears instead.

Whenever PostgreSQL needs to combine rows from multiple sources into a single result set, it uses an Append or MergeAppend plan node. This commonly happens when implementing UNION ALL or when scanning a partitioned table. Such nodes can be used in parallel plans just as they can in any other plan. However, in a parallel plan, the planner may instead use a Parallel Append node.

When an Append node is used in a parallel plan, each process will execute the child plans in the order in which they appear, so that all participating processes cooperate to execute the first child plan until it is complete and then move to the second plan at around the same time. When a Parallel Append is used instead, the executor will instead spread out the participating processes as evenly as possible across its child plans, so that multiple child plans are executed simultaneously. This avoids contention, and also avoids paying the startup cost of a child plan in those processes that never execute it.

Also, unlike a regular Append node, which can only have partial children when used within a parallel plan, a Parallel Append node can have both partial and non-partial child plans. Non-partial children will be scanned by only a single process, since scanning them more than once would produce duplicate results. Plans that involve appending multiple result sets can therefore achieve coarse-grained parallelism even when efficient partial plans are not available. For example, consider a query against a partitioned table that can only be implemented efficiently by using an index that does not support parallel scans. The planner might choose a Parallel Append of regular Index Scan plans; each individual index scan would have to be executed to completion by a single process, but different scans could be performed at the same time by different processes.

Examples from this manual build

Example copied from the PostgreSQL 18.6 manual; it was not executed for this collection.

When an UPDATE , DELETE , or MERGE command affects a partitioned table or inheritance hierarchy, the output might look like this:

EXPLAIN UPDATE gtest_parent SET f1 = CURRENT_DATE WHERE f2 = 101;

                                       QUERY PLAN
----------------------------------------------------------------------------------------
 Update on gtest_parent  (cost=0.00..3.06 rows=0 width=0)
   Update on gtest_child gtest_parent_1
   Update on gtest_child2 gtest_parent_2
   Update on gtest_child3 gtest_parent_3
   ->  Append  (cost=0.00..3.06 rows=3 width=14)
         ->  Seq Scan on gtest_child gtest_parent_1  (cost=0.00..1.01 rows=1 width=14)
               Filter: (f2 = 101)
         ->  Seq Scan on gtest_child2 gtest_parent_2  (cost=0.00..1.01 rows=1 width=14)
               Filter: (f2 = 101)
         ->  Seq Scan on gtest_child3 gtest_parent_3  (cost=0.00..1.01 rows=1 width=14)
               Filter: (f2 = 101)

Executor implementation notes

NOTES Each append node contains a list of one or more subplans which must be iteratively processed (forwards or backwards). Tuples are retrieved by executing the 'whichplan'th subplan until the subplan stops returning tuples, at which point that plan is shut down and the next started up.

Append nodes don't make use of their left and right subtrees, rather they maintain a list of subplans so a typical append node looks like this in the plan tree:

... / Append -------+------+------+--- nil / \ | | | nil nil ... ... ... subplans

Append nodes are currently used for unions, and to support inheritance queries, where several relations need to be scanned. For example, in our standard person/student/employee/student-emp example, where student and employee inherit from person and student-emp inherits from student and employee, the query:

| Append -------+-------+--------+--------+ / \ | | | | nil nil Scan Scan Scan Scan | | | | person employee student student-emp

EXPLAIN identity in core source

case T_Append:
			pname = sname = "Append";
			break;

EXPLAIN labels in this source build

Text-format labelStructured node identity
AppendAppend

Related entries

Documentation and source

Source build
Version
18.6
Build
PostgreSQL 18.6 source archive
Source fingerprint
555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f

Compare versions

PostgreSQL 10 → 11: changed.

--- PostgreSQL 10
+++ PostgreSQL 11
@@ -2,7 +2,12 @@
   "initializer": "ExecInitAppend",
   "memory_mechanism": "unclassified",
   "node_tag": "T_Append",
-  "parallel_callbacks": [],
+  "parallel_callbacks": [
+    "ExecAppendEstimate",
+    "ExecAppendInitializeDSM",
+    "ExecAppendInitializeWorker",
+    "ExecAppendReInitializeDSM"
+  ],
   "partial_modes": [],
   "strategies": [],
   "text_names": [

Compares recorded interfaces and attributes. Source fingerprints and build metadata are excluded; an absent sample is not proof of the introduction or removal release.

Related entries

Export JSON · Back to Plan Nodes · Recorded in PostgreSQL 10 through 20; the first sample is not necessarily its introduction.