52.4. ÐланиÑование запÑоÑов Ñ Ð¾Ð±ÑÑÑками ÑÑоÑÐ¾Ð½Ð½Ð¸Ñ Ð´Ð°Ð½Ð½ÑÑ
ÐÑоÑедÑÑÑ Ð² FDW, ÑеализÑÑÑие ÑÑнкÑии GetForeignRelSize, GetForeignPaths, GetForeignPlan, PlanForeignModify, GetForeignJoinPaths, GetForeignUpperPaths и PlanDirectModify, Ð´Ð¾Ð»Ð¶Ð½Ñ Ð²Ð¿Ð¸ÑÑваÑÑÑÑ Ð² ÑабоÑÑ Ð¿Ð»Ð°Ð½Ð¸ÑовÑика Postgres Pro. ÐдеÑÑ Ð´Ð°ÑÑÑÑ Ð½ÐµÑколÑко замеÑаний о Ñом, как ÑÑо должно пÑоиÑÑ
одиÑÑ.
ÐÐ»Ñ ÑменÑÑÐµÐ½Ð¸Ñ Ð¾Ð±ÑÑма вÑбиÑаемÑÑ
из ÑÑоÑонней ÑаблиÑÑ Ð´Ð°Ð½Ð½ÑÑ
(и как ÑледÑÑвие, ÑокÑаÑÐµÐ½Ð¸Ñ ÑÑоимоÑÑи) Ð¼Ð¾Ð¶ÐµÑ Ð¸ÑполÑзоваÑÑÑÑ Ð¸Ð½ÑоÑмаÑиÑ, поÑÑÑпаÑÑÐ°Ñ Ð² root и baserel. ÐÑобÑй инÑеÑÐµÑ Ð¿ÑедÑÑавлÑÐµÑ Ð¿Ð¾Ð»Ðµ baserel->baserestrictinfo, Ñак как оно ÑодеÑÐ¶Ð¸Ñ Ð¾Ð³ÑаниÑиваÑÑие ÑÑÐ»Ð¾Ð²Ð¸Ñ (пÑедложение WHERE), по коÑоÑÑм можно оÑÑилÑÑÑоваÑÑ Ð²ÑбиÑаемÑе ÑÑÑоки. (Сама FDW не обÑзаÑелÑно должна пÑименÑÑÑ ÑÑи огÑаниÑениÑ, Ñак как иÑ
Ð¼Ð¾Ð¶ÐµÑ Ð¿ÑовеÑиÑÑ Ð¸ ÑдÑо иÑполниÑелÑ.) СпиÑок baserel->reltarget->exprs позволÑÐµÑ Ð¾Ð¿ÑеделиÑÑ, какие именно ÑÑолбÑÑ ÑÑебÑеÑÑÑ Ð²ÑбÑаÑÑ; но ÑÑÑиÑе, ÑÑо в нÑм пеÑеÑиÑлÑÑÑÑÑ ÑолÑко Ñе ÑÑолбÑÑ, коÑоÑÑе вÑдаÑÑÑÑ Ñзлом плана ForeignScan, но не ÑÑолбÑÑ, коÑоÑÑе задейÑÑÐ²Ð¾Ð²Ð°Ð½Ñ Ð² огÑаниÑиваÑÑиÑ
ÑÑловиÑÑ
и пÑи ÑÑом не вÑводÑÑÑÑ Ð·Ð°Ð¿ÑоÑом.
Ðогда ÑÑнкÑиÑм планиÑÐ¾Ð²Ð°Ð½Ð¸Ñ FDW ÑÑебÑеÑÑÑ ÑÐ¾Ñ ÑанÑÑÑ ÑÐ²Ð¾Ñ Ð¸Ð½ÑоÑмаÑиÑ, они могÑÑ Ð¸ÑполÑзоваÑÑ ÑазлиÑнÑе ÑаÑÑнÑе полÑ. ÐообÑе, вÑе ÑÑÑÑкÑÑÑÑ, коÑоÑÑе FDW помеÑÐ°ÐµÑ Ð² закÑÑÑÑе полÑ, Ð´Ð¾Ð»Ð¶Ð½Ñ Ð²ÑделÑÑÑÑÑ ÑÑнкÑией palloc, ÑÑÐ¾Ð±Ñ Ð¾Ð½Ð¸ авÑомаÑиÑеÑки оÑвобождалиÑÑ Ð¿Ñи завеÑÑении планиÑованиÑ.
ÐÐ»Ñ Ñ
ÑÐ°Ð½ÐµÐ½Ð¸Ñ Ð¸Ð½ÑоÑмаÑии, оÑноÑÑÑейÑÑ Ðº опÑеделÑнной ÑÑоÑонней ÑаблиÑе, ÑÑнкÑии планиÑÐ¾Ð²Ð°Ð½Ð¸Ñ FDW могÑÑ Ð¸ÑполÑзоваÑÑ Ð¿Ð¾Ð»Ðµ baserel->fdw_private, коÑоÑое Ð¼Ð¾Ð¶ÐµÑ ÑодеÑжаÑÑ ÑказаÑÐµÐ»Ñ Ð½Ð° void. ЯдÑо планиÑовÑика никак не каÑаеÑÑÑ ÐµÐ³Ð¾, кÑоме Ñого, ÑÑо запиÑÑÐ²Ð°ÐµÑ Ð² него NULL пÑи Ñоздании Ñзла RelOptInfo. Ðно полезно Ð´Ð»Ñ Ð¿ÐµÑедаÑи инÑоÑмаÑии из GetForeignRelSize в GetForeignPaths и/или из GetForeignPaths в GetForeignPlan и позволÑÐµÑ Ð¸Ð·Ð±ÐµÐ¶Ð°ÑÑ Ð¿Ð¾Ð²ÑоÑнÑÑ
вÑÑиÑлений.
GetForeignPaths Ð¼Ð¾Ð¶ÐµÑ Ð¾Ð±Ð¾Ð·Ð½Ð°ÑиÑÑ ÑвойÑÑва ÑазлиÑнÑÑ
пÑÑей доÑÑÑпа, ÑоÑ
Ñанив ÑаÑÑнÑÑ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð² поле fdw_private Ñзлов ForeignPath. ÐÑо поле fdw_private обÑÑвлено как ÑказаÑÐµÐ»Ñ Ð½Ð° ÑпиÑок (List), но в пÑинÑипе Ð¼Ð¾Ð¶ÐµÑ ÑодеÑжаÑÑ Ð²ÑÑ, ÑÑо Ñгодно, Ñак как ÑдÑо планиÑовÑика его не каÑаеÑÑÑ. Ðднако лÑÑÑе помеÑÑиÑÑ Ð² него даннÑе, коÑоÑÑе ÑÐ¼Ð¾Ð¶ÐµÑ Ð¿ÑедÑÑавиÑÑ ÑÑнкÑÐ¸Ñ nodeToString, Ð´Ð»Ñ Ð¿ÑÐ¸Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ ÑÑедÑÑв оÑладки, имеÑÑиÑ
ÑÑ Ð½Ð° ÑеÑвеÑе.
GetForeignPlan Ð¼Ð¾Ð¶ÐµÑ Ð¸Ð·ÑÑиÑÑ Ð¿Ð¾Ð»Ðµ fdw_private вÑбÑанного Ñзла ForeignPath и ÑÑоÑмиÑоваÑÑ ÑпиÑки fdw_exprs и fdw_private, коÑоÑÑе бÑдÑÑ Ð¿Ð¾Ð¼ÐµÑÐµÐ½Ñ Ð² Ñзел ForeignScan, где они бÑдÑÑ Ð½Ð°Ñ
одиÑÑÑÑ Ð²Ð¾ вÑÐµÐ¼Ñ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð·Ð°Ð¿ÑоÑа. Ðба ÑÑи ÑпиÑка Ð´Ð¾Ð»Ð¶Ð½Ñ Ð±ÑÑÑ Ð¿ÑедÑÑÐ°Ð²Ð»ÐµÐ½Ñ Ð² ÑоÑме, коÑоÑÑÑ ÑпоÑобна копиÑоваÑÑ ÑÑнкÑÐ¸Ñ copyObject. СпиÑок fdw_private не Ð¸Ð¼ÐµÐµÑ Ð´ÑÑгиÑ
огÑаниÑений и никаким обÑазом не инÑеÑпÑеÑиÑÑеÑÑÑ ÑдÑом ÑеÑвеÑа. СпиÑок fdw_exprs, еÑли ÑÑÐ¾Ñ ÑказаÑÐµÐ»Ñ Ð½Ðµ NULL, пÑедположиÑелÑно ÑодеÑÐ¶Ð¸Ñ Ð´ÐµÑевÑÑ Ð²ÑÑажений, коÑоÑÑе Ð´Ð¾Ð»Ð¶Ð½Ñ Ð±ÑÑÑ Ð²ÑÑиÑÐ»ÐµÐ½Ñ Ð¿Ñи вÑполнении запÑоÑа. ÐаÑем планиÑовÑик обÑабаÑÑÐ²Ð°ÐµÑ ÑÑи деÑевÑÑ, ÑÑÐ¾Ð±Ñ Ð¾Ð½Ð¸ бÑли полноÑÑÑÑ Ð³Ð¾ÑÐ¾Ð²Ñ Ðº вÑполнениÑ.
GetForeignPlan обÑÑно Ð¼Ð¾Ð¶ÐµÑ ÑкопиÑоваÑÑ Ð¿Ð¾Ð»ÑÑеннÑй Ñелевой ÑпиÑок в Ñзел плана как еÑÑÑ. ÐеÑедаваемÑй ÑпиÑок scan_clauses ÑодеÑÐ¶Ð¸Ñ Ñе же пÑедложениÑ, ÑÑо и baserel->baserestrictinfo, но, возможно, в дÑÑгом поÑÑдке Ð´Ð»Ñ Ð±Ð¾Ð»ÐµÐµ ÑÑÑекÑивного вÑполнениÑ. РпÑоÑÑÑÑ
ÑлÑÑаÑÑ
FDW Ð¼Ð¾Ð¶ÐµÑ Ð¿ÑоÑÑо ÑбÑаÑÑ ÑÐ·Ð»Ñ RestrictInfo из ÑпиÑка scan_clauses (иÑполÑзÑÑ ÑÑнкÑÐ¸Ñ extract_actual_clauses) и помеÑÑиÑÑ Ð²Ñе пÑÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð² ÑпиÑок огÑаниÑений Ñзла плана, ÑÑо бÑÐ´ÐµÑ Ð¾Ð·Ð½Ð°ÑаÑÑ, ÑÑо ÑÑи пÑÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð±ÑдÑÑ Ð¿ÑовеÑÑÑÑÑÑ Ð¸ÑполниÑелем во вÑÐµÐ¼Ñ Ð²ÑполнениÑ. Ðолее ÑложнÑе FDW могÑÑ ÑамоÑÑоÑÑелÑно пÑовеÑÑÑÑ Ð½ÐµÐºÐ¾ÑоÑÑе пÑедложениÑ, и в ÑÑом ÑлÑÑае Ñакие пÑÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¼Ð¾Ð¶Ð½Ð¾ ÑдалиÑÑ Ð¸Ð· ÑпиÑка огÑаниÑений Ñзла, ÑÑÐ¾Ð±Ñ Ð¸ÑполниÑÐµÐ»Ñ Ð½Ðµ ÑÑаÑил вÑÐµÐ¼Ñ Ð½Ð° иÑ
пеÑепÑовеÑкÑ.
ÐапÑимеÑ, FDW Ð¼Ð¾Ð¶ÐµÑ ÑаÑпознаваÑÑ Ð½ÐµÐºÐ¾ÑоÑÑе пÑÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¾Ð³ÑаниÑений вида ÑÑоÑоннÑÑ_пеÑÐµÐ¼ÐµÐ½Ð½Ð°Ñ = подвÑÑажение, коÑоÑÑе, по ÐµÑ Ð¿ÑедÑÑавлениÑ, могÑÑ Ð²ÑполнÑÑÑÑÑ Ð½Ð° ÑдалÑнном ÑеÑвеÑе Ñ Ð»Ð¾ÐºÐ°Ð»Ñно вÑÑиÑленнÑм знаÑением подвÑÑажениÑ. СобÑÑвенно вÑÑвление Ñакого пÑÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ð¾ пÑоиÑÑ
одиÑÑ Ð² ÑÑнкÑии GetForeignPaths, Ñак как ÑÑо влиÑÐµÑ Ð½Ð° оÑÐµÐ½ÐºÑ ÑÑоимоÑÑи пÑÑи. ÐÑа ÑÑнкÑÐ¸Ñ Ð¼Ð¾Ð¶ÐµÑ Ð²ÐºÐ»ÑÑиÑÑ Ð² поле fdw_private конкÑеÑного пÑÑи ÑказаÑÐµÐ»Ñ Ð½Ð° Ñзел RestrictInfo ÑÑого пÑедложениÑ. ÐаÑем GetForeignPlan ÑÐ´Ð°Ð»Ð¸Ñ ÑÑо пÑедложение из scan_clauses, но Ð´Ð¾Ð±Ð°Ð²Ð¸Ñ Ð¿Ð¾Ð´Ð²ÑÑажение в fdw_exprs, ÑÑÐ¾Ð±Ñ Ð¾Ð½Ð¾ бÑло пÑиведено к иÑполнÑемой ÑоÑме. Ðна Ñакже Ð¼Ð¾Ð¶ÐµÑ Ð¿Ð¾Ð¼ÐµÑÑиÑÑ ÑпÑавлÑÑÑÑÑ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð² поле fdw_private плана Ñзла, коÑоÑÐ°Ñ ÑÐºÐ°Ð¶ÐµÑ Ð¸ÑполнÑÑÑим ÑÑнкÑиÑм, ÑÑо делаÑÑ Ð²Ð¾ вÑÐµÐ¼Ñ Ð²ÑполнениÑ. ÐапÑоÑ, пеÑедаваемÑй ÑдалÑÐ½Ð½Ð¾Ð¼Ñ ÑеÑвеÑÑ, бÑÐ´ÐµÑ ÑодеÑжаÑÑ ÑÑо-Ñо вÑоде WHERE , а знаÑение паÑамеÑÑа бÑÐ´ÐµÑ Ð¿Ð¾Ð»ÑÑено во вÑÐµÐ¼Ñ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð² ÑезÑлÑÑаÑе вÑÑиÑÐ»ÐµÐ½Ð¸Ñ Ð´ÐµÑева вÑÑÐ°Ð¶ÐµÐ½Ð¸Ñ ÑÑоÑоннÑÑ_пеÑÐµÐ¼ÐµÐ½Ð½Ð°Ñ = $1fdw_exprs.
ÐÑе пÑедложениÑ, ÑдалÑемÑе из ÑпиÑка ÑÑловий Ñзла плана, Ð´Ð¾Ð»Ð¶Ð½Ñ Ð±ÑÑÑ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ñ Ð² fdw_recheck_quals или пеÑепÑовеÑÐµÐ½Ñ ÑÑнкÑией RecheckForeignScan Ð´Ð»Ñ Ð¾Ð±ÐµÑпеÑÐµÐ½Ð¸Ñ ÐºÐ¾ÑÑекÑного Ð¿Ð¾Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð½Ð° ÑÑовне изолÑÑии READ COMMITTED. Ðогда Ð¸Ð¼ÐµÐµÑ Ð¼ÐµÑÑо паÑаллелÑное изменение в некоÑоÑой дÑÑгой ÑаблиÑе, задейÑÑвованной в запÑоÑе, иÑполниÑÐµÐ»Ñ Ð¼Ð¾Ð¶ÐµÑ Ð¿Ð¾ÑÑебоваÑÑÑÑ ÑбедиÑÑÑÑ Ð² Ñом, ÑÑо вÑе иÑÑ
однÑе ÑÑÐ»Ð¾Ð²Ð¸Ñ Ð¿Ð¾-пÑÐµÐ¶Ð½ÐµÐ¼Ñ Ð²ÑполнÑÑÑÑÑ Ð´Ð»Ñ ÐºÐ¾ÑÑежа, возможно, Ñ Ð´ÑÑгим набоÑом знаÑений паÑамеÑÑов. ÐÑполÑзоваÑÑ fdw_recheck_quals обÑÑно пÑоÑе, Ñем ÑеализовÑваÑÑ Ð¿ÑовеÑки внÑÑÑи RecheckForeignScan, но ÑÑÐ¾Ñ Ð¼ÐµÑод недоÑÑаÑоÑен, когда внеÑние ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ð²ÑноÑÑÑÑÑ Ð½Ð°ÑÑжÑ, Ñак как вÑледÑÑвие пеÑепÑовеÑки в ÑоединÑннÑÑ
коÑÑежаÑ
могÑÑ Ð¾Ð±Ð½ÑлÑÑÑÑÑ Ð½ÐµÐºÐ¾ÑоÑÑе полÑ, но Ñами коÑÑежи не бÑдÑÑ Ð¸ÑклÑÑаÑÑÑÑ.
ÐÑÑ Ð¾Ð´Ð½Ð¾ поле ForeignScan, коÑоÑое могÑÑ Ð·Ð°Ð¿Ð¾Ð»Ð½ÑÑÑ FDW, ÑÑо fdw_scan_tlist, опиÑÑваÑÑее коÑÑежи, возвÑаÑаемÑе обÑÑÑкой Ð´Ð»Ñ ÑÑого Ñзла плана. ÐÐ»Ñ Ð¿ÑоÑÑÑÑ
ÑÑоÑонниÑ
ÑÐ°Ð±Ð»Ð¸Ñ Ð² него можно запиÑаÑÑ NIL, из Ñего бÑÐ´ÐµÑ ÑледоваÑÑ, ÑÑо возвÑаÑÑннÑе коÑÑежи имеÑÑ Ñип, обÑÑвленнÑй Ð´Ð»Ñ ÑÑоÑонней ÑаблиÑÑ. ÐÑлиÑное Ð¾Ñ NIL знаÑение должно ÑказÑваÑÑ Ð½Ð° ÑпиÑок ÑелевÑÑ
ÑлеменÑов (ÑпиÑок ÑÑÑÑкÑÑÑ TargetEntry), ÑодеÑжаÑий пеÑеменнÑе и/или вÑÑажениÑ, пÑедÑÑавлÑÑÑие возвÑаÑаемÑе ÑÑолбÑÑ. ÐÑо можно иÑполÑзоваÑÑ, напÑимеÑ, ÑÑÐ¾Ð±Ñ Ð¿Ð¾ÐºÐ°Ð·Ð°ÑÑ, ÑÑо FDW опÑÑÑила некоÑоÑÑе ÑÑолбÑÑ, коÑоÑÑе по ÐµÑ Ð½Ð°Ð±Ð»ÑÐ´ÐµÐ½Ð¸Ñ Ð½Ðµ нÑÐ¶Ð½Ñ Ð´Ð»Ñ Ð·Ð°Ð¿ÑоÑа. Также, еÑли FDW Ð¼Ð¾Ð¶ÐµÑ Ð²ÑÑиÑлиÑÑ Ð²ÑÑажениÑ, иÑполÑзÑемÑе в запÑоÑе, более ÑÑÑекÑивно, Ñем ÑÑо можно ÑделаÑÑ Ð»Ð¾ÐºÐ°Ð»Ñно, она должна добавиÑÑ ÑÑи вÑÑÐ°Ð¶ÐµÐ½Ð¸Ñ Ð² ÑпиÑок fdw_scan_tlist. ÐамеÑÑÑе, ÑÑо Ð¿Ð»Ð°Ð½Ñ ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ (полÑÑеннÑе из пÑÑей, ÑозданнÑÑ
ÑÑнкÑией GetForeignJoinPaths) Ð´Ð¾Ð»Ð¶Ð½Ñ Ð²Ñегда заполнÑÑÑ fdw_scan_tlist, опиÑÑÐ²Ð°Ñ Ð½Ð°Ð±Ð¾Ñ ÑÑолбÑов, коÑоÑÑе они бÑдÑÑ Ð²Ð¾Ð·Ð²ÑаÑаÑÑ.
FDW должна вÑегда ÑÑÑоиÑÑ Ð¼Ð¸Ð½Ð¸Ð¼Ñм один пÑÑÑ, завиÑÑÑий ÑолÑко Ð¾Ñ Ð¿Ñедложений огÑаниÑÐµÐ½Ð¸Ñ ÑаблиÑÑ. РзапÑоÑаÑ
Ñ Ñоединением она Ð¼Ð¾Ð¶ÐµÑ Ñакже поÑÑÑоиÑÑ Ð¿ÑÑи, завиÑÑÑие Ð¾Ñ Ð¾Ð³ÑаниÑÐµÐ½Ð¸Ñ ÑоединениÑ, напÑÐ¸Ð¼ÐµÑ ÑÑоÑоннÑÑ_пеÑÐµÐ¼ÐµÐ½Ð½Ð°Ñ = локалÑнаÑ_пеÑеменнаÑ. Такие пÑÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð±ÑдÑÑ Ð¾ÑÑÑÑÑÑвоваÑÑ Ð² baserel->baserestrictinfo; иÑ
нÑжно иÑкаÑÑ Ð² ÑпиÑкаÑ
Ñоединений оÑноÑений. ÐÑÑÑ, поÑÑÑоеннÑй Ñ Ñаким пÑедложением, назÑваеÑÑÑ Â«Ð¿Ð°ÑамеÑÑизованнÑм». ÐÑÑгие оÑноÑениÑ, задейÑÑвованнÑе в вÑбÑанном пÑедложении ÑоединениÑ, Ð´Ð¾Ð»Ð¶Ð½Ñ ÑвÑзÑваÑÑÑÑ c ÑÑим пÑÑÑм ÑооÑвеÑÑÑвÑÑÑим знаÑением param_info; Ð´Ð»Ñ Ð¿Ð¾Ð»ÑÑÐµÐ½Ð¸Ñ ÑÑого знаÑÐµÐ½Ð¸Ñ Ð¸ÑполÑзÑеÑÑÑ get_baserel_parampathinfo. Ð GetForeignPlan ÑаÑÑÑ Ð»Ð¾ÐºÐ°Ð»ÑнаÑ_пеÑÐµÐ¼ÐµÐ½Ð½Ð°Ñ Ð¿ÑÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ð±ÑÐ´ÐµÑ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð° в fdw_exprs, и заÑем, во вÑÐµÐ¼Ñ Ð²ÑполнениÑ, ÑÑо бÑÐ´ÐµÑ ÑабоÑаÑÑ Ñак же, как и обÑÑное пÑедложение огÑаниÑениÑ.
ÐÑли FDW поддеÑÐ¶Ð¸Ð²Ð°ÐµÑ ÑдалÑннÑе ÑоединениÑ, GetForeignJoinPaths должна вÑдаваÑÑ Ð¿ÑÑи ForeignPath Ð´Ð»Ñ Ð¿Ð¾ÑенÑиалÑно ÑдалÑннÑÑ
Ñоединений поÑÑи Ñак же, как ÑÑо Ð´ÐµÐ»Ð°ÐµÑ GetForeignPaths Ð´Ð»Ñ Ð±Ð°Ð·Ð¾Ð²ÑÑ
ÑаблиÑ. ÐнÑоÑмаÑÐ¸Ñ Ð¾ вÑбÑанном Ñоединении Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¿ÐµÑедана ÑÑнкÑии GetForeignPlan Ñак же, как бÑло опиÑано вÑÑе. Ðднако поле baserestrictinfo непÑименимо к оÑноÑениÑм ÑоединениÑ; вмеÑÑо ÑÑого ÑооÑвеÑÑÑвÑÑÑие пÑÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ð´Ð»Ñ ÐºÐ¾Ð½ÐºÑеÑного ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ð¿ÐµÑедаÑÑÑÑ Ð² GetForeignJoinPaths в оÑделÑном паÑамеÑÑе (extra->restrictlist).
FDW Ð¼Ð¾Ð¶ÐµÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑно поддеÑживаÑÑ Ð¿ÑÑмое вÑполнение некоÑоÑÑÑ
дейÑÑвий плана, наÑ
одÑÑиÑ
ÑÑ Ð²ÑÑе ÑÑÐ¾Ð²Ð½Ñ ÑканиÑований и Ñоединений, напÑимеÑ, гÑÑппиÑовки или агÑегиÑованиÑ. ÐÐ»Ñ ÑеализаÑии ÑÑой возможноÑÑи FDW должна ÑÑоÑмиÑоваÑÑ Ð¿ÑÑи и вÑÑавиÑÑ Ð¸Ñ
в ÑооÑвеÑÑÑвÑÑÑее веÑÑ
нее оÑноÑение. ÐапÑимеÑ, пÑÑÑ, пÑедÑÑавлÑÑÑий ÑдалÑнное агÑегиÑование, должен вÑÑавлÑÑÑÑÑ Ð² оÑноÑение UPPERREL_GROUP_AGG Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ add_path. ÐÑÐ¾Ñ Ð¿ÑÑÑ Ð±ÑÐ´ÐµÑ ÑÑавниваÑÑÑÑ Ð¿Ð¾ ÑÑоимоÑÑи Ñ Ð»Ð¾ÐºÐ°Ð»ÑнÑм агÑегиÑованием, вÑполненнÑм по ÑезÑлÑÑаÑам пÑÑи пÑоÑÑого ÑканиÑÐ¾Ð²Ð°Ð½Ð¸Ñ ÑÑоÑоннего оÑноÑÐµÐ½Ð¸Ñ (замеÑÑÑе, ÑÑо Ñакой пÑÑÑ Ñакже должен бÑÑÑ ÑÑоÑмиÑован, инаÑе во вÑÐµÐ¼Ñ Ð¿Ð»Ð°Ð½Ð¸ÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð¿ÑоизойдÑÑ Ð¾Ñибка). ÐÑли пÑÑÑ Ñ ÑдалÑннÑм агÑегиÑованием вÑигÑÑваеÑ, ÑÑо, как пÑавило, и пÑоиÑÑ
одиÑ, он бÑÐ´ÐµÑ Ð¿ÑеобÑазован в план обÑÑнÑм обÑазом, вÑзовом GetForeignPlan. Такие пÑÑи ÑекомендÑеÑÑÑ ÑоÑмиÑоваÑÑ Ð² обÑабоÑÑике GetForeignUpperPaths, коÑоÑÑй вÑзÑваеÑÑÑ Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ веÑÑ
него оÑноÑÐµÐ½Ð¸Ñ (Ñо еÑÑÑ Ð½Ð° каждом Ñаге обÑабоÑки поÑле ÑканиÑованиÑ/ÑоединениÑ), еÑли вÑе базовÑе оÑноÑÐµÐ½Ð¸Ñ Ð·Ð°Ð¿ÑоÑа вÑдаÑÑÑÑ Ð¾Ð´Ð½Ð¾Ð¹ обÑÑÑкой.
PlanForeignModify и дÑÑгие обÑабоÑÑики, опиÑаннÑе в ÐодÑазделе 52.2.4, ÑаÑÑÑиÑÐ°Ð½Ñ Ð½Ð° Ñо, ÑÑо ÑÑоÑоннее оÑноÑение бÑÐ´ÐµÑ ÑканиÑоваÑÑÑÑ Ð¾Ð±ÑÑнÑм ÑпоÑобом, а заÑем оÑделÑнÑе Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ ÑÑÑок бÑдÑÑ Ð¾Ð±ÑабаÑÑваÑÑÑÑ Ð»Ð¾ÐºÐ°Ð»ÑнÑм Ñзлом плана ModifyTable. ÐÑÐ¾Ñ Ð¿Ð¾Ð´Ñ
од необÑ
одим в обÑем ÑлÑÑае, когда Ð´Ð»Ñ Ñакого Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ ÑÑебÑеÑÑÑ Ð¿ÑоÑиÑаÑÑ Ð½Ðµ ÑолÑко ÑÑоÑонние, но и локалÑнÑе ÑаблиÑÑ. Ðднако еÑли опеÑаÑÐ¸Ñ Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ñеликом вÑполнена ÑÑоÑонним ÑеÑвеÑом, FDW Ð¼Ð¾Ð¶ÐµÑ Ð¿Ð¾ÑÑÑоиÑÑ Ð¿ÑÑÑ, пÑедÑÑавлÑÑÑий ÑÑÑ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑÑ, и вÑÑавиÑÑ ÐµÐ³Ð¾ в веÑÑ
нее оÑноÑение UPPERREL_FINAL, где он бÑÐ´ÐµÑ ÐºÐ¾Ð½ÐºÑÑиÑоваÑÑ Ñ Ð¿Ð¾Ð´Ñ
одом ModifyTable. ÐÑÐ¾Ñ Ð¿Ð¾Ð´Ñ
од Ñакже должен пÑименÑÑÑÑÑ Ð´Ð»Ñ ÑеализаÑии ÑдалÑнного SELECT FOR UPDATE, вмеÑÑо обÑабоÑÑиков блокиÑовки ÑÑÑок, опиÑаннÑÑ
ÐодÑазделе 52.2.5. УÑÑиÑе, ÑÑо пÑÑÑ, вÑÑавлÑемÑй в UPPERREL_FINAL, оÑвеÑÐ°ÐµÑ Ð·Ð° ÑеализаÑÐ¸Ñ Ð²ÑеÑ
аÑпекÑов Ð¿Ð¾Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð·Ð°Ð¿ÑоÑа.
ÐÑи планиÑовании запÑоÑов UPDATE или DELETE ÑÑнкÑии PlanForeignModify и PlanDirectModify могÑÑ Ð¾Ð±ÑаÑиÑÑÑÑ Ðº ÑÑÑÑкÑÑÑе RelOptInfo ÑÑоÑонней ÑаблиÑÑ Ð¸ воÑполÑзоваÑÑÑÑ Ð¸Ð½ÑоÑмаÑией baserel->fdw_private, запиÑанной Ñанее ÑÑнкÑиÑми планиÑÐ¾Ð²Ð°Ð½Ð¸Ñ ÑканиÑованиÑ. Ðднако пÑи запÑоÑе INSERT ÑÐµÐ»ÐµÐ²Ð°Ñ ÑаблиÑа не ÑканиÑÑеÑÑÑ, Ñак ÑÑо Ð´Ð»Ñ Ð½ÐµÑ RelOptInfo не заполнÑеÑÑÑ. Ðа ÑпиÑок (List), возвÑаÑаемÑй ÑÑнкÑией PlanForeignModify, накладÑваÑÑÑÑ Ñе же огÑаниÑениÑ, ÑÑо и на ÑпиÑок fdw_private в Ñзле плана ForeignScan, Ñо еÑÑÑ Ð¾Ð½ должен ÑодеÑжаÑÑ ÑолÑко Ñакие ÑÑÑÑкÑÑÑÑ, коÑоÑÑе ÑпоÑобна копиÑоваÑÑ ÑÑнкÑÐ¸Ñ copyObject.
Ðоманда INSERT Ñ Ð¿Ñедложением ON CONFLICT не поддеÑÐ¶Ð¸Ð²Ð°ÐµÑ Ñказание обÑекÑа конÑликÑа, Ñак как ÑникалÑнÑе огÑаниÑÐµÐ½Ð¸Ñ Ð¸Ð»Ð¸ огÑаниÑениÑ-иÑклÑÑÐµÐ½Ð¸Ñ Ð² ÑдалÑннÑÑ
ÑаблиÑаÑ
неизвеÑÑÐ½Ñ Ð»Ð¾ÐºÐ°Ð»Ñно. Ðз ÑÑого, в ÑÐ²Ð¾Ñ Ð¾ÑеÑедÑ, вÑÑекаеÑ, ÑÑо пÑедложение ON CONFLICT DO UPDATE не поддеÑживаеÑÑÑ, Ñак как в нÑм ÑÑо Ñказание ÑвлÑеÑÑÑ Ð¾Ð±ÑзаÑелÑнÑм.