{"Entry":{"collection":"hook","key":"create_upper_paths_hook","name":"create_upper_paths_hook","aliases":[],"metadata":{"aliases":[],"category":"Query planning","content_hash":"1d435494e0bf82c277ed8669b2175e587cb0828724930a64328f85bbef51bfc2","derived_content_hash":"b8ee6df135880930ce0039cbf365a660f6421c0d963fadc646a419086ce0e404","imported_at":"2026-09-27T17:57:58.870042+08:00","name":"create_upper_paths_hook","name_zh":"create_upper_paths_hook","repair_provenance":{"original_source_revision":"","receipt_sha256":"76c6db3bd2dbbfef0eed72c41435a2a3713379b5bf64498570c6c3f550d87c11","repair":"wiki-repair-20261023"},"slug":"create_upper_paths_hook","source_rev":"wiki-repair-20261023:8ab1e0b5865dc54cc349085f8b2fb1becb6e3db4fe24b6ed5ee3bf25f5ccdab9","summary":"Hook for plugins to get control when grouping_planner() plans upper rels"}},"Definition":{"Collection":"hook","Key":"create_upper_paths_hook","SourceDatabase":"center","Version":"18","SourceTable":"hook","SourceKey":"create_upper_paths_hook","SourceRevision":"753057e340da8f22e57c9a409ea7a235fd6a46bd","Facts":{"description":["Hook for plugins to get control when grouping_planner() plans upper rels"],"description_zh":"供插件在 grouping_planner() 规划上层关系时接管处理的钩子。","description_zh_html":"\u003cp\u003e供插件在 grouping_planner() 规划上层关系时接管处理的钩子。\u003c/p\u003e\u003cp\u003e以下中文为本站依据所列 PostgreSQL 源码注释编译的说明。\u003c/p\u003e\u003ch3\u003e接口声明\u003c/h3\u003e\u003cpre\u003etypedef void (*create_upper_paths_hook_type) (PlannerInfo *root, UpperRelationKind stage, RelOptInfo *input_rel, RelOptInfo *output_rel, void *extra);\nextern PGDLLIMPORT create_upper_paths_hook_type create_upper_paths_hook;\u003c/pre\u003e\u003ch3\u003e源码说明\u003c/h3\u003e\u003cp\u003e允许扩展添加更多路径。\u003c/p\u003e\u003cp\u003e允许扩展添加更多部分路径。\u003c/p\u003e\u003ch3\u003e调用位置\u003c/h3\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003esrc/backend/optimizer/plan/planner.c:2386\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003esrc/backend/optimizer/plan/planner.c:4379\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003esrc/backend/optimizer/plan/planner.c:4819\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003esrc/backend/optimizer/plan/planner.c:5062\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003esrc/backend/optimizer/plan/planner.c:5237\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003esrc/backend/optimizer/plan/planner.c:5707\u003c/code\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch3\u003e核心调用上下文：src/backend/optimizer/plan/planner.c:2380–2394\u003c/h3\u003e\u003cpre\u003e\t\tfinal_rel-\u0026gt;fdwroutine-\u0026gt;GetForeignUpperPaths(root, UPPERREL_FINAL,\n\t\t\t\t\t\t\t\t\t\t\t\t\tcurrent_rel, final_rel,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\u0026amp;extra);\n\n\t/* Let extensions possibly add some more paths */\n\tif (create_upper_paths_hook)\n\t\t(*create_upper_paths_hook) (root, UPPERREL_FINAL,\n\t\t\t\t\t\t\t\t\tcurrent_rel, final_rel, \u0026amp;extra);\n\n\t/* Note: currently, we leave it to callers to do set_cheapest() */\n}\n\n/*\n * Do preprocessing for groupingSets clause and related data.\n *\u003c/pre\u003e\u003ch3\u003e核心调用上下文：src/backend/optimizer/plan/planner.c:4373–4387\u003c/h3\u003e\u003cpre\u003e\t\tgrouped_rel-\u0026gt;fdwroutine-\u0026gt;GetForeignUpperPaths(root, UPPERREL_GROUP_AGG,\n\t\t\t\t\t\t\t\t\t\t\t\t\t  input_rel, grouped_rel,\n\t\t\t\t\t\t\t\t\t\t\t\t\t  extra);\n\n\t/* Let extensions possibly add some more paths */\n\tif (create_upper_paths_hook)\n\t\t(*create_upper_paths_hook) (root, UPPERREL_GROUP_AGG,\n\t\t\t\t\t\t\t\t\tinput_rel, grouped_rel,\n\t\t\t\t\t\t\t\t\textra);\n}\n\n/*\n * For a given input path, consider the possible ways of doing grouping sets on\n * it, by combinations of hashing and sorting.  This can be called multiple\n * times, so it\u0026#x27;s important that it not scribble on input.  No result is\u003c/pre\u003e\u003ch3\u003e核心调用上下文：src/backend/optimizer/plan/planner.c:4813–4827\u003c/h3\u003e\u003cpre\u003e\t\twindow_rel-\u0026gt;fdwroutine-\u0026gt;GetForeignUpperPaths(root, UPPERREL_WINDOW,\n\t\t\t\t\t\t\t\t\t\t\t\t\t input_rel, window_rel,\n\t\t\t\t\t\t\t\t\t\t\t\t\t NULL);\n\n\t/* Let extensions possibly add some more paths */\n\tif (create_upper_paths_hook)\n\t\t(*create_upper_paths_hook) (root, UPPERREL_WINDOW,\n\t\t\t\t\t\t\t\t\tinput_rel, window_rel, NULL);\n\n\t/* Now choose the best path(s) */\n\tset_cheapest(window_rel);\n\n\treturn window_rel;\n}\n\u003c/pre\u003e","facts":[{"label":"Interface type","value":"create_upper_paths_hook_type"},{"label":"Header","value":"src/include/optimizer/planner.h"},{"label":"Subsystem","value":"Query planning"},{"label":"Initial value","value":"NULL (no hook installed)"}],"related":[{"label":"The Planner/Optimizer","url":"/docs/18/planner-optimizer.html"}],"release":{"channel":"stable","label":"18","major":"18","ref":"REL_18_STABLE","revision":"753057e340da8f22e57c9a409ea7a235fd6a46bd"},"sections":[{"paragraphs":["Let extensions possibly add some more paths","Let extensions possibly add some more partial paths"],"title":"Core source comments"},{"paragraphs":["src/backend/optimizer/plan/planner.c:2386","src/backend/optimizer/plan/planner.c:4379","src/backend/optimizer/plan/planner.c:4819","src/backend/optimizer/plan/planner.c:5062","src/backend/optimizer/plan/planner.c:5237","src/backend/optimizer/plan/planner.c:5707"],"title":"Call sites"},{"code":"\t\tfinal_rel-\u003efdwroutine-\u003eGetForeignUpperPaths(root, UPPERREL_FINAL,\n\t\t\t\t\t\t\t\t\t\t\t\t\tcurrent_rel, final_rel,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\u0026extra);\n\n\t/* Let extensions possibly add some more paths */\n\tif (create_upper_paths_hook)\n\t\t(*create_upper_paths_hook) (root, UPPERREL_FINAL,\n\t\t\t\t\t\t\t\t\tcurrent_rel, final_rel, \u0026extra);\n\n\t/* Note: currently, we leave it to callers to do set_cheapest() */\n}\n\n/*\n * Do preprocessing for groupingSets clause and related data.\n *","paragraphs":[],"title":"Core call context: src/backend/optimizer/plan/planner.c:2380–2394"},{"code":"\t\tgrouped_rel-\u003efdwroutine-\u003eGetForeignUpperPaths(root, UPPERREL_GROUP_AGG,\n\t\t\t\t\t\t\t\t\t\t\t\t\t  input_rel, grouped_rel,\n\t\t\t\t\t\t\t\t\t\t\t\t\t  extra);\n\n\t/* Let extensions possibly add some more paths */\n\tif (create_upper_paths_hook)\n\t\t(*create_upper_paths_hook) (root, UPPERREL_GROUP_AGG,\n\t\t\t\t\t\t\t\t\tinput_rel, grouped_rel,\n\t\t\t\t\t\t\t\t\textra);\n}\n\n/*\n * For a given input path, consider the possible ways of doing grouping sets on\n * it, by combinations of hashing and sorting.  This can be called multiple\n * times, so it's important that it not scribble on input.  No result is","paragraphs":[],"title":"Core call context: src/backend/optimizer/plan/planner.c:4373–4387"},{"code":"\t\twindow_rel-\u003efdwroutine-\u003eGetForeignUpperPaths(root, UPPERREL_WINDOW,\n\t\t\t\t\t\t\t\t\t\t\t\t\t input_rel, window_rel,\n\t\t\t\t\t\t\t\t\t\t\t\t\t NULL);\n\n\t/* Let extensions possibly add some more paths */\n\tif (create_upper_paths_hook)\n\t\t(*create_upper_paths_hook) (root, UPPERREL_WINDOW,\n\t\t\t\t\t\t\t\t\tinput_rel, window_rel, NULL);\n\n\t/* Now choose the best path(s) */\n\tset_cheapest(window_rel);\n\n\treturn window_rel;\n}\n","paragraphs":[],"title":"Core call context: src/backend/optimizer/plan/planner.c:4813–4827"}],"signature":"typedef void (*create_upper_paths_hook_type) (PlannerInfo *root, UpperRelationKind stage, RelOptInfo *input_rel, RelOptInfo *output_rel, void *extra);\nextern PGDLLIMPORT create_upper_paths_hook_type create_upper_paths_hook;","sources":[{"label":"Interface declaration","path":"src/include/optimizer/planner.h","sha256":"2b48e2afeff0e27570bc5bf536f3d5cdaab6111beb0b98bef9e5ce069598d08b","url":"https://github.com/postgres/postgres/blob/753057e340da8f22e57c9a409ea7a235fd6a46bd/src/include/optimizer/planner.h#L33"},{"label":"Core definition","path":"src/backend/optimizer/plan/planner.c","sha256":"70faebbc45551e477e5d75000911b029ea648e8cc616725f3b0032480cf16878","url":"https://github.com/postgres/postgres/blob/753057e340da8f22e57c9a409ea7a235fd6a46bd/src/backend/optimizer/plan/planner.c#L77"},{"label":"Call sites","path":"src/backend/optimizer/plan/planner.c","sha256":"70faebbc45551e477e5d75000911b029ea648e8cc616725f3b0032480cf16878","url":"https://github.com/postgres/postgres/blob/753057e340da8f22e57c9a409ea7a235fd6a46bd/src/backend/optimizer/plan/planner.c#L2386"}],"translation_provenance":{"inputs":[{"label":"Interface declaration","path":"src/include/optimizer/planner.h","sha256":"2b48e2afeff0e27570bc5bf536f3d5cdaab6111beb0b98bef9e5ce069598d08b","url":"https://github.com/postgres/postgres/blob/753057e340da8f22e57c9a409ea7a235fd6a46bd/src/include/optimizer/planner.h#L33"},{"label":"Core definition","path":"src/backend/optimizer/plan/planner.c","sha256":"70faebbc45551e477e5d75000911b029ea648e8cc616725f3b0032480cf16878","url":"https://github.com/postgres/postgres/blob/753057e340da8f22e57c9a409ea7a235fd6a46bd/src/backend/optimizer/plan/planner.c#L77"},{"label":"Call sites","path":"src/backend/optimizer/plan/planner.c","sha256":"70faebbc45551e477e5d75000911b029ea648e8cc616725f3b0032480cf16878","url":"https://github.com/postgres/postgres/blob/753057e340da8f22e57c9a409ea7a235fd6a46bd/src/backend/optimizer/plan/planner.c#L2386"}],"kind":"authored-source-translation","locale":"zh-Hans","source_revision":"753057e340da8f22e57c9a409ea7a235fd6a46bd","translated_source_sha256":"0c96a0f91258256edd1b7a4b0af4bcdc693cd0e239d159dee2e47dd5c6149971","version":"18"},"zh_from":"authored-source-translation"},"ManualEvidence":{"release":{"channel":"stable","label":"18","major":"18","ref":"REL_18_STABLE","revision":"753057e340da8f22e57c9a409ea7a235fd6a46bd"},"sources":[{"label":"Interface declaration","path":"src/include/optimizer/planner.h","sha256":"2b48e2afeff0e27570bc5bf536f3d5cdaab6111beb0b98bef9e5ce069598d08b","url":"https://github.com/postgres/postgres/blob/753057e340da8f22e57c9a409ea7a235fd6a46bd/src/include/optimizer/planner.h#L33"},{"label":"Core definition","path":"src/backend/optimizer/plan/planner.c","sha256":"70faebbc45551e477e5d75000911b029ea648e8cc616725f3b0032480cf16878","url":"https://github.com/postgres/postgres/blob/753057e340da8f22e57c9a409ea7a235fd6a46bd/src/backend/optimizer/plan/planner.c#L77"},{"label":"Call sites","path":"src/backend/optimizer/plan/planner.c","sha256":"70faebbc45551e477e5d75000911b029ea648e8cc616725f3b0032480cf16878","url":"https://github.com/postgres/postgres/blob/753057e340da8f22e57c9a409ea7a235fd6a46bd/src/backend/optimizer/plan/planner.c#L2386"}]},"MeasuredEvidence":{}},"Text":{"Collection":"hook","Key":"create_upper_paths_hook","SourceDatabase":"center","Version":"18","Locale":"en","Title":"create_upper_paths_hook","Summary":"Hook for plugins to get control when grouping_planner() plans upper rels","BodyHTML":"\u003cp\u003eHook for plugins to get control when grouping_planner() plans upper rels\u003c/p\u003e","SourceRevision":"753057e340da8f22e57c9a409ea7a235fd6a46bd","ContentHash":"17f9b431192b9e2779b3d802346e6434aa3b723218d556358d3ff498188db811","Payload":{"description":["Hook for plugins to get control when grouping_planner() plans upper rels"],"related":[{"label":"The Planner/Optimizer","url":"/docs/18/planner-optimizer.html"}],"sections":[{"paragraphs":["Let extensions possibly add some more paths","Let extensions possibly add some more partial paths"],"title":"Core source comments"},{"paragraphs":["src/backend/optimizer/plan/planner.c:2386","src/backend/optimizer/plan/planner.c:4379","src/backend/optimizer/plan/planner.c:4819","src/backend/optimizer/plan/planner.c:5062","src/backend/optimizer/plan/planner.c:5237","src/backend/optimizer/plan/planner.c:5707"],"title":"Call sites"},{"code":"\t\tfinal_rel-\u003efdwroutine-\u003eGetForeignUpperPaths(root, UPPERREL_FINAL,\n\t\t\t\t\t\t\t\t\t\t\t\t\tcurrent_rel, final_rel,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\u0026extra);\n\n\t/* Let extensions possibly add some more paths */\n\tif (create_upper_paths_hook)\n\t\t(*create_upper_paths_hook) (root, UPPERREL_FINAL,\n\t\t\t\t\t\t\t\t\tcurrent_rel, final_rel, \u0026extra);\n\n\t/* Note: currently, we leave it to callers to do set_cheapest() */\n}\n\n/*\n * Do preprocessing for groupingSets clause and related data.\n *","paragraphs":[],"title":"Core call context: src/backend/optimizer/plan/planner.c:2380–2394"},{"code":"\t\tgrouped_rel-\u003efdwroutine-\u003eGetForeignUpperPaths(root, UPPERREL_GROUP_AGG,\n\t\t\t\t\t\t\t\t\t\t\t\t\t  input_rel, grouped_rel,\n\t\t\t\t\t\t\t\t\t\t\t\t\t  extra);\n\n\t/* Let extensions possibly add some more paths */\n\tif (create_upper_paths_hook)\n\t\t(*create_upper_paths_hook) (root, UPPERREL_GROUP_AGG,\n\t\t\t\t\t\t\t\t\tinput_rel, grouped_rel,\n\t\t\t\t\t\t\t\t\textra);\n}\n\n/*\n * For a given input path, consider the possible ways of doing grouping sets on\n * it, by combinations of hashing and sorting.  This can be called multiple\n * times, so it's important that it not scribble on input.  No result is","paragraphs":[],"title":"Core call context: src/backend/optimizer/plan/planner.c:4373–4387"},{"code":"\t\twindow_rel-\u003efdwroutine-\u003eGetForeignUpperPaths(root, UPPERREL_WINDOW,\n\t\t\t\t\t\t\t\t\t\t\t\t\t input_rel, window_rel,\n\t\t\t\t\t\t\t\t\t\t\t\t\t NULL);\n\n\t/* Let extensions possibly add some more paths */\n\tif (create_upper_paths_hook)\n\t\t(*create_upper_paths_hook) (root, UPPERREL_WINDOW,\n\t\t\t\t\t\t\t\t\tinput_rel, window_rel, NULL);\n\n\t/* Now choose the best path(s) */\n\tset_cheapest(window_rel);\n\n\treturn window_rel;\n}\n","paragraphs":[],"title":"Core call context: src/backend/optimizer/plan/planner.c:4813–4827"}]}},"RequestedLocale":"en","Fallback":false,"Versions":["10","11","12","13","14","15","16","17","18","19","20"],"Locales":["en","zh-Hans"],"Signatures":null,"Spellings":null,"SQLState":null,"Evidence":null}
