{"Entry":{"collection":"plan","key":"merge-append","name":"Merge Append","aliases":["Merge Append","MergeAppend","T_MergeAppend"],"metadata":{"aliases":["Merge Append","MergeAppend","T_MergeAppend"],"category":"Combination","content_hash":"da20a53f434828ff7d07c8f5cabfffdfc7c34de544ea2aea19d6d6445278525a","imported_at":"2026-09-30T00:40:44.047171+08:00","name":"Merge Append","name_zh":"MergeAppend","slug":"merge-append","summary":"Merges sorted child streams while preserving the required ordering."}},"Definition":{"Collection":"plan","Key":"merge-append","SourceDatabase":"center","Version":"18","SourceTable":"plan_node","SourceKey":"merge-append","SourceRevision":"555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f","Facts":{"comparison_data":{"initializer":"ExecInitMergeAppend","memory_mechanism":"unclassified","node_tag":"T_MergeAppend","parallel_callbacks":[],"partial_modes":[],"strategies":[],"text_names":["Merge Append"]},"comparison_hash":"5428ffe21c76597da696d12a775fd915b1be22e9ba2d2d5ba3d84704f51ff3d9","description":["Merges sorted child streams while preserving the required ordering."],"evidence_kind":"source and documentation","explain_names":["Merge Append"],"explain_prefixes":["Parallel","Async"],"facts":[{"label":"Core node tag","value":"T_MergeAppend"},{"label":"Structured EXPLAIN Node Type","value":"Merge Append"},{"label":"Inputs","value":"Multiple sorted child plans"},{"label":"Output","value":"Merged ordered tuples"},{"label":"Executor initializer","value":"ExecInitMergeAppend"},{"label":"Memory mechanism","value":"unclassified"}],"memory":{"description":"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.","evidence":[{"archive_sha256":"555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f","label":"src/backend/executor/nodeMergeAppend.c","path":"src/backend/executor/nodeMergeAppend.c","sha256":"1b2b532b2b964d9312554f28334c603928340a89599d23860209acf9105a06df","url":"https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2"}],"mechanism":"unclassified","source_notes":[]},"node_tag":"T_MergeAppend","parallel_callbacks":[],"partial_modes":[],"related":[{"label":"EXPLAIN","url":"/wiki/sql/explain/?v=18"},{"label":"Using EXPLAIN","url":"/docs/18/using-explain.html"},{"label":"Parallel plans","url":"/docs/18/parallel-plans.html"}],"release":{"channel":"stable","label":"18.6","major":"18","ref":"PostgreSQL 18.6 source archive","revision":"555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f","source_snapshot_utc":"","source_url":"https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2"},"runtime_verified":false,"sections":[{"paragraphs":["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: Merge Append.","Parallel-aware and parallel-safe are different plan properties. A node running inside a parallel worker is not necessarily a parallel-aware node."],"title":"EXPLAIN names and attributes"},{"paragraphs":["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."],"title":"Memory and temporary storage"},{"paragraphs":["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: none extracted from this node implementation."],"title":"Parallel execution and instrumentation"},{"paragraphs":["NOTES A MergeAppend node contains a list of one or more subplans. These are each expected to deliver tuples that are sorted according to a common sort key. The MergeAppend node merges these streams to produce output sorted the same way.","MergeAppend nodes don't make use of their left and right subtrees, rather they maintain a list of subplans so a typical MergeAppend node looks like this in the plan tree:","... / MergeAppend---+------+------+--- nil / \\ | | | nil nil ... ... ... subplans","We have one slot for each item in the heap array. We use SlotNumber to store slot indexes. This doesn't actually provide any formal type-safety, but it makes the code more self-documenting.","If run-time partition pruning is enabled, then set that up now"],"title":"Executor implementation notes"},{"code":"case T_MergeAppend:\n\t\t\tpname = sname = \"Merge Append\";\n\t\t\tbreak;","title":"EXPLAIN identity in core source"}],"source_inventory":{"executor":"src/backend/executor/execProcnode.c","explain":"src/backend/commands/explain.c","implementation":"src/backend/executor/nodeMergeAppend.c"},"sources":[{"archive_sha256":"555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f","label":"src/backend/commands/explain.c:1409","line":1409,"path":"src/backend/commands/explain.c","sha256":"34c86d6070224a0e981efef51f79101d6d505e5874f1684ace183034bab14bb4","url":"https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2"},{"archive_sha256":"555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f","label":"src/backend/executor/execProcnode.c:186","line":186,"path":"src/backend/executor/execProcnode.c","sha256":"f8a06a3f539077249b20664b2812433db6d7bd12b2c0ca633525db43d06f112a","url":"https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2"},{"archive_sha256":"555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f","label":"src/backend/executor/nodeMergeAppend.c","path":"src/backend/executor/nodeMergeAppend.c","sha256":"1b2b532b2b964d9312554f28334c603928340a89599d23860209acf9105a06df","url":"https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2"},{"archive_sha256":"555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f","label":"src/include/nodes/plannodes.h","path":"src/include/nodes/plannodes.h","sha256":"52422b327a8049fbbb20d8b96008a0fc0a6fafa60f7eff3c695d5b2e83830120","url":"https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2"}],"strategies":[],"tables":[{"columns":[{"key":"label","label":"Text-format label"},{"key":"identity","label":"Structured node identity"}],"key":"explain-labels","rows":[{"identity":"Merge Append","label":"Merge Append"}],"title":"EXPLAIN labels in this source build"}]},"ManualEvidence":{"release":{"channel":"stable","label":"18.6","major":"18","ref":"PostgreSQL 18.6 source archive","revision":"555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f","source_snapshot_utc":"","source_url":"https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2"},"sources":[{"archive_sha256":"555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f","label":"src/backend/commands/explain.c:1409","line":1409,"path":"src/backend/commands/explain.c","sha256":"34c86d6070224a0e981efef51f79101d6d505e5874f1684ace183034bab14bb4","url":"https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2"},{"archive_sha256":"555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f","label":"src/backend/executor/execProcnode.c:186","line":186,"path":"src/backend/executor/execProcnode.c","sha256":"f8a06a3f539077249b20664b2812433db6d7bd12b2c0ca633525db43d06f112a","url":"https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2"},{"archive_sha256":"555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f","label":"src/backend/executor/nodeMergeAppend.c","path":"src/backend/executor/nodeMergeAppend.c","sha256":"1b2b532b2b964d9312554f28334c603928340a89599d23860209acf9105a06df","url":"https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2"},{"archive_sha256":"555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f","label":"src/include/nodes/plannodes.h","path":"src/include/nodes/plannodes.h","sha256":"52422b327a8049fbbb20d8b96008a0fc0a6fafa60f7eff3c695d5b2e83830120","url":"https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2"}]},"MeasuredEvidence":{"runtime_verified":false}},"Text":{"Collection":"plan","Key":"merge-append","SourceDatabase":"center","Version":"18","Locale":"en","Title":"Merge Append","Summary":"Merges sorted child streams while preserving the required ordering.","BodyHTML":"\u003cp\u003eMerges sorted child streams while preserving the required ordering.\u003c/p\u003e","SourceRevision":"555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f","ContentHash":"b7a85f414cd5663908f781bc0c02a29c03b28a06d2e348a0625e877cdf36243d","Payload":{"description":["Merges sorted child streams while preserving the required ordering."],"related":[{"label":"EXPLAIN","url":"/wiki/sql/explain/?v=18"},{"label":"Using EXPLAIN","url":"/docs/18/using-explain.html"},{"label":"Parallel plans","url":"/docs/18/parallel-plans.html"}],"sections":[{"paragraphs":["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: Merge Append.","Parallel-aware and parallel-safe are different plan properties. A node running inside a parallel worker is not necessarily a parallel-aware node."],"title":"EXPLAIN names and attributes"},{"paragraphs":["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."],"title":"Memory and temporary storage"},{"paragraphs":["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: none extracted from this node implementation."],"title":"Parallel execution and instrumentation"},{"paragraphs":["NOTES A MergeAppend node contains a list of one or more subplans. These are each expected to deliver tuples that are sorted according to a common sort key. The MergeAppend node merges these streams to produce output sorted the same way.","MergeAppend nodes don't make use of their left and right subtrees, rather they maintain a list of subplans so a typical MergeAppend node looks like this in the plan tree:","... / MergeAppend---+------+------+--- nil / \\ | | | nil nil ... ... ... subplans","We have one slot for each item in the heap array. We use SlotNumber to store slot indexes. This doesn't actually provide any formal type-safety, but it makes the code more self-documenting.","If run-time partition pruning is enabled, then set that up now"],"title":"Executor implementation notes"},{"code":"case T_MergeAppend:\n\t\t\tpname = sname = \"Merge Append\";\n\t\t\tbreak;","title":"EXPLAIN identity in core source"}],"tables":[{"columns":[{"key":"label","label":"Text-format label"},{"key":"identity","label":"Structured node identity"}],"key":"explain-labels","rows":[{"identity":"Merge Append","label":"Merge Append"}],"title":"EXPLAIN labels in this source build"}]}},"RequestedLocale":"zh-Hans","Fallback":true,"Versions":["10","11","12","13","14","15","16","17","18","19","20"],"Locales":["en"],"Signatures":null,"Spellings":null,"SQLState":null,"Evidence":null}
