55.3. ÐÑполнение неÑÑандаÑÑного ÑканиÑованиÑ
Ðогда вÑполнÑеÑÑÑ Ñзел CustomScan, его ÑоÑÑоÑние пÑедÑÑавлÑеÑÑÑ ÑÑÑÑкÑÑÑой CustomScanState, обÑÑвленной ÑледÑÑÑим обÑазом:
typedef struct CustomScanState
{
ScanState ss;
uint32 flags;
const CustomExecMethods *methods;
} CustomScanState;Ðоле ss иниÑиализиÑÑеÑÑÑ ÐºÐ°Ðº и Ð´Ð»Ñ ÑоÑÑоÑÐ½Ð¸Ñ Ð»Ñбого дÑÑгого ÑканиÑованиÑ, за иÑклÑÑением Ñого, ÑÑо когда ÑÑо ÑканиÑование Ð´Ð»Ñ ÑоединениÑ, а не Ð´Ð»Ñ Ð±Ð°Ð·Ð¾Ð²Ð¾Ð³Ð¾ оÑноÑениÑ, в ss.ss_currentRelation оÑÑаÑÑÑÑ NULL. Ðоле flags ÑодеÑÐ¶Ð¸Ñ Ð±Ð¸ÑовÑÑ Ð¼Ð°ÑÐºÑ Ñ Ñем же знаÑением, ÑÑо и в CustomPath и CustomScan. Ðоле methods должно ÑказÑваÑÑ Ð½Ð° обÑÐµÐºÑ (обÑÑно ÑÑаÑиÑеÑки ÑазмеÑÑннÑй), ÑеализÑÑÑий ÑÑебÑемÑе меÑÐ¾Ð´Ñ ÑоÑÑоÑÐ½Ð¸Ñ Ð½ÐµÑÑандаÑÑного ÑканиÑованиÑ, подÑобнее опиÑаннÑе ниже. ÐбÑÑно ÑÑÑÑкÑÑÑа CustomScanState, коÑоÑой не нÑжно поддеÑживаÑÑ copyObject, ÑакÑиÑеÑки вклÑÑаеÑÑÑ Ð² ÑаÑÑиÑеннÑÑ ÑÑÑÑкÑÑÑÑ Ð² каÑеÑÑве ÐµÑ Ð¿ÐµÑвого Ñлена.
55.3.1. ÐбÑабоÑÑики вÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð½ÐµÑÑандаÑÑного ÑканиÑованиÑ
void (*BeginCustomScan) (CustomScanState *node,
EState *estate,
int eflags); ÐавеÑÑÐ°ÐµÑ Ð¸Ð½Ð¸ÑиализаÑÐ¸Ñ Ð¿ÐµÑеданного обÑекÑа CustomScanState. СÑандаÑÑнÑе Ð¿Ð¾Ð»Ñ Ð¸Ð½Ð¸ÑиализиÑÑÑÑÑÑ Ð² ExecInitCustomScan, но вÑе внÑÑÑенние Ð¿Ð¾Ð»Ñ Ð´Ð¾Ð»Ð¶Ð½Ñ Ð¸Ð½Ð¸ÑиализиÑоваÑÑÑÑ Ð·Ð´ÐµÑÑ.
TupleTableSlot *(*ExecCustomScan) (CustomScanState *node);
СÑиÑÑÐ²Ð°ÐµÑ ÑледÑÑÑий коÑÑеж. Ð ÑлÑÑае налиÑÐ¸Ñ ÐºÐ¾ÑÑежей ÑÑа ÑÑнкÑÐ¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° запиÑаÑÑ Ð² ps_ResultTupleSlot ÑледÑÑÑий коÑÑеж в ÑекÑÑем напÑавлении ÑканиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð¸ веÑнÑÑÑ ÑÐ»Ð¾Ñ Ñ ÐºÐ¾ÑÑежем. ÐÑли же коÑÑежей болÑÑе неÑ, она должна веÑнÑÑÑ NULL или пÑÑÑой ÑлоÑ.
void (*EndCustomScan) (CustomScanState *node);
ÐÑиÑÐ°ÐµÑ Ð²Ñе внÑÑÑенние даннÑе, ÑвÑзаннÑе Ñ CustomScanState. ÐÑÐ¾Ñ Ð¼ÐµÑод ÑвлÑеÑÑÑ Ð¾Ð±ÑзаÑелÑнÑм, но он Ð¼Ð¾Ð¶ÐµÑ Ð½Ð¸Ñего не делаÑÑ, еÑли Ñакие даннÑе оÑÑÑÑÑÑвÑÑÑ Ð¸Ð»Ð¸ они бÑдÑÑ Ð¾ÑиÑÐµÐ½Ñ Ð°Ð²ÑомаÑиÑеÑки.
void (*ReScanCustomScan) (CustomScanState *node);
ÐозвÑаÑÐ°ÐµÑ Ð¿Ð¾Ð·Ð¸ÑÐ¸Ñ ÑекÑÑего ÑканиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð² наÑало и подгоÑÐ°Ð²Ð»Ð¸Ð²Ð°ÐµÑ Ð¿Ð¾Ð²ÑоÑное ÑканиÑование оÑноÑениÑ.
void (*MarkPosCustomScan) (CustomScanState *node);
СоÑ
ÑанÑÐµÑ ÑекÑÑÑÑ Ð¿Ð¾Ð·Ð¸ÑÐ¸Ñ ÑканиÑованиÑ, ÑÑÐ¾Ð±Ñ Ðº ней впоÑледÑÑвии можно бÑло веÑнÑÑÑÑÑ, вÑзвав обÑабоÑÑик RestrPosCustomScan. ÐаннÑй обÑабоÑÑик ÑвлÑеÑÑÑ Ð½ÐµÐ¾Ð±ÑзаÑелÑнÑм и должен пÑиÑÑÑÑÑвоваÑÑ, ÑолÑко еÑли ÑÑÑановлен Ñлаг CUSTOMPATH_SUPPORT_MARK_RESTORE.
void (*RestrPosCustomScan) (CustomScanState *node);
ÐоÑÑÑÐ°Ð½Ð°Ð²Ð»Ð¸Ð²Ð°ÐµÑ Ð¿ÑедÑдÑÑÑÑ Ð¿Ð¾Ð·Ð¸ÑÐ¸Ñ ÑканиÑованиÑ, ÑоÑ
ÑанÑннÑÑ Ð¾Ð±ÑабоÑÑиком MarkPosCustomScan. ÐаннÑй обÑабоÑÑик ÑвлÑеÑÑÑ Ð½ÐµÐ¾Ð±ÑзаÑелÑнÑм и должен пÑиÑÑÑÑÑвоваÑÑ, ÑолÑко еÑли ÑÑÑановлен Ñлаг CUSTOMPATH_SUPPORT_MARK_RESTORE.
Size (*EstimateDSMCustomScan) (CustomScanState *node,
ParallelContext *pcxt);ÐÑÐµÐ½Ð¸Ð²Ð°ÐµÑ Ð¾Ð±ÑÑм динамиÑеÑкой ÑазделÑемой памÑÑи, коÑоÑÐ°Ñ Ð¿Ð¾ÑÑебÑеÑÑÑ Ð´Ð»Ñ Ð¿Ð°ÑаллелÑной опеÑаÑии. ÐÑо знаÑение Ð¼Ð¾Ð¶ÐµÑ Ð¿ÑевÑÑаÑÑ Ð¾Ð±ÑÑм, коÑоÑÑй бÑÐ´ÐµÑ Ð·Ð°Ð½ÑÑ ÑакÑиÑеÑки, но не должно бÑÑÑ Ð¼ÐµÐ½ÑÑе. ÐозвÑаÑаемое знаÑение задаÑÑÑÑ Ð² байÑÐ°Ñ . ÐÑÐ¾Ñ Ð¾Ð±ÑабоÑÑик не ÑвлÑеÑÑÑ Ð¾Ð±ÑзаÑелÑнÑм и должен ÑÑÑанавливаÑÑÑÑ, ÑолÑко еÑли пÑÐ¾Ð²Ð°Ð¹Ð´ÐµÑ Ð½ÐµÑÑандаÑÑного ÑканиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ð¾Ð´Ð´ÐµÑÐ¶Ð¸Ð²Ð°ÐµÑ Ð¿Ð°ÑаллелÑное вÑполнение.
void (*InitializeDSMCustomScan) (CustomScanState *node,
ParallelContext *pcxt,
void *coordinate); ÐниÑиализиÑÑÐµÑ Ð´Ð¸Ð½Ð°Ð¼Ð¸ÑеÑкÑÑ ÑазделÑемÑÑ Ð¿Ð°Ð¼ÑÑÑ, коÑоÑÐ°Ñ Ð¿Ð¾ÑÑебÑеÑÑÑ Ð´Ð»Ñ Ð¿Ð°ÑаллелÑной опеÑаÑии; coordinate ÑказÑÐ²Ð°ÐµÑ Ð½Ð° облаÑÑÑ ÑазделÑемой памÑÑи ÑазмеÑа, Ñавного возвÑаÑÐ°ÐµÐ¼Ð¾Ð¼Ñ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ EstimateDSMCustomScan. ÐÑÐ¾Ñ Ð¾Ð±ÑабоÑÑик ÑвлÑеÑÑÑ Ð½ÐµÐ¾Ð±ÑзаÑелÑнÑм и должен ÑÑÑанавливаÑÑÑÑ, ÑолÑко еÑли пÑÐ¾Ð²Ð°Ð¹Ð´ÐµÑ Ð½ÐµÑÑандаÑÑного ÑканиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ð¾Ð´Ð´ÐµÑÐ¶Ð¸Ð²Ð°ÐµÑ Ð¿Ð°ÑаллелÑное вÑполнение.
void (*ReInitializeDSMCustomScan) (CustomScanState *node,
ParallelContext *pcxt,
void *coordinate); Ðаново иниÑиализиÑÑÐµÑ Ð´Ð¸Ð½Ð°Ð¼Ð¸ÑеÑкÑÑ ÑазделÑемÑÑ Ð¿Ð°Ð¼ÑÑÑ, ÑÑебÑемÑÑ Ð´Ð»Ñ Ð¿Ð°ÑаллелÑной опеÑаÑии, пеÑед Ñем как бÑÐ´ÐµÑ Ð¿Ð¾Ð²ÑоÑно пÑоÑканиÑован Ñзел неÑÑандаÑÑного ÑканиÑованиÑ. ÐÑÐ¾Ñ Ð¾Ð±ÑабоÑÑик ÑвлÑеÑÑÑ Ð½ÐµÐ¾Ð±ÑзаÑелÑнÑм и должен ÑÑÑанавливаÑÑÑÑ, ÑолÑко еÑли пÑÐ¾Ð²Ð°Ð¹Ð´ÐµÑ Ð½ÐµÑÑандаÑÑного ÑканиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ð¾Ð´Ð´ÐµÑÐ¶Ð¸Ð²Ð°ÐµÑ Ð¿Ð°ÑаллелÑное вÑполнение. Ð ÑÑом обÑабоÑÑике ÑекомендÑеÑÑÑ ÑбÑаÑÑваÑÑ ÑолÑко обÑее ÑоÑÑоÑние, а в обÑабоÑÑике ReScanCustomScan ÑбÑаÑÑваÑÑ ÑолÑко локалÑное. РнаÑÑоÑÑее вÑÐµÐ¼Ñ ÑÑÐ¾Ñ Ð¾Ð±ÑабоÑÑик бÑÐ´ÐµÑ Ð²ÑзÑваÑÑÑÑ Ð¿ÐµÑед ReScanCustomScan, но лÑÑÑе на ÑÑÐ¾Ñ Ð¿Ð¾ÑÑдок не ÑаÑÑÑиÑÑваÑÑ.
void (*InitializeWorkerCustomScan) (CustomScanState *node,
shm_toc *toc,
void *coordinate); ÐниÑиализиÑÑÐµÑ Ð»Ð¾ÐºÐ°Ð»Ñное ÑоÑÑоÑние паÑаллелÑного иÑполниÑÐµÐ»Ñ Ð½Ð° оÑнове обÑего ÑоÑÑоÑниÑ, заданного ведÑÑим иÑполниÑелем во вÑÐµÐ¼Ñ InitializeDSMCustomScan. ÐÑÐ¾Ñ Ð¾Ð±ÑабоÑÑик ÑвлÑеÑÑÑ Ð½ÐµÐ¾Ð±ÑзаÑелÑнÑм и должен ÑÑÑанавливаÑÑÑÑ, ÑолÑко еÑли пÑÐ¾Ð²Ð°Ð¹Ð´ÐµÑ Ð½ÐµÑÑандаÑÑного ÑканиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ð¾Ð´Ð´ÐµÑÐ¶Ð¸Ð²Ð°ÐµÑ Ð¿Ð°ÑаллелÑное вÑполнение.
void (*ShutdownCustomScan) (CustomScanState *node);
ÐÑÐ²Ð¾Ð±Ð¾Ð¶Ð´Ð°ÐµÑ ÑеÑÑÑÑÑ, когда ÑÑановиÑÑÑ Ð¿Ð¾Ð½ÑÑно, ÑÑо ÑÑÐ¾Ñ Ñзел болÑÑе не бÑÐ´ÐµÑ Ð²ÑполнÑÑÑÑÑ. ÐÑÐ¾Ñ Ð¾Ð±ÑабоÑÑик вÑзÑваеÑÑÑ Ð½Ðµ во вÑеÑ
ÑлÑÑаÑÑ
; иногда Ð¼Ð¾Ð¶ÐµÑ Ð²ÑзÑваÑÑÑÑ ÑолÑко EndCustomScan. Так как ÑÐµÐ³Ð¼ÐµÐ½Ñ DSM, иÑполÑзÑемÑй паÑаллелÑнÑм запÑоÑом, оÑвобождаеÑÑÑ ÑÑÐ°Ð·Ñ Ð¿Ð¾Ñле вÑзова ÑÑого обÑабоÑÑика, пÑовайдеÑÑ Ð½ÐµÑÑандаÑÑного ÑканиÑованиÑ, коÑоÑÑм нÑжно вÑполнÑÑÑ Ð½ÐµÐºÐ¾ÑоÑÑе дейÑÑÐ²Ð¸Ñ Ð´Ð¾ ликвидаÑии ÑегменÑа DSM, Ð´Ð¾Ð»Ð¶Ð½Ñ ÑеализовÑваÑÑ ÑÑÐ¾Ñ Ð¼ÐµÑод.
void (*ExplainCustomScan) (CustomScanState *node,
List *ancestors,
ExplainState *es); ÐÑÐ²Ð¾Ð´Ð¸Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑнÑÑ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð´Ð»Ñ EXPLAIN об Ñзле неÑÑандаÑÑного ÑканиÑованиÑ. ÐÑÐ¾Ñ Ð¾Ð±ÑабоÑÑик ÑвлÑеÑÑÑ Ð½ÐµÐ¾Ð±ÑзаÑелÑнÑм. ÐбÑие даннÑе, ÑоÑ
ÑанÑннÑе в ScanState, Ñакие как Ñелевой ÑпиÑок и ÑканиÑÑемое оÑноÑение, бÑдÑÑ Ð²ÑводиÑÑÑÑ Ð¸ без ÑÑого обÑабоÑÑика, но Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ ÑÑого обÑабоÑÑика можно вÑдаÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑнÑе, внÑÑÑенние ÑведениÑ.