{"kind": "plan", "major": "18", "item": {"slug": "windowagg", "name": "WindowAgg", "name_zh": "WindowAgg", "category": "\u805a\u5408", "summary": "\u5728\u5b50\u8ba1\u5212\u8f93\u51fa\u7684\u6709\u5e8f\u5206\u533a\u4e0a\u8ba1\u7b97\u7a97\u53e3\u51fd\u6570\u3002", "aliases": ["T_WindowAgg", "WindowAgg"], "content_hash": "7d7f87959d099cc640d19b08aa5c1c68f952e072c640f03947a586a07493cf03", "versions": {"10": {"facts": [{"label": "\u6838\u5fc3\u8282\u70b9\u6807\u7b7e", "value": "T_WindowAgg"}, {"label": "\u7ed3\u6784\u5316 EXPLAIN \u8282\u70b9\u7c7b\u578b", "value": "WindowAgg"}, {"label": "\u8f93\u5165", "value": "\u4e00\u4e2a\u6ee1\u8db3\u6392\u5e8f\u8981\u6c42\u7684\u5b50\u8ba1\u5212"}, {"label": "\u8f93\u51fa", "value": "\u5e26\u7a97\u53e3\u51fd\u6570\u7ed3\u679c\u7684\u5143\u7ec4"}, {"label": "\u6267\u884c\u5668\u521d\u59cb\u5316\u51fd\u6570", "value": "ExecInitWindowAgg"}, {"label": "\u5185\u5b58\u673a\u5236", "value": "tuplestore"}], "memory": {"evidence": [{"url": "https://ftp.postgresql.org/pub/source/v10.23/postgresql-10.23.tar.bz2", "path": "src/backend/executor/nodeWindowAgg.c", "label": "src/backend/executor/nodeWindowAgg.c", "sha256": "bf6cd43b1195757bb6d39b922b7b4e5f6b0fb682a5f19c17260cc8413ed9e033", "archive_sha256": "94a4b2528372458e5662c18d406629266667c437198160a18cdfd2c4a4d6eee9"}, {"url": "https://ftp.postgresql.org/pub/source/v10.23/postgresql-10.23.tar.bz2", "path": "src/backend/utils/sort/tuplestore.c", "label": "src/backend/utils/sort/tuplestore.c", "sha256": "dcf45a15db0b6fce8d77783138557f9fcb956b5c45dceac9ec734c2990f8cb97", "archive_sha256": "94a4b2528372458e5662c18d406629266667c437198160a18cdfd2c4a4d6eee9"}], "mechanism": "tuplestore", "description": "\u6b64\u8282\u70b9\u4f7f\u7528 work_mem \u521b\u5efa tuplestore\u3002tuplestore \u53ef\u4ee5\u5c06\u5b58\u50a8\u7684\u5143\u7ec4\u79fb\u5230\u4e34\u65f6\u6587\u4ef6\uff0c\u4f46\u8fd9\u4e0d\u610f\u5473\u7740 work_mem \u9650\u5236\u4e86\u8282\u70b9\u7684\u5168\u90e8\u5185\u5b58\u5206\u914d\u3002", "source_notes": ["If the tuplestore has spilled to disk, alternate reading and writing becomes quite expensive due to frequent buffer flushes. It's cheaper to force the entire partition to get spooled in one go.", "Read the current row from the tuplestore, and save in ScanTupleSlot. (We can't rely on the outerplan's output slot because we may have to read beyond the current row. Also, we have to actually copy the row out of the tuplestore, since window function evaluation might cause the tuplestore to dump its state to disk.)", "Window functions do not have to call this, but are encouraged to move the mark forward when possible to keep the tuplestore size down and prevent having to spill rows to disk."]}, "tables": [{"key": "explain-labels", "rows": [{"label": "WindowAgg", "identity": "WindowAgg"}], "title": "\u672c\u6784\u5efa\u4e2d\u7684 EXPLAIN \u6807\u7b7e", "columns": [{"key": "label", "label": "\u6587\u672c\u683c\u5f0f\u6807\u7b7e"}, {"key": "identity", "label": "\u7ed3\u6784\u5316\u8282\u70b9\u6807\u8bc6"}]}], "related": [{"url": "/wiki/sql/explain/?v=10", "label": "EXPLAIN"}, {"url": "/docs/10/using-explain.html", "label": "\u4f7f\u7528 EXPLAIN"}, {"url": "/docs/10/parallel-plans.html", "label": "\u5e76\u884c\u8ba1\u5212"}, {"url": "/wiki/guc/work_mem/?v=10", "label": "work_mem"}], "release": {"ref": "PostgreSQL 10.23 source archive", "label": "10.23", "major": "10", "channel": "historical", "revision": "94a4b2528372458e5662c18d406629266667c437198160a18cdfd2c4a4d6eee9", "source_url": "https://ftp.postgresql.org/pub/source/v10.23/postgresql-10.23.tar.bz2", "source_snapshot_utc": ""}, "sources": [{"url": "https://ftp.postgresql.org/pub/source/v10.23/postgresql-10.23.tar.bz2", "line": 1065, "path": "src/backend/commands/explain.c", "label": "src/backend/commands/explain.c:1065", "sha256": "a785298532047cfeda969e78c3597a343dc1c56d61ba85830b0f16a02a14b5a1", "archive_sha256": "94a4b2528372458e5662c18d406629266667c437198160a18cdfd2c4a4d6eee9"}, {"url": "https://ftp.postgresql.org/pub/source/v10.23/postgresql-10.23.tar.bz2", "line": 328, "path": "src/backend/executor/execProcnode.c", "label": "src/backend/executor/execProcnode.c:328", "sha256": "cea76648bb38ae55f18f989768bee1a4ee025691ceea0f86bccb29dcdc166acc", "archive_sha256": "94a4b2528372458e5662c18d406629266667c437198160a18cdfd2c4a4d6eee9"}, {"url": "https://ftp.postgresql.org/pub/source/v10.23/postgresql-10.23.tar.bz2", "path": "src/backend/executor/nodeWindowAgg.c", "label": "src/backend/executor/nodeWindowAgg.c", "sha256": "bf6cd43b1195757bb6d39b922b7b4e5f6b0fb682a5f19c17260cc8413ed9e033", "archive_sha256": "94a4b2528372458e5662c18d406629266667c437198160a18cdfd2c4a4d6eee9"}, {"url": "https://ftp.postgresql.org/pub/source/v10.23/postgresql-10.23.tar.bz2", "path": "src/include/nodes/plannodes.h", "label": "src/include/nodes/plannodes.h", "sha256": "d562c321108844798cd234303fffb618f13d4ee3f3a5ac79bfd963b077e47c22", "archive_sha256": "94a4b2528372458e5662c18d406629266667c437198160a18cdfd2c4a4d6eee9"}, {"url": "https://ftp.postgresql.org/pub/source/v10.23/postgresql-10.23.tar.bz2", "path": "src/backend/utils/sort/tuplestore.c", "label": "src/backend/utils/sort/tuplestore.c", "sha256": "dcf45a15db0b6fce8d77783138557f9fcb956b5c45dceac9ec734c2990f8cb97", "archive_sha256": "94a4b2528372458e5662c18d406629266667c437198160a18cdfd2c4a4d6eee9"}], "node_tag": "T_WindowAgg", "sections": [{"title": "EXPLAIN \u540d\u79f0\u4e0e\u5c5e\u6027", "paragraphs": ["\u7ed3\u6784\u5316\u683c\u5f0f\u4f7f\u7528\u4e0a\u8ff0 Node Type\u3002\u6587\u672c\u683c\u5f0f\u540d\u79f0\u8fd8\u53ef\u80fd\u5305\u542b\u64cd\u4f5c\u3001\u7b56\u7565\u3001\u8fde\u63a5\u7c7b\u578b\u3001\u626b\u63cf\u65b9\u5411\u6216\u805a\u5408\u9636\u6bb5\u5c5e\u6027\u3002", "\u6b64\u6e90\u7801\u8bb0\u5f55\u7684\u6587\u672c\u540d\u79f0\uff1aWindowAgg.", "\u5e76\u884c\u611f\u77e5\u4e0e\u5e76\u884c\u5b89\u5168\u662f\u4e0d\u540c\u7684\u8ba1\u5212\u5c5e\u6027\u3002\u5728\u5e76\u884c\u5de5\u4f5c\u8fdb\u7a0b\u5185\u8fd0\u884c\u7684\u8282\u70b9\u4e0d\u4e00\u5b9a\u662f\u5e76\u884c\u611f\u77e5\u8282\u70b9\u3002"]}, {"title": "\u5185\u5b58\u4e0e\u4e34\u65f6\u5b58\u50a8", "paragraphs": ["\u6b64\u8282\u70b9\u4f7f\u7528 work_mem \u521b\u5efa tuplestore\u3002tuplestore \u53ef\u4ee5\u5c06\u5b58\u50a8\u7684\u5143\u7ec4\u79fb\u5230\u4e34\u65f6\u6587\u4ef6\uff0c\u4f46\u8fd9\u4e0d\u610f\u5473\u7740 work_mem \u9650\u5236\u4e86\u8282\u70b9\u7684\u5168\u90e8\u5185\u5b58\u5206\u914d\u3002", "tuplestore \u5df2\u843d\u76d8\u65f6\uff0c\u4ea4\u66ff\u8bfb\u5199\u4f1a\u9891\u7e41\u5237\u65b0\u7f13\u51b2\u533a\uff0c\u4ee3\u4ef7\u5f88\u9ad8\u3002\u4e00\u6b21\u6027\u5c06\u6574\u4e2a\u5206\u533a\u5b58\u5165\u4e34\u65f6\u5b58\u50a8\u4f1a\u66f4\u4fbf\u5b9c\u3002", "\u4ece tuplestore \u8bfb\u53d6\u5f53\u524d\u884c\u5e76\u4fdd\u5b58\u5230 ScanTupleSlot\u3002\u4e0d\u80fd\u4f9d\u8d56\u5916\u5c42\u8ba1\u5212\u7684\u8f93\u51fa\u69fd\uff0c\u56e0\u4e3a\u53ef\u80fd\u9700\u8981\u8bfb\u53d6\u5f53\u524d\u884c\u4e4b\u540e\u7684\u6570\u636e\u3002\u6b64\u5916\uff0c\u5fc5\u987b\u5c06\u884c\u5b9e\u9645\u590d\u5236\u51fa tuplestore\uff0c\u56e0\u4e3a\u7a97\u53e3\u51fd\u6570\u6c42\u503c\u53ef\u80fd\u4f7f tuplestore \u5c06\u5176\u72b6\u6001\u5199\u5165\u78c1\u76d8\u3002", "\u7a97\u53e3\u51fd\u6570\u5e76\u975e\u5fc5\u987b\u8c03\u7528\u6b64\u51fd\u6570\uff0c\u4f46\u5efa\u8bae\u5728\u53ef\u80fd\u65f6\u524d\u79fb\u6807\u8bb0\uff0c\u4ee5\u51cf\u5c0f tuplestore \u5927\u5c0f\u5e76\u907f\u514d\u5c06\u884c\u5199\u5165\u78c1\u76d8\u3002"]}, {"title": "\u5e76\u884c\u6267\u884c\u4e0e\u8fd0\u884c\u4fe1\u606f\u91c7\u96c6", "paragraphs": ["\u4ee5\u4e0b\u6e90\u7801\u56de\u8c03\u53ef\u4ee5\u534f\u8c03\u6267\u884c\u6216\u6536\u96c6\u5de5\u4f5c\u8fdb\u7a0b\u7684\u6d4b\u91cf\u6570\u636e\u3002\u56de\u8c03\u5b58\u5728\u4e0d\u4ee3\u8868\u8be5\u8282\u70b9\u666e\u904d\u652f\u6301\u5171\u4eab\u5e76\u884c\u626b\u63cf\u6216\u5171\u4eab\u72b6\u6001\u3002", "\u6b64\u6784\u5efa\u7684\u56de\u8c03\uff1anone extracted from this node implementation."]}, {"title": "\u6267\u884c\u5668\u5b9e\u73b0\u8bf4\u660e", "paragraphs": ["WindowAgg \u8282\u70b9\u5728\u8f93\u5165\u5143\u7ec4\u96c6\u5408\u7684\u9002\u5f53\u5206\u533a\u4e0a\u8ba1\u7b97\u201c\u7a97\u53e3\u51fd\u6570\u201d\u3002\u6bcf\u4e2a WindowAgg \u53ea\u5904\u7406\u4e00\u79cd\u7a97\u53e3\u5b9a\u4e49\uff0c\u4f46\u53ef\u4ee5\u8ba1\u7b97\u5171\u4eab\u76f8\u540c\u7a97\u53e3\u5b9a\u4e49\u7684\u591a\u4e2a\u7a97\u53e3\u51fd\u6570\u3002\u8f93\u5165\u5143\u7ec4\u5fc5\u987b\u6309\u6392\u5e8f\u987a\u5e8f\u9001\u8fbe\uff1aPARTITION BY \u5217\uff08\u5982\u679c\u6709\uff09\u4e3a\u4e3b\u8981\u6392\u5e8f\u952e\uff0cORDER BY \u5217\uff08\u5982\u679c\u6709\uff09\u4e3a\u6b21\u8981\u6392\u5e8f\u952e\u3002\uff08\u5982\u679c\u67e5\u8be2\u5305\u542b\u591a\u79cd\u7a97\u53e3\u5b9a\u4e49\uff0c\u89c4\u5212\u5668\u4f1a\u6309\u9700\u751f\u6210\u591a\u4e2a\u5806\u53e0\u7684 WindowAgg\uff0c\u5e76\u5728\u5176\u95f4\u63d2\u5165 Sort \u8282\u70b9\u3002\uff09", "\u7a97\u53e3\u51fd\u6570\u53ef\u80fd\u9700\u8981\u8bbf\u95ee\u5f53\u524d\u5206\u533a\u7684\u4efb\u610f\u884c\u4e43\u81f3\u5168\u90e8\u884c\uff0c\u56e0\u6b64\u5c06\u5206\u533a\u884c\u7d2f\u79ef\u5230\u5143\u7ec4\u5b58\u50a8\u3002\u901a\u8fc7 WindowObject API \u8c03\u7528\u7a97\u53e3\u51fd\u6570\uff0c\u4f7f\u5176\u6309\u9700\u8bbf\u95ee\u8fd9\u4e9b\u884c\u3002", "\u4e5f\u652f\u6301\u5c06\u666e\u901a\u805a\u5408\u51fd\u6570\u7528\u4f5c\u7a97\u53e3\u51fd\u6570\u3002\u6b64\u65f6\u4e3a\u6bcf\u4e2a\u5206\u533a\u6a21\u62df\u5e38\u89c4 Agg \u8282\u70b9\u73af\u5883\u3002\u6309 SQL \u89c4\u8303\uff0c\u8f93\u51fa\u4e3a\u8be5\u805a\u5408\u51fd\u6570\u5728\u5f53\u524d\u884c\u7a97\u53e3\u6846\u67b6\u5185\u5168\u90e8\u884c\u4e0a\u7684\u7ed3\u679c\u3002", "\u6240\u6709\u7a97\u53e3\u51fd\u6570 API \u90fd\u4f7f\u7528\u6b64\u5bf9\u8c61\u8c03\u7528\uff1b\u6b64\u5bf9\u8c61\u901a\u8fc7 fcinfo->context \u4f20\u7ed9\u7a97\u53e3\u51fd\u6570\u3002", "\u6b64\u8282\u70b9\u5904\u7406\u7684\u6bcf\u4e2a\u7a97\u53e3\u51fd\u6570\u548c\u7a97\u53e3\u805a\u5408\u90fd\u5bf9\u5e94\u4e00\u4e2a WindowStatePerFunc \u7ed3\u6784\u3002"]}, {"code": "case T_WindowAgg:\n\t\t\tpname = sname = \"WindowAgg\";\n\t\t\tbreak;", "title": "\u6838\u5fc3\u6e90\u7801\u4e2d\u7684 EXPLAIN \u6807\u8bc6"}], "strategies": [], "description": ["\u5728\u5b50\u8ba1\u5212\u8f93\u51fa\u7684\u6709\u5e8f\u5206\u533a\u4e0a\u8ba1\u7b97\u7a97\u53e3\u51fd\u6570\u3002"], "localization": {"status": "complete", "sources": [], "language": "zh", "original_text": {"/versions/10/description/0": "Evaluates window functions over ordered partitions of its child output.", "/versions/10/facts/0/label": "Core node tag", "/versions/10/facts/1/label": "Structured EXPLAIN Node Type", "/versions/10/facts/2/label": "Inputs", "/versions/10/facts/2/value": "One suitably ordered child plan", "/versions/10/facts/3/label": "Output", "/versions/10/facts/3/value": "Tuples with window-function results", "/versions/10/facts/4/label": "Executor initializer", "/versions/10/facts/5/label": "Memory mechanism", "/versions/10/tables/0/title": "EXPLAIN labels in this source build", "/versions/10/related/1/label": "Using EXPLAIN", "/versions/10/related/2/label": "Parallel plans", "/versions/10/sections/0/title": "EXPLAIN names and attributes", "/versions/10/sections/1/title": "Memory and temporary storage", "/versions/10/sections/2/title": "Parallel execution and instrumentation", "/versions/10/sections/3/title": "Executor implementation notes", "/versions/10/sections/4/title": "EXPLAIN identity in core source", "/versions/10/memory/description": "This node creates a tuplestore with work_mem. The tuplestore can move stored tuples to temporary files; this does not make work_mem a cap on every allocation made by the node.", "/versions/10/sections/0/paragraphs/0": "Structured formats use the Node Type above. Text-format spellings can also include operation, strategy, join type, scan direction or aggregation-stage attributes.", "/versions/10/sections/0/paragraphs/1": "Text names recorded by this source: WindowAgg.", "/versions/10/sections/0/paragraphs/2": "Parallel-aware and parallel-safe are different plan properties. A node running inside a parallel worker is not necessarily a parallel-aware node.", "/versions/10/sections/1/paragraphs/0": "This node creates a tuplestore with work_mem. The tuplestore can move stored tuples to temporary files; this does not make work_mem a cap on every allocation made by the node.", "/versions/10/sections/1/paragraphs/1": "If the tuplestore has spilled to disk, alternate reading and writing becomes quite expensive due to frequent buffer flushes. It's cheaper to force the entire partition to get spooled in one go.", "/versions/10/sections/1/paragraphs/2": "Read the current row from the tuplestore, and save in ScanTupleSlot. (We can't rely on the outerplan's output slot because we may have to read beyond the current row. Also, we have to actually copy the row out of the tuplestore, since window function evaluation might cause the tuplestore to dump its state to disk.)", "/versions/10/sections/1/paragraphs/3": "Window functions do not have to call this, but are encouraged to move the mark forward when possible to keep the tuplestore size down and prevent having to spill rows to disk.", "/versions/10/sections/2/paragraphs/0": "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.", "/versions/10/sections/2/paragraphs/1": "Callbacks in this build: none extracted from this node implementation.", "/versions/10/sections/3/paragraphs/0": "A WindowAgg node evaluates \"window functions\" across suitable partitions of the input tuple set. Any one WindowAgg works for just a single window specification, though it can evaluate multiple window functions sharing identical window specifications. The input tuples are required to be delivered in sorted order, with the PARTITION BY columns (if any) as major sort keys and the ORDER BY columns (if any) as minor sort keys. (The planner generates a stack of WindowAggs with intervening Sort nodes as needed, if a query involves more than one window specification.)", "/versions/10/sections/3/paragraphs/1": "Since window functions can require access to any or all of the rows in the current partition, we accumulate rows of the partition into a tuplestore. The window functions are called using the WindowObject API so that they can access those rows as needed.", "/versions/10/sections/3/paragraphs/2": "We also support using plain aggregate functions as window functions. For these, the regular Agg-node environment is emulated for each partition. As required by the SQL spec, the output represents the value of the aggregate function over all rows in the current row's window frame.", "/versions/10/sections/3/paragraphs/3": "All the window function APIs are called with this object, which is passed to window functions as fcinfo->context.", "/versions/10/sections/3/paragraphs/4": "We have one WindowStatePerFunc struct for each window function and window aggregate handled by this node.", "/versions/10/tables/0/columns/0/label": "Text-format label", "/versions/10/tables/0/columns/1/label": "Structured node identity"}, "fallback_fields": [], "source_language": "en", "original_snapshot_sha256": "53ffa2477d7bbab0f8d7a26aa14c15c0892e0138cf6985c090b0d11840987ee3"}, "evidence_kind": "source and documentation", "explain_names": ["WindowAgg"], "partial_modes": [], "comparison_data": {"node_tag": "T_WindowAgg", "strategies": [], "text_names": ["WindowAgg"], "initializer": "ExecInitWindowAgg", "partial_modes": [], "memory_mechanism": "tuplestore", "parallel_callbacks": []}, "comparison_hash": "186aa5f13e96214f274161ba257307adf452233ebc64c9c0aaebfaee73fac8a4", "explain_prefixes": ["Parallel"], "runtime_verified": false, "source_inventory": {"explain": "src/backend/commands/explain.c", "executor": "src/backend/executor/execProcnode.c", "implementation": "src/backend/executor/nodeWindowAgg.c"}, "parallel_callbacks": []}, "11": {"facts": [{"label": "\u6838\u5fc3\u8282\u70b9\u6807\u7b7e", "value": "T_WindowAgg"}, {"label": "\u7ed3\u6784\u5316 EXPLAIN \u8282\u70b9\u7c7b\u578b", "value": "WindowAgg"}, {"label": "\u8f93\u5165", "value": "\u4e00\u4e2a\u6ee1\u8db3\u6392\u5e8f\u8981\u6c42\u7684\u5b50\u8ba1\u5212"}, {"label": "\u8f93\u51fa", "value": "\u5e26\u7a97\u53e3\u51fd\u6570\u7ed3\u679c\u7684\u5143\u7ec4"}, {"label": "\u6267\u884c\u5668\u521d\u59cb\u5316\u51fd\u6570", "value": "ExecInitWindowAgg"}, {"label": "\u5185\u5b58\u673a\u5236", "value": "tuplestore"}], "memory": {"evidence": [{"url": "https://ftp.postgresql.org/pub/source/v11.22/postgresql-11.22.tar.bz2", "path": "src/backend/executor/nodeWindowAgg.c", "label": "src/backend/executor/nodeWindowAgg.c", "sha256": "b569e9ccfd4410685f86ad101dfce40db4542dacb9bdb8fd3c674585f126d6f3", "archive_sha256": "2cb7c97d7a0d7278851bbc9c61f467b69c094c72b81740b751108e7892ebe1f0"}, {"url": "https://ftp.postgresql.org/pub/source/v11.22/postgresql-11.22.tar.bz2", "path": "src/backend/utils/sort/tuplestore.c", "label": "src/backend/utils/sort/tuplestore.c", "sha256": "2891704a2b38e4f4c52cce4604f1cad8b83781217697c4cddd6d3d99ddc14fce", "archive_sha256": "2cb7c97d7a0d7278851bbc9c61f467b69c094c72b81740b751108e7892ebe1f0"}], "mechanism": "tuplestore", "description": "\u6b64\u8282\u70b9\u4f7f\u7528 work_mem \u521b\u5efa tuplestore\u3002tuplestore \u53ef\u4ee5\u5c06\u5b58\u50a8\u7684\u5143\u7ec4\u79fb\u5230\u4e34\u65f6\u6587\u4ef6\uff0c\u4f46\u8fd9\u4e0d\u610f\u5473\u7740 work_mem \u9650\u5236\u4e86\u8282\u70b9\u7684\u5168\u90e8\u5185\u5b58\u5206\u914d\u3002", "source_notes": ["If the tuplestore has spilled to disk, alternate reading and writing becomes quite expensive due to frequent buffer flushes. It's cheaper to force the entire partition to get spooled in one go.", "Read the current row from the tuplestore, and save in ScanTupleSlot. (We can't rely on the outerplan's output slot because we may have to read beyond the current row. Also, we have to actually copy the row out of the tuplestore, since window function evaluation might cause the tuplestore to dump its state to disk.)", "Window functions do not have to call this, but are encouraged to move the mark forward when possible to keep the tuplestore size down and prevent having to spill rows to disk."]}, "tables": [{"key": "explain-labels", "rows": [{"label": "WindowAgg", "identity": "WindowAgg"}], "title": "\u672c\u6784\u5efa\u4e2d\u7684 EXPLAIN \u6807\u7b7e", "columns": [{"key": "label", "label": "\u6587\u672c\u683c\u5f0f\u6807\u7b7e"}, {"key": "identity", "label": "\u7ed3\u6784\u5316\u8282\u70b9\u6807\u8bc6"}]}], "related": [{"url": "/wiki/sql/explain/?v=11", "label": "EXPLAIN"}, {"url": "/docs/11/using-explain.html", "label": "\u4f7f\u7528 EXPLAIN"}, {"url": "/docs/11/parallel-plans.html", "label": "\u5e76\u884c\u8ba1\u5212"}, {"url": "/wiki/guc/work_mem/?v=11", "label": "work_mem"}], "release": {"ref": "PostgreSQL 11.22 source archive", "label": "11.22", "major": "11", "channel": "historical", "revision": "2cb7c97d7a0d7278851bbc9c61f467b69c094c72b81740b751108e7892ebe1f0", "source_url": "https://ftp.postgresql.org/pub/source/v11.22/postgresql-11.22.tar.bz2", "source_snapshot_utc": ""}, "sources": [{"url": "https://ftp.postgresql.org/pub/source/v11.22/postgresql-11.22.tar.bz2", "line": 1190, "path": "src/backend/commands/explain.c", "label": "src/backend/commands/explain.c:1190", "sha256": "9df8400c1a4377179572ceb916d6020fca4e2760f74bf416d77ed97476523bbd", "archive_sha256": "2cb7c97d7a0d7278851bbc9c61f467b69c094c72b81740b751108e7892ebe1f0"}, {"url": "https://ftp.postgresql.org/pub/source/v11.22/postgresql-11.22.tar.bz2", "line": 328, "path": "src/backend/executor/execProcnode.c", "label": "src/backend/executor/execProcnode.c:328", "sha256": "95ef4d4a5df4c29f14af9763fae2c530449bdacdf3853d9ff297adf1fed6153b", "archive_sha256": "2cb7c97d7a0d7278851bbc9c61f467b69c094c72b81740b751108e7892ebe1f0"}, {"url": "https://ftp.postgresql.org/pub/source/v11.22/postgresql-11.22.tar.bz2", "path": "src/backend/executor/nodeWindowAgg.c", "label": "src/backend/executor/nodeWindowAgg.c", "sha256": "b569e9ccfd4410685f86ad101dfce40db4542dacb9bdb8fd3c674585f126d6f3", "archive_sha256": "2cb7c97d7a0d7278851bbc9c61f467b69c094c72b81740b751108e7892ebe1f0"}, {"url": "https://ftp.postgresql.org/pub/source/v11.22/postgresql-11.22.tar.bz2", "path": "src/include/nodes/plannodes.h", "label": "src/include/nodes/plannodes.h", "sha256": "5e0511194183800e8d6eb293fd4b40639c7d3118e2d199c8e7865ba4fa4cf67f", "archive_sha256": "2cb7c97d7a0d7278851bbc9c61f467b69c094c72b81740b751108e7892ebe1f0"}, {"url": "https://ftp.postgresql.org/pub/source/v11.22/postgresql-11.22.tar.bz2", "path": "src/backend/utils/sort/tuplestore.c", "label": "src/backend/utils/sort/tuplestore.c", "sha256": "2891704a2b38e4f4c52cce4604f1cad8b83781217697c4cddd6d3d99ddc14fce", "archive_sha256": "2cb7c97d7a0d7278851bbc9c61f467b69c094c72b81740b751108e7892ebe1f0"}], "node_tag": "T_WindowAgg", "sections": [{"title": "EXPLAIN \u540d\u79f0\u4e0e\u5c5e\u6027", "paragraphs": ["\u7ed3\u6784\u5316\u683c\u5f0f\u4f7f\u7528\u4e0a\u8ff0 Node Type\u3002\u6587\u672c\u683c\u5f0f\u540d\u79f0\u8fd8\u53ef\u80fd\u5305\u542b\u64cd\u4f5c\u3001\u7b56\u7565\u3001\u8fde\u63a5\u7c7b\u578b\u3001\u626b\u63cf\u65b9\u5411\u6216\u805a\u5408\u9636\u6bb5\u5c5e\u6027\u3002", "\u6b64\u6e90\u7801\u8bb0\u5f55\u7684\u6587\u672c\u540d\u79f0\uff1aWindowAgg.", "\u5e76\u884c\u611f\u77e5\u4e0e\u5e76\u884c\u5b89\u5168\u662f\u4e0d\u540c\u7684\u8ba1\u5212\u5c5e\u6027\u3002\u5728\u5e76\u884c\u5de5\u4f5c\u8fdb\u7a0b\u5185\u8fd0\u884c\u7684\u8282\u70b9\u4e0d\u4e00\u5b9a\u662f\u5e76\u884c\u611f\u77e5\u8282\u70b9\u3002"]}, {"title": "\u5185\u5b58\u4e0e\u4e34\u65f6\u5b58\u50a8", "paragraphs": ["\u6b64\u8282\u70b9\u4f7f\u7528 work_mem \u521b\u5efa tuplestore\u3002tuplestore \u53ef\u4ee5\u5c06\u5b58\u50a8\u7684\u5143\u7ec4\u79fb\u5230\u4e34\u65f6\u6587\u4ef6\uff0c\u4f46\u8fd9\u4e0d\u610f\u5473\u7740 work_mem \u9650\u5236\u4e86\u8282\u70b9\u7684\u5168\u90e8\u5185\u5b58\u5206\u914d\u3002", "tuplestore \u5df2\u843d\u76d8\u65f6\uff0c\u4ea4\u66ff\u8bfb\u5199\u4f1a\u9891\u7e41\u5237\u65b0\u7f13\u51b2\u533a\uff0c\u4ee3\u4ef7\u5f88\u9ad8\u3002\u4e00\u6b21\u6027\u5c06\u6574\u4e2a\u5206\u533a\u5b58\u5165\u4e34\u65f6\u5b58\u50a8\u4f1a\u66f4\u4fbf\u5b9c\u3002", "\u4ece tuplestore \u8bfb\u53d6\u5f53\u524d\u884c\u5e76\u4fdd\u5b58\u5230 ScanTupleSlot\u3002\u4e0d\u80fd\u4f9d\u8d56\u5916\u5c42\u8ba1\u5212\u7684\u8f93\u51fa\u69fd\uff0c\u56e0\u4e3a\u53ef\u80fd\u9700\u8981\u8bfb\u53d6\u5f53\u524d\u884c\u4e4b\u540e\u7684\u6570\u636e\u3002\u6b64\u5916\uff0c\u5fc5\u987b\u5c06\u884c\u5b9e\u9645\u590d\u5236\u51fa tuplestore\uff0c\u56e0\u4e3a\u7a97\u53e3\u51fd\u6570\u6c42\u503c\u53ef\u80fd\u4f7f tuplestore \u5c06\u5176\u72b6\u6001\u5199\u5165\u78c1\u76d8\u3002", "\u7a97\u53e3\u51fd\u6570\u5e76\u975e\u5fc5\u987b\u8c03\u7528\u6b64\u51fd\u6570\uff0c\u4f46\u5efa\u8bae\u5728\u53ef\u80fd\u65f6\u524d\u79fb\u6807\u8bb0\uff0c\u4ee5\u51cf\u5c0f tuplestore \u5927\u5c0f\u5e76\u907f\u514d\u5c06\u884c\u5199\u5165\u78c1\u76d8\u3002"]}, {"title": "\u5e76\u884c\u6267\u884c\u4e0e\u8fd0\u884c\u4fe1\u606f\u91c7\u96c6", "paragraphs": ["\u4ee5\u4e0b\u6e90\u7801\u56de\u8c03\u53ef\u4ee5\u534f\u8c03\u6267\u884c\u6216\u6536\u96c6\u5de5\u4f5c\u8fdb\u7a0b\u7684\u6d4b\u91cf\u6570\u636e\u3002\u56de\u8c03\u5b58\u5728\u4e0d\u4ee3\u8868\u8be5\u8282\u70b9\u666e\u904d\u652f\u6301\u5171\u4eab\u5e76\u884c\u626b\u63cf\u6216\u5171\u4eab\u72b6\u6001\u3002", "\u6b64\u6784\u5efa\u7684\u56de\u8c03\uff1anone extracted from this node implementation."]}, {"title": "\u6267\u884c\u5668\u5b9e\u73b0\u8bf4\u660e", "paragraphs": ["WindowAgg \u8282\u70b9\u5728\u8f93\u5165\u5143\u7ec4\u96c6\u5408\u7684\u9002\u5f53\u5206\u533a\u4e0a\u8ba1\u7b97\u201c\u7a97\u53e3\u51fd\u6570\u201d\u3002\u6bcf\u4e2a WindowAgg \u53ea\u5904\u7406\u4e00\u79cd\u7a97\u53e3\u5b9a\u4e49\uff0c\u4f46\u53ef\u4ee5\u8ba1\u7b97\u5171\u4eab\u76f8\u540c\u7a97\u53e3\u5b9a\u4e49\u7684\u591a\u4e2a\u7a97\u53e3\u51fd\u6570\u3002\u8f93\u5165\u5143\u7ec4\u5fc5\u987b\u6309\u6392\u5e8f\u987a\u5e8f\u9001\u8fbe\uff1aPARTITION BY \u5217\uff08\u5982\u679c\u6709\uff09\u4e3a\u4e3b\u8981\u6392\u5e8f\u952e\uff0cORDER BY \u5217\uff08\u5982\u679c\u6709\uff09\u4e3a\u6b21\u8981\u6392\u5e8f\u952e\u3002\uff08\u5982\u679c\u67e5\u8be2\u5305\u542b\u591a\u79cd\u7a97\u53e3\u5b9a\u4e49\uff0c\u89c4\u5212\u5668\u4f1a\u6309\u9700\u751f\u6210\u591a\u4e2a\u5806\u53e0\u7684 WindowAgg\uff0c\u5e76\u5728\u5176\u95f4\u63d2\u5165 Sort \u8282\u70b9\u3002\uff09", "\u7a97\u53e3\u51fd\u6570\u53ef\u80fd\u9700\u8981\u8bbf\u95ee\u5f53\u524d\u5206\u533a\u7684\u4efb\u610f\u884c\u4e43\u81f3\u5168\u90e8\u884c\uff0c\u56e0\u6b64\u5c06\u5206\u533a\u884c\u7d2f\u79ef\u5230\u5143\u7ec4\u5b58\u50a8\u3002\u901a\u8fc7 WindowObject API \u8c03\u7528\u7a97\u53e3\u51fd\u6570\uff0c\u4f7f\u5176\u6309\u9700\u8bbf\u95ee\u8fd9\u4e9b\u884c\u3002", "\u4e5f\u652f\u6301\u5c06\u666e\u901a\u805a\u5408\u51fd\u6570\u7528\u4f5c\u7a97\u53e3\u51fd\u6570\u3002\u6b64\u65f6\u4e3a\u6bcf\u4e2a\u5206\u533a\u6a21\u62df\u5e38\u89c4 Agg \u8282\u70b9\u73af\u5883\u3002\u6309 SQL \u89c4\u8303\uff0c\u8f93\u51fa\u4e3a\u8be5\u805a\u5408\u51fd\u6570\u5728\u5f53\u524d\u884c\u7a97\u53e3\u6846\u67b6\u5185\u5168\u90e8\u884c\u4e0a\u7684\u7ed3\u679c\u3002", "\u6240\u6709\u7a97\u53e3\u51fd\u6570 API \u90fd\u4f7f\u7528\u6b64\u5bf9\u8c61\u8c03\u7528\uff1b\u6b64\u5bf9\u8c61\u901a\u8fc7 fcinfo->context \u4f20\u7ed9\u7a97\u53e3\u51fd\u6570\u3002", "\u6b64\u8282\u70b9\u5904\u7406\u7684\u6bcf\u4e2a\u7a97\u53e3\u51fd\u6570\u548c\u7a97\u53e3\u805a\u5408\u90fd\u5bf9\u5e94\u4e00\u4e2a WindowStatePerFunc \u7ed3\u6784\u3002"]}, {"code": "case T_WindowAgg:\n\t\t\tpname = sname = \"WindowAgg\";\n\t\t\tbreak;", "title": "\u6838\u5fc3\u6e90\u7801\u4e2d\u7684 EXPLAIN \u6807\u8bc6"}], "strategies": [], "description": ["\u5728\u5b50\u8ba1\u5212\u8f93\u51fa\u7684\u6709\u5e8f\u5206\u533a\u4e0a\u8ba1\u7b97\u7a97\u53e3\u51fd\u6570\u3002"], "localization": {"status": "complete", "sources": [], "language": "zh", "original_text": {"/versions/11/description/0": "Evaluates window functions over ordered partitions of its child output.", "/versions/11/facts/0/label": "Core node tag", "/versions/11/facts/1/label": "Structured EXPLAIN Node Type", "/versions/11/facts/2/label": "Inputs", "/versions/11/facts/2/value": "One suitably ordered child plan", "/versions/11/facts/3/label": "Output", "/versions/11/facts/3/value": "Tuples with window-function results", "/versions/11/facts/4/label": "Executor initializer", "/versions/11/facts/5/label": "Memory mechanism", "/versions/11/tables/0/title": "EXPLAIN labels in this source build", "/versions/11/related/1/label": "Using EXPLAIN", "/versions/11/related/2/label": "Parallel plans", "/versions/11/sections/0/title": "EXPLAIN names and attributes", "/versions/11/sections/1/title": "Memory and temporary storage", "/versions/11/sections/2/title": "Parallel execution and instrumentation", "/versions/11/sections/3/title": "Executor implementation notes", "/versions/11/sections/4/title": "EXPLAIN identity in core source", "/versions/11/memory/description": "This node creates a tuplestore with work_mem. The tuplestore can move stored tuples to temporary files; this does not make work_mem a cap on every allocation made by the node.", "/versions/11/sections/0/paragraphs/0": "Structured formats use the Node Type above. Text-format spellings can also include operation, strategy, join type, scan direction or aggregation-stage attributes.", "/versions/11/sections/0/paragraphs/1": "Text names recorded by this source: WindowAgg.", "/versions/11/sections/0/paragraphs/2": "Parallel-aware and parallel-safe are different plan properties. A node running inside a parallel worker is not necessarily a parallel-aware node.", "/versions/11/sections/1/paragraphs/0": "This node creates a tuplestore with work_mem. The tuplestore can move stored tuples to temporary files; this does not make work_mem a cap on every allocation made by the node.", "/versions/11/sections/1/paragraphs/1": "If the tuplestore has spilled to disk, alternate reading and writing becomes quite expensive due to frequent buffer flushes. It's cheaper to force the entire partition to get spooled in one go.", "/versions/11/sections/1/paragraphs/2": "Read the current row from the tuplestore, and save in ScanTupleSlot. (We can't rely on the outerplan's output slot because we may have to read beyond the current row. Also, we have to actually copy the row out of the tuplestore, since window function evaluation might cause the tuplestore to dump its state to disk.)", "/versions/11/sections/1/paragraphs/3": "Window functions do not have to call this, but are encouraged to move the mark forward when possible to keep the tuplestore size down and prevent having to spill rows to disk.", "/versions/11/sections/2/paragraphs/0": "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.", "/versions/11/sections/2/paragraphs/1": "Callbacks in this build: none extracted from this node implementation.", "/versions/11/sections/3/paragraphs/0": "A WindowAgg node evaluates \"window functions\" across suitable partitions of the input tuple set. Any one WindowAgg works for just a single window specification, though it can evaluate multiple window functions sharing identical window specifications. The input tuples are required to be delivered in sorted order, with the PARTITION BY columns (if any) as major sort keys and the ORDER BY columns (if any) as minor sort keys. (The planner generates a stack of WindowAggs with intervening Sort nodes as needed, if a query involves more than one window specification.)", "/versions/11/sections/3/paragraphs/1": "Since window functions can require access to any or all of the rows in the current partition, we accumulate rows of the partition into a tuplestore. The window functions are called using the WindowObject API so that they can access those rows as needed.", "/versions/11/sections/3/paragraphs/2": "We also support using plain aggregate functions as window functions. For these, the regular Agg-node environment is emulated for each partition. As required by the SQL spec, the output represents the value of the aggregate function over all rows in the current row's window frame.", "/versions/11/sections/3/paragraphs/3": "All the window function APIs are called with this object, which is passed to window functions as fcinfo->context.", "/versions/11/sections/3/paragraphs/4": "We have one WindowStatePerFunc struct for each window function and window aggregate handled by this node.", "/versions/11/tables/0/columns/0/label": "Text-format label", "/versions/11/tables/0/columns/1/label": "Structured node identity"}, "fallback_fields": [], "source_language": "en", "original_snapshot_sha256": "bbd4b2106b82f546a4ed07baa41ea1072207aadc4ea927fc6a9ecb9541d57236"}, "evidence_kind": "source and documentation", "explain_names": ["WindowAgg"], "partial_modes": [], "comparison_data": {"node_tag": "T_WindowAgg", "strategies": [], "text_names": ["WindowAgg"], "initializer": "ExecInitWindowAgg", "partial_modes": [], "memory_mechanism": "tuplestore", "parallel_callbacks": []}, "comparison_hash": "186aa5f13e96214f274161ba257307adf452233ebc64c9c0aaebfaee73fac8a4", "explain_prefixes": ["Parallel"], "runtime_verified": false, "source_inventory": {"explain": "src/backend/commands/explain.c", "executor": "src/backend/executor/execProcnode.c", "implementation": "src/backend/executor/nodeWindowAgg.c"}, "parallel_callbacks": []}, "12": {"facts": [{"label": "\u6838\u5fc3\u8282\u70b9\u6807\u7b7e", "value": "T_WindowAgg"}, {"label": "\u7ed3\u6784\u5316 EXPLAIN \u8282\u70b9\u7c7b\u578b", "value": "WindowAgg"}, {"label": "\u8f93\u5165", "value": "\u4e00\u4e2a\u6ee1\u8db3\u6392\u5e8f\u8981\u6c42\u7684\u5b50\u8ba1\u5212"}, {"label": "\u8f93\u51fa", "value": "\u5e26\u7a97\u53e3\u51fd\u6570\u7ed3\u679c\u7684\u5143\u7ec4"}, {"label": "\u6267\u884c\u5668\u521d\u59cb\u5316\u51fd\u6570", "value": "ExecInitWindowAgg"}, {"label": "\u5185\u5b58\u673a\u5236", "value": "tuplestore"}], "memory": {"evidence": [{"url": "https://ftp.postgresql.org/pub/source/v12.22/postgresql-12.22.tar.bz2", "path": "src/backend/executor/nodeWindowAgg.c", "label": "src/backend/executor/nodeWindowAgg.c", "sha256": "65d021db964aca5d05a10eebbf2b0010dd783d35214a9f131fe97e8135bd0ed1", "archive_sha256": "8df3c0474782589d3c6f374b5133b1bd14d168086edbc13c6e72e67dd4527a3b"}, {"url": "https://ftp.postgresql.org/pub/source/v12.22/postgresql-12.22.tar.bz2", "path": "src/backend/utils/sort/tuplestore.c", "label": "src/backend/utils/sort/tuplestore.c", "sha256": "44cccd98d659272f5c8f3ff6adffb1f6cc911acd13a3cfafc74cc7841318f929", "archive_sha256": "8df3c0474782589d3c6f374b5133b1bd14d168086edbc13c6e72e67dd4527a3b"}], "mechanism": "tuplestore", "description": "\u6b64\u8282\u70b9\u4f7f\u7528 work_mem \u521b\u5efa tuplestore\u3002tuplestore \u53ef\u4ee5\u5c06\u5b58\u50a8\u7684\u5143\u7ec4\u79fb\u5230\u4e34\u65f6\u6587\u4ef6\uff0c\u4f46\u8fd9\u4e0d\u610f\u5473\u7740 work_mem \u9650\u5236\u4e86\u8282\u70b9\u7684\u5168\u90e8\u5185\u5b58\u5206\u914d\u3002", "source_notes": ["If the tuplestore has spilled to disk, alternate reading and writing becomes quite expensive due to frequent buffer flushes. It's cheaper to force the entire partition to get spooled in one go.", "Read the current row from the tuplestore, and save in ScanTupleSlot. (We can't rely on the outerplan's output slot because we may have to read beyond the current row. Also, we have to actually copy the row out of the tuplestore, since window function evaluation might cause the tuplestore to dump its state to disk.)", "Window functions do not have to call this, but are encouraged to move the mark forward when possible to keep the tuplestore size down and prevent having to spill rows to disk."]}, "tables": [{"key": "explain-labels", "rows": [{"label": "WindowAgg", "identity": "WindowAgg"}], "title": "\u672c\u6784\u5efa\u4e2d\u7684 EXPLAIN \u6807\u7b7e", "columns": [{"key": "label", "label": "\u6587\u672c\u683c\u5f0f\u6807\u7b7e"}, {"key": "identity", "label": "\u7ed3\u6784\u5316\u8282\u70b9\u6807\u8bc6"}]}], "related": [{"url": "/wiki/sql/explain/?v=12", "label": "EXPLAIN"}, {"url": "/docs/12/using-explain.html", "label": "\u4f7f\u7528 EXPLAIN"}, {"url": "/docs/12/parallel-plans.html", "label": "\u5e76\u884c\u8ba1\u5212"}, {"url": "/wiki/guc/work_mem/?v=12", "label": "work_mem"}], "release": {"ref": "PostgreSQL 12.22 source archive", "label": "12.22", "major": "12", "channel": "historical", "revision": "8df3c0474782589d3c6f374b5133b1bd14d168086edbc13c6e72e67dd4527a3b", "source_url": "https://ftp.postgresql.org/pub/source/v12.22/postgresql-12.22.tar.bz2", "source_snapshot_utc": ""}, "sources": [{"url": "https://ftp.postgresql.org/pub/source/v12.22/postgresql-12.22.tar.bz2", "line": 1261, "path": "src/backend/commands/explain.c", "label": "src/backend/commands/explain.c:1261", "sha256": "d02ea84fdaa201de5d9360645a9f24bfbd2c31f7d45a639e09560ac0e6b6471d", "archive_sha256": "8df3c0474782589d3c6f374b5133b1bd14d168086edbc13c6e72e67dd4527a3b"}, {"url": "https://ftp.postgresql.org/pub/source/v12.22/postgresql-12.22.tar.bz2", "line": 328, "path": "src/backend/executor/execProcnode.c", "label": "src/backend/executor/execProcnode.c:328", "sha256": "311b17379fe54e3f342fe5ad41c43afbdfa1b844978db2bb2eb22b82520d3256", "archive_sha256": "8df3c0474782589d3c6f374b5133b1bd14d168086edbc13c6e72e67dd4527a3b"}, {"url": "https://ftp.postgresql.org/pub/source/v12.22/postgresql-12.22.tar.bz2", "path": "src/backend/executor/nodeWindowAgg.c", "label": "src/backend/executor/nodeWindowAgg.c", "sha256": "65d021db964aca5d05a10eebbf2b0010dd783d35214a9f131fe97e8135bd0ed1", "archive_sha256": "8df3c0474782589d3c6f374b5133b1bd14d168086edbc13c6e72e67dd4527a3b"}, {"url": "https://ftp.postgresql.org/pub/source/v12.22/postgresql-12.22.tar.bz2", "path": "src/include/nodes/plannodes.h", "label": "src/include/nodes/plannodes.h", "sha256": "b0c4a0aeb48660ce06e5e700d5529ca9066fd16682bd15783d6e71b5420b07b0", "archive_sha256": "8df3c0474782589d3c6f374b5133b1bd14d168086edbc13c6e72e67dd4527a3b"}, {"url": "https://ftp.postgresql.org/pub/source/v12.22/postgresql-12.22.tar.bz2", "path": "src/backend/utils/sort/tuplestore.c", "label": "src/backend/utils/sort/tuplestore.c", "sha256": "44cccd98d659272f5c8f3ff6adffb1f6cc911acd13a3cfafc74cc7841318f929", "archive_sha256": "8df3c0474782589d3c6f374b5133b1bd14d168086edbc13c6e72e67dd4527a3b"}], "node_tag": "T_WindowAgg", "sections": [{"title": "EXPLAIN \u540d\u79f0\u4e0e\u5c5e\u6027", "paragraphs": ["\u7ed3\u6784\u5316\u683c\u5f0f\u4f7f\u7528\u4e0a\u8ff0 Node Type\u3002\u6587\u672c\u683c\u5f0f\u540d\u79f0\u8fd8\u53ef\u80fd\u5305\u542b\u64cd\u4f5c\u3001\u7b56\u7565\u3001\u8fde\u63a5\u7c7b\u578b\u3001\u626b\u63cf\u65b9\u5411\u6216\u805a\u5408\u9636\u6bb5\u5c5e\u6027\u3002", "\u6b64\u6e90\u7801\u8bb0\u5f55\u7684\u6587\u672c\u540d\u79f0\uff1aWindowAgg.", "\u5e76\u884c\u611f\u77e5\u4e0e\u5e76\u884c\u5b89\u5168\u662f\u4e0d\u540c\u7684\u8ba1\u5212\u5c5e\u6027\u3002\u5728\u5e76\u884c\u5de5\u4f5c\u8fdb\u7a0b\u5185\u8fd0\u884c\u7684\u8282\u70b9\u4e0d\u4e00\u5b9a\u662f\u5e76\u884c\u611f\u77e5\u8282\u70b9\u3002"]}, {"title": "\u5185\u5b58\u4e0e\u4e34\u65f6\u5b58\u50a8", "paragraphs": ["\u6b64\u8282\u70b9\u4f7f\u7528 work_mem \u521b\u5efa tuplestore\u3002tuplestore \u53ef\u4ee5\u5c06\u5b58\u50a8\u7684\u5143\u7ec4\u79fb\u5230\u4e34\u65f6\u6587\u4ef6\uff0c\u4f46\u8fd9\u4e0d\u610f\u5473\u7740 work_mem \u9650\u5236\u4e86\u8282\u70b9\u7684\u5168\u90e8\u5185\u5b58\u5206\u914d\u3002", "tuplestore \u5df2\u843d\u76d8\u65f6\uff0c\u4ea4\u66ff\u8bfb\u5199\u4f1a\u9891\u7e41\u5237\u65b0\u7f13\u51b2\u533a\uff0c\u4ee3\u4ef7\u5f88\u9ad8\u3002\u4e00\u6b21\u6027\u5c06\u6574\u4e2a\u5206\u533a\u5b58\u5165\u4e34\u65f6\u5b58\u50a8\u4f1a\u66f4\u4fbf\u5b9c\u3002", "\u4ece tuplestore \u8bfb\u53d6\u5f53\u524d\u884c\u5e76\u4fdd\u5b58\u5230 ScanTupleSlot\u3002\u4e0d\u80fd\u4f9d\u8d56\u5916\u5c42\u8ba1\u5212\u7684\u8f93\u51fa\u69fd\uff0c\u56e0\u4e3a\u53ef\u80fd\u9700\u8981\u8bfb\u53d6\u5f53\u524d\u884c\u4e4b\u540e\u7684\u6570\u636e\u3002\u6b64\u5916\uff0c\u5fc5\u987b\u5c06\u884c\u5b9e\u9645\u590d\u5236\u51fa tuplestore\uff0c\u56e0\u4e3a\u7a97\u53e3\u51fd\u6570\u6c42\u503c\u53ef\u80fd\u4f7f tuplestore \u5c06\u5176\u72b6\u6001\u5199\u5165\u78c1\u76d8\u3002", "\u7a97\u53e3\u51fd\u6570\u5e76\u975e\u5fc5\u987b\u8c03\u7528\u6b64\u51fd\u6570\uff0c\u4f46\u5efa\u8bae\u5728\u53ef\u80fd\u65f6\u524d\u79fb\u6807\u8bb0\uff0c\u4ee5\u51cf\u5c0f tuplestore \u5927\u5c0f\u5e76\u907f\u514d\u5c06\u884c\u5199\u5165\u78c1\u76d8\u3002"]}, {"title": "\u5e76\u884c\u6267\u884c\u4e0e\u8fd0\u884c\u4fe1\u606f\u91c7\u96c6", "paragraphs": ["\u4ee5\u4e0b\u6e90\u7801\u56de\u8c03\u53ef\u4ee5\u534f\u8c03\u6267\u884c\u6216\u6536\u96c6\u5de5\u4f5c\u8fdb\u7a0b\u7684\u6d4b\u91cf\u6570\u636e\u3002\u56de\u8c03\u5b58\u5728\u4e0d\u4ee3\u8868\u8be5\u8282\u70b9\u666e\u904d\u652f\u6301\u5171\u4eab\u5e76\u884c\u626b\u63cf\u6216\u5171\u4eab\u72b6\u6001\u3002", "\u6b64\u6784\u5efa\u7684\u56de\u8c03\uff1anone extracted from this node implementation."]}, {"title": "\u6267\u884c\u5668\u5b9e\u73b0\u8bf4\u660e", "paragraphs": ["WindowAgg \u8282\u70b9\u5728\u8f93\u5165\u5143\u7ec4\u96c6\u5408\u7684\u9002\u5f53\u5206\u533a\u4e0a\u8ba1\u7b97\u201c\u7a97\u53e3\u51fd\u6570\u201d\u3002\u6bcf\u4e2a WindowAgg \u53ea\u5904\u7406\u4e00\u79cd\u7a97\u53e3\u5b9a\u4e49\uff0c\u4f46\u53ef\u4ee5\u8ba1\u7b97\u5171\u4eab\u76f8\u540c\u7a97\u53e3\u5b9a\u4e49\u7684\u591a\u4e2a\u7a97\u53e3\u51fd\u6570\u3002\u8f93\u5165\u5143\u7ec4\u5fc5\u987b\u6309\u6392\u5e8f\u987a\u5e8f\u9001\u8fbe\uff1aPARTITION BY \u5217\uff08\u5982\u679c\u6709\uff09\u4e3a\u4e3b\u8981\u6392\u5e8f\u952e\uff0cORDER BY \u5217\uff08\u5982\u679c\u6709\uff09\u4e3a\u6b21\u8981\u6392\u5e8f\u952e\u3002\uff08\u5982\u679c\u67e5\u8be2\u5305\u542b\u591a\u79cd\u7a97\u53e3\u5b9a\u4e49\uff0c\u89c4\u5212\u5668\u4f1a\u6309\u9700\u751f\u6210\u591a\u4e2a\u5806\u53e0\u7684 WindowAgg\uff0c\u5e76\u5728\u5176\u95f4\u63d2\u5165 Sort \u8282\u70b9\u3002\uff09", "\u7a97\u53e3\u51fd\u6570\u53ef\u80fd\u9700\u8981\u8bbf\u95ee\u5f53\u524d\u5206\u533a\u7684\u4efb\u610f\u884c\u4e43\u81f3\u5168\u90e8\u884c\uff0c\u56e0\u6b64\u5c06\u5206\u533a\u884c\u7d2f\u79ef\u5230\u5143\u7ec4\u5b58\u50a8\u3002\u901a\u8fc7 WindowObject API \u8c03\u7528\u7a97\u53e3\u51fd\u6570\uff0c\u4f7f\u5176\u6309\u9700\u8bbf\u95ee\u8fd9\u4e9b\u884c\u3002", "\u4e5f\u652f\u6301\u5c06\u666e\u901a\u805a\u5408\u51fd\u6570\u7528\u4f5c\u7a97\u53e3\u51fd\u6570\u3002\u6b64\u65f6\u4e3a\u6bcf\u4e2a\u5206\u533a\u6a21\u62df\u5e38\u89c4 Agg \u8282\u70b9\u73af\u5883\u3002\u6309 SQL \u89c4\u8303\uff0c\u8f93\u51fa\u4e3a\u8be5\u805a\u5408\u51fd\u6570\u5728\u5f53\u524d\u884c\u7a97\u53e3\u6846\u67b6\u5185\u5168\u90e8\u884c\u4e0a\u7684\u7ed3\u679c\u3002", "\u6240\u6709\u7a97\u53e3\u51fd\u6570 API \u90fd\u4f7f\u7528\u6b64\u5bf9\u8c61\u8c03\u7528\uff1b\u6b64\u5bf9\u8c61\u901a\u8fc7 fcinfo->context \u4f20\u7ed9\u7a97\u53e3\u51fd\u6570\u3002", "\u6b64\u8282\u70b9\u5904\u7406\u7684\u6bcf\u4e2a\u7a97\u53e3\u51fd\u6570\u548c\u7a97\u53e3\u805a\u5408\u90fd\u5bf9\u5e94\u4e00\u4e2a WindowStatePerFunc \u7ed3\u6784\u3002"]}, {"code": "case T_WindowAgg:\n\t\t\tpname = sname = \"WindowAgg\";\n\t\t\tbreak;", "title": "\u6838\u5fc3\u6e90\u7801\u4e2d\u7684 EXPLAIN \u6807\u8bc6"}], "strategies": [], "description": ["\u5728\u5b50\u8ba1\u5212\u8f93\u51fa\u7684\u6709\u5e8f\u5206\u533a\u4e0a\u8ba1\u7b97\u7a97\u53e3\u51fd\u6570\u3002"], "localization": {"status": "complete", "sources": [], "language": "zh", "original_text": {"/versions/12/description/0": "Evaluates window functions over ordered partitions of its child output.", "/versions/12/facts/0/label": "Core node tag", "/versions/12/facts/1/label": "Structured EXPLAIN Node Type", "/versions/12/facts/2/label": "Inputs", "/versions/12/facts/2/value": "One suitably ordered child plan", "/versions/12/facts/3/label": "Output", "/versions/12/facts/3/value": "Tuples with window-function results", "/versions/12/facts/4/label": "Executor initializer", "/versions/12/facts/5/label": "Memory mechanism", "/versions/12/tables/0/title": "EXPLAIN labels in this source build", "/versions/12/related/1/label": "Using EXPLAIN", "/versions/12/related/2/label": "Parallel plans", "/versions/12/sections/0/title": "EXPLAIN names and attributes", "/versions/12/sections/1/title": "Memory and temporary storage", "/versions/12/sections/2/title": "Parallel execution and instrumentation", "/versions/12/sections/3/title": "Executor implementation notes", "/versions/12/sections/4/title": "EXPLAIN identity in core source", "/versions/12/memory/description": "This node creates a tuplestore with work_mem. The tuplestore can move stored tuples to temporary files; this does not make work_mem a cap on every allocation made by the node.", "/versions/12/sections/0/paragraphs/0": "Structured formats use the Node Type above. Text-format spellings can also include operation, strategy, join type, scan direction or aggregation-stage attributes.", "/versions/12/sections/0/paragraphs/1": "Text names recorded by this source: WindowAgg.", "/versions/12/sections/0/paragraphs/2": "Parallel-aware and parallel-safe are different plan properties. A node running inside a parallel worker is not necessarily a parallel-aware node.", "/versions/12/sections/1/paragraphs/0": "This node creates a tuplestore with work_mem. The tuplestore can move stored tuples to temporary files; this does not make work_mem a cap on every allocation made by the node.", "/versions/12/sections/1/paragraphs/1": "If the tuplestore has spilled to disk, alternate reading and writing becomes quite expensive due to frequent buffer flushes. It's cheaper to force the entire partition to get spooled in one go.", "/versions/12/sections/1/paragraphs/2": "Read the current row from the tuplestore, and save in ScanTupleSlot. (We can't rely on the outerplan's output slot because we may have to read beyond the current row. Also, we have to actually copy the row out of the tuplestore, since window function evaluation might cause the tuplestore to dump its state to disk.)", "/versions/12/sections/1/paragraphs/3": "Window functions do not have to call this, but are encouraged to move the mark forward when possible to keep the tuplestore size down and prevent having to spill rows to disk.", "/versions/12/sections/2/paragraphs/0": "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.", "/versions/12/sections/2/paragraphs/1": "Callbacks in this build: none extracted from this node implementation.", "/versions/12/sections/3/paragraphs/0": "A WindowAgg node evaluates \"window functions\" across suitable partitions of the input tuple set. Any one WindowAgg works for just a single window specification, though it can evaluate multiple window functions sharing identical window specifications. The input tuples are required to be delivered in sorted order, with the PARTITION BY columns (if any) as major sort keys and the ORDER BY columns (if any) as minor sort keys. (The planner generates a stack of WindowAggs with intervening Sort nodes as needed, if a query involves more than one window specification.)", "/versions/12/sections/3/paragraphs/1": "Since window functions can require access to any or all of the rows in the current partition, we accumulate rows of the partition into a tuplestore. The window functions are called using the WindowObject API so that they can access those rows as needed.", "/versions/12/sections/3/paragraphs/2": "We also support using plain aggregate functions as window functions. For these, the regular Agg-node environment is emulated for each partition. As required by the SQL spec, the output represents the value of the aggregate function over all rows in the current row's window frame.", "/versions/12/sections/3/paragraphs/3": "All the window function APIs are called with this object, which is passed to window functions as fcinfo->context.", "/versions/12/sections/3/paragraphs/4": "We have one WindowStatePerFunc struct for each window function and window aggregate handled by this node.", "/versions/12/tables/0/columns/0/label": "Text-format label", "/versions/12/tables/0/columns/1/label": "Structured node identity"}, "fallback_fields": [], "source_language": "en", "original_snapshot_sha256": "78406ed66e3f3fba42eac9904da9a00d37229a2e9d602af86076dda3fbfafdf9"}, "evidence_kind": "source and documentation", "explain_names": ["WindowAgg"], "partial_modes": [], "comparison_data": {"node_tag": "T_WindowAgg", "strategies": [], "text_names": ["WindowAgg"], "initializer": "ExecInitWindowAgg", "partial_modes": [], "memory_mechanism": "tuplestore", "parallel_callbacks": []}, "comparison_hash": "186aa5f13e96214f274161ba257307adf452233ebc64c9c0aaebfaee73fac8a4", "explain_prefixes": ["Parallel"], "runtime_verified": false, "source_inventory": {"explain": "src/backend/commands/explain.c", "executor": "src/backend/executor/execProcnode.c", "implementation": "src/backend/executor/nodeWindowAgg.c"}, "parallel_callbacks": []}, "13": {"facts": [{"label": "\u6838\u5fc3\u8282\u70b9\u6807\u7b7e", "value": "T_WindowAgg"}, {"label": "\u7ed3\u6784\u5316 EXPLAIN \u8282\u70b9\u7c7b\u578b", "value": "WindowAgg"}, {"label": "\u8f93\u5165", "value": "\u4e00\u4e2a\u6ee1\u8db3\u6392\u5e8f\u8981\u6c42\u7684\u5b50\u8ba1\u5212"}, {"label": "\u8f93\u51fa", "value": "\u5e26\u7a97\u53e3\u51fd\u6570\u7ed3\u679c\u7684\u5143\u7ec4"}, {"label": "\u6267\u884c\u5668\u521d\u59cb\u5316\u51fd\u6570", "value": "ExecInitWindowAgg"}, {"label": "\u5185\u5b58\u673a\u5236", "value": "tuplestore"}], "memory": {"evidence": [{"url": "https://ftp.postgresql.org/pub/source/v13.23/postgresql-13.23.tar.bz2", "path": "src/backend/executor/nodeWindowAgg.c", "label": "src/backend/executor/nodeWindowAgg.c", "sha256": "30ba44a99a9bc839d16554b84fda581924842fb434ab12226d74cfb80de83c1c", "archive_sha256": "6ec3c82726af92b7dec873fa1cdf881eca92a4219787dfad05acb6b10e041fd6"}, {"url": "https://ftp.postgresql.org/pub/source/v13.23/postgresql-13.23.tar.bz2", "path": "src/backend/utils/sort/tuplestore.c", "label": "src/backend/utils/sort/tuplestore.c", "sha256": "4cba6490949d7dd9338b8499fcbb489e84cfd6cda9b98599512eb40bfbde6f9d", "archive_sha256": "6ec3c82726af92b7dec873fa1cdf881eca92a4219787dfad05acb6b10e041fd6"}], "mechanism": "tuplestore", "description": "\u6b64\u8282\u70b9\u4f7f\u7528 work_mem \u521b\u5efa tuplestore\u3002tuplestore \u53ef\u4ee5\u5c06\u5b58\u50a8\u7684\u5143\u7ec4\u79fb\u5230\u4e34\u65f6\u6587\u4ef6\uff0c\u4f46\u8fd9\u4e0d\u610f\u5473\u7740 work_mem \u9650\u5236\u4e86\u8282\u70b9\u7684\u5168\u90e8\u5185\u5b58\u5206\u914d\u3002", "source_notes": ["If the tuplestore has spilled to disk, alternate reading and writing becomes quite expensive due to frequent buffer flushes. It's cheaper to force the entire partition to get spooled in one go.", "Read the current row from the tuplestore, and save in ScanTupleSlot. (We can't rely on the outerplan's output slot because we may have to read beyond the current row. Also, we have to actually copy the row out of the tuplestore, since window function evaluation might cause the tuplestore to dump its state to disk.)", "Window functions do not have to call this, but are encouraged to move the mark forward when possible to keep the tuplestore size down and prevent having to spill rows to disk."]}, "tables": [{"key": "explain-labels", "rows": [{"label": "WindowAgg", "identity": "WindowAgg"}], "title": "\u672c\u6784\u5efa\u4e2d\u7684 EXPLAIN \u6807\u7b7e", "columns": [{"key": "label", "label": "\u6587\u672c\u683c\u5f0f\u6807\u7b7e"}, {"key": "identity", "label": "\u7ed3\u6784\u5316\u8282\u70b9\u6807\u8bc6"}]}], "related": [{"url": "/wiki/sql/explain/?v=13", "label": "EXPLAIN"}, {"url": "/docs/13/using-explain.html", "label": "\u4f7f\u7528 EXPLAIN"}, {"url": "/docs/13/parallel-plans.html", "label": "\u5e76\u884c\u8ba1\u5212"}, {"url": "/wiki/guc/work_mem/?v=13", "label": "work_mem"}], "release": {"ref": "PostgreSQL 13.23 source archive", "label": "13.23", "major": "13", "channel": "historical", "revision": "6ec3c82726af92b7dec873fa1cdf881eca92a4219787dfad05acb6b10e041fd6", "source_url": "https://ftp.postgresql.org/pub/source/v13.23/postgresql-13.23.tar.bz2", "source_snapshot_utc": ""}, "sources": [{"url": "https://ftp.postgresql.org/pub/source/v13.23/postgresql-13.23.tar.bz2", "line": 1322, "path": "src/backend/commands/explain.c", "label": "src/backend/commands/explain.c:1322", "sha256": "541713e0e7f1c9cc352c2b6028964d440c19d2678a4463000094c24a88c1e730", "archive_sha256": "6ec3c82726af92b7dec873fa1cdf881eca92a4219787dfad05acb6b10e041fd6"}, {"url": "https://ftp.postgresql.org/pub/source/v13.23/postgresql-13.23.tar.bz2", "line": 333, "path": "src/backend/executor/execProcnode.c", "label": "src/backend/executor/execProcnode.c:333", "sha256": "d085ee99acfa00587e6ade3a1d9f8108a0566beedbbee3f54a50c9fc0cc2e875", "archive_sha256": "6ec3c82726af92b7dec873fa1cdf881eca92a4219787dfad05acb6b10e041fd6"}, {"url": "https://ftp.postgresql.org/pub/source/v13.23/postgresql-13.23.tar.bz2", "path": "src/backend/executor/nodeWindowAgg.c", "label": "src/backend/executor/nodeWindowAgg.c", "sha256": "30ba44a99a9bc839d16554b84fda581924842fb434ab12226d74cfb80de83c1c", "archive_sha256": "6ec3c82726af92b7dec873fa1cdf881eca92a4219787dfad05acb6b10e041fd6"}, {"url": "https://ftp.postgresql.org/pub/source/v13.23/postgresql-13.23.tar.bz2", "path": "src/include/nodes/plannodes.h", "label": "src/include/nodes/plannodes.h", "sha256": "dcb296833777b02008c4b6bae8e8f7c6423b7ffba21f36702597c9d596d039ab", "archive_sha256": "6ec3c82726af92b7dec873fa1cdf881eca92a4219787dfad05acb6b10e041fd6"}, {"url": "https://ftp.postgresql.org/pub/source/v13.23/postgresql-13.23.tar.bz2", "path": "src/backend/utils/sort/tuplestore.c", "label": "src/backend/utils/sort/tuplestore.c", "sha256": "4cba6490949d7dd9338b8499fcbb489e84cfd6cda9b98599512eb40bfbde6f9d", "archive_sha256": "6ec3c82726af92b7dec873fa1cdf881eca92a4219787dfad05acb6b10e041fd6"}], "node_tag": "T_WindowAgg", "sections": [{"title": "EXPLAIN \u540d\u79f0\u4e0e\u5c5e\u6027", "paragraphs": ["\u7ed3\u6784\u5316\u683c\u5f0f\u4f7f\u7528\u4e0a\u8ff0 Node Type\u3002\u6587\u672c\u683c\u5f0f\u540d\u79f0\u8fd8\u53ef\u80fd\u5305\u542b\u64cd\u4f5c\u3001\u7b56\u7565\u3001\u8fde\u63a5\u7c7b\u578b\u3001\u626b\u63cf\u65b9\u5411\u6216\u805a\u5408\u9636\u6bb5\u5c5e\u6027\u3002", "\u6b64\u6e90\u7801\u8bb0\u5f55\u7684\u6587\u672c\u540d\u79f0\uff1aWindowAgg.", "\u5e76\u884c\u611f\u77e5\u4e0e\u5e76\u884c\u5b89\u5168\u662f\u4e0d\u540c\u7684\u8ba1\u5212\u5c5e\u6027\u3002\u5728\u5e76\u884c\u5de5\u4f5c\u8fdb\u7a0b\u5185\u8fd0\u884c\u7684\u8282\u70b9\u4e0d\u4e00\u5b9a\u662f\u5e76\u884c\u611f\u77e5\u8282\u70b9\u3002"]}, {"title": "\u5185\u5b58\u4e0e\u4e34\u65f6\u5b58\u50a8", "paragraphs": ["\u6b64\u8282\u70b9\u4f7f\u7528 work_mem \u521b\u5efa tuplestore\u3002tuplestore \u53ef\u4ee5\u5c06\u5b58\u50a8\u7684\u5143\u7ec4\u79fb\u5230\u4e34\u65f6\u6587\u4ef6\uff0c\u4f46\u8fd9\u4e0d\u610f\u5473\u7740 work_mem \u9650\u5236\u4e86\u8282\u70b9\u7684\u5168\u90e8\u5185\u5b58\u5206\u914d\u3002", "tuplestore \u5df2\u843d\u76d8\u65f6\uff0c\u4ea4\u66ff\u8bfb\u5199\u4f1a\u9891\u7e41\u5237\u65b0\u7f13\u51b2\u533a\uff0c\u4ee3\u4ef7\u5f88\u9ad8\u3002\u4e00\u6b21\u6027\u5c06\u6574\u4e2a\u5206\u533a\u5b58\u5165\u4e34\u65f6\u5b58\u50a8\u4f1a\u66f4\u4fbf\u5b9c\u3002", "\u4ece tuplestore \u8bfb\u53d6\u5f53\u524d\u884c\u5e76\u4fdd\u5b58\u5230 ScanTupleSlot\u3002\u4e0d\u80fd\u4f9d\u8d56\u5916\u5c42\u8ba1\u5212\u7684\u8f93\u51fa\u69fd\uff0c\u56e0\u4e3a\u53ef\u80fd\u9700\u8981\u8bfb\u53d6\u5f53\u524d\u884c\u4e4b\u540e\u7684\u6570\u636e\u3002\u6b64\u5916\uff0c\u5fc5\u987b\u5c06\u884c\u5b9e\u9645\u590d\u5236\u51fa tuplestore\uff0c\u56e0\u4e3a\u7a97\u53e3\u51fd\u6570\u6c42\u503c\u53ef\u80fd\u4f7f tuplestore \u5c06\u5176\u72b6\u6001\u5199\u5165\u78c1\u76d8\u3002", "\u7a97\u53e3\u51fd\u6570\u5e76\u975e\u5fc5\u987b\u8c03\u7528\u6b64\u51fd\u6570\uff0c\u4f46\u5efa\u8bae\u5728\u53ef\u80fd\u65f6\u524d\u79fb\u6807\u8bb0\uff0c\u4ee5\u51cf\u5c0f tuplestore \u5927\u5c0f\u5e76\u907f\u514d\u5c06\u884c\u5199\u5165\u78c1\u76d8\u3002"]}, {"title": "\u5e76\u884c\u6267\u884c\u4e0e\u8fd0\u884c\u4fe1\u606f\u91c7\u96c6", "paragraphs": ["\u4ee5\u4e0b\u6e90\u7801\u56de\u8c03\u53ef\u4ee5\u534f\u8c03\u6267\u884c\u6216\u6536\u96c6\u5de5\u4f5c\u8fdb\u7a0b\u7684\u6d4b\u91cf\u6570\u636e\u3002\u56de\u8c03\u5b58\u5728\u4e0d\u4ee3\u8868\u8be5\u8282\u70b9\u666e\u904d\u652f\u6301\u5171\u4eab\u5e76\u884c\u626b\u63cf\u6216\u5171\u4eab\u72b6\u6001\u3002", "\u6b64\u6784\u5efa\u7684\u56de\u8c03\uff1anone extracted from this node implementation."]}, {"title": "\u6267\u884c\u5668\u5b9e\u73b0\u8bf4\u660e", "paragraphs": ["WindowAgg \u8282\u70b9\u5728\u8f93\u5165\u5143\u7ec4\u96c6\u5408\u7684\u9002\u5f53\u5206\u533a\u4e0a\u8ba1\u7b97\u201c\u7a97\u53e3\u51fd\u6570\u201d\u3002\u6bcf\u4e2a WindowAgg \u53ea\u5904\u7406\u4e00\u79cd\u7a97\u53e3\u5b9a\u4e49\uff0c\u4f46\u53ef\u4ee5\u8ba1\u7b97\u5171\u4eab\u76f8\u540c\u7a97\u53e3\u5b9a\u4e49\u7684\u591a\u4e2a\u7a97\u53e3\u51fd\u6570\u3002\u8f93\u5165\u5143\u7ec4\u5fc5\u987b\u6309\u6392\u5e8f\u987a\u5e8f\u9001\u8fbe\uff1aPARTITION BY \u5217\uff08\u5982\u679c\u6709\uff09\u4e3a\u4e3b\u8981\u6392\u5e8f\u952e\uff0cORDER BY \u5217\uff08\u5982\u679c\u6709\uff09\u4e3a\u6b21\u8981\u6392\u5e8f\u952e\u3002\uff08\u5982\u679c\u67e5\u8be2\u5305\u542b\u591a\u79cd\u7a97\u53e3\u5b9a\u4e49\uff0c\u89c4\u5212\u5668\u4f1a\u6309\u9700\u751f\u6210\u591a\u4e2a\u5806\u53e0\u7684 WindowAgg\uff0c\u5e76\u5728\u5176\u95f4\u63d2\u5165 Sort \u8282\u70b9\u3002\uff09", "\u7a97\u53e3\u51fd\u6570\u53ef\u80fd\u9700\u8981\u8bbf\u95ee\u5f53\u524d\u5206\u533a\u7684\u4efb\u610f\u884c\u4e43\u81f3\u5168\u90e8\u884c\uff0c\u56e0\u6b64\u5c06\u5206\u533a\u884c\u7d2f\u79ef\u5230\u5143\u7ec4\u5b58\u50a8\u3002\u901a\u8fc7 WindowObject API \u8c03\u7528\u7a97\u53e3\u51fd\u6570\uff0c\u4f7f\u5176\u6309\u9700\u8bbf\u95ee\u8fd9\u4e9b\u884c\u3002", "\u4e5f\u652f\u6301\u5c06\u666e\u901a\u805a\u5408\u51fd\u6570\u7528\u4f5c\u7a97\u53e3\u51fd\u6570\u3002\u6b64\u65f6\u4e3a\u6bcf\u4e2a\u5206\u533a\u6a21\u62df\u5e38\u89c4 Agg \u8282\u70b9\u73af\u5883\u3002\u6309 SQL \u89c4\u8303\uff0c\u8f93\u51fa\u4e3a\u8be5\u805a\u5408\u51fd\u6570\u5728\u5f53\u524d\u884c\u7a97\u53e3\u6846\u67b6\u5185\u5168\u90e8\u884c\u4e0a\u7684\u7ed3\u679c\u3002", "\u6240\u6709\u7a97\u53e3\u51fd\u6570 API \u90fd\u4f7f\u7528\u6b64\u5bf9\u8c61\u8c03\u7528\uff1b\u6b64\u5bf9\u8c61\u901a\u8fc7 fcinfo->context \u4f20\u7ed9\u7a97\u53e3\u51fd\u6570\u3002", "\u6b64\u8282\u70b9\u5904\u7406\u7684\u6bcf\u4e2a\u7a97\u53e3\u51fd\u6570\u548c\u7a97\u53e3\u805a\u5408\u90fd\u5bf9\u5e94\u4e00\u4e2a WindowStatePerFunc \u7ed3\u6784\u3002"]}, {"code": "case T_WindowAgg:\n\t\t\tpname = sname = \"WindowAgg\";\n\t\t\tbreak;", "title": "\u6838\u5fc3\u6e90\u7801\u4e2d\u7684 EXPLAIN \u6807\u8bc6"}], "strategies": [], "description": ["\u5728\u5b50\u8ba1\u5212\u8f93\u51fa\u7684\u6709\u5e8f\u5206\u533a\u4e0a\u8ba1\u7b97\u7a97\u53e3\u51fd\u6570\u3002"], "localization": {"status": "complete", "sources": [], "language": "zh", "original_text": {"/versions/13/description/0": "Evaluates window functions over ordered partitions of its child output.", "/versions/13/facts/0/label": "Core node tag", "/versions/13/facts/1/label": "Structured EXPLAIN Node Type", "/versions/13/facts/2/label": "Inputs", "/versions/13/facts/2/value": "One suitably ordered child plan", "/versions/13/facts/3/label": "Output", "/versions/13/facts/3/value": "Tuples with window-function results", "/versions/13/facts/4/label": "Executor initializer", "/versions/13/facts/5/label": "Memory mechanism", "/versions/13/tables/0/title": "EXPLAIN labels in this source build", "/versions/13/related/1/label": "Using EXPLAIN", "/versions/13/related/2/label": "Parallel plans", "/versions/13/sections/0/title": "EXPLAIN names and attributes", "/versions/13/sections/1/title": "Memory and temporary storage", "/versions/13/sections/2/title": "Parallel execution and instrumentation", "/versions/13/sections/3/title": "Executor implementation notes", "/versions/13/sections/4/title": "EXPLAIN identity in core source", "/versions/13/memory/description": "This node creates a tuplestore with work_mem. The tuplestore can move stored tuples to temporary files; this does not make work_mem a cap on every allocation made by the node.", "/versions/13/sections/0/paragraphs/0": "Structured formats use the Node Type above. Text-format spellings can also include operation, strategy, join type, scan direction or aggregation-stage attributes.", "/versions/13/sections/0/paragraphs/1": "Text names recorded by this source: WindowAgg.", "/versions/13/sections/0/paragraphs/2": "Parallel-aware and parallel-safe are different plan properties. A node running inside a parallel worker is not necessarily a parallel-aware node.", "/versions/13/sections/1/paragraphs/0": "This node creates a tuplestore with work_mem. The tuplestore can move stored tuples to temporary files; this does not make work_mem a cap on every allocation made by the node.", "/versions/13/sections/1/paragraphs/1": "If the tuplestore has spilled to disk, alternate reading and writing becomes quite expensive due to frequent buffer flushes. It's cheaper to force the entire partition to get spooled in one go.", "/versions/13/sections/1/paragraphs/2": "Read the current row from the tuplestore, and save in ScanTupleSlot. (We can't rely on the outerplan's output slot because we may have to read beyond the current row. Also, we have to actually copy the row out of the tuplestore, since window function evaluation might cause the tuplestore to dump its state to disk.)", "/versions/13/sections/1/paragraphs/3": "Window functions do not have to call this, but are encouraged to move the mark forward when possible to keep the tuplestore size down and prevent having to spill rows to disk.", "/versions/13/sections/2/paragraphs/0": "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.", "/versions/13/sections/2/paragraphs/1": "Callbacks in this build: none extracted from this node implementation.", "/versions/13/sections/3/paragraphs/0": "A WindowAgg node evaluates \"window functions\" across suitable partitions of the input tuple set. Any one WindowAgg works for just a single window specification, though it can evaluate multiple window functions sharing identical window specifications. The input tuples are required to be delivered in sorted order, with the PARTITION BY columns (if any) as major sort keys and the ORDER BY columns (if any) as minor sort keys. (The planner generates a stack of WindowAggs with intervening Sort nodes as needed, if a query involves more than one window specification.)", "/versions/13/sections/3/paragraphs/1": "Since window functions can require access to any or all of the rows in the current partition, we accumulate rows of the partition into a tuplestore. The window functions are called using the WindowObject API so that they can access those rows as needed.", "/versions/13/sections/3/paragraphs/2": "We also support using plain aggregate functions as window functions. For these, the regular Agg-node environment is emulated for each partition. As required by the SQL spec, the output represents the value of the aggregate function over all rows in the current row's window frame.", "/versions/13/sections/3/paragraphs/3": "All the window function APIs are called with this object, which is passed to window functions as fcinfo->context.", "/versions/13/sections/3/paragraphs/4": "We have one WindowStatePerFunc struct for each window function and window aggregate handled by this node.", "/versions/13/tables/0/columns/0/label": "Text-format label", "/versions/13/tables/0/columns/1/label": "Structured node identity"}, "fallback_fields": [], "source_language": "en", "original_snapshot_sha256": "ffadddfb2106a295fabec5a075264a73074abda5bb838dde9bbb2aceaf50299c"}, "evidence_kind": "source and documentation", "explain_names": ["WindowAgg"], "partial_modes": [], "comparison_data": {"node_tag": "T_WindowAgg", "strategies": [], "text_names": ["WindowAgg"], "initializer": "ExecInitWindowAgg", "partial_modes": [], "memory_mechanism": "tuplestore", "parallel_callbacks": []}, "comparison_hash": "186aa5f13e96214f274161ba257307adf452233ebc64c9c0aaebfaee73fac8a4", "explain_prefixes": ["Parallel"], "runtime_verified": false, "source_inventory": {"explain": "src/backend/commands/explain.c", "executor": "src/backend/executor/execProcnode.c", "implementation": "src/backend/executor/nodeWindowAgg.c"}, "parallel_callbacks": []}, "14": {"facts": [{"label": "\u6838\u5fc3\u8282\u70b9\u6807\u7b7e", "value": "T_WindowAgg"}, {"label": "\u7ed3\u6784\u5316 EXPLAIN \u8282\u70b9\u7c7b\u578b", "value": "WindowAgg"}, {"label": "\u8f93\u5165", "value": "\u4e00\u4e2a\u6ee1\u8db3\u6392\u5e8f\u8981\u6c42\u7684\u5b50\u8ba1\u5212"}, {"label": "\u8f93\u51fa", "value": "\u5e26\u7a97\u53e3\u51fd\u6570\u7ed3\u679c\u7684\u5143\u7ec4"}, {"label": "\u6267\u884c\u5668\u521d\u59cb\u5316\u51fd\u6570", "value": "ExecInitWindowAgg"}, {"label": "\u5185\u5b58\u673a\u5236", "value": "tuplestore"}], "memory": {"evidence": [{"url": "https://ftp.postgresql.org/pub/source/v14.24/postgresql-14.24.tar.bz2", "path": "src/backend/executor/nodeWindowAgg.c", "label": "src/backend/executor/nodeWindowAgg.c", "sha256": "86d317e7e788d54127581f8367496a9df2d73acc0b3d816aafaf4ca089d48001", "archive_sha256": "a7fa7ed3d558172355f51406097a7bd4f6b473be80f311ef7cda96bf383d8897"}, {"url": "https://ftp.postgresql.org/pub/source/v14.24/postgresql-14.24.tar.bz2", "path": "src/backend/utils/sort/tuplestore.c", "label": "src/backend/utils/sort/tuplestore.c", "sha256": "833cff27e0a2c863b9e897cd3bf4127df1b3e3a9b976694f3323a1c1a466d9b2", "archive_sha256": "a7fa7ed3d558172355f51406097a7bd4f6b473be80f311ef7cda96bf383d8897"}], "mechanism": "tuplestore", "description": "\u6b64\u8282\u70b9\u4f7f\u7528 work_mem \u521b\u5efa tuplestore\u3002tuplestore \u53ef\u4ee5\u5c06\u5b58\u50a8\u7684\u5143\u7ec4\u79fb\u5230\u4e34\u65f6\u6587\u4ef6\uff0c\u4f46\u8fd9\u4e0d\u610f\u5473\u7740 work_mem \u9650\u5236\u4e86\u8282\u70b9\u7684\u5168\u90e8\u5185\u5b58\u5206\u914d\u3002", "source_notes": ["If the tuplestore has spilled to disk, alternate reading and writing becomes quite expensive due to frequent buffer flushes. It's cheaper to force the entire partition to get spooled in one go.", "Read the current row from the tuplestore, and save in ScanTupleSlot. (We can't rely on the outerplan's output slot because we may have to read beyond the current row. Also, we have to actually copy the row out of the tuplestore, since window function evaluation might cause the tuplestore to dump its state to disk.)", "Window functions do not have to call this, but are encouraged to move the mark forward when possible to keep the tuplestore size down and prevent having to spill rows to disk."]}, "tables": [{"key": "explain-labels", "rows": [{"label": "WindowAgg", "identity": "WindowAgg"}], "title": "\u672c\u6784\u5efa\u4e2d\u7684 EXPLAIN \u6807\u7b7e", "columns": [{"key": "label", "label": "\u6587\u672c\u683c\u5f0f\u6807\u7b7e"}, {"key": "identity", "label": "\u7ed3\u6784\u5316\u8282\u70b9\u6807\u8bc6"}]}], "related": [{"url": "/wiki/sql/explain/?v=14", "label": "EXPLAIN"}, {"url": "/docs/14/using-explain.html", "label": "\u4f7f\u7528 EXPLAIN"}, {"url": "/docs/14/parallel-plans.html", "label": "\u5e76\u884c\u8ba1\u5212"}, {"url": "/wiki/guc/work_mem/?v=14", "label": "work_mem"}], "release": {"ref": "PostgreSQL 14.24 source archive", "label": "14.24", "major": "14", "channel": "stable", "revision": "a7fa7ed3d558172355f51406097a7bd4f6b473be80f311ef7cda96bf383d8897", "source_url": "https://ftp.postgresql.org/pub/source/v14.24/postgresql-14.24.tar.bz2", "source_snapshot_utc": ""}, "sources": [{"url": "https://ftp.postgresql.org/pub/source/v14.24/postgresql-14.24.tar.bz2", "line": 1364, "path": "src/backend/commands/explain.c", "label": "src/backend/commands/explain.c:1364", "sha256": "e091be4e2a083b8dea39ccd09beedede22c1716ef974da66c214a44f48be8c41", "archive_sha256": "a7fa7ed3d558172355f51406097a7bd4f6b473be80f311ef7cda96bf383d8897"}, {"url": "https://ftp.postgresql.org/pub/source/v14.24/postgresql-14.24.tar.bz2", "line": 345, "path": "src/backend/executor/execProcnode.c", "label": "src/backend/executor/execProcnode.c:345", "sha256": "72da1c5ad457f1d92a39ab73531701794df858419e3b89d6e6cb7079634e68fa", "archive_sha256": "a7fa7ed3d558172355f51406097a7bd4f6b473be80f311ef7cda96bf383d8897"}, {"url": "https://ftp.postgresql.org/pub/source/v14.24/postgresql-14.24.tar.bz2", "path": "src/backend/executor/nodeWindowAgg.c", "label": "src/backend/executor/nodeWindowAgg.c", "sha256": "86d317e7e788d54127581f8367496a9df2d73acc0b3d816aafaf4ca089d48001", "archive_sha256": "a7fa7ed3d558172355f51406097a7bd4f6b473be80f311ef7cda96bf383d8897"}, {"url": "https://ftp.postgresql.org/pub/source/v14.24/postgresql-14.24.tar.bz2", "path": "src/include/nodes/plannodes.h", "label": "src/include/nodes/plannodes.h", "sha256": "302f51a16b570dba7ec4e7bc045f7df5800d21630280354d1a24025f3baec75d", "archive_sha256": "a7fa7ed3d558172355f51406097a7bd4f6b473be80f311ef7cda96bf383d8897"}, {"url": "https://ftp.postgresql.org/pub/source/v14.24/postgresql-14.24.tar.bz2", "path": "src/backend/utils/sort/tuplestore.c", "label": "src/backend/utils/sort/tuplestore.c", "sha256": "833cff27e0a2c863b9e897cd3bf4127df1b3e3a9b976694f3323a1c1a466d9b2", "archive_sha256": "a7fa7ed3d558172355f51406097a7bd4f6b473be80f311ef7cda96bf383d8897"}], "node_tag": "T_WindowAgg", "sections": [{"title": "EXPLAIN \u540d\u79f0\u4e0e\u5c5e\u6027", "paragraphs": ["\u7ed3\u6784\u5316\u683c\u5f0f\u4f7f\u7528\u4e0a\u8ff0 Node Type\u3002\u6587\u672c\u683c\u5f0f\u540d\u79f0\u8fd8\u53ef\u80fd\u5305\u542b\u64cd\u4f5c\u3001\u7b56\u7565\u3001\u8fde\u63a5\u7c7b\u578b\u3001\u626b\u63cf\u65b9\u5411\u6216\u805a\u5408\u9636\u6bb5\u5c5e\u6027\u3002", "\u6b64\u6e90\u7801\u8bb0\u5f55\u7684\u6587\u672c\u540d\u79f0\uff1aWindowAgg.", "\u5e76\u884c\u611f\u77e5\u4e0e\u5e76\u884c\u5b89\u5168\u662f\u4e0d\u540c\u7684\u8ba1\u5212\u5c5e\u6027\u3002\u5728\u5e76\u884c\u5de5\u4f5c\u8fdb\u7a0b\u5185\u8fd0\u884c\u7684\u8282\u70b9\u4e0d\u4e00\u5b9a\u662f\u5e76\u884c\u611f\u77e5\u8282\u70b9\u3002"]}, {"title": "\u5185\u5b58\u4e0e\u4e34\u65f6\u5b58\u50a8", "paragraphs": ["\u6b64\u8282\u70b9\u4f7f\u7528 work_mem \u521b\u5efa tuplestore\u3002tuplestore \u53ef\u4ee5\u5c06\u5b58\u50a8\u7684\u5143\u7ec4\u79fb\u5230\u4e34\u65f6\u6587\u4ef6\uff0c\u4f46\u8fd9\u4e0d\u610f\u5473\u7740 work_mem \u9650\u5236\u4e86\u8282\u70b9\u7684\u5168\u90e8\u5185\u5b58\u5206\u914d\u3002", "tuplestore \u5df2\u843d\u76d8\u65f6\uff0c\u4ea4\u66ff\u8bfb\u5199\u4f1a\u9891\u7e41\u5237\u65b0\u7f13\u51b2\u533a\uff0c\u4ee3\u4ef7\u5f88\u9ad8\u3002\u4e00\u6b21\u6027\u5c06\u6574\u4e2a\u5206\u533a\u5b58\u5165\u4e34\u65f6\u5b58\u50a8\u4f1a\u66f4\u4fbf\u5b9c\u3002", "\u4ece tuplestore \u8bfb\u53d6\u5f53\u524d\u884c\u5e76\u4fdd\u5b58\u5230 ScanTupleSlot\u3002\u4e0d\u80fd\u4f9d\u8d56\u5916\u5c42\u8ba1\u5212\u7684\u8f93\u51fa\u69fd\uff0c\u56e0\u4e3a\u53ef\u80fd\u9700\u8981\u8bfb\u53d6\u5f53\u524d\u884c\u4e4b\u540e\u7684\u6570\u636e\u3002\u6b64\u5916\uff0c\u5fc5\u987b\u5c06\u884c\u5b9e\u9645\u590d\u5236\u51fa tuplestore\uff0c\u56e0\u4e3a\u7a97\u53e3\u51fd\u6570\u6c42\u503c\u53ef\u80fd\u4f7f tuplestore \u5c06\u5176\u72b6\u6001\u5199\u5165\u78c1\u76d8\u3002", "\u7a97\u53e3\u51fd\u6570\u5e76\u975e\u5fc5\u987b\u8c03\u7528\u6b64\u51fd\u6570\uff0c\u4f46\u5efa\u8bae\u5728\u53ef\u80fd\u65f6\u524d\u79fb\u6807\u8bb0\uff0c\u4ee5\u51cf\u5c0f tuplestore \u5927\u5c0f\u5e76\u907f\u514d\u5c06\u884c\u5199\u5165\u78c1\u76d8\u3002"]}, {"title": "\u5e76\u884c\u6267\u884c\u4e0e\u8fd0\u884c\u4fe1\u606f\u91c7\u96c6", "paragraphs": ["\u4ee5\u4e0b\u6e90\u7801\u56de\u8c03\u53ef\u4ee5\u534f\u8c03\u6267\u884c\u6216\u6536\u96c6\u5de5\u4f5c\u8fdb\u7a0b\u7684\u6d4b\u91cf\u6570\u636e\u3002\u56de\u8c03\u5b58\u5728\u4e0d\u4ee3\u8868\u8be5\u8282\u70b9\u666e\u904d\u652f\u6301\u5171\u4eab\u5e76\u884c\u626b\u63cf\u6216\u5171\u4eab\u72b6\u6001\u3002", "\u6b64\u6784\u5efa\u7684\u56de\u8c03\uff1anone extracted from this node implementation."]}, {"title": "\u6267\u884c\u5668\u5b9e\u73b0\u8bf4\u660e", "paragraphs": ["WindowAgg \u8282\u70b9\u5728\u8f93\u5165\u5143\u7ec4\u96c6\u5408\u7684\u9002\u5f53\u5206\u533a\u4e0a\u8ba1\u7b97\u201c\u7a97\u53e3\u51fd\u6570\u201d\u3002\u6bcf\u4e2a WindowAgg \u53ea\u5904\u7406\u4e00\u79cd\u7a97\u53e3\u5b9a\u4e49\uff0c\u4f46\u53ef\u4ee5\u8ba1\u7b97\u5171\u4eab\u76f8\u540c\u7a97\u53e3\u5b9a\u4e49\u7684\u591a\u4e2a\u7a97\u53e3\u51fd\u6570\u3002\u8f93\u5165\u5143\u7ec4\u5fc5\u987b\u6309\u6392\u5e8f\u987a\u5e8f\u9001\u8fbe\uff1aPARTITION BY \u5217\uff08\u5982\u679c\u6709\uff09\u4e3a\u4e3b\u8981\u6392\u5e8f\u952e\uff0cORDER BY \u5217\uff08\u5982\u679c\u6709\uff09\u4e3a\u6b21\u8981\u6392\u5e8f\u952e\u3002\uff08\u5982\u679c\u67e5\u8be2\u5305\u542b\u591a\u79cd\u7a97\u53e3\u5b9a\u4e49\uff0c\u89c4\u5212\u5668\u4f1a\u6309\u9700\u751f\u6210\u591a\u4e2a\u5806\u53e0\u7684 WindowAgg\uff0c\u5e76\u5728\u5176\u95f4\u63d2\u5165 Sort \u8282\u70b9\u3002\uff09", "\u7a97\u53e3\u51fd\u6570\u53ef\u80fd\u9700\u8981\u8bbf\u95ee\u5f53\u524d\u5206\u533a\u7684\u4efb\u610f\u884c\u4e43\u81f3\u5168\u90e8\u884c\uff0c\u56e0\u6b64\u5c06\u5206\u533a\u884c\u7d2f\u79ef\u5230\u5143\u7ec4\u5b58\u50a8\u3002\u901a\u8fc7 WindowObject API \u8c03\u7528\u7a97\u53e3\u51fd\u6570\uff0c\u4f7f\u5176\u6309\u9700\u8bbf\u95ee\u8fd9\u4e9b\u884c\u3002", "\u4e5f\u652f\u6301\u5c06\u666e\u901a\u805a\u5408\u51fd\u6570\u7528\u4f5c\u7a97\u53e3\u51fd\u6570\u3002\u6b64\u65f6\u4e3a\u6bcf\u4e2a\u5206\u533a\u6a21\u62df\u5e38\u89c4 Agg \u8282\u70b9\u73af\u5883\u3002\u6309 SQL \u89c4\u8303\uff0c\u8f93\u51fa\u4e3a\u8be5\u805a\u5408\u51fd\u6570\u5728\u5f53\u524d\u884c\u7a97\u53e3\u6846\u67b6\u5185\u5168\u90e8\u884c\u4e0a\u7684\u7ed3\u679c\u3002", "\u6240\u6709\u7a97\u53e3\u51fd\u6570 API \u90fd\u4f7f\u7528\u6b64\u5bf9\u8c61\u8c03\u7528\uff1b\u6b64\u5bf9\u8c61\u901a\u8fc7 fcinfo->context \u4f20\u7ed9\u7a97\u53e3\u51fd\u6570\u3002", "\u6b64\u8282\u70b9\u5904\u7406\u7684\u6bcf\u4e2a\u7a97\u53e3\u51fd\u6570\u548c\u7a97\u53e3\u805a\u5408\u90fd\u5bf9\u5e94\u4e00\u4e2a WindowStatePerFunc \u7ed3\u6784\u3002"]}, {"code": "case T_WindowAgg:\n\t\t\tpname = sname = \"WindowAgg\";\n\t\t\tbreak;", "title": "\u6838\u5fc3\u6e90\u7801\u4e2d\u7684 EXPLAIN \u6807\u8bc6"}], "strategies": [], "description": ["\u5728\u5b50\u8ba1\u5212\u8f93\u51fa\u7684\u6709\u5e8f\u5206\u533a\u4e0a\u8ba1\u7b97\u7a97\u53e3\u51fd\u6570\u3002"], "localization": {"status": "complete", "sources": [], "language": "zh", "original_text": {"/versions/14/description/0": "Evaluates window functions over ordered partitions of its child output.", "/versions/14/facts/0/label": "Core node tag", "/versions/14/facts/1/label": "Structured EXPLAIN Node Type", "/versions/14/facts/2/label": "Inputs", "/versions/14/facts/2/value": "One suitably ordered child plan", "/versions/14/facts/3/label": "Output", "/versions/14/facts/3/value": "Tuples with window-function results", "/versions/14/facts/4/label": "Executor initializer", "/versions/14/facts/5/label": "Memory mechanism", "/versions/14/tables/0/title": "EXPLAIN labels in this source build", "/versions/14/related/1/label": "Using EXPLAIN", "/versions/14/related/2/label": "Parallel plans", "/versions/14/sections/0/title": "EXPLAIN names and attributes", "/versions/14/sections/1/title": "Memory and temporary storage", "/versions/14/sections/2/title": "Parallel execution and instrumentation", "/versions/14/sections/3/title": "Executor implementation notes", "/versions/14/sections/4/title": "EXPLAIN identity in core source", "/versions/14/memory/description": "This node creates a tuplestore with work_mem. The tuplestore can move stored tuples to temporary files; this does not make work_mem a cap on every allocation made by the node.", "/versions/14/sections/0/paragraphs/0": "Structured formats use the Node Type above. Text-format spellings can also include operation, strategy, join type, scan direction or aggregation-stage attributes.", "/versions/14/sections/0/paragraphs/1": "Text names recorded by this source: WindowAgg.", "/versions/14/sections/0/paragraphs/2": "Parallel-aware and parallel-safe are different plan properties. A node running inside a parallel worker is not necessarily a parallel-aware node.", "/versions/14/sections/1/paragraphs/0": "This node creates a tuplestore with work_mem. The tuplestore can move stored tuples to temporary files; this does not make work_mem a cap on every allocation made by the node.", "/versions/14/sections/1/paragraphs/1": "If the tuplestore has spilled to disk, alternate reading and writing becomes quite expensive due to frequent buffer flushes. It's cheaper to force the entire partition to get spooled in one go.", "/versions/14/sections/1/paragraphs/2": "Read the current row from the tuplestore, and save in ScanTupleSlot. (We can't rely on the outerplan's output slot because we may have to read beyond the current row. Also, we have to actually copy the row out of the tuplestore, since window function evaluation might cause the tuplestore to dump its state to disk.)", "/versions/14/sections/1/paragraphs/3": "Window functions do not have to call this, but are encouraged to move the mark forward when possible to keep the tuplestore size down and prevent having to spill rows to disk.", "/versions/14/sections/2/paragraphs/0": "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.", "/versions/14/sections/2/paragraphs/1": "Callbacks in this build: none extracted from this node implementation.", "/versions/14/sections/3/paragraphs/0": "A WindowAgg node evaluates \"window functions\" across suitable partitions of the input tuple set. Any one WindowAgg works for just a single window specification, though it can evaluate multiple window functions sharing identical window specifications. The input tuples are required to be delivered in sorted order, with the PARTITION BY columns (if any) as major sort keys and the ORDER BY columns (if any) as minor sort keys. (The planner generates a stack of WindowAggs with intervening Sort nodes as needed, if a query involves more than one window specification.)", "/versions/14/sections/3/paragraphs/1": "Since window functions can require access to any or all of the rows in the current partition, we accumulate rows of the partition into a tuplestore. The window functions are called using the WindowObject API so that they can access those rows as needed.", "/versions/14/sections/3/paragraphs/2": "We also support using plain aggregate functions as window functions. For these, the regular Agg-node environment is emulated for each partition. As required by the SQL spec, the output represents the value of the aggregate function over all rows in the current row's window frame.", "/versions/14/sections/3/paragraphs/3": "All the window function APIs are called with this object, which is passed to window functions as fcinfo->context.", "/versions/14/sections/3/paragraphs/4": "We have one WindowStatePerFunc struct for each window function and window aggregate handled by this node.", "/versions/14/tables/0/columns/0/label": "Text-format label", "/versions/14/tables/0/columns/1/label": "Structured node identity"}, "fallback_fields": [], "source_language": "en", "original_snapshot_sha256": "f0f4fcdb33679af42954fab949c9cae3004f9865a0608632f91fc0772c9e029b"}, "evidence_kind": "source and documentation", "explain_names": ["WindowAgg"], "partial_modes": [], "comparison_data": {"node_tag": "T_WindowAgg", "strategies": [], "text_names": ["WindowAgg"], "initializer": "ExecInitWindowAgg", "partial_modes": [], "memory_mechanism": "tuplestore", "parallel_callbacks": []}, "comparison_hash": "186aa5f13e96214f274161ba257307adf452233ebc64c9c0aaebfaee73fac8a4", "explain_prefixes": ["Parallel", "Async"], "runtime_verified": false, "source_inventory": {"explain": "src/backend/commands/explain.c", "executor": "src/backend/executor/execProcnode.c", "implementation": "src/backend/executor/nodeWindowAgg.c"}, "parallel_callbacks": []}, "15": {"facts": [{"label": "\u6838\u5fc3\u8282\u70b9\u6807\u7b7e", "value": "T_WindowAgg"}, {"label": "\u7ed3\u6784\u5316 EXPLAIN \u8282\u70b9\u7c7b\u578b", "value": "WindowAgg"}, {"label": "\u8f93\u5165", "value": "\u4e00\u4e2a\u6ee1\u8db3\u6392\u5e8f\u8981\u6c42\u7684\u5b50\u8ba1\u5212"}, {"label": "\u8f93\u51fa", "value": "\u5e26\u7a97\u53e3\u51fd\u6570\u7ed3\u679c\u7684\u5143\u7ec4"}, {"label": "\u6267\u884c\u5668\u521d\u59cb\u5316\u51fd\u6570", "value": "ExecInitWindowAgg"}, {"label": "\u5185\u5b58\u673a\u5236", "value": "tuplestore"}], "memory": {"evidence": [{"url": "https://ftp.postgresql.org/pub/source/v15.19/postgresql-15.19.tar.bz2", "path": "src/backend/executor/nodeWindowAgg.c", "label": "src/backend/executor/nodeWindowAgg.c", "sha256": "ff783ae98437fb6679ec73ba6c2faa06d6cd722cc0a319339b2eaba76f00793d", "archive_sha256": "e1a64a87a46b825b88c082e4518161a47aab53c45694964f8ba1df28f7859f89"}, {"url": "https://ftp.postgresql.org/pub/source/v15.19/postgresql-15.19.tar.bz2", "path": "src/backend/utils/sort/tuplestore.c", "label": "src/backend/utils/sort/tuplestore.c", "sha256": "37be0ffb18c97558ea6fe6e1e0072564026b231edb9edf0a29faf27f13827aab", "archive_sha256": "e1a64a87a46b825b88c082e4518161a47aab53c45694964f8ba1df28f7859f89"}], "mechanism": "tuplestore", "description": "\u6b64\u8282\u70b9\u4f7f\u7528 work_mem \u521b\u5efa tuplestore\u3002tuplestore \u53ef\u4ee5\u5c06\u5b58\u50a8\u7684\u5143\u7ec4\u79fb\u5230\u4e34\u65f6\u6587\u4ef6\uff0c\u4f46\u8fd9\u4e0d\u610f\u5473\u7740 work_mem \u9650\u5236\u4e86\u8282\u70b9\u7684\u5168\u90e8\u5185\u5b58\u5206\u914d\u3002", "source_notes": ["If the tuplestore has spilled to disk, alternate reading and writing becomes quite expensive due to frequent buffer flushes. It's cheaper to force the entire partition to get spooled in one go.", "Read the current row from the tuplestore, and save in ScanTupleSlot. (We can't rely on the outerplan's output slot because we may have to read beyond the current row. Also, we have to actually copy the row out of the tuplestore, since window function evaluation might cause the tuplestore to dump its state to disk.)", "Window functions do not have to call this, but are encouraged to move the mark forward when possible to keep the tuplestore size down and prevent having to spill rows to disk."]}, "tables": [{"key": "explain-labels", "rows": [{"label": "WindowAgg", "identity": "WindowAgg"}], "title": "\u672c\u6784\u5efa\u4e2d\u7684 EXPLAIN \u6807\u7b7e", "columns": [{"key": "label", "label": "\u6587\u672c\u683c\u5f0f\u6807\u7b7e"}, {"key": "identity", "label": "\u7ed3\u6784\u5316\u8282\u70b9\u6807\u8bc6"}]}], "related": [{"url": "/wiki/sql/explain/?v=15", "label": "EXPLAIN"}, {"url": "/docs/15/using-explain.html", "label": "\u4f7f\u7528 EXPLAIN"}, {"url": "/docs/15/parallel-plans.html", "label": "\u5e76\u884c\u8ba1\u5212"}, {"url": "/wiki/guc/work_mem/?v=15", "label": "work_mem"}], "release": {"ref": "PostgreSQL 15.19 source archive", "label": "15.19", "major": "15", "channel": "stable", "revision": "e1a64a87a46b825b88c082e4518161a47aab53c45694964f8ba1df28f7859f89", "source_url": "https://ftp.postgresql.org/pub/source/v15.19/postgresql-15.19.tar.bz2", "source_snapshot_utc": ""}, "sources": [{"url": "https://ftp.postgresql.org/pub/source/v15.19/postgresql-15.19.tar.bz2", "line": 1367, "path": "src/backend/commands/explain.c", "label": "src/backend/commands/explain.c:1367", "sha256": "bb3b442d0f1b098aa8707335250102f027a596cd94117308bd16d1d36b258f5c", "archive_sha256": "e1a64a87a46b825b88c082e4518161a47aab53c45694964f8ba1df28f7859f89"}, {"url": "https://ftp.postgresql.org/pub/source/v15.19/postgresql-15.19.tar.bz2", "line": 345, "path": "src/backend/executor/execProcnode.c", "label": "src/backend/executor/execProcnode.c:345", "sha256": "19836c50a272741a4eac653541e655437c2e00710a541e5348d6a277d0669d7c", "archive_sha256": "e1a64a87a46b825b88c082e4518161a47aab53c45694964f8ba1df28f7859f89"}, {"url": "https://ftp.postgresql.org/pub/source/v15.19/postgresql-15.19.tar.bz2", "path": "src/backend/executor/nodeWindowAgg.c", "label": "src/backend/executor/nodeWindowAgg.c", "sha256": "ff783ae98437fb6679ec73ba6c2faa06d6cd722cc0a319339b2eaba76f00793d", "archive_sha256": "e1a64a87a46b825b88c082e4518161a47aab53c45694964f8ba1df28f7859f89"}, {"url": "https://ftp.postgresql.org/pub/source/v15.19/postgresql-15.19.tar.bz2", "path": "src/include/nodes/plannodes.h", "label": "src/include/nodes/plannodes.h", "sha256": "fb4a4c8165495299131173680bc02a950d88e1ff610231fd97997bc0c9afc1d7", "archive_sha256": "e1a64a87a46b825b88c082e4518161a47aab53c45694964f8ba1df28f7859f89"}, {"url": "https://ftp.postgresql.org/pub/source/v15.19/postgresql-15.19.tar.bz2", "path": "src/backend/utils/sort/tuplestore.c", "label": "src/backend/utils/sort/tuplestore.c", "sha256": "37be0ffb18c97558ea6fe6e1e0072564026b231edb9edf0a29faf27f13827aab", "archive_sha256": "e1a64a87a46b825b88c082e4518161a47aab53c45694964f8ba1df28f7859f89"}], "node_tag": "T_WindowAgg", "sections": [{"title": "EXPLAIN \u540d\u79f0\u4e0e\u5c5e\u6027", "paragraphs": ["\u7ed3\u6784\u5316\u683c\u5f0f\u4f7f\u7528\u4e0a\u8ff0 Node Type\u3002\u6587\u672c\u683c\u5f0f\u540d\u79f0\u8fd8\u53ef\u80fd\u5305\u542b\u64cd\u4f5c\u3001\u7b56\u7565\u3001\u8fde\u63a5\u7c7b\u578b\u3001\u626b\u63cf\u65b9\u5411\u6216\u805a\u5408\u9636\u6bb5\u5c5e\u6027\u3002", "\u6b64\u6e90\u7801\u8bb0\u5f55\u7684\u6587\u672c\u540d\u79f0\uff1aWindowAgg.", "\u5e76\u884c\u611f\u77e5\u4e0e\u5e76\u884c\u5b89\u5168\u662f\u4e0d\u540c\u7684\u8ba1\u5212\u5c5e\u6027\u3002\u5728\u5e76\u884c\u5de5\u4f5c\u8fdb\u7a0b\u5185\u8fd0\u884c\u7684\u8282\u70b9\u4e0d\u4e00\u5b9a\u662f\u5e76\u884c\u611f\u77e5\u8282\u70b9\u3002"]}, {"title": "\u5185\u5b58\u4e0e\u4e34\u65f6\u5b58\u50a8", "paragraphs": ["\u6b64\u8282\u70b9\u4f7f\u7528 work_mem \u521b\u5efa tuplestore\u3002tuplestore \u53ef\u4ee5\u5c06\u5b58\u50a8\u7684\u5143\u7ec4\u79fb\u5230\u4e34\u65f6\u6587\u4ef6\uff0c\u4f46\u8fd9\u4e0d\u610f\u5473\u7740 work_mem \u9650\u5236\u4e86\u8282\u70b9\u7684\u5168\u90e8\u5185\u5b58\u5206\u914d\u3002", "tuplestore \u5df2\u843d\u76d8\u65f6\uff0c\u4ea4\u66ff\u8bfb\u5199\u4f1a\u9891\u7e41\u5237\u65b0\u7f13\u51b2\u533a\uff0c\u4ee3\u4ef7\u5f88\u9ad8\u3002\u4e00\u6b21\u6027\u5c06\u6574\u4e2a\u5206\u533a\u5b58\u5165\u4e34\u65f6\u5b58\u50a8\u4f1a\u66f4\u4fbf\u5b9c\u3002", "\u4ece tuplestore \u8bfb\u53d6\u5f53\u524d\u884c\u5e76\u4fdd\u5b58\u5230 ScanTupleSlot\u3002\u4e0d\u80fd\u4f9d\u8d56\u5916\u5c42\u8ba1\u5212\u7684\u8f93\u51fa\u69fd\uff0c\u56e0\u4e3a\u53ef\u80fd\u9700\u8981\u8bfb\u53d6\u5f53\u524d\u884c\u4e4b\u540e\u7684\u6570\u636e\u3002\u6b64\u5916\uff0c\u5fc5\u987b\u5c06\u884c\u5b9e\u9645\u590d\u5236\u51fa tuplestore\uff0c\u56e0\u4e3a\u7a97\u53e3\u51fd\u6570\u6c42\u503c\u53ef\u80fd\u4f7f tuplestore \u5c06\u5176\u72b6\u6001\u5199\u5165\u78c1\u76d8\u3002", "\u7a97\u53e3\u51fd\u6570\u5e76\u975e\u5fc5\u987b\u8c03\u7528\u6b64\u51fd\u6570\uff0c\u4f46\u5efa\u8bae\u5728\u53ef\u80fd\u65f6\u524d\u79fb\u6807\u8bb0\uff0c\u4ee5\u51cf\u5c0f tuplestore \u5927\u5c0f\u5e76\u907f\u514d\u5c06\u884c\u5199\u5165\u78c1\u76d8\u3002"]}, {"title": "\u5e76\u884c\u6267\u884c\u4e0e\u8fd0\u884c\u4fe1\u606f\u91c7\u96c6", "paragraphs": ["\u4ee5\u4e0b\u6e90\u7801\u56de\u8c03\u53ef\u4ee5\u534f\u8c03\u6267\u884c\u6216\u6536\u96c6\u5de5\u4f5c\u8fdb\u7a0b\u7684\u6d4b\u91cf\u6570\u636e\u3002\u56de\u8c03\u5b58\u5728\u4e0d\u4ee3\u8868\u8be5\u8282\u70b9\u666e\u904d\u652f\u6301\u5171\u4eab\u5e76\u884c\u626b\u63cf\u6216\u5171\u4eab\u72b6\u6001\u3002", "\u6b64\u6784\u5efa\u7684\u56de\u8c03\uff1anone extracted from this node implementation."]}, {"title": "\u6267\u884c\u5668\u5b9e\u73b0\u8bf4\u660e", "paragraphs": ["WindowAgg \u8282\u70b9\u5728\u8f93\u5165\u5143\u7ec4\u96c6\u5408\u7684\u9002\u5f53\u5206\u533a\u4e0a\u8ba1\u7b97\u201c\u7a97\u53e3\u51fd\u6570\u201d\u3002\u6bcf\u4e2a WindowAgg \u53ea\u5904\u7406\u4e00\u79cd\u7a97\u53e3\u5b9a\u4e49\uff0c\u4f46\u53ef\u4ee5\u8ba1\u7b97\u5171\u4eab\u76f8\u540c\u7a97\u53e3\u5b9a\u4e49\u7684\u591a\u4e2a\u7a97\u53e3\u51fd\u6570\u3002\u8f93\u5165\u5143\u7ec4\u5fc5\u987b\u6309\u6392\u5e8f\u987a\u5e8f\u9001\u8fbe\uff1aPARTITION BY \u5217\uff08\u5982\u679c\u6709\uff09\u4e3a\u4e3b\u8981\u6392\u5e8f\u952e\uff0cORDER BY \u5217\uff08\u5982\u679c\u6709\uff09\u4e3a\u6b21\u8981\u6392\u5e8f\u952e\u3002\uff08\u5982\u679c\u67e5\u8be2\u5305\u542b\u591a\u79cd\u7a97\u53e3\u5b9a\u4e49\uff0c\u89c4\u5212\u5668\u4f1a\u6309\u9700\u751f\u6210\u591a\u4e2a\u5806\u53e0\u7684 WindowAgg\uff0c\u5e76\u5728\u5176\u95f4\u63d2\u5165 Sort \u8282\u70b9\u3002\uff09", "\u7a97\u53e3\u51fd\u6570\u53ef\u80fd\u9700\u8981\u8bbf\u95ee\u5f53\u524d\u5206\u533a\u7684\u4efb\u610f\u884c\u4e43\u81f3\u5168\u90e8\u884c\uff0c\u56e0\u6b64\u5c06\u5206\u533a\u884c\u7d2f\u79ef\u5230\u5143\u7ec4\u5b58\u50a8\u3002\u901a\u8fc7 WindowObject API \u8c03\u7528\u7a97\u53e3\u51fd\u6570\uff0c\u4f7f\u5176\u6309\u9700\u8bbf\u95ee\u8fd9\u4e9b\u884c\u3002", "\u4e5f\u652f\u6301\u5c06\u666e\u901a\u805a\u5408\u51fd\u6570\u7528\u4f5c\u7a97\u53e3\u51fd\u6570\u3002\u6b64\u65f6\u4e3a\u6bcf\u4e2a\u5206\u533a\u6a21\u62df\u5e38\u89c4 Agg \u8282\u70b9\u73af\u5883\u3002\u6309 SQL \u89c4\u8303\uff0c\u8f93\u51fa\u4e3a\u8be5\u805a\u5408\u51fd\u6570\u5728\u5f53\u524d\u884c\u7a97\u53e3\u6846\u67b6\u5185\u5168\u90e8\u884c\u4e0a\u7684\u7ed3\u679c\u3002", "\u6240\u6709\u7a97\u53e3\u51fd\u6570 API \u90fd\u4f7f\u7528\u6b64\u5bf9\u8c61\u8c03\u7528\uff1b\u6b64\u5bf9\u8c61\u901a\u8fc7 fcinfo->context \u4f20\u7ed9\u7a97\u53e3\u51fd\u6570\u3002", "\u6b64\u8282\u70b9\u5904\u7406\u7684\u6bcf\u4e2a\u7a97\u53e3\u51fd\u6570\u548c\u7a97\u53e3\u805a\u5408\u90fd\u5bf9\u5e94\u4e00\u4e2a WindowStatePerFunc \u7ed3\u6784\u3002"]}, {"code": "case T_WindowAgg:\n\t\t\tpname = sname = \"WindowAgg\";\n\t\t\tbreak;", "title": "\u6838\u5fc3\u6e90\u7801\u4e2d\u7684 EXPLAIN \u6807\u8bc6"}], "strategies": [], "description": ["\u5728\u5b50\u8ba1\u5212\u8f93\u51fa\u7684\u6709\u5e8f\u5206\u533a\u4e0a\u8ba1\u7b97\u7a97\u53e3\u51fd\u6570\u3002"], "localization": {"status": "complete", "sources": [], "language": "zh", "original_text": {"/versions/15/description/0": "Evaluates window functions over ordered partitions of its child output.", "/versions/15/facts/0/label": "Core node tag", "/versions/15/facts/1/label": "Structured EXPLAIN Node Type", "/versions/15/facts/2/label": "Inputs", "/versions/15/facts/2/value": "One suitably ordered child plan", "/versions/15/facts/3/label": "Output", "/versions/15/facts/3/value": "Tuples with window-function results", "/versions/15/facts/4/label": "Executor initializer", "/versions/15/facts/5/label": "Memory mechanism", "/versions/15/tables/0/title": "EXPLAIN labels in this source build", "/versions/15/related/1/label": "Using EXPLAIN", "/versions/15/related/2/label": "Parallel plans", "/versions/15/sections/0/title": "EXPLAIN names and attributes", "/versions/15/sections/1/title": "Memory and temporary storage", "/versions/15/sections/2/title": "Parallel execution and instrumentation", "/versions/15/sections/3/title": "Executor implementation notes", "/versions/15/sections/4/title": "EXPLAIN identity in core source", "/versions/15/memory/description": "This node creates a tuplestore with work_mem. The tuplestore can move stored tuples to temporary files; this does not make work_mem a cap on every allocation made by the node.", "/versions/15/sections/0/paragraphs/0": "Structured formats use the Node Type above. Text-format spellings can also include operation, strategy, join type, scan direction or aggregation-stage attributes.", "/versions/15/sections/0/paragraphs/1": "Text names recorded by this source: WindowAgg.", "/versions/15/sections/0/paragraphs/2": "Parallel-aware and parallel-safe are different plan properties. A node running inside a parallel worker is not necessarily a parallel-aware node.", "/versions/15/sections/1/paragraphs/0": "This node creates a tuplestore with work_mem. The tuplestore can move stored tuples to temporary files; this does not make work_mem a cap on every allocation made by the node.", "/versions/15/sections/1/paragraphs/1": "If the tuplestore has spilled to disk, alternate reading and writing becomes quite expensive due to frequent buffer flushes. It's cheaper to force the entire partition to get spooled in one go.", "/versions/15/sections/1/paragraphs/2": "Read the current row from the tuplestore, and save in ScanTupleSlot. (We can't rely on the outerplan's output slot because we may have to read beyond the current row. Also, we have to actually copy the row out of the tuplestore, since window function evaluation might cause the tuplestore to dump its state to disk.)", "/versions/15/sections/1/paragraphs/3": "Window functions do not have to call this, but are encouraged to move the mark forward when possible to keep the tuplestore size down and prevent having to spill rows to disk.", "/versions/15/sections/2/paragraphs/0": "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.", "/versions/15/sections/2/paragraphs/1": "Callbacks in this build: none extracted from this node implementation.", "/versions/15/sections/3/paragraphs/0": "A WindowAgg node evaluates \"window functions\" across suitable partitions of the input tuple set. Any one WindowAgg works for just a single window specification, though it can evaluate multiple window functions sharing identical window specifications. The input tuples are required to be delivered in sorted order, with the PARTITION BY columns (if any) as major sort keys and the ORDER BY columns (if any) as minor sort keys. (The planner generates a stack of WindowAggs with intervening Sort nodes as needed, if a query involves more than one window specification.)", "/versions/15/sections/3/paragraphs/1": "Since window functions can require access to any or all of the rows in the current partition, we accumulate rows of the partition into a tuplestore. The window functions are called using the WindowObject API so that they can access those rows as needed.", "/versions/15/sections/3/paragraphs/2": "We also support using plain aggregate functions as window functions. For these, the regular Agg-node environment is emulated for each partition. As required by the SQL spec, the output represents the value of the aggregate function over all rows in the current row's window frame.", "/versions/15/sections/3/paragraphs/3": "All the window function APIs are called with this object, which is passed to window functions as fcinfo->context.", "/versions/15/sections/3/paragraphs/4": "We have one WindowStatePerFunc struct for each window function and window aggregate handled by this node.", "/versions/15/tables/0/columns/0/label": "Text-format label", "/versions/15/tables/0/columns/1/label": "Structured node identity"}, "fallback_fields": [], "source_language": "en", "original_snapshot_sha256": "9e93dac1a5fd668e75a68bda49379fc0be2394bbdf1d195cb9957f41685060ce"}, "evidence_kind": "source and documentation", "explain_names": ["WindowAgg"], "partial_modes": [], "comparison_data": {"node_tag": "T_WindowAgg", "strategies": [], "text_names": ["WindowAgg"], "initializer": "ExecInitWindowAgg", "partial_modes": [], "memory_mechanism": "tuplestore", "parallel_callbacks": []}, "comparison_hash": "186aa5f13e96214f274161ba257307adf452233ebc64c9c0aaebfaee73fac8a4", "explain_prefixes": ["Parallel", "Async"], "runtime_verified": false, "source_inventory": {"explain": "src/backend/commands/explain.c", "executor": "src/backend/executor/execProcnode.c", "implementation": "src/backend/executor/nodeWindowAgg.c"}, "parallel_callbacks": []}, "16": {"facts": [{"label": "\u6838\u5fc3\u8282\u70b9\u6807\u7b7e", "value": "T_WindowAgg"}, {"label": "\u7ed3\u6784\u5316 EXPLAIN \u8282\u70b9\u7c7b\u578b", "value": "WindowAgg"}, {"label": "\u8f93\u5165", "value": "\u4e00\u4e2a\u6ee1\u8db3\u6392\u5e8f\u8981\u6c42\u7684\u5b50\u8ba1\u5212"}, {"label": "\u8f93\u51fa", "value": "\u5e26\u7a97\u53e3\u51fd\u6570\u7ed3\u679c\u7684\u5143\u7ec4"}, {"label": "\u6267\u884c\u5668\u521d\u59cb\u5316\u51fd\u6570", "value": "ExecInitWindowAgg"}, {"label": "\u5185\u5b58\u673a\u5236", "value": "tuplestore"}], "memory": {"evidence": [{"url": "https://ftp.postgresql.org/pub/source/v16.15/postgresql-16.15.tar.bz2", "path": "src/backend/executor/nodeWindowAgg.c", "label": "src/backend/executor/nodeWindowAgg.c", "sha256": "cb383f6ee98c12958b7fee31cf4f143ec29c465c0b2a4a06fccc63197c3fc397", "archive_sha256": "c1575341fa7bd40f5274ea465b34390f4dc64cdd0770af327005caaeb9f6b7ed"}, {"url": "https://ftp.postgresql.org/pub/source/v16.15/postgresql-16.15.tar.bz2", "path": "src/backend/utils/sort/tuplestore.c", "label": "src/backend/utils/sort/tuplestore.c", "sha256": "a990669858f1847ac83b5e1e65cf5515fe05ea0ad45ff64dd9347ba4f2110e62", "archive_sha256": "c1575341fa7bd40f5274ea465b34390f4dc64cdd0770af327005caaeb9f6b7ed"}], "mechanism": "tuplestore", "description": "\u6b64\u8282\u70b9\u4f7f\u7528 work_mem \u521b\u5efa tuplestore\u3002tuplestore \u53ef\u4ee5\u5c06\u5b58\u50a8\u7684\u5143\u7ec4\u79fb\u5230\u4e34\u65f6\u6587\u4ef6\uff0c\u4f46\u8fd9\u4e0d\u610f\u5473\u7740 work_mem \u9650\u5236\u4e86\u8282\u70b9\u7684\u5168\u90e8\u5185\u5b58\u5206\u914d\u3002", "source_notes": ["If the tuplestore has spilled to disk, alternate reading and writing becomes quite expensive due to frequent buffer flushes. It's cheaper to force the entire partition to get spooled in one go.", "Read the current row from the tuplestore, and save in ScanTupleSlot. (We can't rely on the outerplan's output slot because we may have to read beyond the current row. Also, we have to actually copy the row out of the tuplestore, since window function evaluation might cause the tuplestore to dump its state to disk.)", "Window functions do not have to call this, but are encouraged to move the mark forward when possible to keep the tuplestore size down and prevent having to spill rows to disk."]}, "tables": [{"key": "explain-labels", "rows": [{"label": "WindowAgg", "identity": "WindowAgg"}], "title": "\u672c\u6784\u5efa\u4e2d\u7684 EXPLAIN \u6807\u7b7e", "columns": [{"key": "label", "label": "\u6587\u672c\u683c\u5f0f\u6807\u7b7e"}, {"key": "identity", "label": "\u7ed3\u6784\u5316\u8282\u70b9\u6807\u8bc6"}]}], "related": [{"url": "/wiki/sql/explain/?v=16", "label": "EXPLAIN"}, {"url": "/docs/16/using-explain.html", "label": "\u4f7f\u7528 EXPLAIN"}, {"url": "/docs/16/parallel-plans.html", "label": "\u5e76\u884c\u8ba1\u5212"}, {"url": "/wiki/guc/work_mem/?v=16", "label": "work_mem"}], "release": {"ref": "PostgreSQL 16.15 source archive", "label": "16.15", "major": "16", "channel": "stable", "revision": "c1575341fa7bd40f5274ea465b34390f4dc64cdd0770af327005caaeb9f6b7ed", "source_url": "https://ftp.postgresql.org/pub/source/v16.15/postgresql-16.15.tar.bz2", "source_snapshot_utc": ""}, "sources": [{"url": "https://ftp.postgresql.org/pub/source/v16.15/postgresql-16.15.tar.bz2", "line": 1400, "path": "src/backend/commands/explain.c", "label": "src/backend/commands/explain.c:1400", "sha256": "8e017f0116dbea471339b40c37a667cc9f95039e7e0329c783e5e8ce194de7e1", "archive_sha256": "c1575341fa7bd40f5274ea465b34390f4dc64cdd0770af327005caaeb9f6b7ed"}, {"url": "https://ftp.postgresql.org/pub/source/v16.15/postgresql-16.15.tar.bz2", "line": 345, "path": "src/backend/executor/execProcnode.c", "label": "src/backend/executor/execProcnode.c:345", "sha256": "e48c08e555f8cb4e4bb43df516c4b8906ce9bc374b2a745d98a1fc8c22cc5099", "archive_sha256": "c1575341fa7bd40f5274ea465b34390f4dc64cdd0770af327005caaeb9f6b7ed"}, {"url": "https://ftp.postgresql.org/pub/source/v16.15/postgresql-16.15.tar.bz2", "path": "src/backend/executor/nodeWindowAgg.c", "label": "src/backend/executor/nodeWindowAgg.c", "sha256": "cb383f6ee98c12958b7fee31cf4f143ec29c465c0b2a4a06fccc63197c3fc397", "archive_sha256": "c1575341fa7bd40f5274ea465b34390f4dc64cdd0770af327005caaeb9f6b7ed"}, {"url": "https://ftp.postgresql.org/pub/source/v16.15/postgresql-16.15.tar.bz2", "path": "src/include/nodes/plannodes.h", "label": "src/include/nodes/plannodes.h", "sha256": "97db47353db76326b874589a5ad0a04501cc74cd72e237e7bd956e7472c41f1f", "archive_sha256": "c1575341fa7bd40f5274ea465b34390f4dc64cdd0770af327005caaeb9f6b7ed"}, {"url": "https://ftp.postgresql.org/pub/source/v16.15/postgresql-16.15.tar.bz2", "path": "src/backend/utils/sort/tuplestore.c", "label": "src/backend/utils/sort/tuplestore.c", "sha256": "a990669858f1847ac83b5e1e65cf5515fe05ea0ad45ff64dd9347ba4f2110e62", "archive_sha256": "c1575341fa7bd40f5274ea465b34390f4dc64cdd0770af327005caaeb9f6b7ed"}], "node_tag": "T_WindowAgg", "sections": [{"title": "EXPLAIN \u540d\u79f0\u4e0e\u5c5e\u6027", "paragraphs": ["\u7ed3\u6784\u5316\u683c\u5f0f\u4f7f\u7528\u4e0a\u8ff0 Node Type\u3002\u6587\u672c\u683c\u5f0f\u540d\u79f0\u8fd8\u53ef\u80fd\u5305\u542b\u64cd\u4f5c\u3001\u7b56\u7565\u3001\u8fde\u63a5\u7c7b\u578b\u3001\u626b\u63cf\u65b9\u5411\u6216\u805a\u5408\u9636\u6bb5\u5c5e\u6027\u3002", "\u6b64\u6e90\u7801\u8bb0\u5f55\u7684\u6587\u672c\u540d\u79f0\uff1aWindowAgg.", "\u5e76\u884c\u611f\u77e5\u4e0e\u5e76\u884c\u5b89\u5168\u662f\u4e0d\u540c\u7684\u8ba1\u5212\u5c5e\u6027\u3002\u5728\u5e76\u884c\u5de5\u4f5c\u8fdb\u7a0b\u5185\u8fd0\u884c\u7684\u8282\u70b9\u4e0d\u4e00\u5b9a\u662f\u5e76\u884c\u611f\u77e5\u8282\u70b9\u3002"]}, {"title": "\u5185\u5b58\u4e0e\u4e34\u65f6\u5b58\u50a8", "paragraphs": ["\u6b64\u8282\u70b9\u4f7f\u7528 work_mem \u521b\u5efa tuplestore\u3002tuplestore \u53ef\u4ee5\u5c06\u5b58\u50a8\u7684\u5143\u7ec4\u79fb\u5230\u4e34\u65f6\u6587\u4ef6\uff0c\u4f46\u8fd9\u4e0d\u610f\u5473\u7740 work_mem \u9650\u5236\u4e86\u8282\u70b9\u7684\u5168\u90e8\u5185\u5b58\u5206\u914d\u3002", "tuplestore \u5df2\u843d\u76d8\u65f6\uff0c\u4ea4\u66ff\u8bfb\u5199\u4f1a\u9891\u7e41\u5237\u65b0\u7f13\u51b2\u533a\uff0c\u4ee3\u4ef7\u5f88\u9ad8\u3002\u4e00\u6b21\u6027\u5c06\u6574\u4e2a\u5206\u533a\u5b58\u5165\u4e34\u65f6\u5b58\u50a8\u4f1a\u66f4\u4fbf\u5b9c\u3002", "\u4ece tuplestore \u8bfb\u53d6\u5f53\u524d\u884c\u5e76\u4fdd\u5b58\u5230 ScanTupleSlot\u3002\u4e0d\u80fd\u4f9d\u8d56\u5916\u5c42\u8ba1\u5212\u7684\u8f93\u51fa\u69fd\uff0c\u56e0\u4e3a\u53ef\u80fd\u9700\u8981\u8bfb\u53d6\u5f53\u524d\u884c\u4e4b\u540e\u7684\u6570\u636e\u3002\u6b64\u5916\uff0c\u5fc5\u987b\u5c06\u884c\u5b9e\u9645\u590d\u5236\u51fa tuplestore\uff0c\u56e0\u4e3a\u7a97\u53e3\u51fd\u6570\u6c42\u503c\u53ef\u80fd\u4f7f tuplestore \u5c06\u5176\u72b6\u6001\u5199\u5165\u78c1\u76d8\u3002", "\u7a97\u53e3\u51fd\u6570\u5e76\u975e\u5fc5\u987b\u8c03\u7528\u6b64\u51fd\u6570\uff0c\u4f46\u5efa\u8bae\u5728\u53ef\u80fd\u65f6\u524d\u79fb\u6807\u8bb0\uff0c\u4ee5\u51cf\u5c0f tuplestore \u5927\u5c0f\u5e76\u907f\u514d\u5c06\u884c\u5199\u5165\u78c1\u76d8\u3002"]}, {"title": "\u5e76\u884c\u6267\u884c\u4e0e\u8fd0\u884c\u4fe1\u606f\u91c7\u96c6", "paragraphs": ["\u4ee5\u4e0b\u6e90\u7801\u56de\u8c03\u53ef\u4ee5\u534f\u8c03\u6267\u884c\u6216\u6536\u96c6\u5de5\u4f5c\u8fdb\u7a0b\u7684\u6d4b\u91cf\u6570\u636e\u3002\u56de\u8c03\u5b58\u5728\u4e0d\u4ee3\u8868\u8be5\u8282\u70b9\u666e\u904d\u652f\u6301\u5171\u4eab\u5e76\u884c\u626b\u63cf\u6216\u5171\u4eab\u72b6\u6001\u3002", "\u6b64\u6784\u5efa\u7684\u56de\u8c03\uff1anone extracted from this node implementation."]}, {"title": "\u6267\u884c\u5668\u5b9e\u73b0\u8bf4\u660e", "paragraphs": ["WindowAgg \u8282\u70b9\u5728\u8f93\u5165\u5143\u7ec4\u96c6\u5408\u7684\u9002\u5f53\u5206\u533a\u4e0a\u8ba1\u7b97\u201c\u7a97\u53e3\u51fd\u6570\u201d\u3002\u6bcf\u4e2a WindowAgg \u53ea\u5904\u7406\u4e00\u79cd\u7a97\u53e3\u5b9a\u4e49\uff0c\u4f46\u53ef\u4ee5\u8ba1\u7b97\u5171\u4eab\u76f8\u540c\u7a97\u53e3\u5b9a\u4e49\u7684\u591a\u4e2a\u7a97\u53e3\u51fd\u6570\u3002\u8f93\u5165\u5143\u7ec4\u5fc5\u987b\u6309\u6392\u5e8f\u987a\u5e8f\u9001\u8fbe\uff1aPARTITION BY \u5217\uff08\u5982\u679c\u6709\uff09\u4e3a\u4e3b\u8981\u6392\u5e8f\u952e\uff0cORDER BY \u5217\uff08\u5982\u679c\u6709\uff09\u4e3a\u6b21\u8981\u6392\u5e8f\u952e\u3002\uff08\u5982\u679c\u67e5\u8be2\u5305\u542b\u591a\u79cd\u7a97\u53e3\u5b9a\u4e49\uff0c\u89c4\u5212\u5668\u4f1a\u6309\u9700\u751f\u6210\u591a\u4e2a\u5806\u53e0\u7684 WindowAgg\uff0c\u5e76\u5728\u5176\u95f4\u63d2\u5165 Sort \u8282\u70b9\u3002\uff09", "\u7a97\u53e3\u51fd\u6570\u53ef\u80fd\u9700\u8981\u8bbf\u95ee\u5f53\u524d\u5206\u533a\u7684\u4efb\u610f\u884c\u4e43\u81f3\u5168\u90e8\u884c\uff0c\u56e0\u6b64\u5c06\u5206\u533a\u884c\u7d2f\u79ef\u5230\u5143\u7ec4\u5b58\u50a8\u3002\u901a\u8fc7 WindowObject API \u8c03\u7528\u7a97\u53e3\u51fd\u6570\uff0c\u4f7f\u5176\u6309\u9700\u8bbf\u95ee\u8fd9\u4e9b\u884c\u3002", "\u4e5f\u652f\u6301\u5c06\u666e\u901a\u805a\u5408\u51fd\u6570\u7528\u4f5c\u7a97\u53e3\u51fd\u6570\u3002\u6b64\u65f6\u4e3a\u6bcf\u4e2a\u5206\u533a\u6a21\u62df\u5e38\u89c4 Agg \u8282\u70b9\u73af\u5883\u3002\u6309 SQL \u89c4\u8303\uff0c\u8f93\u51fa\u4e3a\u8be5\u805a\u5408\u51fd\u6570\u5728\u5f53\u524d\u884c\u7a97\u53e3\u6846\u67b6\u5185\u5168\u90e8\u884c\u4e0a\u7684\u7ed3\u679c\u3002", "\u6240\u6709\u7a97\u53e3\u51fd\u6570 API \u90fd\u4f7f\u7528\u6b64\u5bf9\u8c61\u8c03\u7528\uff1b\u6b64\u5bf9\u8c61\u901a\u8fc7 fcinfo->context \u4f20\u7ed9\u7a97\u53e3\u51fd\u6570\u3002", "\u6b64\u8282\u70b9\u5904\u7406\u7684\u6bcf\u4e2a\u7a97\u53e3\u51fd\u6570\u548c\u7a97\u53e3\u805a\u5408\u90fd\u5bf9\u5e94\u4e00\u4e2a WindowStatePerFunc \u7ed3\u6784\u3002"]}, {"code": "case T_WindowAgg:\n\t\t\tpname = sname = \"WindowAgg\";\n\t\t\tbreak;", "title": "\u6838\u5fc3\u6e90\u7801\u4e2d\u7684 EXPLAIN \u6807\u8bc6"}], "strategies": [], "description": ["\u5728\u5b50\u8ba1\u5212\u8f93\u51fa\u7684\u6709\u5e8f\u5206\u533a\u4e0a\u8ba1\u7b97\u7a97\u53e3\u51fd\u6570\u3002"], "localization": {"status": "complete", "sources": [], "language": "zh", "original_text": {"/versions/16/description/0": "Evaluates window functions over ordered partitions of its child output.", "/versions/16/facts/0/label": "Core node tag", "/versions/16/facts/1/label": "Structured EXPLAIN Node Type", "/versions/16/facts/2/label": "Inputs", "/versions/16/facts/2/value": "One suitably ordered child plan", "/versions/16/facts/3/label": "Output", "/versions/16/facts/3/value": "Tuples with window-function results", "/versions/16/facts/4/label": "Executor initializer", "/versions/16/facts/5/label": "Memory mechanism", "/versions/16/tables/0/title": "EXPLAIN labels in this source build", "/versions/16/related/1/label": "Using EXPLAIN", "/versions/16/related/2/label": "Parallel plans", "/versions/16/sections/0/title": "EXPLAIN names and attributes", "/versions/16/sections/1/title": "Memory and temporary storage", "/versions/16/sections/2/title": "Parallel execution and instrumentation", "/versions/16/sections/3/title": "Executor implementation notes", "/versions/16/sections/4/title": "EXPLAIN identity in core source", "/versions/16/memory/description": "This node creates a tuplestore with work_mem. The tuplestore can move stored tuples to temporary files; this does not make work_mem a cap on every allocation made by the node.", "/versions/16/sections/0/paragraphs/0": "Structured formats use the Node Type above. Text-format spellings can also include operation, strategy, join type, scan direction or aggregation-stage attributes.", "/versions/16/sections/0/paragraphs/1": "Text names recorded by this source: WindowAgg.", "/versions/16/sections/0/paragraphs/2": "Parallel-aware and parallel-safe are different plan properties. A node running inside a parallel worker is not necessarily a parallel-aware node.", "/versions/16/sections/1/paragraphs/0": "This node creates a tuplestore with work_mem. The tuplestore can move stored tuples to temporary files; this does not make work_mem a cap on every allocation made by the node.", "/versions/16/sections/1/paragraphs/1": "If the tuplestore has spilled to disk, alternate reading and writing becomes quite expensive due to frequent buffer flushes. It's cheaper to force the entire partition to get spooled in one go.", "/versions/16/sections/1/paragraphs/2": "Read the current row from the tuplestore, and save in ScanTupleSlot. (We can't rely on the outerplan's output slot because we may have to read beyond the current row. Also, we have to actually copy the row out of the tuplestore, since window function evaluation might cause the tuplestore to dump its state to disk.)", "/versions/16/sections/1/paragraphs/3": "Window functions do not have to call this, but are encouraged to move the mark forward when possible to keep the tuplestore size down and prevent having to spill rows to disk.", "/versions/16/sections/2/paragraphs/0": "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.", "/versions/16/sections/2/paragraphs/1": "Callbacks in this build: none extracted from this node implementation.", "/versions/16/sections/3/paragraphs/0": "A WindowAgg node evaluates \"window functions\" across suitable partitions of the input tuple set. Any one WindowAgg works for just a single window specification, though it can evaluate multiple window functions sharing identical window specifications. The input tuples are required to be delivered in sorted order, with the PARTITION BY columns (if any) as major sort keys and the ORDER BY columns (if any) as minor sort keys. (The planner generates a stack of WindowAggs with intervening Sort nodes as needed, if a query involves more than one window specification.)", "/versions/16/sections/3/paragraphs/1": "Since window functions can require access to any or all of the rows in the current partition, we accumulate rows of the partition into a tuplestore. The window functions are called using the WindowObject API so that they can access those rows as needed.", "/versions/16/sections/3/paragraphs/2": "We also support using plain aggregate functions as window functions. For these, the regular Agg-node environment is emulated for each partition. As required by the SQL spec, the output represents the value of the aggregate function over all rows in the current row's window frame.", "/versions/16/sections/3/paragraphs/3": "All the window function APIs are called with this object, which is passed to window functions as fcinfo->context.", "/versions/16/sections/3/paragraphs/4": "We have one WindowStatePerFunc struct for each window function and window aggregate handled by this node.", "/versions/16/tables/0/columns/0/label": "Text-format label", "/versions/16/tables/0/columns/1/label": "Structured node identity"}, "fallback_fields": [], "source_language": "en", "original_snapshot_sha256": "db7cf400815f1e100453ded6dabfce537f2f298787df4f000082e79fd65b6d9c"}, "evidence_kind": "source and documentation", "explain_names": ["WindowAgg"], "partial_modes": [], "comparison_data": {"node_tag": "T_WindowAgg", "strategies": [], "text_names": ["WindowAgg"], "initializer": "ExecInitWindowAgg", "partial_modes": [], "memory_mechanism": "tuplestore", "parallel_callbacks": []}, "comparison_hash": "186aa5f13e96214f274161ba257307adf452233ebc64c9c0aaebfaee73fac8a4", "explain_prefixes": ["Parallel", "Async"], "runtime_verified": false, "source_inventory": {"explain": "src/backend/commands/explain.c", "executor": "src/backend/executor/execProcnode.c", "implementation": "src/backend/executor/nodeWindowAgg.c"}, "parallel_callbacks": []}, "17": {"facts": [{"label": "\u6838\u5fc3\u8282\u70b9\u6807\u7b7e", "value": "T_WindowAgg"}, {"label": "\u7ed3\u6784\u5316 EXPLAIN \u8282\u70b9\u7c7b\u578b", "value": "WindowAgg"}, {"label": "\u8f93\u5165", "value": "\u4e00\u4e2a\u6ee1\u8db3\u6392\u5e8f\u8981\u6c42\u7684\u5b50\u8ba1\u5212"}, {"label": "\u8f93\u51fa", "value": "\u5e26\u7a97\u53e3\u51fd\u6570\u7ed3\u679c\u7684\u5143\u7ec4"}, {"label": "\u6267\u884c\u5668\u521d\u59cb\u5316\u51fd\u6570", "value": "ExecInitWindowAgg"}, {"label": "\u5185\u5b58\u673a\u5236", "value": "tuplestore"}], "memory": {"evidence": [{"url": "https://ftp.postgresql.org/pub/source/v17.11/postgresql-17.11.tar.bz2", "path": "src/backend/executor/nodeWindowAgg.c", "label": "src/backend/executor/nodeWindowAgg.c", "sha256": "3900bf7cfa857fbbee107195347946e83ba83aa9ac5e7ba6d5d6d54df216edb3", "archive_sha256": "dd27f2b3c59e73ed14aa3324901242bf69a032a6347805f274e6260322d42979"}, {"url": "https://ftp.postgresql.org/pub/source/v17.11/postgresql-17.11.tar.bz2", "path": "src/backend/utils/sort/tuplestore.c", "label": "src/backend/utils/sort/tuplestore.c", "sha256": "0d4316ed2d09288c2e3be15be1ce01b88622354bcd571ac7ebc45aa9319b90e7", "archive_sha256": "dd27f2b3c59e73ed14aa3324901242bf69a032a6347805f274e6260322d42979"}], "mechanism": "tuplestore", "description": "\u6b64\u8282\u70b9\u4f7f\u7528 work_mem \u521b\u5efa tuplestore\u3002tuplestore \u53ef\u4ee5\u5c06\u5b58\u50a8\u7684\u5143\u7ec4\u79fb\u5230\u4e34\u65f6\u6587\u4ef6\uff0c\u4f46\u8fd9\u4e0d\u610f\u5473\u7740 work_mem \u9650\u5236\u4e86\u8282\u70b9\u7684\u5168\u90e8\u5185\u5b58\u5206\u914d\u3002", "source_notes": ["If the tuplestore has spilled to disk, alternate reading and writing becomes quite expensive due to frequent buffer flushes. It's cheaper to force the entire partition to get spooled in one go.", "Read the current row from the tuplestore, and save in ScanTupleSlot. (We can't rely on the outerplan's output slot because we may have to read beyond the current row. Also, we have to actually copy the row out of the tuplestore, since window function evaluation might cause the tuplestore to dump its state to disk.)", "Window functions do not have to call this, but are encouraged to move the mark forward when possible to keep the tuplestore size down and prevent having to spill rows to disk."]}, "tables": [{"key": "explain-labels", "rows": [{"label": "WindowAgg", "identity": "WindowAgg"}], "title": "\u672c\u6784\u5efa\u4e2d\u7684 EXPLAIN \u6807\u7b7e", "columns": [{"key": "label", "label": "\u6587\u672c\u683c\u5f0f\u6807\u7b7e"}, {"key": "identity", "label": "\u7ed3\u6784\u5316\u8282\u70b9\u6807\u8bc6"}]}], "related": [{"url": "/wiki/sql/explain/?v=17", "label": "EXPLAIN"}, {"url": "/docs/17/using-explain.html", "label": "\u4f7f\u7528 EXPLAIN"}, {"url": "/docs/17/parallel-plans.html", "label": "\u5e76\u884c\u8ba1\u5212"}, {"url": "/wiki/guc/work_mem/?v=17", "label": "work_mem"}], "release": {"ref": "PostgreSQL 17.11 source archive", "label": "17.11", "major": "17", "channel": "stable", "revision": "dd27f2b3c59e73ed14aa3324901242bf69a032a6347805f274e6260322d42979", "source_url": "https://ftp.postgresql.org/pub/source/v17.11/postgresql-17.11.tar.bz2", "source_snapshot_utc": ""}, "sources": [{"url": "https://ftp.postgresql.org/pub/source/v17.11/postgresql-17.11.tar.bz2", "line": 1589, "path": "src/backend/commands/explain.c", "label": "src/backend/commands/explain.c:1589", "sha256": "741251b1a3b6d269a52a673d42eb63b02e13a5872db7b359b137086ab21b63c8", "archive_sha256": "dd27f2b3c59e73ed14aa3324901242bf69a032a6347805f274e6260322d42979"}, {"url": "https://ftp.postgresql.org/pub/source/v17.11/postgresql-17.11.tar.bz2", "line": 345, "path": "src/backend/executor/execProcnode.c", "label": "src/backend/executor/execProcnode.c:345", "sha256": "a77576e158b94cb01fa8c5174ba133004eabdd727660323f8afc66c8d2e757b8", "archive_sha256": "dd27f2b3c59e73ed14aa3324901242bf69a032a6347805f274e6260322d42979"}, {"url": "https://ftp.postgresql.org/pub/source/v17.11/postgresql-17.11.tar.bz2", "path": "src/backend/executor/nodeWindowAgg.c", "label": "src/backend/executor/nodeWindowAgg.c", "sha256": "3900bf7cfa857fbbee107195347946e83ba83aa9ac5e7ba6d5d6d54df216edb3", "archive_sha256": "dd27f2b3c59e73ed14aa3324901242bf69a032a6347805f274e6260322d42979"}, {"url": "https://ftp.postgresql.org/pub/source/v17.11/postgresql-17.11.tar.bz2", "path": "src/include/nodes/plannodes.h", "label": "src/include/nodes/plannodes.h", "sha256": "d390dd69e2d3f5085beb42b33e46ff0676a2959b916a12b82118a7e545f8e562", "archive_sha256": "dd27f2b3c59e73ed14aa3324901242bf69a032a6347805f274e6260322d42979"}, {"url": "https://ftp.postgresql.org/pub/source/v17.11/postgresql-17.11.tar.bz2", "path": "src/backend/utils/sort/tuplestore.c", "label": "src/backend/utils/sort/tuplestore.c", "sha256": "0d4316ed2d09288c2e3be15be1ce01b88622354bcd571ac7ebc45aa9319b90e7", "archive_sha256": "dd27f2b3c59e73ed14aa3324901242bf69a032a6347805f274e6260322d42979"}], "node_tag": "T_WindowAgg", "sections": [{"title": "EXPLAIN \u540d\u79f0\u4e0e\u5c5e\u6027", "paragraphs": ["\u7ed3\u6784\u5316\u683c\u5f0f\u4f7f\u7528\u4e0a\u8ff0 Node Type\u3002\u6587\u672c\u683c\u5f0f\u540d\u79f0\u8fd8\u53ef\u80fd\u5305\u542b\u64cd\u4f5c\u3001\u7b56\u7565\u3001\u8fde\u63a5\u7c7b\u578b\u3001\u626b\u63cf\u65b9\u5411\u6216\u805a\u5408\u9636\u6bb5\u5c5e\u6027\u3002", "\u6b64\u6e90\u7801\u8bb0\u5f55\u7684\u6587\u672c\u540d\u79f0\uff1aWindowAgg.", "\u5e76\u884c\u611f\u77e5\u4e0e\u5e76\u884c\u5b89\u5168\u662f\u4e0d\u540c\u7684\u8ba1\u5212\u5c5e\u6027\u3002\u5728\u5e76\u884c\u5de5\u4f5c\u8fdb\u7a0b\u5185\u8fd0\u884c\u7684\u8282\u70b9\u4e0d\u4e00\u5b9a\u662f\u5e76\u884c\u611f\u77e5\u8282\u70b9\u3002"]}, {"title": "\u5185\u5b58\u4e0e\u4e34\u65f6\u5b58\u50a8", "paragraphs": ["\u6b64\u8282\u70b9\u4f7f\u7528 work_mem \u521b\u5efa tuplestore\u3002tuplestore \u53ef\u4ee5\u5c06\u5b58\u50a8\u7684\u5143\u7ec4\u79fb\u5230\u4e34\u65f6\u6587\u4ef6\uff0c\u4f46\u8fd9\u4e0d\u610f\u5473\u7740 work_mem \u9650\u5236\u4e86\u8282\u70b9\u7684\u5168\u90e8\u5185\u5b58\u5206\u914d\u3002", "tuplestore \u5df2\u843d\u76d8\u65f6\uff0c\u4ea4\u66ff\u8bfb\u5199\u4f1a\u9891\u7e41\u5237\u65b0\u7f13\u51b2\u533a\uff0c\u4ee3\u4ef7\u5f88\u9ad8\u3002\u4e00\u6b21\u6027\u5c06\u6574\u4e2a\u5206\u533a\u5b58\u5165\u4e34\u65f6\u5b58\u50a8\u4f1a\u66f4\u4fbf\u5b9c\u3002", "\u4ece tuplestore \u8bfb\u53d6\u5f53\u524d\u884c\u5e76\u4fdd\u5b58\u5230 ScanTupleSlot\u3002\u4e0d\u80fd\u4f9d\u8d56\u5916\u5c42\u8ba1\u5212\u7684\u8f93\u51fa\u69fd\uff0c\u56e0\u4e3a\u53ef\u80fd\u9700\u8981\u8bfb\u53d6\u5f53\u524d\u884c\u4e4b\u540e\u7684\u6570\u636e\u3002\u6b64\u5916\uff0c\u5fc5\u987b\u5c06\u884c\u5b9e\u9645\u590d\u5236\u51fa tuplestore\uff0c\u56e0\u4e3a\u7a97\u53e3\u51fd\u6570\u6c42\u503c\u53ef\u80fd\u4f7f tuplestore \u5c06\u5176\u72b6\u6001\u5199\u5165\u78c1\u76d8\u3002", "\u7a97\u53e3\u51fd\u6570\u5e76\u975e\u5fc5\u987b\u8c03\u7528\u6b64\u51fd\u6570\uff0c\u4f46\u5efa\u8bae\u5728\u53ef\u80fd\u65f6\u524d\u79fb\u6807\u8bb0\uff0c\u4ee5\u51cf\u5c0f tuplestore \u5927\u5c0f\u5e76\u907f\u514d\u5c06\u884c\u5199\u5165\u78c1\u76d8\u3002"]}, {"title": "\u5e76\u884c\u6267\u884c\u4e0e\u8fd0\u884c\u4fe1\u606f\u91c7\u96c6", "paragraphs": ["\u4ee5\u4e0b\u6e90\u7801\u56de\u8c03\u53ef\u4ee5\u534f\u8c03\u6267\u884c\u6216\u6536\u96c6\u5de5\u4f5c\u8fdb\u7a0b\u7684\u6d4b\u91cf\u6570\u636e\u3002\u56de\u8c03\u5b58\u5728\u4e0d\u4ee3\u8868\u8be5\u8282\u70b9\u666e\u904d\u652f\u6301\u5171\u4eab\u5e76\u884c\u626b\u63cf\u6216\u5171\u4eab\u72b6\u6001\u3002", "\u6b64\u6784\u5efa\u7684\u56de\u8c03\uff1anone extracted from this node implementation."]}, {"title": "\u6267\u884c\u5668\u5b9e\u73b0\u8bf4\u660e", "paragraphs": ["WindowAgg \u8282\u70b9\u5728\u8f93\u5165\u5143\u7ec4\u96c6\u5408\u7684\u9002\u5f53\u5206\u533a\u4e0a\u8ba1\u7b97\u201c\u7a97\u53e3\u51fd\u6570\u201d\u3002\u6bcf\u4e2a WindowAgg \u53ea\u5904\u7406\u4e00\u79cd\u7a97\u53e3\u5b9a\u4e49\uff0c\u4f46\u53ef\u4ee5\u8ba1\u7b97\u5171\u4eab\u76f8\u540c\u7a97\u53e3\u5b9a\u4e49\u7684\u591a\u4e2a\u7a97\u53e3\u51fd\u6570\u3002\u8f93\u5165\u5143\u7ec4\u5fc5\u987b\u6309\u6392\u5e8f\u987a\u5e8f\u9001\u8fbe\uff1aPARTITION BY \u5217\uff08\u5982\u679c\u6709\uff09\u4e3a\u4e3b\u8981\u6392\u5e8f\u952e\uff0cORDER BY \u5217\uff08\u5982\u679c\u6709\uff09\u4e3a\u6b21\u8981\u6392\u5e8f\u952e\u3002\uff08\u5982\u679c\u67e5\u8be2\u5305\u542b\u591a\u79cd\u7a97\u53e3\u5b9a\u4e49\uff0c\u89c4\u5212\u5668\u4f1a\u6309\u9700\u751f\u6210\u591a\u4e2a\u5806\u53e0\u7684 WindowAgg\uff0c\u5e76\u5728\u5176\u95f4\u63d2\u5165 Sort \u8282\u70b9\u3002\uff09", "\u7a97\u53e3\u51fd\u6570\u53ef\u80fd\u9700\u8981\u8bbf\u95ee\u5f53\u524d\u5206\u533a\u7684\u4efb\u610f\u884c\u4e43\u81f3\u5168\u90e8\u884c\uff0c\u56e0\u6b64\u5c06\u5206\u533a\u884c\u7d2f\u79ef\u5230\u5143\u7ec4\u5b58\u50a8\u3002\u901a\u8fc7 WindowObject API \u8c03\u7528\u7a97\u53e3\u51fd\u6570\uff0c\u4f7f\u5176\u6309\u9700\u8bbf\u95ee\u8fd9\u4e9b\u884c\u3002", "\u4e5f\u652f\u6301\u5c06\u666e\u901a\u805a\u5408\u51fd\u6570\u7528\u4f5c\u7a97\u53e3\u51fd\u6570\u3002\u6b64\u65f6\u4e3a\u6bcf\u4e2a\u5206\u533a\u6a21\u62df\u5e38\u89c4 Agg \u8282\u70b9\u73af\u5883\u3002\u6309 SQL \u89c4\u8303\uff0c\u8f93\u51fa\u4e3a\u8be5\u805a\u5408\u51fd\u6570\u5728\u5f53\u524d\u884c\u7a97\u53e3\u6846\u67b6\u5185\u5168\u90e8\u884c\u4e0a\u7684\u7ed3\u679c\u3002", "\u6240\u6709\u7a97\u53e3\u51fd\u6570 API \u90fd\u4f7f\u7528\u6b64\u5bf9\u8c61\u8c03\u7528\uff1b\u6b64\u5bf9\u8c61\u901a\u8fc7 fcinfo->context \u4f20\u7ed9\u7a97\u53e3\u51fd\u6570\u3002", "\u6b64\u8282\u70b9\u5904\u7406\u7684\u6bcf\u4e2a\u7a97\u53e3\u51fd\u6570\u548c\u7a97\u53e3\u805a\u5408\u90fd\u5bf9\u5e94\u4e00\u4e2a WindowStatePerFunc \u7ed3\u6784\u3002"]}, {"code": "case T_WindowAgg:\n\t\t\tpname = sname = \"WindowAgg\";\n\t\t\tbreak;", "title": "\u6838\u5fc3\u6e90\u7801\u4e2d\u7684 EXPLAIN \u6807\u8bc6"}], "strategies": [], "description": ["\u5728\u5b50\u8ba1\u5212\u8f93\u51fa\u7684\u6709\u5e8f\u5206\u533a\u4e0a\u8ba1\u7b97\u7a97\u53e3\u51fd\u6570\u3002"], "localization": {"status": "complete", "sources": [], "language": "zh", "original_text": {"/versions/17/description/0": "Evaluates window functions over ordered partitions of its child output.", "/versions/17/facts/0/label": "Core node tag", "/versions/17/facts/1/label": "Structured EXPLAIN Node Type", "/versions/17/facts/2/label": "Inputs", "/versions/17/facts/2/value": "One suitably ordered child plan", "/versions/17/facts/3/label": "Output", "/versions/17/facts/3/value": "Tuples with window-function results", "/versions/17/facts/4/label": "Executor initializer", "/versions/17/facts/5/label": "Memory mechanism", "/versions/17/tables/0/title": "EXPLAIN labels in this source build", "/versions/17/related/1/label": "Using EXPLAIN", "/versions/17/related/2/label": "Parallel plans", "/versions/17/sections/0/title": "EXPLAIN names and attributes", "/versions/17/sections/1/title": "Memory and temporary storage", "/versions/17/sections/2/title": "Parallel execution and instrumentation", "/versions/17/sections/3/title": "Executor implementation notes", "/versions/17/sections/4/title": "EXPLAIN identity in core source", "/versions/17/memory/description": "This node creates a tuplestore with work_mem. The tuplestore can move stored tuples to temporary files; this does not make work_mem a cap on every allocation made by the node.", "/versions/17/sections/0/paragraphs/0": "Structured formats use the Node Type above. Text-format spellings can also include operation, strategy, join type, scan direction or aggregation-stage attributes.", "/versions/17/sections/0/paragraphs/1": "Text names recorded by this source: WindowAgg.", "/versions/17/sections/0/paragraphs/2": "Parallel-aware and parallel-safe are different plan properties. A node running inside a parallel worker is not necessarily a parallel-aware node.", "/versions/17/sections/1/paragraphs/0": "This node creates a tuplestore with work_mem. The tuplestore can move stored tuples to temporary files; this does not make work_mem a cap on every allocation made by the node.", "/versions/17/sections/1/paragraphs/1": "If the tuplestore has spilled to disk, alternate reading and writing becomes quite expensive due to frequent buffer flushes. It's cheaper to force the entire partition to get spooled in one go.", "/versions/17/sections/1/paragraphs/2": "Read the current row from the tuplestore, and save in ScanTupleSlot. (We can't rely on the outerplan's output slot because we may have to read beyond the current row. Also, we have to actually copy the row out of the tuplestore, since window function evaluation might cause the tuplestore to dump its state to disk.)", "/versions/17/sections/1/paragraphs/3": "Window functions do not have to call this, but are encouraged to move the mark forward when possible to keep the tuplestore size down and prevent having to spill rows to disk.", "/versions/17/sections/2/paragraphs/0": "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.", "/versions/17/sections/2/paragraphs/1": "Callbacks in this build: none extracted from this node implementation.", "/versions/17/sections/3/paragraphs/0": "A WindowAgg node evaluates \"window functions\" across suitable partitions of the input tuple set. Any one WindowAgg works for just a single window specification, though it can evaluate multiple window functions sharing identical window specifications. The input tuples are required to be delivered in sorted order, with the PARTITION BY columns (if any) as major sort keys and the ORDER BY columns (if any) as minor sort keys. (The planner generates a stack of WindowAggs with intervening Sort nodes as needed, if a query involves more than one window specification.)", "/versions/17/sections/3/paragraphs/1": "Since window functions can require access to any or all of the rows in the current partition, we accumulate rows of the partition into a tuplestore. The window functions are called using the WindowObject API so that they can access those rows as needed.", "/versions/17/sections/3/paragraphs/2": "We also support using plain aggregate functions as window functions. For these, the regular Agg-node environment is emulated for each partition. As required by the SQL spec, the output represents the value of the aggregate function over all rows in the current row's window frame.", "/versions/17/sections/3/paragraphs/3": "All the window function APIs are called with this object, which is passed to window functions as fcinfo->context.", "/versions/17/sections/3/paragraphs/4": "We have one WindowStatePerFunc struct for each window function and window aggregate handled by this node.", "/versions/17/tables/0/columns/0/label": "Text-format label", "/versions/17/tables/0/columns/1/label": "Structured node identity"}, "fallback_fields": [], "source_language": "en", "original_snapshot_sha256": "751b14cd8c1dac96a83a7aa6b2649af3739b61ce66ee42477c25bd6507b4ad20"}, "evidence_kind": "source and documentation", "explain_names": ["WindowAgg"], "partial_modes": [], "comparison_data": {"node_tag": "T_WindowAgg", "strategies": [], "text_names": ["WindowAgg"], "initializer": "ExecInitWindowAgg", "partial_modes": [], "memory_mechanism": "tuplestore", "parallel_callbacks": []}, "comparison_hash": "186aa5f13e96214f274161ba257307adf452233ebc64c9c0aaebfaee73fac8a4", "explain_prefixes": ["Parallel", "Async"], "runtime_verified": false, "source_inventory": {"explain": "src/backend/commands/explain.c", "executor": "src/backend/executor/execProcnode.c", "implementation": "src/backend/executor/nodeWindowAgg.c"}, "parallel_callbacks": []}, "18": {"facts": [{"label": "\u6838\u5fc3\u8282\u70b9\u6807\u7b7e", "value": "T_WindowAgg"}, {"label": "\u7ed3\u6784\u5316 EXPLAIN \u8282\u70b9\u7c7b\u578b", "value": "WindowAgg"}, {"label": "\u8f93\u5165", "value": "\u4e00\u4e2a\u6ee1\u8db3\u6392\u5e8f\u8981\u6c42\u7684\u5b50\u8ba1\u5212"}, {"label": "\u8f93\u51fa", "value": "\u5e26\u7a97\u53e3\u51fd\u6570\u7ed3\u679c\u7684\u5143\u7ec4"}, {"label": "\u6267\u884c\u5668\u521d\u59cb\u5316\u51fd\u6570", "value": "ExecInitWindowAgg"}, {"label": "\u5185\u5b58\u673a\u5236", "value": "tuplestore"}], "memory": {"evidence": [{"url": "https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2", "path": "src/backend/executor/nodeWindowAgg.c", "label": "src/backend/executor/nodeWindowAgg.c", "sha256": "c365e6750bc77a89562254903d099c3e5914e001d3aae418322ccffc1d535d17", "archive_sha256": "555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f"}, {"url": "https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2", "path": "src/backend/utils/sort/tuplestore.c", "label": "src/backend/utils/sort/tuplestore.c", "sha256": "27a85416bafed557006c705ab5d0c5dce3d3c1702812bb54d136f2ac4c41055a", "archive_sha256": "555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f"}], "mechanism": "tuplestore", "description": "\u6b64\u8282\u70b9\u4f7f\u7528 work_mem \u521b\u5efa tuplestore\u3002tuplestore \u53ef\u4ee5\u5c06\u5b58\u50a8\u7684\u5143\u7ec4\u79fb\u5230\u4e34\u65f6\u6587\u4ef6\uff0c\u4f46\u8fd9\u4e0d\u610f\u5473\u7740 work_mem \u9650\u5236\u4e86\u8282\u70b9\u7684\u5168\u90e8\u5185\u5b58\u5206\u914d\u3002", "source_notes": ["If the tuplestore has spilled to disk, alternate reading and writing becomes quite expensive due to frequent buffer flushes. It's cheaper to force the entire partition to get spooled in one go.", "Read the current row from the tuplestore, and save in ScanTupleSlot. (We can't rely on the outerplan's output slot because we may have to read beyond the current row. Also, we have to actually copy the row out of the tuplestore, since window function evaluation might cause the tuplestore to dump its state to disk.)", "Window functions do not have to call this, but are encouraged to move the mark forward when possible to keep the tuplestore size down and prevent having to spill rows to disk."]}, "tables": [{"key": "explain-labels", "rows": [{"label": "WindowAgg", "identity": "WindowAgg"}], "title": "\u672c\u6784\u5efa\u4e2d\u7684 EXPLAIN \u6807\u7b7e", "columns": [{"key": "label", "label": "\u6587\u672c\u683c\u5f0f\u6807\u7b7e"}, {"key": "identity", "label": "\u7ed3\u6784\u5316\u8282\u70b9\u6807\u8bc6"}]}], "related": [{"url": "/wiki/sql/explain/?v=18", "label": "EXPLAIN"}, {"url": "/docs/18/using-explain.html", "label": "\u4f7f\u7528 EXPLAIN"}, {"url": "/docs/18/parallel-plans.html", "label": "\u5e76\u884c\u8ba1\u5212"}, {"url": "/wiki/guc/work_mem/?v=18", "label": "work_mem"}], "release": {"ref": "PostgreSQL 18.6 source archive", "label": "18.6", "major": "18", "channel": "stable", "revision": "555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f", "source_url": "https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2", "source_snapshot_utc": ""}, "sources": [{"url": "https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2", "line": 1574, "path": "src/backend/commands/explain.c", "label": "src/backend/commands/explain.c:1574", "sha256": "34c86d6070224a0e981efef51f79101d6d505e5874f1684ace183034bab14bb4", "archive_sha256": "555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f"}, {"url": "https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2", "line": 345, "path": "src/backend/executor/execProcnode.c", "label": "src/backend/executor/execProcnode.c:345", "sha256": "f8a06a3f539077249b20664b2812433db6d7bd12b2c0ca633525db43d06f112a", "archive_sha256": "555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f"}, {"url": "https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2", "path": "src/backend/executor/nodeWindowAgg.c", "label": "src/backend/executor/nodeWindowAgg.c", "sha256": "c365e6750bc77a89562254903d099c3e5914e001d3aae418322ccffc1d535d17", "archive_sha256": "555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f"}, {"url": "https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2", "path": "src/include/nodes/plannodes.h", "label": "src/include/nodes/plannodes.h", "sha256": "52422b327a8049fbbb20d8b96008a0fc0a6fafa60f7eff3c695d5b2e83830120", "archive_sha256": "555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f"}, {"url": "https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2", "path": "src/backend/utils/sort/tuplestore.c", "label": "src/backend/utils/sort/tuplestore.c", "sha256": "27a85416bafed557006c705ab5d0c5dce3d3c1702812bb54d136f2ac4c41055a", "archive_sha256": "555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f"}], "node_tag": "T_WindowAgg", "sections": [{"title": "EXPLAIN \u540d\u79f0\u4e0e\u5c5e\u6027", "paragraphs": ["\u7ed3\u6784\u5316\u683c\u5f0f\u4f7f\u7528\u4e0a\u8ff0 Node Type\u3002\u6587\u672c\u683c\u5f0f\u540d\u79f0\u8fd8\u53ef\u80fd\u5305\u542b\u64cd\u4f5c\u3001\u7b56\u7565\u3001\u8fde\u63a5\u7c7b\u578b\u3001\u626b\u63cf\u65b9\u5411\u6216\u805a\u5408\u9636\u6bb5\u5c5e\u6027\u3002", "\u6b64\u6e90\u7801\u8bb0\u5f55\u7684\u6587\u672c\u540d\u79f0\uff1aWindowAgg.", "\u5e76\u884c\u611f\u77e5\u4e0e\u5e76\u884c\u5b89\u5168\u662f\u4e0d\u540c\u7684\u8ba1\u5212\u5c5e\u6027\u3002\u5728\u5e76\u884c\u5de5\u4f5c\u8fdb\u7a0b\u5185\u8fd0\u884c\u7684\u8282\u70b9\u4e0d\u4e00\u5b9a\u662f\u5e76\u884c\u611f\u77e5\u8282\u70b9\u3002"]}, {"title": "\u5185\u5b58\u4e0e\u4e34\u65f6\u5b58\u50a8", "paragraphs": ["\u6b64\u8282\u70b9\u4f7f\u7528 work_mem \u521b\u5efa tuplestore\u3002tuplestore \u53ef\u4ee5\u5c06\u5b58\u50a8\u7684\u5143\u7ec4\u79fb\u5230\u4e34\u65f6\u6587\u4ef6\uff0c\u4f46\u8fd9\u4e0d\u610f\u5473\u7740 work_mem \u9650\u5236\u4e86\u8282\u70b9\u7684\u5168\u90e8\u5185\u5b58\u5206\u914d\u3002", "tuplestore \u5df2\u843d\u76d8\u65f6\uff0c\u4ea4\u66ff\u8bfb\u5199\u4f1a\u9891\u7e41\u5237\u65b0\u7f13\u51b2\u533a\uff0c\u4ee3\u4ef7\u5f88\u9ad8\u3002\u4e00\u6b21\u6027\u5c06\u6574\u4e2a\u5206\u533a\u5b58\u5165\u4e34\u65f6\u5b58\u50a8\u4f1a\u66f4\u4fbf\u5b9c\u3002", "\u4ece tuplestore \u8bfb\u53d6\u5f53\u524d\u884c\u5e76\u4fdd\u5b58\u5230 ScanTupleSlot\u3002\u4e0d\u80fd\u4f9d\u8d56\u5916\u5c42\u8ba1\u5212\u7684\u8f93\u51fa\u69fd\uff0c\u56e0\u4e3a\u53ef\u80fd\u9700\u8981\u8bfb\u53d6\u5f53\u524d\u884c\u4e4b\u540e\u7684\u6570\u636e\u3002\u6b64\u5916\uff0c\u5fc5\u987b\u5c06\u884c\u5b9e\u9645\u590d\u5236\u51fa tuplestore\uff0c\u56e0\u4e3a\u7a97\u53e3\u51fd\u6570\u6c42\u503c\u53ef\u80fd\u4f7f tuplestore \u5c06\u5176\u72b6\u6001\u5199\u5165\u78c1\u76d8\u3002", "\u7a97\u53e3\u51fd\u6570\u5e76\u975e\u5fc5\u987b\u8c03\u7528\u6b64\u51fd\u6570\uff0c\u4f46\u5efa\u8bae\u5728\u53ef\u80fd\u65f6\u524d\u79fb\u6807\u8bb0\uff0c\u4ee5\u51cf\u5c0f tuplestore \u5927\u5c0f\u5e76\u907f\u514d\u5c06\u884c\u5199\u5165\u78c1\u76d8\u3002"]}, {"title": "\u5e76\u884c\u6267\u884c\u4e0e\u8fd0\u884c\u4fe1\u606f\u91c7\u96c6", "paragraphs": ["\u4ee5\u4e0b\u6e90\u7801\u56de\u8c03\u53ef\u4ee5\u534f\u8c03\u6267\u884c\u6216\u6536\u96c6\u5de5\u4f5c\u8fdb\u7a0b\u7684\u6d4b\u91cf\u6570\u636e\u3002\u56de\u8c03\u5b58\u5728\u4e0d\u4ee3\u8868\u8be5\u8282\u70b9\u666e\u904d\u652f\u6301\u5171\u4eab\u5e76\u884c\u626b\u63cf\u6216\u5171\u4eab\u72b6\u6001\u3002", "\u6b64\u6784\u5efa\u7684\u56de\u8c03\uff1anone extracted from this node implementation."]}, {"title": "\u6267\u884c\u5668\u5b9e\u73b0\u8bf4\u660e", "paragraphs": ["WindowAgg \u8282\u70b9\u5728\u8f93\u5165\u5143\u7ec4\u96c6\u5408\u7684\u9002\u5f53\u5206\u533a\u4e0a\u8ba1\u7b97\u201c\u7a97\u53e3\u51fd\u6570\u201d\u3002\u6bcf\u4e2a WindowAgg \u53ea\u5904\u7406\u4e00\u79cd\u7a97\u53e3\u5b9a\u4e49\uff0c\u4f46\u53ef\u4ee5\u8ba1\u7b97\u5171\u4eab\u76f8\u540c\u7a97\u53e3\u5b9a\u4e49\u7684\u591a\u4e2a\u7a97\u53e3\u51fd\u6570\u3002\u8f93\u5165\u5143\u7ec4\u5fc5\u987b\u6309\u6392\u5e8f\u987a\u5e8f\u9001\u8fbe\uff1aPARTITION BY \u5217\uff08\u5982\u679c\u6709\uff09\u4e3a\u4e3b\u8981\u6392\u5e8f\u952e\uff0cORDER BY \u5217\uff08\u5982\u679c\u6709\uff09\u4e3a\u6b21\u8981\u6392\u5e8f\u952e\u3002\uff08\u5982\u679c\u67e5\u8be2\u5305\u542b\u591a\u79cd\u7a97\u53e3\u5b9a\u4e49\uff0c\u89c4\u5212\u5668\u4f1a\u6309\u9700\u751f\u6210\u591a\u4e2a\u5806\u53e0\u7684 WindowAgg\uff0c\u5e76\u5728\u5176\u95f4\u63d2\u5165 Sort \u8282\u70b9\u3002\uff09", "\u7a97\u53e3\u51fd\u6570\u53ef\u80fd\u9700\u8981\u8bbf\u95ee\u5f53\u524d\u5206\u533a\u7684\u4efb\u610f\u884c\u4e43\u81f3\u5168\u90e8\u884c\uff0c\u56e0\u6b64\u5c06\u5206\u533a\u884c\u7d2f\u79ef\u5230\u5143\u7ec4\u5b58\u50a8\u3002\u901a\u8fc7 WindowObject API \u8c03\u7528\u7a97\u53e3\u51fd\u6570\uff0c\u4f7f\u5176\u6309\u9700\u8bbf\u95ee\u8fd9\u4e9b\u884c\u3002", "\u4e5f\u652f\u6301\u5c06\u666e\u901a\u805a\u5408\u51fd\u6570\u7528\u4f5c\u7a97\u53e3\u51fd\u6570\u3002\u6b64\u65f6\u4e3a\u6bcf\u4e2a\u5206\u533a\u6a21\u62df\u5e38\u89c4 Agg \u8282\u70b9\u73af\u5883\u3002\u6309 SQL \u89c4\u8303\uff0c\u8f93\u51fa\u4e3a\u8be5\u805a\u5408\u51fd\u6570\u5728\u5f53\u524d\u884c\u7a97\u53e3\u6846\u67b6\u5185\u5168\u90e8\u884c\u4e0a\u7684\u7ed3\u679c\u3002", "\u6240\u6709\u7a97\u53e3\u51fd\u6570 API \u90fd\u4f7f\u7528\u6b64\u5bf9\u8c61\u8c03\u7528\uff1b\u6b64\u5bf9\u8c61\u901a\u8fc7 fcinfo->context \u4f20\u7ed9\u7a97\u53e3\u51fd\u6570\u3002", "\u6b64\u8282\u70b9\u5904\u7406\u7684\u6bcf\u4e2a\u7a97\u53e3\u51fd\u6570\u548c\u7a97\u53e3\u805a\u5408\u90fd\u5bf9\u5e94\u4e00\u4e2a WindowStatePerFunc \u7ed3\u6784\u3002"]}, {"code": "case T_WindowAgg:\n\t\t\tpname = sname = \"WindowAgg\";\n\t\t\tbreak;", "title": "\u6838\u5fc3\u6e90\u7801\u4e2d\u7684 EXPLAIN \u6807\u8bc6"}], "strategies": [], "description": ["\u5728\u5b50\u8ba1\u5212\u8f93\u51fa\u7684\u6709\u5e8f\u5206\u533a\u4e0a\u8ba1\u7b97\u7a97\u53e3\u51fd\u6570\u3002"], "localization": {"status": "complete", "sources": [], "language": "zh", "original_text": {"/versions/18/description/0": "Evaluates window functions over ordered partitions of its child output.", "/versions/18/facts/0/label": "Core node tag", "/versions/18/facts/1/label": "Structured EXPLAIN Node Type", "/versions/18/facts/2/label": "Inputs", "/versions/18/facts/2/value": "One suitably ordered child plan", "/versions/18/facts/3/label": "Output", "/versions/18/facts/3/value": "Tuples with window-function results", "/versions/18/facts/4/label": "Executor initializer", "/versions/18/facts/5/label": "Memory mechanism", "/versions/18/tables/0/title": "EXPLAIN labels in this source build", "/versions/18/related/1/label": "Using EXPLAIN", "/versions/18/related/2/label": "Parallel plans", "/versions/18/sections/0/title": "EXPLAIN names and attributes", "/versions/18/sections/1/title": "Memory and temporary storage", "/versions/18/sections/2/title": "Parallel execution and instrumentation", "/versions/18/sections/3/title": "Executor implementation notes", "/versions/18/sections/4/title": "EXPLAIN identity in core source", "/versions/18/memory/description": "This node creates a tuplestore with work_mem. The tuplestore can move stored tuples to temporary files; this does not make work_mem a cap on every allocation made by the node.", "/versions/18/sections/0/paragraphs/0": "Structured formats use the Node Type above. Text-format spellings can also include operation, strategy, join type, scan direction or aggregation-stage attributes.", "/versions/18/sections/0/paragraphs/1": "Text names recorded by this source: WindowAgg.", "/versions/18/sections/0/paragraphs/2": "Parallel-aware and parallel-safe are different plan properties. A node running inside a parallel worker is not necessarily a parallel-aware node.", "/versions/18/sections/1/paragraphs/0": "This node creates a tuplestore with work_mem. The tuplestore can move stored tuples to temporary files; this does not make work_mem a cap on every allocation made by the node.", "/versions/18/sections/1/paragraphs/1": "If the tuplestore has spilled to disk, alternate reading and writing becomes quite expensive due to frequent buffer flushes. It's cheaper to force the entire partition to get spooled in one go.", "/versions/18/sections/1/paragraphs/2": "Read the current row from the tuplestore, and save in ScanTupleSlot. (We can't rely on the outerplan's output slot because we may have to read beyond the current row. Also, we have to actually copy the row out of the tuplestore, since window function evaluation might cause the tuplestore to dump its state to disk.)", "/versions/18/sections/1/paragraphs/3": "Window functions do not have to call this, but are encouraged to move the mark forward when possible to keep the tuplestore size down and prevent having to spill rows to disk.", "/versions/18/sections/2/paragraphs/0": "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.", "/versions/18/sections/2/paragraphs/1": "Callbacks in this build: none extracted from this node implementation.", "/versions/18/sections/3/paragraphs/0": "A WindowAgg node evaluates \"window functions\" across suitable partitions of the input tuple set. Any one WindowAgg works for just a single window specification, though it can evaluate multiple window functions sharing identical window specifications. The input tuples are required to be delivered in sorted order, with the PARTITION BY columns (if any) as major sort keys and the ORDER BY columns (if any) as minor sort keys. (The planner generates a stack of WindowAggs with intervening Sort nodes as needed, if a query involves more than one window specification.)", "/versions/18/sections/3/paragraphs/1": "Since window functions can require access to any or all of the rows in the current partition, we accumulate rows of the partition into a tuplestore. The window functions are called using the WindowObject API so that they can access those rows as needed.", "/versions/18/sections/3/paragraphs/2": "We also support using plain aggregate functions as window functions. For these, the regular Agg-node environment is emulated for each partition. As required by the SQL spec, the output represents the value of the aggregate function over all rows in the current row's window frame.", "/versions/18/sections/3/paragraphs/3": "All the window function APIs are called with this object, which is passed to window functions as fcinfo->context.", "/versions/18/sections/3/paragraphs/4": "We have one WindowStatePerFunc struct for each window function and window aggregate handled by this node.", "/versions/18/tables/0/columns/0/label": "Text-format label", "/versions/18/tables/0/columns/1/label": "Structured node identity"}, "fallback_fields": [], "source_language": "en", "original_snapshot_sha256": "42b526ad1930f461f37cce6b0f3afee4dd366ff4d2929576839deab2c3275cdb"}, "evidence_kind": "source and documentation", "explain_names": ["WindowAgg"], "partial_modes": [], "comparison_data": {"node_tag": "T_WindowAgg", "strategies": [], "text_names": ["WindowAgg"], "initializer": "ExecInitWindowAgg", "partial_modes": [], "memory_mechanism": "tuplestore", "parallel_callbacks": []}, "comparison_hash": "186aa5f13e96214f274161ba257307adf452233ebc64c9c0aaebfaee73fac8a4", "explain_prefixes": ["Parallel", "Async"], "runtime_verified": false, "source_inventory": {"explain": "src/backend/commands/explain.c", "executor": "src/backend/executor/execProcnode.c", "implementation": "src/backend/executor/nodeWindowAgg.c"}, "parallel_callbacks": []}, "19": {"facts": [{"label": "\u6838\u5fc3\u8282\u70b9\u6807\u7b7e", "value": "T_WindowAgg"}, {"label": "\u7ed3\u6784\u5316 EXPLAIN \u8282\u70b9\u7c7b\u578b", "value": "WindowAgg"}, {"label": "\u8f93\u5165", "value": "\u4e00\u4e2a\u6ee1\u8db3\u6392\u5e8f\u8981\u6c42\u7684\u5b50\u8ba1\u5212"}, {"label": "\u8f93\u51fa", "value": "\u5e26\u7a97\u53e3\u51fd\u6570\u7ed3\u679c\u7684\u5143\u7ec4"}, {"label": "\u6267\u884c\u5668\u521d\u59cb\u5316\u51fd\u6570", "value": "ExecInitWindowAgg"}, {"label": "\u5185\u5b58\u673a\u5236", "value": "tuplestore"}], "memory": {"evidence": [{"url": "https://ftp.postgresql.org/pub/source/v19beta4/postgresql-19beta4.tar.bz2", "path": "src/backend/executor/nodeWindowAgg.c", "label": "src/backend/executor/nodeWindowAgg.c", "sha256": "6a186fd12c312f61143ea1f11f1eaf5cc895029c480b786dbaf137258ceffd42", "archive_sha256": "83157ee9c599d03b2f7a3d73ef3a56ec24e0e79cc2b3501a64d1364f56398c86"}, {"url": "https://ftp.postgresql.org/pub/source/v19beta4/postgresql-19beta4.tar.bz2", "path": "src/backend/utils/sort/tuplestore.c", "label": "src/backend/utils/sort/tuplestore.c", "sha256": "cda3af245b88d079a32616b4cc5316913d349ba3acaab5fc1fd8aec479cc51ee", "archive_sha256": "83157ee9c599d03b2f7a3d73ef3a56ec24e0e79cc2b3501a64d1364f56398c86"}], "mechanism": "tuplestore", "description": "\u6b64\u8282\u70b9\u4f7f\u7528 work_mem \u521b\u5efa tuplestore\u3002tuplestore \u53ef\u4ee5\u5c06\u5b58\u50a8\u7684\u5143\u7ec4\u79fb\u5230\u4e34\u65f6\u6587\u4ef6\uff0c\u4f46\u8fd9\u4e0d\u610f\u5473\u7740 work_mem \u9650\u5236\u4e86\u8282\u70b9\u7684\u5168\u90e8\u5185\u5b58\u5206\u914d\u3002", "source_notes": ["If the tuplestore has spilled to disk, alternate reading and writing becomes quite expensive due to frequent buffer flushes. It's cheaper to force the entire partition to get spooled in one go.", "Read the current row from the tuplestore, and save in ScanTupleSlot. (We can't rely on the outerplan's output slot because we may have to read beyond the current row. Also, we have to actually copy the row out of the tuplestore, since window function evaluation might cause the tuplestore to dump its state to disk.)", "Window functions do not have to call this, but are encouraged to move the mark forward when possible to keep the tuplestore size down and prevent having to spill rows to disk."]}, "tables": [{"key": "explain-labels", "rows": [{"label": "WindowAgg", "identity": "WindowAgg"}], "title": "\u672c\u6784\u5efa\u4e2d\u7684 EXPLAIN \u6807\u7b7e", "columns": [{"key": "label", "label": "\u6587\u672c\u683c\u5f0f\u6807\u7b7e"}, {"key": "identity", "label": "\u7ed3\u6784\u5316\u8282\u70b9\u6807\u8bc6"}]}], "related": [{"url": "/wiki/sql/explain/?v=19", "label": "EXPLAIN"}, {"url": "/docs/19/using-explain.html", "label": "\u4f7f\u7528 EXPLAIN"}, {"url": "/docs/19/parallel-plans.html", "label": "\u5e76\u884c\u8ba1\u5212"}, {"url": "/wiki/guc/work_mem/?v=19", "label": "work_mem"}], "release": {"ref": "PostgreSQL 19beta4 source archive", "label": "19beta4", "major": "19", "channel": "preview", "revision": "83157ee9c599d03b2f7a3d73ef3a56ec24e0e79cc2b3501a64d1364f56398c86", "source_url": "https://ftp.postgresql.org/pub/source/v19beta4/postgresql-19beta4.tar.bz2", "source_snapshot_utc": ""}, "sources": [{"url": "https://ftp.postgresql.org/pub/source/v19beta4/postgresql-19beta4.tar.bz2", "line": 1586, "path": "src/backend/commands/explain.c", "label": "src/backend/commands/explain.c:1586", "sha256": "8b115b1c194a4b54ae630209a741e293b1df49a9052f10b2de9ca092a48998e3", "archive_sha256": "83157ee9c599d03b2f7a3d73ef3a56ec24e0e79cc2b3501a64d1364f56398c86"}, {"url": "https://ftp.postgresql.org/pub/source/v19beta4/postgresql-19beta4.tar.bz2", "line": 345, "path": "src/backend/executor/execProcnode.c", "label": "src/backend/executor/execProcnode.c:345", "sha256": "5e39b2037bed672da55104229ecc32da5abde44c26bcad01479edcfa044d09ed", "archive_sha256": "83157ee9c599d03b2f7a3d73ef3a56ec24e0e79cc2b3501a64d1364f56398c86"}, {"url": "https://ftp.postgresql.org/pub/source/v19beta4/postgresql-19beta4.tar.bz2", "path": "src/backend/executor/nodeWindowAgg.c", "label": "src/backend/executor/nodeWindowAgg.c", "sha256": "6a186fd12c312f61143ea1f11f1eaf5cc895029c480b786dbaf137258ceffd42", "archive_sha256": "83157ee9c599d03b2f7a3d73ef3a56ec24e0e79cc2b3501a64d1364f56398c86"}, {"url": "https://ftp.postgresql.org/pub/source/v19beta4/postgresql-19beta4.tar.bz2", "path": "src/include/nodes/plannodes.h", "label": "src/include/nodes/plannodes.h", "sha256": "1c65d5d6b6c81c71531685843647869bcae630779d815a5036b06e070c6c06c7", "archive_sha256": "83157ee9c599d03b2f7a3d73ef3a56ec24e0e79cc2b3501a64d1364f56398c86"}, {"url": "https://ftp.postgresql.org/pub/source/v19beta4/postgresql-19beta4.tar.bz2", "path": "src/backend/utils/sort/tuplestore.c", "label": "src/backend/utils/sort/tuplestore.c", "sha256": "cda3af245b88d079a32616b4cc5316913d349ba3acaab5fc1fd8aec479cc51ee", "archive_sha256": "83157ee9c599d03b2f7a3d73ef3a56ec24e0e79cc2b3501a64d1364f56398c86"}], "node_tag": "T_WindowAgg", "sections": [{"title": "EXPLAIN \u540d\u79f0\u4e0e\u5c5e\u6027", "paragraphs": ["\u7ed3\u6784\u5316\u683c\u5f0f\u4f7f\u7528\u4e0a\u8ff0 Node Type\u3002\u6587\u672c\u683c\u5f0f\u540d\u79f0\u8fd8\u53ef\u80fd\u5305\u542b\u64cd\u4f5c\u3001\u7b56\u7565\u3001\u8fde\u63a5\u7c7b\u578b\u3001\u626b\u63cf\u65b9\u5411\u6216\u805a\u5408\u9636\u6bb5\u5c5e\u6027\u3002", "\u6b64\u6e90\u7801\u8bb0\u5f55\u7684\u6587\u672c\u540d\u79f0\uff1aWindowAgg.", "\u5e76\u884c\u611f\u77e5\u4e0e\u5e76\u884c\u5b89\u5168\u662f\u4e0d\u540c\u7684\u8ba1\u5212\u5c5e\u6027\u3002\u5728\u5e76\u884c\u5de5\u4f5c\u8fdb\u7a0b\u5185\u8fd0\u884c\u7684\u8282\u70b9\u4e0d\u4e00\u5b9a\u662f\u5e76\u884c\u611f\u77e5\u8282\u70b9\u3002"]}, {"title": "\u5185\u5b58\u4e0e\u4e34\u65f6\u5b58\u50a8", "paragraphs": ["\u6b64\u8282\u70b9\u4f7f\u7528 work_mem \u521b\u5efa tuplestore\u3002tuplestore \u53ef\u4ee5\u5c06\u5b58\u50a8\u7684\u5143\u7ec4\u79fb\u5230\u4e34\u65f6\u6587\u4ef6\uff0c\u4f46\u8fd9\u4e0d\u610f\u5473\u7740 work_mem \u9650\u5236\u4e86\u8282\u70b9\u7684\u5168\u90e8\u5185\u5b58\u5206\u914d\u3002", "tuplestore \u5df2\u843d\u76d8\u65f6\uff0c\u4ea4\u66ff\u8bfb\u5199\u4f1a\u9891\u7e41\u5237\u65b0\u7f13\u51b2\u533a\uff0c\u4ee3\u4ef7\u5f88\u9ad8\u3002\u4e00\u6b21\u6027\u5c06\u6574\u4e2a\u5206\u533a\u5b58\u5165\u4e34\u65f6\u5b58\u50a8\u4f1a\u66f4\u4fbf\u5b9c\u3002", "\u4ece tuplestore \u8bfb\u53d6\u5f53\u524d\u884c\u5e76\u4fdd\u5b58\u5230 ScanTupleSlot\u3002\u4e0d\u80fd\u4f9d\u8d56\u5916\u5c42\u8ba1\u5212\u7684\u8f93\u51fa\u69fd\uff0c\u56e0\u4e3a\u53ef\u80fd\u9700\u8981\u8bfb\u53d6\u5f53\u524d\u884c\u4e4b\u540e\u7684\u6570\u636e\u3002\u6b64\u5916\uff0c\u5fc5\u987b\u5c06\u884c\u5b9e\u9645\u590d\u5236\u51fa tuplestore\uff0c\u56e0\u4e3a\u7a97\u53e3\u51fd\u6570\u6c42\u503c\u53ef\u80fd\u4f7f tuplestore \u5c06\u5176\u72b6\u6001\u5199\u5165\u78c1\u76d8\u3002", "\u7a97\u53e3\u51fd\u6570\u5e76\u975e\u5fc5\u987b\u8c03\u7528\u6b64\u51fd\u6570\uff0c\u4f46\u5efa\u8bae\u5728\u53ef\u80fd\u65f6\u524d\u79fb\u6807\u8bb0\uff0c\u4ee5\u51cf\u5c0f tuplestore \u5927\u5c0f\u5e76\u907f\u514d\u5c06\u884c\u5199\u5165\u78c1\u76d8\u3002"]}, {"title": "\u5e76\u884c\u6267\u884c\u4e0e\u8fd0\u884c\u4fe1\u606f\u91c7\u96c6", "paragraphs": ["\u4ee5\u4e0b\u6e90\u7801\u56de\u8c03\u53ef\u4ee5\u534f\u8c03\u6267\u884c\u6216\u6536\u96c6\u5de5\u4f5c\u8fdb\u7a0b\u7684\u6d4b\u91cf\u6570\u636e\u3002\u56de\u8c03\u5b58\u5728\u4e0d\u4ee3\u8868\u8be5\u8282\u70b9\u666e\u904d\u652f\u6301\u5171\u4eab\u5e76\u884c\u626b\u63cf\u6216\u5171\u4eab\u72b6\u6001\u3002", "\u6b64\u6784\u5efa\u7684\u56de\u8c03\uff1anone extracted from this node implementation."]}, {"title": "\u6267\u884c\u5668\u5b9e\u73b0\u8bf4\u660e", "paragraphs": ["WindowAgg \u8282\u70b9\u5728\u8f93\u5165\u5143\u7ec4\u96c6\u5408\u7684\u9002\u5f53\u5206\u533a\u4e0a\u8ba1\u7b97\u201c\u7a97\u53e3\u51fd\u6570\u201d\u3002\u6bcf\u4e2a WindowAgg \u53ea\u5904\u7406\u4e00\u79cd\u7a97\u53e3\u5b9a\u4e49\uff0c\u4f46\u53ef\u4ee5\u8ba1\u7b97\u5171\u4eab\u76f8\u540c\u7a97\u53e3\u5b9a\u4e49\u7684\u591a\u4e2a\u7a97\u53e3\u51fd\u6570\u3002\u8f93\u5165\u5143\u7ec4\u5fc5\u987b\u6309\u6392\u5e8f\u987a\u5e8f\u9001\u8fbe\uff1aPARTITION BY \u5217\uff08\u5982\u679c\u6709\uff09\u4e3a\u4e3b\u8981\u6392\u5e8f\u952e\uff0cORDER BY \u5217\uff08\u5982\u679c\u6709\uff09\u4e3a\u6b21\u8981\u6392\u5e8f\u952e\u3002\uff08\u5982\u679c\u67e5\u8be2\u5305\u542b\u591a\u79cd\u7a97\u53e3\u5b9a\u4e49\uff0c\u89c4\u5212\u5668\u4f1a\u6309\u9700\u751f\u6210\u591a\u4e2a\u5806\u53e0\u7684 WindowAgg\uff0c\u5e76\u5728\u5176\u95f4\u63d2\u5165 Sort \u8282\u70b9\u3002\uff09", "\u7a97\u53e3\u51fd\u6570\u53ef\u80fd\u9700\u8981\u8bbf\u95ee\u5f53\u524d\u5206\u533a\u7684\u4efb\u610f\u884c\u4e43\u81f3\u5168\u90e8\u884c\uff0c\u56e0\u6b64\u5c06\u5206\u533a\u884c\u7d2f\u79ef\u5230\u5143\u7ec4\u5b58\u50a8\u3002\u901a\u8fc7 WindowObject API \u8c03\u7528\u7a97\u53e3\u51fd\u6570\uff0c\u4f7f\u5176\u6309\u9700\u8bbf\u95ee\u8fd9\u4e9b\u884c\u3002", "\u4e5f\u652f\u6301\u5c06\u666e\u901a\u805a\u5408\u51fd\u6570\u7528\u4f5c\u7a97\u53e3\u51fd\u6570\u3002\u6b64\u65f6\u4e3a\u6bcf\u4e2a\u5206\u533a\u6a21\u62df\u5e38\u89c4 Agg \u8282\u70b9\u73af\u5883\u3002\u6309 SQL \u89c4\u8303\uff0c\u8f93\u51fa\u4e3a\u8be5\u805a\u5408\u51fd\u6570\u5728\u5f53\u524d\u884c\u7a97\u53e3\u6846\u67b6\u5185\u5168\u90e8\u884c\u4e0a\u7684\u7ed3\u679c\u3002", "\u6240\u6709\u7a97\u53e3\u51fd\u6570 API \u90fd\u4f7f\u7528\u6b64\u5bf9\u8c61\u8c03\u7528\uff1b\u6b64\u5bf9\u8c61\u901a\u8fc7 fcinfo->context \u4f20\u7ed9\u7a97\u53e3\u51fd\u6570\u3002", "\u4e3a\u6bcf\u4e2a\u51fd\u6570\u53c2\u6570\u8ddf\u8e2a notnull_info \u6570\u7ec4\u5927\u5c0f\uff08\u5206\u533a\u4e2d\u7684\u5143\u7ec4\u6570\uff09\u3002"]}, {"code": "case T_WindowAgg:\n\t\t\tpname = sname = \"WindowAgg\";\n\t\t\tbreak;", "title": "\u6838\u5fc3\u6e90\u7801\u4e2d\u7684 EXPLAIN \u6807\u8bc6"}], "strategies": [], "description": ["\u5728\u5b50\u8ba1\u5212\u8f93\u51fa\u7684\u6709\u5e8f\u5206\u533a\u4e0a\u8ba1\u7b97\u7a97\u53e3\u51fd\u6570\u3002"], "localization": {"status": "complete", "sources": [], "language": "zh", "original_text": {"/versions/19/description/0": "Evaluates window functions over ordered partitions of its child output.", "/versions/19/facts/0/label": "Core node tag", "/versions/19/facts/1/label": "Structured EXPLAIN Node Type", "/versions/19/facts/2/label": "Inputs", "/versions/19/facts/2/value": "One suitably ordered child plan", "/versions/19/facts/3/label": "Output", "/versions/19/facts/3/value": "Tuples with window-function results", "/versions/19/facts/4/label": "Executor initializer", "/versions/19/facts/5/label": "Memory mechanism", "/versions/19/tables/0/title": "EXPLAIN labels in this source build", "/versions/19/related/1/label": "Using EXPLAIN", "/versions/19/related/2/label": "Parallel plans", "/versions/19/sections/0/title": "EXPLAIN names and attributes", "/versions/19/sections/1/title": "Memory and temporary storage", "/versions/19/sections/2/title": "Parallel execution and instrumentation", "/versions/19/sections/3/title": "Executor implementation notes", "/versions/19/sections/4/title": "EXPLAIN identity in core source", "/versions/19/memory/description": "This node creates a tuplestore with work_mem. The tuplestore can move stored tuples to temporary files; this does not make work_mem a cap on every allocation made by the node.", "/versions/19/sections/0/paragraphs/0": "Structured formats use the Node Type above. Text-format spellings can also include operation, strategy, join type, scan direction or aggregation-stage attributes.", "/versions/19/sections/0/paragraphs/1": "Text names recorded by this source: WindowAgg.", "/versions/19/sections/0/paragraphs/2": "Parallel-aware and parallel-safe are different plan properties. A node running inside a parallel worker is not necessarily a parallel-aware node.", "/versions/19/sections/1/paragraphs/0": "This node creates a tuplestore with work_mem. The tuplestore can move stored tuples to temporary files; this does not make work_mem a cap on every allocation made by the node.", "/versions/19/sections/1/paragraphs/1": "If the tuplestore has spilled to disk, alternate reading and writing becomes quite expensive due to frequent buffer flushes. It's cheaper to force the entire partition to get spooled in one go.", "/versions/19/sections/1/paragraphs/2": "Read the current row from the tuplestore, and save in ScanTupleSlot. (We can't rely on the outerplan's output slot because we may have to read beyond the current row. Also, we have to actually copy the row out of the tuplestore, since window function evaluation might cause the tuplestore to dump its state to disk.)", "/versions/19/sections/1/paragraphs/3": "Window functions do not have to call this, but are encouraged to move the mark forward when possible to keep the tuplestore size down and prevent having to spill rows to disk.", "/versions/19/sections/2/paragraphs/0": "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.", "/versions/19/sections/2/paragraphs/1": "Callbacks in this build: none extracted from this node implementation.", "/versions/19/sections/3/paragraphs/0": "A WindowAgg node evaluates \"window functions\" across suitable partitions of the input tuple set. Any one WindowAgg works for just a single window specification, though it can evaluate multiple window functions sharing identical window specifications. The input tuples are required to be delivered in sorted order, with the PARTITION BY columns (if any) as major sort keys and the ORDER BY columns (if any) as minor sort keys. (The planner generates a stack of WindowAggs with intervening Sort nodes as needed, if a query involves more than one window specification.)", "/versions/19/sections/3/paragraphs/1": "Since window functions can require access to any or all of the rows in the current partition, we accumulate rows of the partition into a tuplestore. The window functions are called using the WindowObject API so that they can access those rows as needed.", "/versions/19/sections/3/paragraphs/2": "We also support using plain aggregate functions as window functions. For these, the regular Agg-node environment is emulated for each partition. As required by the SQL spec, the output represents the value of the aggregate function over all rows in the current row's window frame.", "/versions/19/sections/3/paragraphs/3": "All the window function APIs are called with this object, which is passed to window functions as fcinfo->context.", "/versions/19/sections/3/paragraphs/4": "track size (number of tuples in partition) of the notnull_info array for each func args", "/versions/19/tables/0/columns/0/label": "Text-format label", "/versions/19/tables/0/columns/1/label": "Structured node identity"}, "fallback_fields": [], "source_language": "en", "original_snapshot_sha256": "86104d951f7a70bb1bdee319faece63a18257ca9e35d47b018a2207fa67b2cde"}, "evidence_kind": "source and documentation", "explain_names": ["WindowAgg"], "partial_modes": [], "comparison_data": {"node_tag": "T_WindowAgg", "strategies": [], "text_names": ["WindowAgg"], "initializer": "ExecInitWindowAgg", "partial_modes": [], "memory_mechanism": "tuplestore", "parallel_callbacks": []}, "comparison_hash": "186aa5f13e96214f274161ba257307adf452233ebc64c9c0aaebfaee73fac8a4", "explain_prefixes": ["Parallel", "Async"], "runtime_verified": false, "source_inventory": {"explain": "src/backend/commands/explain.c", "executor": "src/backend/executor/execProcnode.c", "implementation": "src/backend/executor/nodeWindowAgg.c"}, "parallel_callbacks": []}, "20": {"facts": [{"label": "\u6838\u5fc3\u8282\u70b9\u6807\u7b7e", "value": "T_WindowAgg"}, {"label": "\u7ed3\u6784\u5316 EXPLAIN \u8282\u70b9\u7c7b\u578b", "value": "WindowAgg"}, {"label": "\u8f93\u5165", "value": "\u4e00\u4e2a\u6ee1\u8db3\u6392\u5e8f\u8981\u6c42\u7684\u5b50\u8ba1\u5212"}, {"label": "\u8f93\u51fa", "value": "\u5e26\u7a97\u53e3\u51fd\u6570\u7ed3\u679c\u7684\u5143\u7ec4"}, {"label": "\u6267\u884c\u5668\u521d\u59cb\u5316\u51fd\u6570", "value": "ExecInitWindowAgg"}, {"label": "\u5185\u5b58\u673a\u5236", "value": "tuplestore"}], "memory": {"evidence": [{"url": "https://ftp.postgresql.org/pub/snapshot/dev/postgresql-snapshot.tar.bz2", "path": "src/backend/executor/nodeWindowAgg.c", "label": "src/backend/executor/nodeWindowAgg.c", "sha256": "6a186fd12c312f61143ea1f11f1eaf5cc895029c480b786dbaf137258ceffd42", "archive_sha256": "4d3346909b201ac1648232cf290462a7070c119326f56196f1f0253ed80fae41"}, {"url": "https://ftp.postgresql.org/pub/snapshot/dev/postgresql-snapshot.tar.bz2", "path": "src/backend/utils/sort/tuplestore.c", "label": "src/backend/utils/sort/tuplestore.c", "sha256": "46a50e4790274348dfdc6e24f63ae12809d38e639d19378c01d6daff55e61644", "archive_sha256": "4d3346909b201ac1648232cf290462a7070c119326f56196f1f0253ed80fae41"}], "mechanism": "tuplestore", "description": "\u6b64\u8282\u70b9\u4f7f\u7528 work_mem \u521b\u5efa tuplestore\u3002tuplestore \u53ef\u4ee5\u5c06\u5b58\u50a8\u7684\u5143\u7ec4\u79fb\u5230\u4e34\u65f6\u6587\u4ef6\uff0c\u4f46\u8fd9\u4e0d\u610f\u5473\u7740 work_mem \u9650\u5236\u4e86\u8282\u70b9\u7684\u5168\u90e8\u5185\u5b58\u5206\u914d\u3002", "source_notes": ["If the tuplestore has spilled to disk, alternate reading and writing becomes quite expensive due to frequent buffer flushes. It's cheaper to force the entire partition to get spooled in one go.", "Read the current row from the tuplestore, and save in ScanTupleSlot. (We can't rely on the outerplan's output slot because we may have to read beyond the current row. Also, we have to actually copy the row out of the tuplestore, since window function evaluation might cause the tuplestore to dump its state to disk.)", "Window functions do not have to call this, but are encouraged to move the mark forward when possible to keep the tuplestore size down and prevent having to spill rows to disk."]}, "tables": [{"key": "explain-labels", "rows": [{"label": "WindowAgg", "identity": "WindowAgg"}], "title": "\u672c\u6784\u5efa\u4e2d\u7684 EXPLAIN \u6807\u7b7e", "columns": [{"key": "label", "label": "\u6587\u672c\u683c\u5f0f\u6807\u7b7e"}, {"key": "identity", "label": "\u7ed3\u6784\u5316\u8282\u70b9\u6807\u8bc6"}]}], "related": [{"url": "/wiki/sql/explain/?v=20", "label": "EXPLAIN"}, {"url": "/docs/devel/using-explain.html", "label": "\u4f7f\u7528 EXPLAIN"}, {"url": "/docs/devel/parallel-plans.html", "label": "\u5e76\u884c\u8ba1\u5212"}, {"url": "/wiki/guc/work_mem/?v=20", "label": "work_mem"}], "release": {"ref": "PostgreSQL 20devel source archive", "label": "20devel", "major": "20", "channel": "devel", "revision": "4d3346909b201ac1648232cf290462a7070c119326f56196f1f0253ed80fae41", "source_url": "https://ftp.postgresql.org/pub/snapshot/dev/postgresql-snapshot.tar.bz2", "source_snapshot_utc": "26-Sep-2026 20:22"}, "sources": [{"url": "https://ftp.postgresql.org/pub/snapshot/dev/postgresql-snapshot.tar.bz2", "line": 1586, "path": "src/backend/commands/explain.c", "label": "src/backend/commands/explain.c:1586", "sha256": "13402758013520451539427b5993db06d463ca11c4e2d4cc5444e82367688077", "archive_sha256": "4d3346909b201ac1648232cf290462a7070c119326f56196f1f0253ed80fae41"}, {"url": "https://ftp.postgresql.org/pub/snapshot/dev/postgresql-snapshot.tar.bz2", "line": 345, "path": "src/backend/executor/execProcnode.c", "label": "src/backend/executor/execProcnode.c:345", "sha256": "5e39b2037bed672da55104229ecc32da5abde44c26bcad01479edcfa044d09ed", "archive_sha256": "4d3346909b201ac1648232cf290462a7070c119326f56196f1f0253ed80fae41"}, {"url": "https://ftp.postgresql.org/pub/snapshot/dev/postgresql-snapshot.tar.bz2", "path": "src/backend/executor/nodeWindowAgg.c", "label": "src/backend/executor/nodeWindowAgg.c", "sha256": "6a186fd12c312f61143ea1f11f1eaf5cc895029c480b786dbaf137258ceffd42", "archive_sha256": "4d3346909b201ac1648232cf290462a7070c119326f56196f1f0253ed80fae41"}, {"url": "https://ftp.postgresql.org/pub/snapshot/dev/postgresql-snapshot.tar.bz2", "path": "src/include/nodes/plannodes.h", "label": "src/include/nodes/plannodes.h", "sha256": "7a94ed1652f0d74d50c39971d1cd3e8051dbc0d6058f31b6de71a433ca343521", "archive_sha256": "4d3346909b201ac1648232cf290462a7070c119326f56196f1f0253ed80fae41"}, {"url": "https://ftp.postgresql.org/pub/snapshot/dev/postgresql-snapshot.tar.bz2", "path": "src/backend/utils/sort/tuplestore.c", "label": "src/backend/utils/sort/tuplestore.c", "sha256": "46a50e4790274348dfdc6e24f63ae12809d38e639d19378c01d6daff55e61644", "archive_sha256": "4d3346909b201ac1648232cf290462a7070c119326f56196f1f0253ed80fae41"}], "node_tag": "T_WindowAgg", "sections": [{"title": "EXPLAIN \u540d\u79f0\u4e0e\u5c5e\u6027", "paragraphs": ["\u7ed3\u6784\u5316\u683c\u5f0f\u4f7f\u7528\u4e0a\u8ff0 Node Type\u3002\u6587\u672c\u683c\u5f0f\u540d\u79f0\u8fd8\u53ef\u80fd\u5305\u542b\u64cd\u4f5c\u3001\u7b56\u7565\u3001\u8fde\u63a5\u7c7b\u578b\u3001\u626b\u63cf\u65b9\u5411\u6216\u805a\u5408\u9636\u6bb5\u5c5e\u6027\u3002", "\u6b64\u6e90\u7801\u8bb0\u5f55\u7684\u6587\u672c\u540d\u79f0\uff1aWindowAgg.", "\u5e76\u884c\u611f\u77e5\u4e0e\u5e76\u884c\u5b89\u5168\u662f\u4e0d\u540c\u7684\u8ba1\u5212\u5c5e\u6027\u3002\u5728\u5e76\u884c\u5de5\u4f5c\u8fdb\u7a0b\u5185\u8fd0\u884c\u7684\u8282\u70b9\u4e0d\u4e00\u5b9a\u662f\u5e76\u884c\u611f\u77e5\u8282\u70b9\u3002"]}, {"title": "\u5185\u5b58\u4e0e\u4e34\u65f6\u5b58\u50a8", "paragraphs": ["\u6b64\u8282\u70b9\u4f7f\u7528 work_mem \u521b\u5efa tuplestore\u3002tuplestore \u53ef\u4ee5\u5c06\u5b58\u50a8\u7684\u5143\u7ec4\u79fb\u5230\u4e34\u65f6\u6587\u4ef6\uff0c\u4f46\u8fd9\u4e0d\u610f\u5473\u7740 work_mem \u9650\u5236\u4e86\u8282\u70b9\u7684\u5168\u90e8\u5185\u5b58\u5206\u914d\u3002", "tuplestore \u5df2\u843d\u76d8\u65f6\uff0c\u4ea4\u66ff\u8bfb\u5199\u4f1a\u9891\u7e41\u5237\u65b0\u7f13\u51b2\u533a\uff0c\u4ee3\u4ef7\u5f88\u9ad8\u3002\u4e00\u6b21\u6027\u5c06\u6574\u4e2a\u5206\u533a\u5b58\u5165\u4e34\u65f6\u5b58\u50a8\u4f1a\u66f4\u4fbf\u5b9c\u3002", "\u4ece tuplestore \u8bfb\u53d6\u5f53\u524d\u884c\u5e76\u4fdd\u5b58\u5230 ScanTupleSlot\u3002\u4e0d\u80fd\u4f9d\u8d56\u5916\u5c42\u8ba1\u5212\u7684\u8f93\u51fa\u69fd\uff0c\u56e0\u4e3a\u53ef\u80fd\u9700\u8981\u8bfb\u53d6\u5f53\u524d\u884c\u4e4b\u540e\u7684\u6570\u636e\u3002\u6b64\u5916\uff0c\u5fc5\u987b\u5c06\u884c\u5b9e\u9645\u590d\u5236\u51fa tuplestore\uff0c\u56e0\u4e3a\u7a97\u53e3\u51fd\u6570\u6c42\u503c\u53ef\u80fd\u4f7f tuplestore \u5c06\u5176\u72b6\u6001\u5199\u5165\u78c1\u76d8\u3002", "\u7a97\u53e3\u51fd\u6570\u5e76\u975e\u5fc5\u987b\u8c03\u7528\u6b64\u51fd\u6570\uff0c\u4f46\u5efa\u8bae\u5728\u53ef\u80fd\u65f6\u524d\u79fb\u6807\u8bb0\uff0c\u4ee5\u51cf\u5c0f tuplestore \u5927\u5c0f\u5e76\u907f\u514d\u5c06\u884c\u5199\u5165\u78c1\u76d8\u3002"]}, {"title": "\u5e76\u884c\u6267\u884c\u4e0e\u8fd0\u884c\u4fe1\u606f\u91c7\u96c6", "paragraphs": ["\u4ee5\u4e0b\u6e90\u7801\u56de\u8c03\u53ef\u4ee5\u534f\u8c03\u6267\u884c\u6216\u6536\u96c6\u5de5\u4f5c\u8fdb\u7a0b\u7684\u6d4b\u91cf\u6570\u636e\u3002\u56de\u8c03\u5b58\u5728\u4e0d\u4ee3\u8868\u8be5\u8282\u70b9\u666e\u904d\u652f\u6301\u5171\u4eab\u5e76\u884c\u626b\u63cf\u6216\u5171\u4eab\u72b6\u6001\u3002", "\u6b64\u6784\u5efa\u7684\u56de\u8c03\uff1anone extracted from this node implementation."]}, {"title": "\u6267\u884c\u5668\u5b9e\u73b0\u8bf4\u660e", "paragraphs": ["WindowAgg \u8282\u70b9\u5728\u8f93\u5165\u5143\u7ec4\u96c6\u5408\u7684\u9002\u5f53\u5206\u533a\u4e0a\u8ba1\u7b97\u201c\u7a97\u53e3\u51fd\u6570\u201d\u3002\u6bcf\u4e2a WindowAgg \u53ea\u5904\u7406\u4e00\u79cd\u7a97\u53e3\u5b9a\u4e49\uff0c\u4f46\u53ef\u4ee5\u8ba1\u7b97\u5171\u4eab\u76f8\u540c\u7a97\u53e3\u5b9a\u4e49\u7684\u591a\u4e2a\u7a97\u53e3\u51fd\u6570\u3002\u8f93\u5165\u5143\u7ec4\u5fc5\u987b\u6309\u6392\u5e8f\u987a\u5e8f\u9001\u8fbe\uff1aPARTITION BY \u5217\uff08\u5982\u679c\u6709\uff09\u4e3a\u4e3b\u8981\u6392\u5e8f\u952e\uff0cORDER BY \u5217\uff08\u5982\u679c\u6709\uff09\u4e3a\u6b21\u8981\u6392\u5e8f\u952e\u3002\uff08\u5982\u679c\u67e5\u8be2\u5305\u542b\u591a\u79cd\u7a97\u53e3\u5b9a\u4e49\uff0c\u89c4\u5212\u5668\u4f1a\u6309\u9700\u751f\u6210\u591a\u4e2a\u5806\u53e0\u7684 WindowAgg\uff0c\u5e76\u5728\u5176\u95f4\u63d2\u5165 Sort \u8282\u70b9\u3002\uff09", "\u7a97\u53e3\u51fd\u6570\u53ef\u80fd\u9700\u8981\u8bbf\u95ee\u5f53\u524d\u5206\u533a\u7684\u4efb\u610f\u884c\u4e43\u81f3\u5168\u90e8\u884c\uff0c\u56e0\u6b64\u5c06\u5206\u533a\u884c\u7d2f\u79ef\u5230\u5143\u7ec4\u5b58\u50a8\u3002\u901a\u8fc7 WindowObject API \u8c03\u7528\u7a97\u53e3\u51fd\u6570\uff0c\u4f7f\u5176\u6309\u9700\u8bbf\u95ee\u8fd9\u4e9b\u884c\u3002", "\u4e5f\u652f\u6301\u5c06\u666e\u901a\u805a\u5408\u51fd\u6570\u7528\u4f5c\u7a97\u53e3\u51fd\u6570\u3002\u6b64\u65f6\u4e3a\u6bcf\u4e2a\u5206\u533a\u6a21\u62df\u5e38\u89c4 Agg \u8282\u70b9\u73af\u5883\u3002\u6309 SQL \u89c4\u8303\uff0c\u8f93\u51fa\u4e3a\u8be5\u805a\u5408\u51fd\u6570\u5728\u5f53\u524d\u884c\u7a97\u53e3\u6846\u67b6\u5185\u5168\u90e8\u884c\u4e0a\u7684\u7ed3\u679c\u3002", "\u6240\u6709\u7a97\u53e3\u51fd\u6570 API \u90fd\u4f7f\u7528\u6b64\u5bf9\u8c61\u8c03\u7528\uff1b\u6b64\u5bf9\u8c61\u901a\u8fc7 fcinfo->context \u4f20\u7ed9\u7a97\u53e3\u51fd\u6570\u3002", "\u4e3a\u6bcf\u4e2a\u51fd\u6570\u53c2\u6570\u8ddf\u8e2a notnull_info \u6570\u7ec4\u5927\u5c0f\uff08\u5206\u533a\u4e2d\u7684\u5143\u7ec4\u6570\uff09\u3002"]}, {"code": "case T_WindowAgg:\n\t\t\tpname = sname = \"WindowAgg\";\n\t\t\tbreak;", "title": "\u6838\u5fc3\u6e90\u7801\u4e2d\u7684 EXPLAIN \u6807\u8bc6"}], "strategies": [], "description": ["\u5728\u5b50\u8ba1\u5212\u8f93\u51fa\u7684\u6709\u5e8f\u5206\u533a\u4e0a\u8ba1\u7b97\u7a97\u53e3\u51fd\u6570\u3002"], "localization": {"status": "complete", "sources": [], "language": "zh", "original_text": {"/summary": "Evaluates window functions over ordered partitions of its child output.", "/category": "Aggregation", "/versions/20/description/0": "Evaluates window functions over ordered partitions of its child output.", "/versions/20/facts/0/label": "Core node tag", "/versions/20/facts/1/label": "Structured EXPLAIN Node Type", "/versions/20/facts/2/label": "Inputs", "/versions/20/facts/2/value": "One suitably ordered child plan", "/versions/20/facts/3/label": "Output", "/versions/20/facts/3/value": "Tuples with window-function results", "/versions/20/facts/4/label": "Executor initializer", "/versions/20/facts/5/label": "Memory mechanism", "/versions/20/tables/0/title": "EXPLAIN labels in this source build", "/versions/20/related/1/label": "Using EXPLAIN", "/versions/20/related/2/label": "Parallel plans", "/versions/20/sections/0/title": "EXPLAIN names and attributes", "/versions/20/sections/1/title": "Memory and temporary storage", "/versions/20/sections/2/title": "Parallel execution and instrumentation", "/versions/20/sections/3/title": "Executor implementation notes", "/versions/20/sections/4/title": "EXPLAIN identity in core source", "/versions/20/memory/description": "This node creates a tuplestore with work_mem. The tuplestore can move stored tuples to temporary files; this does not make work_mem a cap on every allocation made by the node.", "/versions/20/sections/0/paragraphs/0": "Structured formats use the Node Type above. Text-format spellings can also include operation, strategy, join type, scan direction or aggregation-stage attributes.", "/versions/20/sections/0/paragraphs/1": "Text names recorded by this source: WindowAgg.", "/versions/20/sections/0/paragraphs/2": "Parallel-aware and parallel-safe are different plan properties. A node running inside a parallel worker is not necessarily a parallel-aware node.", "/versions/20/sections/1/paragraphs/0": "This node creates a tuplestore with work_mem. The tuplestore can move stored tuples to temporary files; this does not make work_mem a cap on every allocation made by the node.", "/versions/20/sections/1/paragraphs/1": "If the tuplestore has spilled to disk, alternate reading and writing becomes quite expensive due to frequent buffer flushes. It's cheaper to force the entire partition to get spooled in one go.", "/versions/20/sections/1/paragraphs/2": "Read the current row from the tuplestore, and save in ScanTupleSlot. (We can't rely on the outerplan's output slot because we may have to read beyond the current row. Also, we have to actually copy the row out of the tuplestore, since window function evaluation might cause the tuplestore to dump its state to disk.)", "/versions/20/sections/1/paragraphs/3": "Window functions do not have to call this, but are encouraged to move the mark forward when possible to keep the tuplestore size down and prevent having to spill rows to disk.", "/versions/20/sections/2/paragraphs/0": "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.", "/versions/20/sections/2/paragraphs/1": "Callbacks in this build: none extracted from this node implementation.", "/versions/20/sections/3/paragraphs/0": "A WindowAgg node evaluates \"window functions\" across suitable partitions of the input tuple set. Any one WindowAgg works for just a single window specification, though it can evaluate multiple window functions sharing identical window specifications. The input tuples are required to be delivered in sorted order, with the PARTITION BY columns (if any) as major sort keys and the ORDER BY columns (if any) as minor sort keys. (The planner generates a stack of WindowAggs with intervening Sort nodes as needed, if a query involves more than one window specification.)", "/versions/20/sections/3/paragraphs/1": "Since window functions can require access to any or all of the rows in the current partition, we accumulate rows of the partition into a tuplestore. The window functions are called using the WindowObject API so that they can access those rows as needed.", "/versions/20/sections/3/paragraphs/2": "We also support using plain aggregate functions as window functions. For these, the regular Agg-node environment is emulated for each partition. As required by the SQL spec, the output represents the value of the aggregate function over all rows in the current row's window frame.", "/versions/20/sections/3/paragraphs/3": "All the window function APIs are called with this object, which is passed to window functions as fcinfo->context.", "/versions/20/sections/3/paragraphs/4": "track size (number of tuples in partition) of the notnull_info array for each func args", "/versions/20/tables/0/columns/0/label": "Text-format label", "/versions/20/tables/0/columns/1/label": "Structured node identity"}, "fallback_fields": [], "source_language": "en", "original_snapshot_sha256": "d22fd00173c833c7805c76f02928ce83a04db3df35df9c644a184497a2b3979e"}, "evidence_kind": "source and documentation", "explain_names": ["WindowAgg"], "partial_modes": [], "comparison_data": {"node_tag": "T_WindowAgg", "strategies": [], "text_names": ["WindowAgg"], "initializer": "ExecInitWindowAgg", "partial_modes": [], "memory_mechanism": "tuplestore", "parallel_callbacks": []}, "comparison_hash": "186aa5f13e96214f274161ba257307adf452233ebc64c9c0aaebfaee73fac8a4", "explain_prefixes": ["Parallel", "Async"], "runtime_verified": false, "source_inventory": {"explain": "src/backend/commands/explain.c", "executor": "src/backend/executor/execProcnode.c", "implementation": "src/backend/executor/nodeWindowAgg.c"}, "parallel_callbacks": []}}}, "snapshot": {"facts": [{"label": "\u6838\u5fc3\u8282\u70b9\u6807\u7b7e", "value": "T_WindowAgg"}, {"label": "\u7ed3\u6784\u5316 EXPLAIN \u8282\u70b9\u7c7b\u578b", "value": "WindowAgg"}, {"label": "\u8f93\u5165", "value": "\u4e00\u4e2a\u6ee1\u8db3\u6392\u5e8f\u8981\u6c42\u7684\u5b50\u8ba1\u5212"}, {"label": "\u8f93\u51fa", "value": "\u5e26\u7a97\u53e3\u51fd\u6570\u7ed3\u679c\u7684\u5143\u7ec4"}, {"label": "\u6267\u884c\u5668\u521d\u59cb\u5316\u51fd\u6570", "value": "ExecInitWindowAgg"}, {"label": "\u5185\u5b58\u673a\u5236", "value": "tuplestore"}], "memory": {"evidence": [{"url": "https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2", "path": "src/backend/executor/nodeWindowAgg.c", "label": "src/backend/executor/nodeWindowAgg.c", "sha256": "c365e6750bc77a89562254903d099c3e5914e001d3aae418322ccffc1d535d17", "archive_sha256": "555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f"}, {"url": "https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2", "path": "src/backend/utils/sort/tuplestore.c", "label": "src/backend/utils/sort/tuplestore.c", "sha256": "27a85416bafed557006c705ab5d0c5dce3d3c1702812bb54d136f2ac4c41055a", "archive_sha256": "555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f"}], "mechanism": "tuplestore", "description": "\u6b64\u8282\u70b9\u4f7f\u7528 work_mem \u521b\u5efa tuplestore\u3002tuplestore \u53ef\u4ee5\u5c06\u5b58\u50a8\u7684\u5143\u7ec4\u79fb\u5230\u4e34\u65f6\u6587\u4ef6\uff0c\u4f46\u8fd9\u4e0d\u610f\u5473\u7740 work_mem \u9650\u5236\u4e86\u8282\u70b9\u7684\u5168\u90e8\u5185\u5b58\u5206\u914d\u3002", "source_notes": ["If the tuplestore has spilled to disk, alternate reading and writing becomes quite expensive due to frequent buffer flushes. It's cheaper to force the entire partition to get spooled in one go.", "Read the current row from the tuplestore, and save in ScanTupleSlot. (We can't rely on the outerplan's output slot because we may have to read beyond the current row. Also, we have to actually copy the row out of the tuplestore, since window function evaluation might cause the tuplestore to dump its state to disk.)", "Window functions do not have to call this, but are encouraged to move the mark forward when possible to keep the tuplestore size down and prevent having to spill rows to disk."]}, "tables": [{"key": "explain-labels", "rows": [{"label": "WindowAgg", "identity": "WindowAgg"}], "title": "\u672c\u6784\u5efa\u4e2d\u7684 EXPLAIN \u6807\u7b7e", "columns": [{"key": "label", "label": "\u6587\u672c\u683c\u5f0f\u6807\u7b7e"}, {"key": "identity", "label": "\u7ed3\u6784\u5316\u8282\u70b9\u6807\u8bc6"}]}], "related": [{"url": "/wiki/sql/explain/?v=18", "label": "EXPLAIN"}, {"url": "/docs/18/using-explain.html", "label": "\u4f7f\u7528 EXPLAIN"}, {"url": "/docs/18/parallel-plans.html", "label": "\u5e76\u884c\u8ba1\u5212"}, {"url": "/wiki/guc/work_mem/?v=18", "label": "work_mem"}], "release": {"ref": "PostgreSQL 18.6 source archive", "label": "18.6", "major": "18", "channel": "stable", "revision": "555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f", "source_url": "https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2", "source_snapshot_utc": ""}, "sources": [{"url": "https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2", "line": 1574, "path": "src/backend/commands/explain.c", "label": "src/backend/commands/explain.c:1574", "sha256": "34c86d6070224a0e981efef51f79101d6d505e5874f1684ace183034bab14bb4", "archive_sha256": "555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f"}, {"url": "https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2", "line": 345, "path": "src/backend/executor/execProcnode.c", "label": "src/backend/executor/execProcnode.c:345", "sha256": "f8a06a3f539077249b20664b2812433db6d7bd12b2c0ca633525db43d06f112a", "archive_sha256": "555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f"}, {"url": "https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2", "path": "src/backend/executor/nodeWindowAgg.c", "label": "src/backend/executor/nodeWindowAgg.c", "sha256": "c365e6750bc77a89562254903d099c3e5914e001d3aae418322ccffc1d535d17", "archive_sha256": "555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f"}, {"url": "https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2", "path": "src/include/nodes/plannodes.h", "label": "src/include/nodes/plannodes.h", "sha256": "52422b327a8049fbbb20d8b96008a0fc0a6fafa60f7eff3c695d5b2e83830120", "archive_sha256": "555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f"}, {"url": "https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2", "path": "src/backend/utils/sort/tuplestore.c", "label": "src/backend/utils/sort/tuplestore.c", "sha256": "27a85416bafed557006c705ab5d0c5dce3d3c1702812bb54d136f2ac4c41055a", "archive_sha256": "555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f"}], "node_tag": "T_WindowAgg", "sections": [{"title": "EXPLAIN \u540d\u79f0\u4e0e\u5c5e\u6027", "paragraphs": ["\u7ed3\u6784\u5316\u683c\u5f0f\u4f7f\u7528\u4e0a\u8ff0 Node Type\u3002\u6587\u672c\u683c\u5f0f\u540d\u79f0\u8fd8\u53ef\u80fd\u5305\u542b\u64cd\u4f5c\u3001\u7b56\u7565\u3001\u8fde\u63a5\u7c7b\u578b\u3001\u626b\u63cf\u65b9\u5411\u6216\u805a\u5408\u9636\u6bb5\u5c5e\u6027\u3002", "\u6b64\u6e90\u7801\u8bb0\u5f55\u7684\u6587\u672c\u540d\u79f0\uff1aWindowAgg.", "\u5e76\u884c\u611f\u77e5\u4e0e\u5e76\u884c\u5b89\u5168\u662f\u4e0d\u540c\u7684\u8ba1\u5212\u5c5e\u6027\u3002\u5728\u5e76\u884c\u5de5\u4f5c\u8fdb\u7a0b\u5185\u8fd0\u884c\u7684\u8282\u70b9\u4e0d\u4e00\u5b9a\u662f\u5e76\u884c\u611f\u77e5\u8282\u70b9\u3002"]}, {"title": "\u5185\u5b58\u4e0e\u4e34\u65f6\u5b58\u50a8", "paragraphs": ["\u6b64\u8282\u70b9\u4f7f\u7528 work_mem \u521b\u5efa tuplestore\u3002tuplestore \u53ef\u4ee5\u5c06\u5b58\u50a8\u7684\u5143\u7ec4\u79fb\u5230\u4e34\u65f6\u6587\u4ef6\uff0c\u4f46\u8fd9\u4e0d\u610f\u5473\u7740 work_mem \u9650\u5236\u4e86\u8282\u70b9\u7684\u5168\u90e8\u5185\u5b58\u5206\u914d\u3002", "tuplestore \u5df2\u843d\u76d8\u65f6\uff0c\u4ea4\u66ff\u8bfb\u5199\u4f1a\u9891\u7e41\u5237\u65b0\u7f13\u51b2\u533a\uff0c\u4ee3\u4ef7\u5f88\u9ad8\u3002\u4e00\u6b21\u6027\u5c06\u6574\u4e2a\u5206\u533a\u5b58\u5165\u4e34\u65f6\u5b58\u50a8\u4f1a\u66f4\u4fbf\u5b9c\u3002", "\u4ece tuplestore \u8bfb\u53d6\u5f53\u524d\u884c\u5e76\u4fdd\u5b58\u5230 ScanTupleSlot\u3002\u4e0d\u80fd\u4f9d\u8d56\u5916\u5c42\u8ba1\u5212\u7684\u8f93\u51fa\u69fd\uff0c\u56e0\u4e3a\u53ef\u80fd\u9700\u8981\u8bfb\u53d6\u5f53\u524d\u884c\u4e4b\u540e\u7684\u6570\u636e\u3002\u6b64\u5916\uff0c\u5fc5\u987b\u5c06\u884c\u5b9e\u9645\u590d\u5236\u51fa tuplestore\uff0c\u56e0\u4e3a\u7a97\u53e3\u51fd\u6570\u6c42\u503c\u53ef\u80fd\u4f7f tuplestore \u5c06\u5176\u72b6\u6001\u5199\u5165\u78c1\u76d8\u3002", "\u7a97\u53e3\u51fd\u6570\u5e76\u975e\u5fc5\u987b\u8c03\u7528\u6b64\u51fd\u6570\uff0c\u4f46\u5efa\u8bae\u5728\u53ef\u80fd\u65f6\u524d\u79fb\u6807\u8bb0\uff0c\u4ee5\u51cf\u5c0f tuplestore \u5927\u5c0f\u5e76\u907f\u514d\u5c06\u884c\u5199\u5165\u78c1\u76d8\u3002"]}, {"title": "\u5e76\u884c\u6267\u884c\u4e0e\u8fd0\u884c\u4fe1\u606f\u91c7\u96c6", "paragraphs": ["\u4ee5\u4e0b\u6e90\u7801\u56de\u8c03\u53ef\u4ee5\u534f\u8c03\u6267\u884c\u6216\u6536\u96c6\u5de5\u4f5c\u8fdb\u7a0b\u7684\u6d4b\u91cf\u6570\u636e\u3002\u56de\u8c03\u5b58\u5728\u4e0d\u4ee3\u8868\u8be5\u8282\u70b9\u666e\u904d\u652f\u6301\u5171\u4eab\u5e76\u884c\u626b\u63cf\u6216\u5171\u4eab\u72b6\u6001\u3002", "\u6b64\u6784\u5efa\u7684\u56de\u8c03\uff1anone extracted from this node implementation."]}, {"title": "\u6267\u884c\u5668\u5b9e\u73b0\u8bf4\u660e", "paragraphs": ["WindowAgg \u8282\u70b9\u5728\u8f93\u5165\u5143\u7ec4\u96c6\u5408\u7684\u9002\u5f53\u5206\u533a\u4e0a\u8ba1\u7b97\u201c\u7a97\u53e3\u51fd\u6570\u201d\u3002\u6bcf\u4e2a WindowAgg \u53ea\u5904\u7406\u4e00\u79cd\u7a97\u53e3\u5b9a\u4e49\uff0c\u4f46\u53ef\u4ee5\u8ba1\u7b97\u5171\u4eab\u76f8\u540c\u7a97\u53e3\u5b9a\u4e49\u7684\u591a\u4e2a\u7a97\u53e3\u51fd\u6570\u3002\u8f93\u5165\u5143\u7ec4\u5fc5\u987b\u6309\u6392\u5e8f\u987a\u5e8f\u9001\u8fbe\uff1aPARTITION BY \u5217\uff08\u5982\u679c\u6709\uff09\u4e3a\u4e3b\u8981\u6392\u5e8f\u952e\uff0cORDER BY \u5217\uff08\u5982\u679c\u6709\uff09\u4e3a\u6b21\u8981\u6392\u5e8f\u952e\u3002\uff08\u5982\u679c\u67e5\u8be2\u5305\u542b\u591a\u79cd\u7a97\u53e3\u5b9a\u4e49\uff0c\u89c4\u5212\u5668\u4f1a\u6309\u9700\u751f\u6210\u591a\u4e2a\u5806\u53e0\u7684 WindowAgg\uff0c\u5e76\u5728\u5176\u95f4\u63d2\u5165 Sort \u8282\u70b9\u3002\uff09", "\u7a97\u53e3\u51fd\u6570\u53ef\u80fd\u9700\u8981\u8bbf\u95ee\u5f53\u524d\u5206\u533a\u7684\u4efb\u610f\u884c\u4e43\u81f3\u5168\u90e8\u884c\uff0c\u56e0\u6b64\u5c06\u5206\u533a\u884c\u7d2f\u79ef\u5230\u5143\u7ec4\u5b58\u50a8\u3002\u901a\u8fc7 WindowObject API \u8c03\u7528\u7a97\u53e3\u51fd\u6570\uff0c\u4f7f\u5176\u6309\u9700\u8bbf\u95ee\u8fd9\u4e9b\u884c\u3002", "\u4e5f\u652f\u6301\u5c06\u666e\u901a\u805a\u5408\u51fd\u6570\u7528\u4f5c\u7a97\u53e3\u51fd\u6570\u3002\u6b64\u65f6\u4e3a\u6bcf\u4e2a\u5206\u533a\u6a21\u62df\u5e38\u89c4 Agg \u8282\u70b9\u73af\u5883\u3002\u6309 SQL \u89c4\u8303\uff0c\u8f93\u51fa\u4e3a\u8be5\u805a\u5408\u51fd\u6570\u5728\u5f53\u524d\u884c\u7a97\u53e3\u6846\u67b6\u5185\u5168\u90e8\u884c\u4e0a\u7684\u7ed3\u679c\u3002", "\u6240\u6709\u7a97\u53e3\u51fd\u6570 API \u90fd\u4f7f\u7528\u6b64\u5bf9\u8c61\u8c03\u7528\uff1b\u6b64\u5bf9\u8c61\u901a\u8fc7 fcinfo->context \u4f20\u7ed9\u7a97\u53e3\u51fd\u6570\u3002", "\u6b64\u8282\u70b9\u5904\u7406\u7684\u6bcf\u4e2a\u7a97\u53e3\u51fd\u6570\u548c\u7a97\u53e3\u805a\u5408\u90fd\u5bf9\u5e94\u4e00\u4e2a WindowStatePerFunc \u7ed3\u6784\u3002"]}, {"code": "case T_WindowAgg:\n\t\t\tpname = sname = \"WindowAgg\";\n\t\t\tbreak;", "title": "\u6838\u5fc3\u6e90\u7801\u4e2d\u7684 EXPLAIN \u6807\u8bc6"}], "strategies": [], "description": ["\u5728\u5b50\u8ba1\u5212\u8f93\u51fa\u7684\u6709\u5e8f\u5206\u533a\u4e0a\u8ba1\u7b97\u7a97\u53e3\u51fd\u6570\u3002"], "localization": {"status": "complete", "sources": [], "language": "zh", "original_text": {"/versions/18/description/0": "Evaluates window functions over ordered partitions of its child output.", "/versions/18/facts/0/label": "Core node tag", "/versions/18/facts/1/label": "Structured EXPLAIN Node Type", "/versions/18/facts/2/label": "Inputs", "/versions/18/facts/2/value": "One suitably ordered child plan", "/versions/18/facts/3/label": "Output", "/versions/18/facts/3/value": "Tuples with window-function results", "/versions/18/facts/4/label": "Executor initializer", "/versions/18/facts/5/label": "Memory mechanism", "/versions/18/tables/0/title": "EXPLAIN labels in this source build", "/versions/18/related/1/label": "Using EXPLAIN", "/versions/18/related/2/label": "Parallel plans", "/versions/18/sections/0/title": "EXPLAIN names and attributes", "/versions/18/sections/1/title": "Memory and temporary storage", "/versions/18/sections/2/title": "Parallel execution and instrumentation", "/versions/18/sections/3/title": "Executor implementation notes", "/versions/18/sections/4/title": "EXPLAIN identity in core source", "/versions/18/memory/description": "This node creates a tuplestore with work_mem. The tuplestore can move stored tuples to temporary files; this does not make work_mem a cap on every allocation made by the node.", "/versions/18/sections/0/paragraphs/0": "Structured formats use the Node Type above. Text-format spellings can also include operation, strategy, join type, scan direction or aggregation-stage attributes.", "/versions/18/sections/0/paragraphs/1": "Text names recorded by this source: WindowAgg.", "/versions/18/sections/0/paragraphs/2": "Parallel-aware and parallel-safe are different plan properties. A node running inside a parallel worker is not necessarily a parallel-aware node.", "/versions/18/sections/1/paragraphs/0": "This node creates a tuplestore with work_mem. The tuplestore can move stored tuples to temporary files; this does not make work_mem a cap on every allocation made by the node.", "/versions/18/sections/1/paragraphs/1": "If the tuplestore has spilled to disk, alternate reading and writing becomes quite expensive due to frequent buffer flushes. It's cheaper to force the entire partition to get spooled in one go.", "/versions/18/sections/1/paragraphs/2": "Read the current row from the tuplestore, and save in ScanTupleSlot. (We can't rely on the outerplan's output slot because we may have to read beyond the current row. Also, we have to actually copy the row out of the tuplestore, since window function evaluation might cause the tuplestore to dump its state to disk.)", "/versions/18/sections/1/paragraphs/3": "Window functions do not have to call this, but are encouraged to move the mark forward when possible to keep the tuplestore size down and prevent having to spill rows to disk.", "/versions/18/sections/2/paragraphs/0": "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.", "/versions/18/sections/2/paragraphs/1": "Callbacks in this build: none extracted from this node implementation.", "/versions/18/sections/3/paragraphs/0": "A WindowAgg node evaluates \"window functions\" across suitable partitions of the input tuple set. Any one WindowAgg works for just a single window specification, though it can evaluate multiple window functions sharing identical window specifications. The input tuples are required to be delivered in sorted order, with the PARTITION BY columns (if any) as major sort keys and the ORDER BY columns (if any) as minor sort keys. (The planner generates a stack of WindowAggs with intervening Sort nodes as needed, if a query involves more than one window specification.)", "/versions/18/sections/3/paragraphs/1": "Since window functions can require access to any or all of the rows in the current partition, we accumulate rows of the partition into a tuplestore. The window functions are called using the WindowObject API so that they can access those rows as needed.", "/versions/18/sections/3/paragraphs/2": "We also support using plain aggregate functions as window functions. For these, the regular Agg-node environment is emulated for each partition. As required by the SQL spec, the output represents the value of the aggregate function over all rows in the current row's window frame.", "/versions/18/sections/3/paragraphs/3": "All the window function APIs are called with this object, which is passed to window functions as fcinfo->context.", "/versions/18/sections/3/paragraphs/4": "We have one WindowStatePerFunc struct for each window function and window aggregate handled by this node.", "/versions/18/tables/0/columns/0/label": "Text-format label", "/versions/18/tables/0/columns/1/label": "Structured node identity"}, "fallback_fields": [], "source_language": "en", "original_snapshot_sha256": "42b526ad1930f461f37cce6b0f3afee4dd366ff4d2929576839deab2c3275cdb"}, "evidence_kind": "source and documentation", "explain_names": ["WindowAgg"], "partial_modes": [], "comparison_data": {"node_tag": "T_WindowAgg", "strategies": [], "text_names": ["WindowAgg"], "initializer": "ExecInitWindowAgg", "partial_modes": [], "memory_mechanism": "tuplestore", "parallel_callbacks": []}, "comparison_hash": "186aa5f13e96214f274161ba257307adf452233ebc64c9c0aaebfaee73fac8a4", "explain_prefixes": ["Parallel", "Async"], "runtime_verified": false, "source_inventory": {"explain": "src/backend/commands/explain.c", "executor": "src/backend/executor/execProcnode.c", "implementation": "src/backend/executor/nodeWindowAgg.c"}, "parallel_callbacks": []}, "comparison": {"left": "17", "right": "18", "status": "unchanged", "diff": ""}}