54.2. ÐодпÑогÑÐ°Ð¼Ð¼Ñ Ð¾Ð±ÑÑÑки ÑÑоÑÐ¾Ð½Ð½Ð¸Ñ Ð´Ð°Ð½Ð½ÑÑ
- 54.2.1. ÐодпÑогÑÐ°Ð¼Ð¼Ñ FDW Ð´Ð»Ñ ÑканиÑÐ¾Ð²Ð°Ð½Ð¸Ñ ÑÑоÑонниÑ
ÑаблиÑ
- 54.2.2. ÐодпÑогÑÐ°Ð¼Ð¼Ñ FDW Ð´Ð»Ñ ÑканиÑÐ¾Ð²Ð°Ð½Ð¸Ñ ÑÑоÑÐ¾Ð½Ð½Ð¸Ñ Ñоединений
- 54.2.3. ÐодпÑогÑÐ°Ð¼Ð¼Ñ FDW Ð´Ð»Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð´Ð°Ð½Ð½ÑÑ Ð² ÑÑоÑÐ¾Ð½Ð½Ð¸Ñ ÑаблиÑаÑ
- 54.2.4. ÐодпÑогÑÐ°Ð¼Ð¼Ñ FDW Ð´Ð»Ñ Ð±Ð»Ð¾ÐºÐ¸Ñовки ÑÑÑок
- 54.2.5. ÐодпÑогÑÐ°Ð¼Ð¼Ñ FDW длÑ
EXPLAIN- 54.2.6. ÐодпÑогÑÐ°Ð¼Ð¼Ñ FDW длÑ
ANALYZE- 54.2.7. ÐодпÑогÑÐ°Ð¼Ð¼Ñ FDW длÑ
IMPORT FOREIGN SCHEMA - 54.2.2. ÐодпÑогÑÐ°Ð¼Ð¼Ñ FDW Ð´Ð»Ñ ÑканиÑÐ¾Ð²Ð°Ð½Ð¸Ñ ÑÑоÑÐ¾Ð½Ð½Ð¸Ñ Ñоединений
ФÑнкÑиÑ-обÑабоÑÑик FDW возвÑаÑÐ°ÐµÑ ÑÑÑÑкÑÑÑÑ FdwRoutine (вÑделеннÑÑ Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ palloc), ÑодеÑжаÑÑÑ ÑказаÑели на подпÑогÑаммÑ, коÑоÑÑе ÑеализÑÑÑ Ð¾Ð¿Ð¸ÑаннÑе ниже ÑÑнкÑии. Ðз вÑеÑ
ÑÑнкÑий обÑзаÑелÑнÑми ÑвлÑÑÑÑÑ ÑолÑко Ñе, ÑÑо каÑаÑÑÑÑ ÑканиÑованиÑ, а оÑÑалÑнÑе могÑÑ Ð¾ÑÑÑÑÑÑвоваÑÑ.
Тип ÑÑÑÑкÑÑÑÑ FdwRoutine обÑÑвлен в src/include/foreign/fdwapi.h, Ñам же можно ÑзнаÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑнÑе подÑобноÑÑи.
54.2.1. ÐодпÑогÑÐ°Ð¼Ð¼Ñ FDW Ð´Ð»Ñ ÑканиÑÐ¾Ð²Ð°Ð½Ð¸Ñ ÑÑоÑÐ¾Ð½Ð½Ð¸Ñ ÑаблиÑ
void
GetForeignRelSize (PlannerInfo *root,
RelOptInfo *baserel,
Oid foreigntableid); ÐÑдаÑÑ Ð¾ÑÐµÐ½ÐºÑ ÑазмеÑа оÑноÑÐµÐ½Ð¸Ñ Ð´Ð»Ñ ÑÑоÑонней ÑаблиÑÑ. Ðна вÑзÑваеÑÑÑ Ð² наÑале планиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð·Ð°Ð¿ÑоÑа, в коÑоÑом ÑканиÑÑеÑÑÑ ÑÑоÑоннÑÑ ÑаблиÑа. РпаÑамеÑÑе root пеÑедаÑÑÑÑ Ð¾Ð±ÑÐ°Ñ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð¿Ð»Ð°Ð½Ð¸ÑовÑика о запÑоÑе, в baserel â инÑоÑмаÑÐ¸Ñ Ð¾ данной ÑаблиÑе, а в foreigntableid â OID запиÑи в pg_class Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð¹ ÑаблиÑÑ. (ÐнаÑение foreigntableid можно полÑÑиÑÑ Ð¸ из ÑÑÑÑкÑÑÑÑ Ð´Ð°Ð½Ð½ÑÑ
планиÑовÑика, но пÑоÑÑоÑÑ Ñади оно пеÑедаÑÑÑÑ Ñвно.)
ÐÑа ÑÑнкÑÐ¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° запиÑаÑÑ Ð² baserel->rows ожидаемое ÑиÑло ÑÑÑок, коÑоÑое бÑÐ´ÐµÑ Ð¿Ð¾Ð»ÑÑено пÑи ÑканиÑовании ÑаблиÑÑ, Ñ ÑÑÑÑом ÑилÑÑÑа, заданного огÑаниÑением вÑбоÑки. ÐзнаÑалÑно в baserel->rows ÑодеÑжиÑÑÑ Ð¿ÑоÑÑо поÑÑоÑÐ½Ð½Ð°Ñ Ð¾Ñенка по ÑмолÑаниÑ, коÑоÑÑÑ ÑледÑÐµÑ Ð·Ð°Ð¼ÐµÐ½Ð¸ÑÑ, еÑли ÑÑо вообÑе возможно. ФÑнкÑÐ¸Ñ Ñакже Ð¼Ð¾Ð¶ÐµÑ Ð¿Ð¾Ð¼ÐµÐ½ÑÑÑ Ð·Ð½Ð°Ñение baserel->width, еÑли она Ð¼Ð¾Ð¶ÐµÑ Ð´Ð°ÑÑ Ð»ÑÑÑÑÑ Ð¾ÑÐµÐ½ÐºÑ ÑÑедней ÑиÑÐ¸Ð½Ñ ÑÑÑоки ÑезÑлÑÑаÑа.
Ðа дополниÑелÑнÑми ÑведениÑми обÑаÑиÑеÑÑ Ðº РазделÑ 54.4.
void
GetForeignPaths (PlannerInfo *root,
RelOptInfo *baserel,
Oid foreigntableid); ФоÑмиÑÑÐµÑ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ñе пÑÑи доÑÑÑпа Ð´Ð»Ñ ÑканиÑÐ¾Ð²Ð°Ð½Ð¸Ñ ÑÑоÑонней ÑаблиÑÑ. ÐÑа ÑÑнкÑÐ¸Ñ Ð²ÑзÑваеÑÑÑ Ð¿Ñи планиÑовании запÑоÑа. Ðй пеÑедаÑÑÑÑ Ñе же паÑамеÑÑÑ, ÑÑо и ÑÑнкÑии GetForeignRelSize, коÑоÑÐ°Ñ Ðº ÑÑÐ¾Ð¼Ñ Ð²Ñемени Ñже бÑÐ´ÐµÑ Ð²Ñзвана.
ÐÑа ÑÑнкÑÐ¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° вÑдаÑÑ Ð¼Ð¸Ð½Ð¸Ð¼Ñм один пÑÑÑ Ð´Ð¾ÑÑÑпа (Ñзел ForeignPath) Ð´Ð»Ñ ÑканиÑÐ¾Ð²Ð°Ð½Ð¸Ñ ÑÑоÑонней ÑаблиÑÑ Ð¸ должна вÑзваÑÑ add_path, ÑÑÐ¾Ð±Ñ Ð´Ð¾Ð±Ð°Ð²Ð¸ÑÑ ÐºÐ°Ð¶Ð´Ñй Ñакой пÑÑÑ Ð² baserel->pathlist. ÐÐ»Ñ ÑоÑмиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ñзлов ForeignPath ÑекомендÑеÑÑÑ Ð²ÑзÑваÑÑ create_foreignscan_path. ÐÐ°Ð½Ð½Ð°Ñ ÑÑнкÑÐ¸Ñ Ð¼Ð¾Ð¶ÐµÑ Ð²ÑдаваÑÑ Ð½ÐµÑколÑко пÑÑей доÑÑÑпа, Ñо еÑÑÑ Ð¿ÑÑей, Ð´Ð»Ñ ÐºÐ¾ÑоÑÑÑ
по заданнÑм pathkeys можно полÑÑиÑÑ Ñже оÑÑоÑÑиÑованнÑй ÑезÑлÑÑаÑ. ÐаждÑй пÑÑÑ Ð´Ð¾ÑÑÑпа должен ÑодеÑжаÑÑ Ð¾Ñенки ÑÑоимоÑÑи и Ð¼Ð¾Ð¶ÐµÑ ÑодеÑжаÑÑ Ð»ÑбÑÑ ÑаÑÑнÑÑ Ð¸Ð½ÑоÑмаÑÐ¸Ñ FDW, необÑ
одимÑÑ Ð´Ð»Ñ Ð²ÑбоÑа Ñелевого меÑода ÑканиÑованиÑ.
Ðа дополниÑелÑнÑми ÑведениÑми обÑаÑиÑеÑÑ Ðº РазделÑ 54.4.
ForeignScan *
GetForeignPlan (PlannerInfo *root,
RelOptInfo *baserel,
Oid foreigntableid,
ForeignPath *best_path,
List *tlist,
List *scan_clauses,
Plan *outer_plan); СоздаÑÑ Ñзел плана ForeignScan из вÑбÑанного пÑÑи доÑÑÑпа к ÑÑоÑонней ÑаблиÑе. ÐÑа ÑÑнкÑÐ¸Ñ Ð²ÑзÑваеÑÑÑ Ð² конÑе планиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð·Ð°Ð¿ÑоÑа. Ðй пеÑедаÑÑÑÑ Ñе же паÑамеÑÑÑ, ÑÑо и GetForeignRelSize, плÑÑ Ð²ÑбÑаннÑй пÑÑÑ ForeignPath (до ÑÑого ÑÑоÑмиÑованнÑй ÑÑнкÑиÑми GetForeignPaths или GetForeignJoinPaths), Ñелевой ÑпиÑок, коÑоÑÑй должен бÑÑÑ Ð²Ñдан ÑÑим Ñзлом плана, ÑÑÐ»Ð¾Ð²Ð¸Ñ Ð¾Ð³ÑаниÑениÑ, коÑоÑÑе Ð´Ð¾Ð»Ð¶Ð½Ñ Ð¿ÑименÑÑÑÑÑ Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð³Ð¾ Ñзла, и внеÑний вложеннÑй подплан ForeignScan, пÑименÑемÑй Ð´Ð»Ñ Ð¿ÐµÑепÑовеÑок, вÑполнÑемÑÑ
ÑÑнкÑией RecheckForeignScan. (ÐÑли пÑÑÑ Ð·Ð°Ð´Ð°ÑÑÑÑ Ð´Ð»Ñ ÑоединениÑ, а не Ð´Ð»Ñ Ð±Ð°Ð·Ð¾Ð²Ð¾Ð³Ð¾ оÑноÑениÑ, в foreigntableid пеÑедаÑÑÑÑ InvalidOid.)
ÐÑа ÑÑнкÑÐ¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° ÑоздаÑÑ Ð¸ вÑдаÑÑ Ñзел плана ForeignScan; Ð´Ð»Ñ ÑоÑмиÑÐ¾Ð²Ð°Ð½Ð¸Ñ ÑÑого Ñзла ÑекомендÑеÑÑÑ Ð¸ÑполÑзоваÑÑ make_foreignscan.
Ðа дополниÑелÑнÑми ÑведениÑми обÑаÑиÑеÑÑ Ðº РазделÑ 54.4.
void
BeginForeignScan (ForeignScanState *node,
int eflags); ÐаÑÐ¸Ð½Ð°ÐµÑ ÑканиÑование ÑÑоÑонней ÑаблиÑÑ. ÐÑа ÑÑнкÑÐ¸Ñ Ð²ÑзÑваеÑÑÑ Ð¿Ñи запÑÑке иÑполниÑелÑ. Ðна должна вÑполниÑÑ Ð²Ñе подгоÑовиÑелÑнÑе дейÑÑвиÑ, необÑ
одимÑе Ð´Ð»Ñ Ð¾ÑÑÑеÑÑÐ²Ð»ÐµÐ½Ð¸Ñ ÑканиÑованиÑ, но не должна ÑобÑÑвенно пÑоизводиÑÑ ÑканиÑование (оно должно наÑаÑÑÑÑ Ñ Ð¿ÐµÑвÑм вÑзовом IterateForeignScan). Узел ForeignScanState Ñже бÑл Ñоздан, но его поле fdw_state по-пÑÐµÐ¶Ð½ÐµÐ¼Ñ NULL. ÐнÑоÑмаÑÐ¸Ñ Ð¾ ÑканиÑÑемой ÑаблиÑе можно полÑÑиÑÑ ÑеÑез Ñзел ForeignScanState (в ÑаÑÑноÑÑи, из нижележаÑего Ñзла ForeignScan, ÑодеÑжаÑего ÑаÑÑнÑÑ Ð¸Ð½ÑоÑмаÑÐ¸Ñ FDW, заданнÑÑ ÑÑнкÑией GetForeignPlan). ÐаÑамеÑÑ eflags ÑодеÑÐ¶Ð¸Ñ Ð±Ð¸ÑовÑе Ñлаги, опиÑÑваÑÑие Ñежим ÑабоÑÑ Ð¸ÑполниÑÐµÐ»Ñ Ð´Ð»Ñ ÑÑого Ñзла плана.
ÐамеÑÑÑе, ÑÑо когда (eflags & EXEC_FLAG_EXPLAIN_ONLY) не Ñавно нÑлÑ, ÑÑа ÑÑнкÑÐ¸Ñ Ð½Ðµ должна вÑполнÑÑÑ ÐºÐ°ÐºÐ¸Ðµ-либо внеÑне пÑоÑвлÑÑÑиеÑÑ Ð´ÐµÐ¹ÑÑвиÑ; она должна ÑделаÑÑ ÑолÑко Ñо, ÑÑо необÑ
одимо Ð´Ð»Ñ Ð¿Ð¾Ð»ÑÑÐµÐ½Ð¸Ñ ÑоÑÑоÑÐ½Ð¸Ñ Ñзла, подÑ
одÑÑего Ð´Ð»Ñ ExplainForeignScan и EndForeignScan.
TupleTableSlot * IterateForeignScan (ForeignScanState *node);
ÐÑбиÑÐ°ÐµÑ Ð¾Ð´Ð½Ñ ÑÑÑÐ¾ÐºÑ Ð¸Ð· ÑÑоÑоннего иÑÑоÑника и возвÑаÑÐ°ÐµÑ ÐµÑ Ð² ÑлоÑе ÑаблиÑÑ ÐºÐ¾ÑÑежей (Ð´Ð»Ñ ÑÑой Ñели ÑледÑÐµÑ Ð¸ÑполÑзоваÑÑ ScanTupleSlot, пеÑеданнÑй Ñ Ñзлом). Ðогда ÑÑÑоки заканÑиваÑÑÑÑ, возвÑаÑÐ°ÐµÑ NULL. ÐнÑÑаÑÑÑÑкÑÑÑа ÑлоÑов ÑаблиÑÑ ÐºÐ¾ÑÑежей позволÑÐµÑ Ð²Ð¾Ð·Ð²ÑаÑаÑÑ ÐºÐ°Ðº ÑизиÑеÑкие, Ñак и виÑÑÑалÑнÑе коÑÑежи; в болÑÑинÑÑве ÑлÑÑаев вÑоÑой ваÑÐ¸Ð°Ð½Ñ Ð¿ÑедпоÑÑиÑелÑнее Ñ ÑоÑки зÑÐµÐ½Ð¸Ñ Ð¿ÑоизводиÑелÑноÑÑи. ÐамеÑÑÑе, ÑÑо ÑÑа ÑÑнкÑÐ¸Ñ Ð²ÑзÑваеÑÑÑ Ð² конÑекÑÑе кÑаÑковÑеменной памÑÑи, коÑоÑÑй бÑÐ´ÐµÑ ÑбÑаÑÑваÑÑÑÑ Ð¼ÐµÐ¶Ð´Ñ Ð²Ñзовами. ÐÑли вам нÑжна более долгоживÑÑÐ°Ñ Ð¿Ð°Ð¼ÑÑÑ, ÑоздайÑе ÑооÑвеÑÑÑвÑÑÑий конÑекÑÑ Ð² BeginForeignScan либо иÑполÑзÑйÑе es_query_cxt из ÑÑÑÑкÑÑÑÑ EState, пеÑеданной Ñ Ñзлом.
ÐозвÑаÑаемÑе ÑÑÑоки Ð´Ð¾Ð»Ð¶Ð½Ñ ÑооÑвеÑÑÑвоваÑÑ ÑÐµÐ»ÐµÐ²Ð¾Ð¼Ñ ÑпиÑÐºÑ fdw_scan_tlist, еÑли он пеÑедаÑÑÑÑ, а в пÑоÑивном ÑлÑÑае â ÑÐ¸Ð¿Ñ ÑÑÑоки ÑканиÑÑемой ÑÑоÑонней ÑаблиÑÑ. ÐÑли Ð²Ñ ÑеÑиÑе Ð´Ð»Ñ Ð¾Ð¿ÑимизаÑии не возвÑаÑаÑÑ Ð½ÐµÐ½ÑжнÑе ÑÑолбÑÑ, в иÑ
позиÑии нÑжно вÑÑавиÑÑ NULL, либо ÑÑоÑмиÑоваÑÑ ÑпиÑок fdw_scan_tlist без ÑÑиÑ
ÑÑолбÑов.
ÐамеÑÑÑе, ÑÑо Ð´Ð»Ñ Ð¸ÑполниÑÐµÐ»Ñ Postgres Pro не важно, ÑдовлеÑвоÑÑÑÑ Ð»Ð¸ возвÑаÑаемÑе ÑÑÑоки каким-либо огÑаниÑениÑм, опÑеделÑннÑм Ð´Ð»Ñ ÑÑоÑонней ÑаблиÑÑ â но ÑÑо важно Ð´Ð»Ñ Ð¿Ð»Ð°Ð½Ð¸ÑовÑика, Ñак ÑÑо запÑоÑÑ Ð¼Ð¾Ð³ÑÑ Ð¾Ð¿ÑимизиÑоваÑÑÑÑ Ð½ÐµÐºÐ¾ÑÑекÑно, еÑли в ÑÑоÑонней ÑаблиÑе бÑдÑÑ Ð²Ð¸Ð´Ð½Ñ ÑÑÑоки, не ÑдовлеÑвоÑÑÑÑие обÑÑÐ²Ð»ÐµÐ½Ð½Ð¾Ð¼Ñ Ð¾Ð³ÑаниÑениÑ. ÐÑли огÑаниÑение наÑÑÑаеÑÑÑ, Ñогда как полÑзоваÑÐµÐ»Ñ Ð¾Ð±ÑÑвил, ÑÑо оно должно вÑполнÑÑÑÑÑ, Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ ÑмеÑÑно ÑообÑиÑÑ Ð¾Ð± оÑибке (ÑоÑно Ñак же, как и пÑи неÑовпадении Ñипов даннÑÑ ).
void ReScanForeignScan (ForeignScanState *node);
ÐеÑезапÑÑÐºÐ°ÐµÑ ÑканиÑование Ñ Ð½Ð°Ñала. ÐамеÑÑÑе, ÑÑо знаÑÐµÐ½Ð¸Ñ Ð¿Ð°ÑамеÑÑов, Ð¾Ñ ÐºÐ¾ÑоÑÑÑ Ð·Ð°Ð²Ð¸ÑÐ¸Ñ ÑканиÑование, могли измениÑÑÑÑ, Ñак ÑÑо новое ÑканиÑование не обÑзаÑелÑно веÑнÑÑ Ñе же ÑÑÑоки.
void EndForeignScan (ForeignScanState *node);
ÐавеÑÑÐ°ÐµÑ ÑканиÑование и оÑÐ²Ð¾Ð±Ð¾Ð¶Ð´Ð°ÐµÑ ÑеÑÑÑÑÑ. ÐбÑÑно пÑи ÑÑом не нÑжно оÑвобождаÑÑ Ð¿Ð°Ð¼ÑÑÑ, вÑделеннÑÑ ÑеÑез palloc, но напÑимеÑ, оÑкÑÑÑÑе ÑÐ°Ð¹Ð»Ñ Ð¸ подклÑÑÐµÐ½Ð¸Ñ Ðº ÑдалÑннÑм ÑеÑвеÑам ÑледÑÐµÑ Ð·Ð°ÐºÑÑÑÑ.
54.2.2. ÐодпÑогÑÐ°Ð¼Ð¼Ñ FDW Ð´Ð»Ñ ÑканиÑÐ¾Ð²Ð°Ð½Ð¸Ñ ÑÑоÑÐ¾Ð½Ð½Ð¸Ñ Ñоединений
ÐÑли FDW поддеÑÐ¶Ð¸Ð²Ð°ÐµÑ ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ð½Ð° ÑдалÑнной ÑÑоÑоне (вмеÑÑо Ñого, ÑÑÐ¾Ð±Ñ ÑÑиÑÑваÑÑ Ð´Ð°Ð½Ð½Ñе Ð¾Ð±ÐµÐ¸Ñ ÑÐ°Ð±Ð»Ð¸Ñ Ð¸ вÑполнÑÑÑ ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ð»Ð¾ÐºÐ°Ð»Ñно), она должна пÑедоÑÑавиÑÑ ÑÑÑ ÑеализÑÑÑÑÑ Ð¿Ð¾Ð´Ð¿ÑогÑаммÑ:
void
GetForeignJoinPaths (PlannerInfo *root,
RelOptInfo *joinrel,
RelOptInfo *outerrel,
RelOptInfo *innerrel,
JoinType jointype,
JoinPathExtraData *extra); ФоÑмиÑÑÐµÑ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ñе пÑÑи доÑÑÑпа Ð´Ð»Ñ ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ð´Ð²ÑÑ
(и более) ÑÑоÑонниÑ
ÑаблиÑ, пÑинадлежаÑиÑ
Ð¾Ð´Ð½Ð¾Ð¼Ñ ÑÑоÑÐ¾Ð½Ð½ÐµÐ¼Ñ ÑеÑвеÑÑ. ÐÑа необÑзаÑелÑÐ½Ð°Ñ ÑÑнкÑÐ¸Ñ Ð²ÑзÑваеÑÑÑ Ð²Ð¾ вÑÐµÐ¼Ñ Ð¿Ð»Ð°Ð½Ð¸ÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð·Ð°Ð¿ÑоÑа. Ðак и GetForeignPaths, ÑÑа ÑÑнкÑÐ¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° поÑÑÑоиÑÑ Ð¿ÑÑи ForeignPath Ð´Ð»Ñ Ð¿ÐµÑеданного joinrel и вÑзваÑÑ add_path, ÑÑÐ¾Ð±Ñ Ð´Ð¾Ð±Ð°Ð²Ð¸ÑÑ ÑÑи пÑÑи в Ð½Ð°Ð±Ð¾Ñ Ð¿ÑÑей, подÑ
одÑÑиÑ
Ð´Ð»Ñ ÑоединениÑ. Ðо, в оÑлиÑие Ð¾Ñ GetForeignPaths, ÑÑа ÑÑнкÑÐ¸Ñ Ð½Ðµ обÑзаÑелÑно должна возвÑаÑаÑÑ Ð¼Ð¸Ð½Ð¸Ð¼Ñм один пÑÑÑ, Ñак как вÑегда возможен алÑÑеÑнаÑивнÑй пÑÑÑ Ñ Ð»Ð¾ÐºÐ°Ð»ÑнÑм Ñоединением ÑаблиÑ.
ÐамеÑÑÑе, ÑÑо ÑÑа ÑÑнкÑÐ¸Ñ Ð±ÑÐ´ÐµÑ Ð²ÑзÑваÑÑÑÑ Ð½ÐµÐ¾Ð´Ð½Ð¾ÐºÑаÑно Ð´Ð»Ñ Ð¾Ð´Ð½Ð¾Ð³Ð¾ и Ñого же ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ñ ÑазнÑми комбинаÑиÑми внÑÑÑеннего и внеÑнего оÑноÑений; минимизиÑоваÑÑ Ð´Ð²Ð¾Ð¹Ð½ÑÑ ÑабоÑÑ Ð´Ð¾Ð»Ð¶Ð½Ð° Ñама FDW.
ÐÑли Ð´Ð»Ñ ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ð²ÑбиÑаеÑÑÑ Ð¿ÑÑÑ ForeignPath, он бÑÐ´ÐµÑ Ð¿ÑедÑÑавлÑÑÑ Ð²ÐµÑÑ Ð¿ÑоÑеÑÑ ÑоединениÑ; пÑÑи, ÑÑоÑмиÑованнÑе Ð´Ð»Ñ Ð·Ð°Ð´ÐµÐ¹ÑÑвованнÑÑ
ÑÐ°Ð±Ð»Ð¸Ñ Ð¸ подÑинÑннÑÑ
Ñоединений, в нÑм пÑименÑÑÑÑÑ Ð½Ðµ бÑдÑÑ. Ðалее ÑÑÐ¾Ñ Ð¿ÑÑÑ ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ð¾Ð±ÑабаÑÑваеÑÑÑ Ð²Ð¾ многом Ñак же, как и пÑÑÑ ÑканиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð¾Ð´Ð½Ð¾Ð¹ ÑÑоÑонней ÑаблиÑÑ. Ðдно ÑазлиÑие ÑоÑÑÐ¾Ð¸Ñ Ð² Ñом, ÑÑо scanrelid ÑезÑлÑÑиÑÑÑÑего плана Ñзла ForeignScan должно бÑÑÑ Ñавно нÑлÑ, Ñак как он не пÑедÑÑавлÑÐµÑ ÐºÐ°ÐºÐ¾Ðµ-либо одно оÑноÑение; вмеÑÑо ÑÑого Ð½Ð°Ð±Ð¾Ñ ÑоединÑемÑÑ
оÑноÑений пÑедÑÑавлÑеÑÑÑ Ð² поле fs_relids Ñзла ForeignScan. (ÐÑо поле заполнÑеÑÑÑ Ð°Ð²ÑомаÑиÑеÑки кодом ÑдÑа планиÑовÑика, Ñак ÑÑо FDW делаÑÑ ÑÑо не нÑжно.) ÐÑÑ Ð¾Ð´Ð½Ð¾ оÑлиÑие в Ñом, ÑÑо ÑпиÑок ÑÑолбÑов Ð´Ð»Ñ ÑдалÑнного ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ð½ÐµÐ»ÑÐ·Ñ Ð¿Ð¾Ð»ÑÑиÑÑ Ð¸Ð· ÑиÑÑемнÑÑ
каÑалогов и поÑÑÐ¾Ð¼Ñ FDW должна вÑдаÑÑ Ð² fdw_scan_tlist ÑÑебÑемÑй ÑпиÑок Ñзлов TargetEntry, пÑедÑÑавлÑÑÑий Ð½Ð°Ð±Ð¾Ñ ÑÑолбÑов, коÑоÑÑе бÑдÑÑ Ð²ÑдаваÑÑÑÑ Ð²Ð¾ вÑÐµÐ¼Ñ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð² возвÑаÑаемÑÑ
коÑÑежаÑ
.
Ðа дополниÑелÑнÑми ÑведениÑми обÑаÑиÑеÑÑ Ðº РазделÑ 54.4.
54.2.3. ÐодпÑогÑÐ°Ð¼Ð¼Ñ FDW Ð´Ð»Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð´Ð°Ð½Ð½ÑÑ Ð² ÑÑоÑÐ¾Ð½Ð½Ð¸Ñ ÑаблиÑаÑ
ÐÑли FDW поддеÑÐ¶Ð¸Ð²Ð°ÐµÑ Ð·Ð°Ð¿Ð¸ÑÑ Ð² ÑÑоÑонние ÑаблиÑÑ, она должна пÑедоÑÑавиÑÑ Ð½ÐµÐºÐ¾ÑоÑÑе или вÑе подпÑогÑаммÑ, ÑеализÑÑÑие ÑледÑÑÑие ÑÑнкÑии, в завиÑимоÑÑи Ð¾Ñ Ð¿Ð¾ÑÑебноÑÑей и возможноÑÑей FDW:
void
AddForeignUpdateTargets (Query *parsetree,
RangeTblEntry *target_rte,
Relation target_relation); ÐпеÑаÑии UPDATE и DELETE вÑполнÑÑÑÑÑ Ñо ÑÑÑоками, Ñанее вÑбÑаннÑми ÑÑнкÑиÑми ÑканиÑÐ¾Ð²Ð°Ð½Ð¸Ñ ÑаблиÑÑ. FDW Ð¼Ð¾Ð¶ÐµÑ Ð¿Ð¾ÑÑебоваÑÑÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑÐ½Ð°Ñ Ð¸Ð½ÑоÑмаÑиÑ, напÑимеÑ, ID ÑÑÑоки или знаÑÐµÐ½Ð¸Ñ ÑÑолбÑов пеÑвиÑного клÑÑа, ÑÑÐ¾Ð±Ñ ÑоÑно знаÑÑ, какÑÑ Ð¸Ð¼ÐµÐ½Ð½Ð¾ ÑÑÑÐ¾ÐºÑ Ð½Ñжно измениÑÑ Ð¸Ð»Ð¸ ÑдалиÑÑ. ÐÐ»Ñ ÑÑого Ð´Ð°Ð½Ð½Ð°Ñ ÑÑнкÑÐ¸Ñ Ð¼Ð¾Ð¶ÐµÑ Ð´Ð¾Ð±Ð°Ð²Ð¸ÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑнÑе ÑкÑÑÑÑе или «оÑбÑоÑовÑе» ÑелевÑе ÑÑолбÑÑ Ð² ÑпиÑок ÑÑолбÑов, коÑоÑÑе Ð´Ð¾Ð»Ð¶Ð½Ñ Ð±ÑÑÑ Ð¿Ð¾Ð»ÑÑÐµÐ½Ñ Ð¸Ð· ÑÑоÑонней ÑаблиÑÑ Ð²Ð¾ вÑÐµÐ¼Ñ UPDATE или DELETE.
ÐÐ»Ñ ÑÑого добавÑÑе в parsetree->targetList ÑлеменÑÑ TargetEntry, ÑодеÑжаÑие вÑÑÐ°Ð¶ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑнÑÑ
вÑбиÑаемÑÑ
знаÑений. У каждой Ñакой запиÑи должен бÑÑÑ Ð¿Ñизнак resjunk = true и должно бÑÑÑ Ð¾ÑделÑное ÑобÑÑвенное Ð¸Ð¼Ñ resname, по коÑоÑÐ¾Ð¼Ñ Ð¾Ð½Ð° бÑÐ´ÐµÑ Ð¸Ð´ÐµÐ½ÑиÑиÑиÑоваÑÑÑÑ Ð²Ð¾ вÑÐµÐ¼Ñ Ð²ÑполнениÑ. ÐзбегайÑе иÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¸Ð¼Ñн вида ctid, Nwholerow или wholerow, Ñак как ÑÑолбÑÑ Ñ Ñакими именами Ð¼Ð¾Ð¶ÐµÑ Ð³ÐµÐ½ÐµÑиÑоваÑÑ ÑдÑо ÑиÑÑемÑ. ÐÑли дополниÑелÑнÑе вÑÑÐ°Ð¶ÐµÐ½Ð¸Ñ Ñложнее, Ñем пÑоÑÑо пеÑеменнÑе, иÑ
нÑжно пÑопÑÑÑиÑÑ ÑеÑез ÑÑнкÑÐ¸Ñ Neval_const_expressions пÑежде Ñем добавлÑÑÑ Ð² Ñелевой ÑпиÑок.
ХоÑÑ ÑÑа ÑÑнкÑÐ¸Ñ Ð²ÑзÑваеÑÑÑ Ð²Ð¾ вÑÐµÐ¼Ñ Ð¿Ð»Ð°Ð½Ð¸ÑованиÑ, пеÑÐµÐ´Ð°Ð²Ð°ÐµÐ¼Ð°Ñ ÐµÐ¹ инÑоÑмаÑÐ¸Ñ Ð½ÐµÑколÑко оÑлиÑаеÑÑÑ Ð¾Ñ Ñой, ÑÑо полÑÑаÑÑ Ð´ÑÑгие подпÑогÑÐ°Ð¼Ð¼Ñ Ð¿Ð»Ð°Ð½Ð¸ÑованиÑ. Ð parsetree пеÑедаÑÑÑÑ Ð´ÐµÑево ÑазбоÑа ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ UPDATE или DELETE, а паÑамеÑÑÑ target_rte и target_relation опиÑÑваÑÑ ÑелевÑÑ ÑÑоÑоннÑÑ ÑаблиÑÑ.
ÐÑли ÑказаÑÐµÐ»Ñ AddForeignUpdateTargets Ñавен NULL, дополниÑелÑнÑе ÑелевÑе вÑÑÐ°Ð¶ÐµÐ½Ð¸Ñ Ð½Ðµ добавлÑÑÑÑÑ. (ÐÑо Ð´ÐµÐ»Ð°ÐµÑ Ð½ÐµÐ²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ñм ÑеализаÑÐ¸Ñ Ð¾Ð¿ÐµÑаÑий DELETE, Ñ
оÑÑ Ð¾Ð¿ÐµÑаÑÐ¸Ñ UPDATE Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð²ÑÑ Ð¶Ðµ возможна, еÑли FDW иденÑиÑиÑиÑÑÐµÑ ÑÑÑоки, полагаÑÑÑ Ð½Ð° Ñо, ÑÑо пеÑвиÑнÑй клÑÑ Ð½Ðµ менÑеÑÑÑ.)
List *
PlanForeignModify (PlannerInfo *root,
ModifyTable *plan,
Index resultRelation,
int subplan_index); ÐÑполнÑÐµÑ Ð»ÑбÑе дополниÑелÑнÑе дейÑÑÐ²Ð¸Ñ Ð¿Ð»Ð°Ð½Ð¸ÑованиÑ, необÑ
одимÑе Ð´Ð»Ñ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ, Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¸Ð»Ð¸ ÑÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ð² ÑÑоÑонней ÑаблиÑе. ÐÑа ÑÑнкÑÐ¸Ñ ÑоÑмиÑÑÐµÑ ÑаÑÑнÑÑ Ð¸Ð½ÑоÑмаÑÐ¸Ñ FDW, коÑоÑÐ°Ñ Ð±ÑÐ´ÐµÑ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð° в Ñзел плана ModifyTable, оÑÑÑеÑÑвлÑÑÑий изменение. ÐÑа инÑоÑмаÑÐ¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° возвÑаÑаÑÑÑÑ Ð² ÑпиÑке (List); она бÑÐ´ÐµÑ Ð´Ð¾ÑÑавлена в ÑÑнкÑÐ¸Ñ BeginForeignModify на ÑÑадии вÑполнениÑ.
Ð root пеÑедаÑÑÑÑ Ð¾Ð±ÑÐ°Ñ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð¿Ð»Ð°Ð½Ð¸ÑовÑика о запÑоÑе, а в plan â Ñзел плана ModifyTable, заполненнÑй, не ÑÑиÑÐ°Ñ Ð¿Ð¾Ð»Ñ fdwPrivLists. ÐаÑамеÑÑ resultRelation ÑказÑÐ²Ð°ÐµÑ Ð½Ð° ÑелевÑÑ ÑÑоÑоннÑÑ ÑаблиÑÑ Ð¿Ð¾ номеÑÑ Ð² ÑпиÑке оÑноÑений, а subplan_index опÑеделÑÐµÑ Ñелевое оÑноÑение в данном Ñзле ModifyTable, наÑÐ¸Ð½Ð°Ñ Ñ Ð½ÑлÑ; воÑполÑзÑйÑеÑÑ ÑÑим индекÑом, обÑаÑаÑÑÑ Ðº plan->plans или дÑÑгой вложенной ÑÑÑÑкÑÑÑе Ñзла plan.
Ðа дополниÑелÑнÑми ÑведениÑми обÑаÑиÑеÑÑ Ðº РазделÑ 54.4.
ÐÑли ÑказаÑÐµÐ»Ñ PlanForeignModify Ñавен NULL, дополниÑелÑнÑе дейÑÑÐ²Ð¸Ñ Ð²Ð¾ вÑÐµÐ¼Ñ Ð¿Ð»Ð°Ð½Ð¸ÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð½Ðµ пÑедпÑинимаÑÑÑÑ, и в каÑеÑÑве fdw_private в BeginForeignModify поÑÑÑÐ¿Ð¸Ñ NULL.
void
BeginForeignModify (ModifyTableState *mtstate,
ResultRelInfo *rinfo,
List *fdw_private,
int subplan_index,
int eflags); ÐаÑÐ¸Ð½Ð°ÐµÑ Ð²Ñполнение опеÑаÑии Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð´Ð°Ð½Ð½ÑÑ
в ÑÑоÑонней ÑаблиÑе. ÐÑа подпÑогÑамма вÑполнÑеÑÑÑ Ð¿Ñи запÑÑке иÑполниÑелÑ. Ðна должна вÑполнÑÑÑ Ð»ÑбÑе подгоÑовиÑелÑнÑе дейÑÑвиÑ, необÑ
одимÑе Ð´Ð»Ñ Ñого, ÑÑÐ¾Ð±Ñ ÑобÑÑвенно пÑоизвеÑÑи Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð² ÑаблиÑе. ÐпоÑледÑÑвии Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ коÑÑежа, коÑоÑÑй бÑÐ´ÐµÑ Ð²ÑÑавлÑÑÑÑÑ, изменÑÑÑÑÑ Ð¸Ð»Ð¸ ÑдалÑÑÑÑÑ, бÑÐ´ÐµÑ Ð²ÑзÑваÑÑÑÑ ExecForeignInsert, ExecForeignUpdate или ExecForeignDelete.
РпаÑамеÑÑе mtstate пеÑедаÑÑÑÑ Ð¾Ð±Ñее ÑоÑÑоÑние вÑполнÑемого плана Ñзла ModifyTable; ÑеÑез ÑÑÑ ÑÑÑÑкÑÑÑÑ Ð´Ð¾ÑÑÑÐ¿Ð½Ñ Ð³Ð»Ð¾Ð±Ð°Ð»ÑнÑе ÑÐ²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾ плане и ÑоÑÑоÑние вÑполнениÑ. Ð rinfo пеÑедаÑÑÑÑ ÑÑÑÑкÑÑÑа ResultRelInfo, опиÑÑваÑÑÐ°Ñ ÑелевÑÑ ÑÑоÑоннÑÑ ÑаблиÑÑ. (ÐÑли FDW нÑжно ÑоÑ
ÑаниÑÑ ÑаÑÑное ÑоÑÑоÑние, необÑ
одимое Ð´Ð»Ñ ÑÑой опеÑаÑии, она Ð¼Ð¾Ð¶ÐµÑ Ð²Ð¾ÑполÑзоваÑÑÑÑ Ð¿Ð¾Ð»ÐµÐ¼ ri_FdwState ÑÑÑÑкÑÑÑÑ ResultRelInfo.) Ð fdw_private пеÑедаÑÑÑÑ ÑаÑÑнÑе даннÑе, еÑли они бÑли ÑÑоÑмиÑÐ¾Ð²Ð°Ð½Ñ Ð¿ÑоÑедÑÑой PlanForeignModify. ÐаÑамеÑÑ subplan_index опÑеделÑÐµÑ Ñелевое оÑноÑение в данном Ñзле ModifyTable, а в eflags пеÑедаÑÑÑÑ Ð±Ð¸ÑовÑе Ñлаги, опиÑÑваÑÑие Ñежим ÑабоÑÑ Ð¸ÑполниÑÐµÐ»Ñ Ð´Ð»Ñ ÑÑого Ñзла плана.
ÐамеÑÑÑе, ÑÑо когда (eflags & EXEC_FLAG_EXPLAIN_ONLY) не Ñавно нÑлÑ, ÑÑа ÑÑнкÑÐ¸Ñ Ð½Ðµ должна вÑполнÑÑÑ ÐºÐ°ÐºÐ¸Ðµ-либо внеÑне пÑоÑвлÑÑÑиеÑÑ Ð´ÐµÐ¹ÑÑвиÑ; она должна ÑделаÑÑ ÑолÑко Ñо, ÑÑо необÑ
одимо Ð´Ð»Ñ Ð¿Ð¾Ð»ÑÑÐµÐ½Ð¸Ñ ÑоÑÑоÑÐ½Ð¸Ñ Ñзла, подÑ
одÑÑего Ð´Ð»Ñ ExplainForeignModify и EndForeignModify.
ÐÑли ÑказаÑÐµÐ»Ñ Ð½Ð° BeginForeignModify Ñавен NULL, никакое дейÑÑвие пÑи запÑÑке иÑполниÑÐµÐ»Ñ Ð½Ðµ вÑполнÑеÑÑÑ.
TupleTableSlot *
ExecForeignInsert (EState *estate,
ResultRelInfo *rinfo,
TupleTableSlot *slot,
TupleTableSlot *planSlot); ÐÑÑавлÑÐµÑ Ð¾Ð´Ð¸Ð½ коÑÑеж в ÑÑоÑоннÑÑ ÑаблиÑÑ. Ð estate пеÑедаÑÑÑÑ Ð³Ð»Ð¾Ð±Ð°Ð»Ñное ÑоÑÑоÑние вÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð·Ð°Ð¿ÑоÑа, а в rinfo â ÑÑÑÑкÑÑÑа ResultRelInfo, опиÑÑваÑÑÐ°Ñ ÑелевÑÑ ÑÑоÑоннÑÑ ÑаблиÑÑ. ÐаÑамеÑÑ slot ÑодеÑÐ¶Ð¸Ñ ÐºÐ¾ÑÑеж, коÑоÑÑй должен бÑÑÑ Ð²ÑÑавлен; он бÑÐ´ÐµÑ ÑооÑвеÑÑÑвоваÑÑ Ð¾Ð¿ÑÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ñипа ÑÑÑоки ÑÑоÑонней ÑаблиÑÑ. ÐаÑамеÑÑ planSlot ÑодеÑÐ¶Ð¸Ñ ÐºÐ¾ÑÑеж, ÑÑоÑмиÑованнÑй вложеннÑм планом Ñзла ModifyTable; он оÑлиÑаеÑÑÑ Ð¾Ñ slot Ñем, ÑÑо Ð¼Ð¾Ð¶ÐµÑ ÑодеÑжаÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑнÑе «оÑбÑоÑовÑе» ÑÑолбÑÑ. (ÐнаÑение planSlot обÑÑно не оÑÐµÐ½Ñ Ð¸Ð½ÑеÑеÑно Ð´Ð»Ñ Ð¾Ð¿ÐµÑаÑий INSERT, но оно пÑедÑÑавлено Ð´Ð»Ñ Ð¿Ð¾Ð»Ð½Ð¾ÑÑ.)
ÐозвÑаÑаемÑм знаÑением бÑÐ´ÐµÑ Ð»Ð¸Ð±Ð¾ ÑлоÑ, ÑодеÑжаÑий даннÑе, коÑоÑÑе бÑли ÑакÑиÑеÑки вÑÑÐ°Ð²Ð»ÐµÐ½Ñ (они могÑÑ Ð¾ÑлиÑаÑÑÑÑ Ð¾Ñ Ð¿ÐµÑеданнÑÑ
даннÑÑ
, напÑимеÑ, в ÑезÑлÑÑаÑе дейÑÑвий ÑÑиггеÑов), либо NULL, еÑли Ð½Ð¸ÐºÐ°ÐºÐ°Ñ ÑÑÑока ÑакÑиÑеÑки не бÑла вÑÑавлена (опÑÑÑ Ð¶Ðµ, обÑÑно в ÑезÑлÑÑаÑе дейÑÑвий ÑÑиггеÑов). ЧÑÐ¾Ð±Ñ Ð²ÐµÑнÑÑÑ ÑезÑлÑÑаÑ, Ñакже можно иÑполÑзоваÑÑ Ð¿ÐµÑедаваемÑй на вÑ
од slot.
ÐаннÑе в возвÑаÑаемом ÑлоÑе иÑполÑзÑÑÑÑÑ, ÑолÑко еÑли запÑÐ¾Ñ INSERT ÑодеÑÐ¶Ð¸Ñ Ð¿Ñедложение RETURNING или Ð´Ð»Ñ ÑÑоÑонней ÑаблиÑÑ Ð¾Ð¿ÑеделÑн ÑÑÐ¸Ð³Ð³ÐµÑ AFTER ROW. ТÑиггеÑам нÑÐ¶Ð½Ñ Ð²Ñе ÑÑолбÑÑ, но Ð´Ð»Ñ Ð¿ÑÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ RETURNING FDW Ð¼Ð¾Ð¶ÐµÑ Ñади опÑимизаÑии не возвÑаÑаÑÑ Ð½ÐµÐºÐ¾ÑоÑÑе или вÑе ÑÑолбÑÑ, в завиÑимоÑÑи Ð¾Ñ ÐµÐ³Ð¾ ÑодеÑжаниÑ. Так или инаÑе, какой-либо ÑÐ»Ð¾Ñ Ð½ÐµÐ¾Ð±Ñ
одимо веÑнÑÑÑ, ÑÑÐ¾Ð±Ñ Ð¾ÑмеÑиÑÑ, ÑÑо опеÑаÑÐ¸Ñ ÑÑпеÑна, инаÑе возвÑаÑÑнное ÑиÑло ÑÑÑок бÑÐ´ÐµÑ Ð½ÐµÐ²ÐµÑнÑм.
ÐÑли ÑказаÑÐµÐ»Ñ Ð½Ð° ExecForeignInsert Ñавен NULL, вÑÑавиÑÑ Ð´Ð°Ð½Ð½Ñе в ÑÑоÑоннÑÑ ÑаблиÑÑ Ð½Ðµ ÑдаÑÑÑÑ, в оÑÐ²ÐµÑ Ð±ÑÐ´ÐµÑ Ð²ÑдаваÑÑÑÑ ÑообÑение об оÑибке.
TupleTableSlot *
ExecForeignUpdate (EState *estate,
ResultRelInfo *rinfo,
TupleTableSlot *slot,
TupleTableSlot *planSlot); ÐзменÑÐµÑ Ð¾Ð´Ð¸Ð½ коÑÑеж в ÑÑоÑонней ÑаблиÑе. Ð estate пеÑедаÑÑÑÑ Ð³Ð»Ð¾Ð±Ð°Ð»Ñное ÑоÑÑоÑние вÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð·Ð°Ð¿ÑоÑа, а в rinfo â ÑÑÑÑкÑÑÑа ResultRelInfo, опиÑÑваÑÑÐ°Ñ ÑелевÑÑ ÑÑоÑоннÑÑ ÑаблиÑÑ. ÐаÑамеÑÑ slot ÑодеÑÐ¶Ð¸Ñ Ð½Ð¾Ð²Ñе даннÑе Ð´Ð»Ñ ÐºÐ¾ÑÑежа; он бÑÐ´ÐµÑ ÑооÑвеÑÑÑвоваÑÑ Ð¾Ð¿ÑÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ñипа ÑÑÑоки ÑÑоÑонней ÑаблиÑÑ. ÐаÑамеÑÑ planSlot ÑодеÑÐ¶Ð¸Ñ ÐºÐ¾ÑÑеж, ÑÑоÑмиÑованнÑй вложеннÑм планом Ñзла ModifyTable; он оÑлиÑаеÑÑÑ Ð¾Ñ slot Ñем, ÑÑо Ð¼Ð¾Ð¶ÐµÑ ÑодеÑжаÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑнÑе «оÑбÑоÑовÑе» ÑÑолбÑÑ. Ð ÑаÑÑноÑÑи, в ÑÑом ÑлоÑе можно полÑÑиÑÑ Ð»ÑбÑе оÑбÑоÑовÑе ÑÑолбÑÑ, запÑоÑеннÑе в AddForeignUpdateTargets.
ÐозвÑаÑаемÑм знаÑением бÑÐ´ÐµÑ Ð»Ð¸Ð±Ð¾ ÑлоÑ, ÑодеÑжаÑий ÑÑÑÐ¾ÐºÑ Ð² ÑоÑÑоÑнии поÑле Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ (ÐµÑ ÑодеÑжимое Ð¼Ð¾Ð¶ÐµÑ Ð¾ÑлиÑаÑÑÑÑ Ð¾Ñ Ð¿ÐµÑеданного, напÑимеÑ, в ÑезÑлÑÑаÑе дейÑÑвий ÑÑиггеÑов), либо NULL, еÑли Ð½Ð¸ÐºÐ°ÐºÐ°Ñ ÑÑÑока ÑакÑиÑеÑки не бÑла изменена (опÑÑÑ Ð¶Ðµ, обÑÑно в ÑезÑлÑÑаÑе дейÑÑвий ÑÑиггеÑов). ЧÑÐ¾Ð±Ñ Ð²ÐµÑнÑÑÑ ÑезÑлÑÑаÑ, Ñакже можно иÑполÑзоваÑÑ Ð¿ÐµÑедаваемÑй на вÑ
од slot.
ÐаннÑе в возвÑаÑаемом ÑлоÑе иÑполÑзÑÑÑÑÑ, ÑолÑко еÑли запÑÐ¾Ñ UPDATE ÑодеÑÐ¶Ð¸Ñ Ð¿Ñедложение RETURNING или Ð´Ð»Ñ ÑÑоÑонней ÑаблиÑÑ Ð¾Ð¿ÑеделÑн ÑÑÐ¸Ð³Ð³ÐµÑ AFTER ROW. ТÑиггеÑам нÑÐ¶Ð½Ñ Ð²Ñе ÑÑолбÑÑ, но Ð´Ð»Ñ Ð¿ÑÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ RETURNING FDW Ð¼Ð¾Ð¶ÐµÑ Ñади опÑимизаÑии не возвÑаÑаÑÑ Ð½ÐµÐºÐ¾ÑоÑÑе или вÑе ÑÑолбÑÑ, в завиÑимоÑÑи Ð¾Ñ ÐµÐ³Ð¾ ÑодеÑжаниÑ. Так или инаÑе, какой-либо ÑÐ»Ð¾Ñ Ð½ÐµÐ¾Ð±Ñ
одимо веÑнÑÑÑ, ÑÑÐ¾Ð±Ñ Ð¾ÑмеÑиÑÑ, ÑÑо опеÑаÑÐ¸Ñ ÑÑпеÑна, инаÑе возвÑаÑÑнное ÑиÑло ÑÑÑок бÑÐ´ÐµÑ Ð½ÐµÐ²ÐµÑнÑм.
ÐÑли ÑказаÑÐµÐ»Ñ Ð½Ð° ExecForeignUpdate Ñавен NULL, измениÑÑ Ð´Ð°Ð½Ð½Ñе в ÑÑоÑонней ÑаблиÑе не ÑдаÑÑÑÑ, а в оÑÐ²ÐµÑ Ð±ÑÐ´ÐµÑ Ð²ÑдаваÑÑÑÑ ÑообÑение об оÑибке.
TupleTableSlot *
ExecForeignDelete (EState *estate,
ResultRelInfo *rinfo,
TupleTableSlot *slot,
TupleTableSlot *planSlot); УдалÑÐµÑ Ð¾Ð´Ð¸Ð½ коÑÑеж из ÑÑоÑонней ÑаблиÑÑ. Ð estate пеÑедаÑÑÑÑ Ð³Ð»Ð¾Ð±Ð°Ð»Ñное ÑоÑÑоÑние вÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð·Ð°Ð¿ÑоÑа, а в rinfo â ÑÑÑÑкÑÑÑа ResultRelInfo, опиÑÑваÑÑÐ°Ñ ÑелевÑÑ ÑÑоÑоннÑÑ ÑаблиÑÑ. ÐаÑамеÑÑ slot пÑи вÑзове не ÑодеÑÐ¶Ð¸Ñ Ð½Ð¸Ñего полезного, но в ÑÑÑ ÑÑÑÑкÑÑÑÑ Ð¼Ð¾Ð¶Ð½Ð¾ помеÑÑиÑÑ Ð²Ð¾Ð·Ð²ÑаÑаемÑй коÑÑеж. ÐаÑамеÑÑ planSlot ÑодеÑÐ¶Ð¸Ñ ÐºÐ¾ÑÑеж, ÑÑоÑмиÑованнÑй вложеннÑм планом Ñзла ModifyTable; в ÑаÑÑноÑÑи, в нÑм могÑÑ ÑодеÑжаÑÑÑÑ Ð¾ÑбÑоÑовÑе ÑÑолбÑÑ, запÑоÑеннÑе в AddForeignUpdateTargets. ÐÑбÑоÑовÑе ÑÑолбÑÑ Ð½ÐµÐ¾Ð±Ñ
одимÑ, ÑÑÐ¾Ð±Ñ Ð¾Ð¿ÑеделиÑÑ, какой именно коÑÑеж ÑдалÑÑÑ.
ÐозвÑаÑаемÑм знаÑением бÑÐ´ÐµÑ Ð»Ð¸Ð±Ð¾ ÑлоÑ, ÑодеÑжаÑий ÑÑÑокÑ, коÑоÑÐ°Ñ Ð±Ñла Ñдалена, либо NULL, еÑли не Ñдалена Ð½Ð¸ÐºÐ°ÐºÐ°Ñ ÑÑÑока (обÑÑно в ÑезÑлÑÑаÑе дейÑÑÐ²Ð¸Ñ ÑÑиггеÑов). ÐÐ»Ñ ÑазмеÑÐµÐ½Ð¸Ñ Ð²Ð¾Ð·Ð²ÑаÑаемого коÑÑежа можно иÑполÑзоваÑÑ Ð¿ÐµÑедаваемÑй на вÑ
од slot.
ÐаннÑе в возвÑаÑаемом ÑлоÑе иÑполÑзÑÑÑÑÑ, ÑолÑко еÑли запÑÐ¾Ñ DELETE ÑодеÑÐ¶Ð¸Ñ Ð¿Ñедложение RETURNING или Ð´Ð»Ñ ÑÑоÑонней ÑаблиÑÑ Ð¾Ð¿ÑеделÑн ÑÑÐ¸Ð³Ð³ÐµÑ AFTER ROW. ТÑиггеÑам нÑÐ¶Ð½Ñ Ð²Ñе ÑÑолбÑÑ, но Ð´Ð»Ñ Ð¿ÑÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ RETURNING FDW Ð¼Ð¾Ð¶ÐµÑ Ñади опÑимизаÑии не возвÑаÑаÑÑ Ð½ÐµÐºÐ¾ÑоÑÑе или вÑе ÑÑолбÑÑ, в завиÑимоÑÑи Ð¾Ñ ÐµÐ³Ð¾ ÑодеÑжаниÑ. Так или инаÑе, какой-либо ÑÐ»Ð¾Ñ Ð½ÐµÐ¾Ð±Ñ
одимо веÑнÑÑÑ, ÑÑÐ¾Ð±Ñ Ð¾ÑмеÑиÑÑ, ÑÑо опеÑаÑÐ¸Ñ ÑÑпеÑна, инаÑе возвÑаÑÑнное ÑиÑло ÑÑÑок бÑÐ´ÐµÑ Ð½ÐµÐ²ÐµÑнÑм.
ÐÑли ÑказаÑÐµÐ»Ñ Ð½Ð° ExecForeignDelete Ñавен NULL, ÑдалиÑÑ Ð´Ð°Ð½Ð½Ñе из ÑÑоÑонней ÑаблиÑÑ Ð½Ðµ ÑдаÑÑÑÑ, а в оÑÐ²ÐµÑ Ð±ÑÐ´ÐµÑ Ð²ÑдаваÑÑÑÑ ÑообÑение об оÑибке.
void
EndForeignModify (EState *estate,
ResultRelInfo *rinfo);ÐавеÑÑÐ°ÐµÑ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ðµ даннÑÑ Ð² ÑаблиÑе и оÑÐ²Ð¾Ð±Ð¾Ð¶Ð´Ð°ÐµÑ ÑеÑÑÑÑÑ. ÐбÑÑно пÑи ÑÑом не нÑжно оÑвобождаÑÑ Ð¿Ð°Ð¼ÑÑÑ, вÑделеннÑÑ ÑеÑез palloc, но напÑимеÑ, оÑкÑÑÑÑе ÑÐ°Ð¹Ð»Ñ Ð¸ подклÑÑÐµÐ½Ð¸Ñ Ðº ÑдалÑннÑм ÑеÑвеÑам ÑледÑÐµÑ Ð·Ð°ÐºÑÑÑÑ.
ÐÑли ÑказаÑÐµÐ»Ñ Ð½Ð° EndForeignModify Ñавен NULL, никакое дейÑÑвие пÑи завеÑÑении иÑполниÑÐµÐ»Ñ Ð½Ðµ вÑполнÑеÑÑÑ.
int IsForeignRelUpdatable (Relation rel);
СообÑаеÑ, какие опеÑаÑии Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð´Ð°Ð½Ð½ÑÑ
поддеÑÐ¶Ð¸Ð²Ð°ÐµÑ ÑÐºÐ°Ð·Ð°Ð½Ð½Ð°Ñ ÑÑоÑоннÑÑ ÑаблиÑа. ÐозвÑаÑаемое знаÑение должно бÑÑÑ Ð±Ð¸Ñовой маÑкой кодов ÑобÑÑий, обознаÑаÑÑиÑ
опеÑаÑии, поддеÑживаемÑе ÑаблиÑей, и заданнÑÑ
в пеÑеÑиÑлении CmdType; Ñо еÑÑÑ, (1 << CMD_UPDATE) = 4 Ð´Ð»Ñ UPDATE, (1 << CMD_INSERT) = 8 Ð´Ð»Ñ INSERT и (1 << CMD_DELETE) = 16 Ð´Ð»Ñ DELETE.
ÐÑли ÑказаÑÐµÐ»Ñ Ð½Ð° IsForeignRelUpdatable Ñавен NULL, пÑедполагаеÑÑÑ, ÑÑо ÑÑоÑонние ÑаблиÑÑ Ð¿Ð¾Ð·Ð²Ð¾Ð»ÑÑÑ Ð´Ð¾Ð±Ð°Ð²Ð»ÑÑÑ, изменÑÑÑ Ð¸ ÑдалÑÑÑ ÑÑÑоки, еÑли FDW пÑедоÑÑавлÑÐµÑ Ð¿ÑоÑедÑÑÑ Ð´Ð»Ñ ÑÑнкÑий ExecForeignInsert, ExecForeignUpdate или ExecForeignDelete, ÑооÑвеÑÑÑвенно. ÐÐ°Ð½Ð½Ð°Ñ ÑÑнкÑÐ¸Ñ Ð½ÐµÐ¾Ð±Ñ
одима, ÑолÑко еÑли FDW поддеÑÐ¶Ð¸Ð²Ð°ÐµÑ Ð¾Ð¿ÐµÑаÑии Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð¾Ð´Ð½Ð¸Ñ
ÑÐ°Ð±Ð»Ð¸Ñ Ð¸ не поддеÑÐ¶Ð¸Ð²Ð°ÐµÑ Ð´Ð»Ñ Ð´ÑÑгиÑ
. (ХоÑÑ Ð´Ð»Ñ ÑÑого можно вÑдаÑÑ Ð¾ÑÐ¸Ð±ÐºÑ Ð² подпÑогÑамме, вÑполнÑÑÑей опеÑаÑиÑ, а не задейÑÑвоваÑÑ ÑÑÑ ÑÑнкÑиÑ. Ðднако Ð´Ð°Ð½Ð½Ð°Ñ ÑÑнкÑÐ¸Ñ Ð¿Ð¾Ð·Ð²Ð¾Ð»ÑÐµÑ ÐºÐ¾ÑÑекÑно оÑÑажаÑÑ Ð¿Ð¾Ð´Ð´ÐµÑÐ¶ÐºÑ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ð¹ в пÑедÑÑавлениÑÑ
information_schema.)
54.2.4. ÐодпÑогÑÐ°Ð¼Ð¼Ñ FDW Ð´Ð»Ñ Ð±Ð»Ð¾ÐºÐ¸Ñовки ÑÑÑок
ÐÑли FDW Ð¶ÐµÐ»Ð°ÐµÑ Ð¿Ð¾Ð´Ð´ÐµÑжаÑÑ ÑÑнкÑÐ¸Ñ Ð¿Ð¾Ð·Ð´Ð½ÐµÐ¹ блокиÑовки ÑÑÑок (опиÑаннÑÑ Ð² Разделе 54.5), она должна пÑедоÑÑавиÑÑ ÑледÑÑÑие ÑеализÑÑÑие подпÑогÑаммÑ:
RowMarkType
GetForeignRowMarkType (RangeTblEntry *rte,
LockClauseStrength strength); СообÑаеÑ, какой ваÑÐ¸Ð°Ð½Ñ Ð¿Ð¾Ð¼ÐµÑки ÑÑÑок бÑÐ´ÐµÑ Ð¸ÑполÑзоваÑÑÑÑ Ð´Ð»Ñ ÑÑоÑонней ÑаблиÑÑ. ÐдеÑÑ rte пÑедÑÑавлÑÐµÑ Ñзел RangeTblEntry Ð´Ð»Ñ ÑаблиÑÑ, а strength опиÑÑÐ²Ð°ÐµÑ ÑÐ¸Ð»Ñ Ð±Ð»Ð¾ÐºÐ¸Ñовки, запÑоÑеннÑÑ ÑооÑвеÑÑÑвÑÑÑим пÑедложением FOR UPDATE/SHARE, еÑли оно имееÑÑÑ. РезÑлÑÑаÑом должно бÑÑÑ Ð·Ð½Ð°Ñение пеÑеÑиÑÐ»ÐµÐ½Ð¸Ñ RowMarkType.
ÐÑа ÑÑнкÑÐ¸Ñ Ð²ÑзÑваеÑÑÑ Ð² пÑоÑеÑÑе планиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð·Ð°Ð¿ÑоÑа Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð¹ ÑÑоÑонней ÑаблиÑÑ, коÑоÑÐ°Ñ ÑÑаÑÑвÑÐµÑ Ð² запÑоÑе UPDATE, DELETE или SELECT FOR UPDATE/SHARE, и не ÑвлÑеÑÑÑ Ñелевой в запÑоÑе UPDATE или DELETE.
ÐÑли ÑказаÑÐµÐ»Ñ GetForeignRowMarkType Ñавен NULL, вÑегда вÑбиÑаеÑÑÑ Ð²Ð°ÑÐ¸Ð°Ð½Ñ ROW_MARK_COPY. (ÐÑледÑÑвие ÑÑого, ÑÑнкÑÐ¸Ñ RefetchForeignRow никогда не бÑÐ´ÐµÑ Ð²ÑзÑваÑÑÑÑ, Ñак ÑÑо и ÐµÑ Ð·Ð°Ð´Ð°Ð²Ð°ÑÑ Ð½Ðµ нÑжно.)
Ðа подÑобноÑÑÑми обÑаÑиÑеÑÑ Ðº РазделÑ 54.5.
HeapTuple
RefetchForeignRow (EState *estate,
ExecRowMark *erm,
Datum rowid,
bool *updated); ÐовÑоÑно ÑÑиÑÑÐ²Ð°ÐµÑ Ð¾Ð´Ð¸Ð½ коÑÑеж из ÑÑоÑонней ÑаблиÑÑ Ð¿Ð¾Ñле блокиÑовки, еÑли она ÑÑебÑеÑÑÑ. Ð estate пеÑедаÑÑÑÑ Ð³Ð»Ð¾Ð±Ð°Ð»Ñное ÑоÑÑоÑние вÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð·Ð°Ð¿ÑоÑа. Ð erm пеÑедаÑÑÑÑ ÑÑÑÑкÑÑÑа ExecRowMark, опиÑÑваÑÑÐ°Ñ ÑелевÑÑ ÑÑоÑоннÑÑ ÑаблиÑÑ Ð¸ Ñип запÑаÑиваемой блокиÑовки (еÑли ÑÑебÑеÑÑÑ Ð±Ð»Ð¾ÐºÐ¸Ñовка). ÐаÑамеÑÑ rowid иденÑиÑиÑиÑÑÐµÑ ÑÑиÑÑваемÑй коÑÑеж. ÐаÑамеÑÑ updated иÑполÑзÑеÑÑÑ ÐºÐ°Ðº вÑÑ
одной.
ÐÑа ÑÑнкÑÐ¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° веÑнÑÑÑ ÐºÐ¾Ð¿Ð¸Ñ Ð²ÑбÑанного коÑÑежа (ÑазмеÑÑннÑÑ Ð² памÑÑи palloc) или NULL, еÑли полÑÑиÑÑ Ð±Ð»Ð¾ÐºÐ¸ÑÐ¾Ð²ÐºÑ ÑÑÑоки не ÑдаÑÑÑÑ. Тип запÑаÑиваемой блокиÑовки ÑÑÑоки опÑеделÑеÑÑÑ Ð·Ð½Ð°Ñением erm->markType, коÑоÑое бÑло до ÑÑого возвÑаÑено ÑÑнкÑией GetForeignRowMarkType. (ÐаÑÐ¸Ð°Ð½Ñ ROW_MARK_REFERENCE ознаÑаеÑ, ÑÑо нÑжно пÑоÑÑо повÑоÑно вÑбÑаÑÑ ÐºÐ¾ÑÑеж, не запÑаÑÐ¸Ð²Ð°Ñ Ð½Ð¸ÐºÐ°ÐºÑÑ Ð±Ð»Ð¾ÐºÐ¸ÑовкÑ, а ROW_MARK_COPY никогда не поÑÑÑÐ¿Ð°ÐµÑ Ð² ÑÑÑ Ð¿Ð¾Ð´Ð¿ÑогÑаммÑ.)
ÐÑоме Ñого, пеÑеменной *updated ÑледÑÐµÑ Ð¿ÑиÑвоиÑÑ true, еÑли бÑла ÑÑиÑана изменÑÐ½Ð½Ð°Ñ Ð²ÐµÑÑÐ¸Ñ ÐºÐ¾ÑÑежа, а не веÑÑиÑ, полÑÑÐµÐ½Ð½Ð°Ñ Ñанее. (ÐÑли FDW не Ð·Ð½Ð°ÐµÑ ÑÑого навеÑнÑка, ÑекомендÑеÑÑÑ Ð²Ñегда возвÑаÑаÑÑ true.)
ÐамеÑÑÑе, ÑÑо по ÑмолÑÐ°Ð½Ð¸Ñ Ð² ÑлÑÑае неÑдаÑи пÑи попÑÑке полÑÑиÑÑ Ð±Ð»Ð¾ÐºÐ¸ÑÐ¾Ð²ÐºÑ ÑÑÑоки должна вÑдаваÑÑÑÑ Ð¾Ñибка; знаÑение NULL Ð¼Ð¾Ð¶ÐµÑ Ð²Ð¾Ð·Ð²ÑаÑаÑÑÑÑ, ÑолÑко еÑли в erm->waitPolicy вÑбÑан ваÑÐ¸Ð°Ð½Ñ SKIP LOCKED.
Ð rowid пеÑедаÑÑÑÑ Ð·Ð½Ð°Ñение ctid, полÑÑенное Ñанее Ð´Ð»Ñ ÑÑÑоки, коÑоÑÑÑ Ð½Ñжно ÑÑиÑаÑÑ Ð¿Ð¾Ð²ÑоÑно. ХоÑÑ Ð·Ð½Ð°Ñение rowid пеÑедаÑÑÑÑ Ð² виде Datum, в наÑÑоÑÑее вÑÐµÐ¼Ñ ÑÑо Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ ÑолÑко tid. Такой инÑеÑÑÐµÐ¹Ñ ÑÑнкÑии вÑбÑан Ñ ÑаÑÑÑÑом на Ñо, ÑÑÐ¾Ð±Ñ Ð² бÑдÑÑем в каÑеÑÑве иденÑиÑикаÑоÑов ÑÑÑок могли пÑинимаÑÑÑÑ Ð¸ дÑÑгие ÑÐ¸Ð¿Ñ Ð´Ð°Ð½Ð½ÑÑ
.
ÐÑли ÑказаÑÐµÐ»Ñ Ð½Ð° RefetchForeignRow Ñавен NULL, повÑоÑно вÑбÑаÑÑ Ð´Ð°Ð½Ð½Ñе не ÑдаÑÑÑÑ, в оÑÐ²ÐµÑ Ð±ÑÐ´ÐµÑ Ð²ÑдаваÑÑÑÑ ÑообÑение об оÑибке.
Ðа подÑобноÑÑÑми обÑаÑиÑеÑÑ Ðº РазделÑ 54.5.
bool RecheckForeignScan (ForeignScanState *node, TupleTableSlot *slot);
ÐеÑепÑовеÑÑеÑ, ÑооÑвеÑÑÑвÑÐµÑ Ð»Ð¸ по-пÑÐµÐ¶Ð½ÐµÐ¼Ñ Ñанее возвÑаÑÑннÑй коÑÑеж пÑименимÑм ÑÑловиÑм ÑканиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð¸ ÑоединениÑ, и возможно вÑдаÑÑ Ð¸Ð·Ð¼ÐµÐ½ÑннÑÑ Ð²ÐµÑÑÐ¸Ñ ÐºÐ¾ÑÑежа. ÐÐ»Ñ Ð¾Ð±ÑÑÑок ÑÑоÑонниÑ
даннÑÑ
, коÑоÑÑе не вÑноÑÑÑ Ñоединение наÑÑжÑ, обÑÑно Ñдобнее пÑиÑвоиÑÑ ÑÑÐ¾Ð¼Ñ ÑказаÑÐµÐ»Ñ NULL и задаÑÑ fdw_recheck_quals. Ðднако, когда внеÑние ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ð²ÑноÑÑÑÑÑ Ð½Ð°ÑÑжÑ, недоÑÑаÑоÑно повÑоÑно пÑимениÑÑ Ðº ÑезÑлÑÑиÑÑÑÑÐµÐ¼Ñ ÐºÐ¾ÑÑÐµÐ¶Ñ Ð¿ÑовеÑки, оÑноÑÑÑиеÑÑ ÐºÐ¾ вÑем базовÑм ÑаблиÑам, даже еÑли пÑиÑÑÑÑÑвÑÑÑ Ð²Ñе аÑÑибÑÑÑ, Ñак как невÑполнение некоÑоÑого ÑÑÐ»Ð¾Ð²Ð¸Ñ Ð¼Ð¾Ð¶ÐµÑ Ð¿ÑиводиÑÑ Ð¸ к обнÑÐ»ÐµÐ½Ð¸Ñ Ð½ÐµÐºÐ¾ÑоÑÑÑ
аÑÑибÑÑов, а не ÑолÑко иÑклÑÑÐµÐ½Ð¸Ñ ÑÑого коÑÑежа. RecheckForeignScan Ð¼Ð¾Ð¶ÐµÑ Ð¿ÐµÑепÑовеÑиÑÑ ÑÑÐ»Ð¾Ð²Ð¸Ñ Ð¸ возвÑаÑиÑÑ true, еÑли они по-пÑÐµÐ¶Ð½ÐµÐ¼Ñ Ð²ÑполнÑÑÑÑÑ, или false в пÑоÑивном ÑлÑÑае, но Ñакже она Ð¼Ð¾Ð¶ÐµÑ Ð·Ð°Ð¿Ð¸ÑаÑÑ Ð² пеÑеданнÑй ÑÐ»Ð¾Ñ ÐºÐ¾ÑÑеж на Ð·Ð°Ð¼ÐµÐ½Ñ Ð¿ÑедÑдÑÑемÑ.
ЧÑÐ¾Ð±Ñ Ð²ÑнеÑÑи Ñоединение наÑÑжÑ, обÑÑÑка ÑÑоÑонниÑ
даннÑÑ
обÑÑно конÑÑÑÑиÑÑÐµÑ Ð°Ð»ÑÑеÑнаÑивнÑй план локалÑного ÑоединениÑ, пÑименÑемÑй ÑолÑко Ð´Ð»Ñ Ð¿ÐµÑепÑовеÑок; он ÑÑановиÑÑÑ Ð²Ð½ÐµÑним подпланом Ñзла ForeignScan. Ðогда ÑÑебÑеÑÑÑ Ð¿ÐµÑепÑовеÑка, Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð²Ñполнен ÑÑÐ¾Ñ Ð¿Ð¾Ð´Ð¿Ð»Ð°Ð½ и ÑезÑлÑÑиÑÑÑÑий коÑÑеж ÑоÑ
ÑанÑн в ÑлоÑе. ÐÑÐ¾Ñ Ð¿Ð»Ð°Ð½ Ð¼Ð¾Ð¶ÐµÑ Ð½Ðµ бÑÑÑ ÑÑÑекÑивнÑм, Ñак как ни одна Ð±Ð°Ð·Ð¾Ð²Ð°Ñ ÑаблиÑа не вÑдаÑÑ Ð±Ð¾Ð»ÑÑе одной ÑÑÑоки; напÑимеÑ, он Ð¼Ð¾Ð¶ÐµÑ ÑеализовÑваÑÑ Ð²Ñе ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ð² виде вложеннÑÑ
Ñиклов.
54.2.5. ÐодпÑогÑÐ°Ð¼Ð¼Ñ FDW Ð´Ð»Ñ EXPLAIN
void
ExplainForeignScan (ForeignScanState *node,
ExplainState *es); ÐополнÑÐµÑ Ð²Ñвод EXPLAIN Ð´Ð»Ñ ÑканиÑÐ¾Ð²Ð°Ð½Ð¸Ñ ÑÑоÑонней ÑаблиÑÑ. ÐÑа ÑÑнкÑÐ¸Ñ Ð¼Ð¾Ð¶ÐµÑ Ð²ÑзÑваÑÑ ExplainPropertyText и ÑвÑзаннÑе ÑÑнкÑии и добавлÑÑÑ Ð¿Ð¾Ð»Ñ Ð² вÑвод EXPLAIN. ÐÐ¾Ð»Ñ Ñлагов в es позволÑÑÑ Ð¾Ð¿ÑеделиÑÑ, ÑÑо именно вÑводиÑÑ, а Ð´Ð»Ñ Ð²ÑдаÑи ÑÑаÑиÑÑики вÑемени вÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð² ÑлÑÑае Ñ EXPLAIN ANALYZE можно пÑоанализиÑоваÑÑ ÑоÑÑоÑние Ñзла ForeignScanState.
ÐÑли ÑказаÑÐµÐ»Ñ ExplainForeignScan Ñавен NULL, Ð½Ð¸ÐºÐ°ÐºÐ°Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑÐ½Ð°Ñ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð¿Ñи EXPLAIN не вÑводиÑÑÑ.
void
ExplainForeignModify (ModifyTableState *mtstate,
ResultRelInfo *rinfo,
List *fdw_private,
int subplan_index,
struct ExplainState *es); ÐополнÑÐµÑ Ð²Ñвод EXPLAIN Ð´Ð»Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ð¹ в ÑÑоÑонней ÑаблиÑе. ÐÑа ÑÑнкÑÐ¸Ñ Ð¼Ð¾Ð¶ÐµÑ Ð²ÑзÑваÑÑ ExplainPropertyText и ÑвÑзаннÑе ÑÑнкÑии и добавлÑÑÑ Ð¿Ð¾Ð»Ñ Ð² вÑвод EXPLAIN. ÐÐ¾Ð»Ñ Ñлагов в es позволÑÑÑ Ð¾Ð¿ÑеделиÑÑ, ÑÑо именно вÑводиÑÑ, а Ð´Ð»Ñ Ð²ÑдаÑи ÑÑаÑиÑÑики вÑемени вÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð² ÑлÑÑае Ñ EXPLAIN ANALYZE можно пÑоанализиÑоваÑÑ ÑоÑÑоÑние Ñзла ModifyTableState. ÐеÑвÑе ÑеÑÑÑе аÑгÑменÑа Ñ ÑÑой ÑÑнкÑии Ñе же, ÑÑо и Ñ BeginForeignModify.
ÐÑли ÑказаÑÐµÐ»Ñ ExplainForeignModify Ñавен NULL, Ð½Ð¸ÐºÐ°ÐºÐ°Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑÐ½Ð°Ñ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð¿Ñи EXPLAIN не вÑводиÑÑÑ.
54.2.6. ÐодпÑогÑÐ°Ð¼Ð¼Ñ FDW Ð´Ð»Ñ ANALYZE
bool
AnalyzeForeignTable (Relation relation,
AcquireSampleRowsFunc *func,
BlockNumber *totalpages); ÐÑа ÑÑнкÑÐ¸Ñ Ð²ÑзÑваеÑÑÑ, когда Ð´Ð»Ñ ÑÑоÑонней ÑаблиÑÑ Ð²ÑполнÑеÑÑÑ ANALYZE. ÐÑли FDW Ð¼Ð¾Ð¶ÐµÑ ÑобÑаÑÑ ÑÑаÑиÑÑÐ¸ÐºÑ Ð´Ð»Ñ ÑÑой ÑÑоÑонней ÑаблиÑÑ, ÑÑа ÑÑнкÑÐ¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° веÑнÑÑÑ true и пеÑедаÑÑ Ð² func ÑказаÑÐµÐ»Ñ Ð½Ð° ÑÑнкÑиÑ, коÑоÑÐ°Ñ Ð±ÑÐ´ÐµÑ Ð²ÑдаваÑÑ ÑÑÑоки вÑбоÑки из ÑаблиÑÑ, а в totalpages ожидаемÑй ÑÐ°Ð·Ð¼ÐµÑ ÑаблиÑÑ Ð² ÑÑÑаниÑаÑ
. РпÑоÑивном ÑлÑÑае ÑÑа ÑÑнкÑÐ¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° веÑнÑÑÑ false.
ÐÑли FDW не поддеÑÐ¶Ð¸Ð²Ð°ÐµÑ ÑÐ±Ð¾Ñ ÑÑаÑиÑÑики ни Ð´Ð»Ñ ÐºÐ°ÐºÐ¸Ñ
ÑаблиÑ, в AnalyzeForeignTable можно ÑÑÑановиÑÑ Ð·Ð½Ð°Ñение NULL.
ФÑнкÑÐ¸Ñ Ð²ÑдаÑи вÑбоÑки, еÑли она пÑедоÑÑавлÑеÑÑÑ, должна имеÑÑ ÑледÑÑÑÑÑ ÑигнаÑÑÑÑ:
int
AcquireSampleRowsFunc (Relation relation, int elevel,
HeapTuple *rows, int targrows,
double *totalrows,
double *totaldeadrows); Ðна должна вÑбиÑаÑÑ Ð¸Ð· ÑаблиÑÑ Ð¼Ð°ÐºÑимÑм targrows ÑÑÑок и помеÑаÑÑ Ð¸Ñ
в пеÑеданнÑй вÑзÑваÑÑим кодом маÑÑив rows. ÐозвÑаÑаÑÑ Ð¾Ð½Ð° должна ÑакÑиÑеÑкое ÑиÑло вÑбÑаннÑÑ
ÑÑÑок. ÐÑоме Ñого, ÑÑа ÑÑнкÑÐ¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° ÑоÑ
ÑаниÑÑ Ð¾Ð±Ñее колиÑеÑÑво акÑÑалÑнÑÑ
и «мÑÑÑвÑÑ
»ÑÑÑок в ÑаблиÑе в вÑÑ
однÑÑ
паÑамеÑÑаÑ
totalrows и totaldeadrows, ÑооÑвеÑÑÑвенно. (ÐÑли Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð¹ FDW Ð½ÐµÑ Ð¿Ð¾Ð½ÑÑÐ¸Ñ Â«Ð¼ÑÑÑвÑÑ
» ÑÑÑок, в totaldeadrows нÑжно запиÑаÑÑ 0.)
54.2.7. ÐодпÑогÑÐ°Ð¼Ð¼Ñ FDW Ð´Ð»Ñ IMPORT FOREIGN SCHEMA
List * ImportForeignSchema (ImportForeignSchemaStmt *stmt, Oid serverOid);
ÐолÑÑÐ°ÐµÑ ÑпиÑок команд, ÑоздаÑÑÐ¸Ñ ÑÑоÑонние ÑаблиÑÑ. ÐÑа ÑÑнкÑÐ¸Ñ Ð²ÑзÑваеÑÑÑ Ð¿Ñи вÑполнении ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ IMPORT FOREIGN SCHEMA; ей пеÑедаÑÑÑÑ Ð´ÐµÑево ÑазбоÑа ÑÑого опеÑаÑоÑа и OID Ñелевого ÑÑоÑоннего ÑеÑвеÑа. Ðна должна веÑнÑÑÑ Ð½Ð°Ð±Ð¾Ñ ÑÑÑок C, в каждой из коÑоÑÑÑ Ð´Ð¾Ð»Ð¶Ð½Ð° ÑодеÑжаÑÑÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð° CREATE FOREIGN TABLE. ÐÑи ÑÑÑоки бÑдÑÑ ÑазобÑÐ°Ð½Ñ Ð¸ вÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ñ ÑдÑом ÑеÑвеÑа.
Ð ÑÑÑÑкÑÑÑе ImportForeignSchemaStmt поле remote_schema задаÑÑ Ð¸Ð¼Ñ ÑдалÑнной ÑÑ
емÑ, из коÑоÑой импоÑÑиÑÑÑÑÑÑ ÑаблиÑÑ. Ðоле list_type ÑÑÑанавливаеÑ, как ÑилÑÑÑоваÑÑ Ð¸Ð¼ÐµÐ½Ð° ÑаблиÑ: ваÑÐ¸Ð°Ð½Ñ FDW_IMPORT_SCHEMA_ALL ознаÑаеÑ, ÑÑо нÑжно импоÑÑиÑоваÑÑ Ð²Ñе ÑаблиÑÑ Ð² ÑдалÑнной ÑÑ
еме (в ÑÑом ÑлÑÑае поле table_list пÑÑÑое), FDW_IMPORT_SCHEMA_LIMIT_TO ознаÑаеÑ, ÑÑо нÑжно импоÑÑиÑоваÑÑ ÑолÑко ÑаблиÑÑ, пеÑеÑиÑленнÑе в table_list, и FDW_IMPORT_SCHEMA_EXCEPT ознаÑаеÑ, ÑÑо нÑжно иÑклÑÑиÑÑ ÑаблиÑÑ, пеÑеÑиÑленнÑе в ÑпиÑке table_list. Рполе options пеÑедаÑÑÑÑ ÑпиÑок паÑамеÑÑов Ð´Ð»Ñ Ð¿ÑоÑеÑÑа импоÑÑа. ÐнаÑение ÑÑиÑ
паÑамеÑÑов опÑеделÑеÑÑÑ Ñамой FDW. ÐапÑимеÑ, Ñ FDW Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¿Ð°ÑамеÑÑ, опÑеделÑÑÑий, нÑжно ли ÑоÑ
ÑанÑÑÑ Ñ Ð¸Ð¼Ð¿Ð¾ÑÑиÑÑемÑÑ
ÑÑолбÑов аÑÑибÑÑ NOT NULL. ÐÑи паÑамеÑÑÑ Ð¼Ð¾Ð³ÑÑ Ð½Ðµ имеÑÑ Ð½Ð¸Ñего обÑего Ñ Ð¿Ð°ÑамеÑÑами, коÑоÑÑе пÑÐ¸Ð½Ð¸Ð¼Ð°ÐµÑ FDW в каÑеÑÑве паÑамеÑÑов обÑекÑов базÑ.
FDW Ð¼Ð¾Ð¶ÐµÑ Ð¸Ð³Ð½Ð¾ÑиÑоваÑÑ Ð¿Ð¾Ð»Ðµ local_schema в ImportForeignSchemaStmt, Ñак как ÑдÑо ÑеÑвеÑа Ñамо вÑÑÐ°Ð²Ð¸Ñ ÑÑо Ð¸Ð¼Ñ Ð² ÑазобÑаннÑе ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ CREATE FOREIGN TABLE.
Также, FDW Ð¼Ð¾Ð¶ÐµÑ Ð½Ðµ вÑполнÑÑÑ Ñама ÑилÑÑÑаÑÐ¸Ñ Ð¿Ð¾ полÑм list_type и table_list, Ñак как ÑдÑо ÑеÑвеÑа авÑомаÑиÑеÑки пÑопÑÑÑÐ¸Ñ Ð²Ñе возвÑаÑÑннÑе ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ Ð´Ð»Ñ ÑаблиÑ, иÑклÑÑÑннÑÑ
по заданнÑм кÑиÑеÑиÑм. Ðднако ÑаÑÑо лÑÑÑе ÑÑÐ°Ð·Ñ Ð¸Ð·Ð±ÐµÐ¶Ð°ÑÑ Ð»Ð¸Ñней ÑабоÑÑ, не ÑоÑмиÑÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ Ð´Ð»Ñ Ð¸ÑклÑÑаемÑÑ
ÑаблиÑ. ÐÐ»Ñ Ð¿ÑовеÑки, ÑдовлеÑвоÑÑÐµÑ Ð»Ð¸ ÑилÑÑÑÑ Ð·Ð°Ð´Ð°Ð½Ð½Ð¾Ðµ Ð¸Ð¼Ñ ÑÑоÑонней ÑаблиÑÑ, Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¿Ð¾Ð»ÐµÐ·Ð½Ð° ÑÑнкÑÐ¸Ñ IsImportableForeignTable().
ÐÑли FDW не поддеÑÐ¶Ð¸Ð²Ð°ÐµÑ Ð¸Ð¼Ð¿Ð¾ÑÑ Ð¾Ð¿Ñеделений ÑаблиÑ, ÑказаÑÐµÐ»Ñ ImportForeignSchema можно пÑиÑвоиÑÑ NULL.