56.1. Создание неÑÑандаÑÑнÑÑ Ð¿ÑÑей ÑканиÑованиÑ
ÐÑÐ¾Ð²Ð°Ð¹Ð´ÐµÑ Ð½ÐµÑÑандаÑÑного ÑканиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð¾Ð±ÑÑно добавлÑÐµÑ Ð¿ÑÑи Ð´Ð»Ñ Ð±Ð°Ð·Ð¾Ð²Ð¾Ð³Ð¾ оÑноÑениÑ, ÑÑÑановив ÑледÑÑÑий обÑабоÑÑик, коÑоÑÑй вÑзÑваеÑÑÑ Ð¿Ð¾Ñле Ñого, как ÑдÑо ÑиÑÑÐµÐ¼Ñ Ð¿Ð¾ÑÑÑоиÑ, по ÐµÑ Ð¼Ð½ÐµÐ½Ð¸Ñ, полнÑй и коÑÑекÑнÑй Ð½Ð°Ð±Ð¾Ñ Ð¿ÑÑей доÑÑÑпа Ð´Ð»Ñ Ð¾ÑноÑениÑ.
typedef void (*set_rel_pathlist_hook_type) (PlannerInfo *root,
RelOptInfo *rel,
Index rti,
RangeTblEntry *rte);
extern PGDLLIMPORT set_rel_pathlist_hook_type set_rel_pathlist_hook;ХоÑÑ ÑÑа ÑÑнкÑиÑ-обÑабоÑÑик Ð¼Ð¾Ð¶ÐµÑ Ð¸Ð·ÑÑаÑÑ, изменÑÑÑ Ð¸Ð»Ð¸ ÑдалÑÑÑ Ð¿ÑÑи, ÑÑоÑмиÑованнÑе оÑновной ÑиÑÑемой, пÑÐ¾Ð²Ð°Ð¹Ð´ÐµÑ Ð½ÐµÑÑандаÑÑного ÑканиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð¾Ð±ÑÑно огÑаниÑиваеÑÑÑ Ñозданием обÑекÑов CustomPath и добавлением иÑ
в rel (Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ add_path). ÐÑÐ¾Ð²Ð°Ð¹Ð´ÐµÑ Ð½ÐµÑÑандаÑÑного ÑканиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð¾ÑвеÑÐ°ÐµÑ Ð·Ð° иниÑиализаÑÐ¸Ñ Ð¾Ð±ÑекÑа CustomPath, коÑоÑÑй опиÑан Ñак:
typedef struct CustomPath
{
Path path;
uint32 flags;
List *custom_paths;
List *custom_private;
const CustomPathMethods *methods;
} CustomPath;Ðоле path должно иниÑиализиÑоваÑÑÑÑ ÐºÐ°Ðº Ð´Ð»Ñ Ð»Ñбого дÑÑгого пÑÑи и вклÑÑаÑÑ Ð¾ÑÐµÐ½ÐºÑ ÑиÑла ÑÑÑок, ÑÑоимоÑÑÑ Ð·Ð°Ð¿ÑÑка и обÑÑÑ, а Ñакже поÑÑдок ÑоÑÑиÑовки, ÑÑÑанавливаемÑй ÑÑим пÑÑÑм. Ðоле flags задаÑÑ Ð±Ð¸ÑовÑÑ Ð¼Ð°ÑкÑ, коÑоÑÐ°Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° вклÑÑаÑÑ Ñлаг CUSTOMPATH_SUPPORT_BACKWARD_SCAN, еÑли неÑÑандаÑÑнÑй пÑÑÑ Ð¿Ð¾Ð´Ð´ÐµÑÐ¶Ð¸Ð²Ð°ÐµÑ ÑканиÑование назад, и CUSTOMPATH_SUPPORT_MARK_RESTORE, еÑли он поддеÑÐ¶Ð¸Ð²Ð°ÐµÑ Ð¿Ð¾Ð¼ÐµÑÐºÑ Ð¿Ð¾Ð·Ð¸Ñии и ÐµÑ Ð²Ð¾ÑÑÑановление. Ðбе ÑÑи возможноÑÑи ÑвлÑÑÑÑÑ ÑакÑлÑÑаÑивнÑми. РнеобÑзаÑелÑном поле custom_paths задаÑÑÑÑ ÑпиÑок Ñзлов Path, иÑполÑзÑемÑÑ
даннÑм Ñзлом; они бÑдÑÑ Ð¿ÑеобÑÐ°Ð·Ð¾Ð²Ð°Ð½Ñ Ð¿Ð»Ð°Ð½Ð¸ÑовÑиком в ÑÐ·Ð»Ñ Plan. Рполе custom_private могÑÑ Ð±ÑÑÑ ÑоÑ
ÑÐ°Ð½ÐµÐ½Ñ Ð²Ð½ÑÑÑенние даннÑе неÑÑандаÑÑного пÑÑи. СоÑ
ÑанÑÑÑ Ð¸Ñ
нÑжно в ÑоÑме, коÑоÑÑÑ Ð¼Ð¾Ð¶ÐµÑ Ð¿ÑинÑÑÑ nodeToString, ÑÑÐ¾Ð±Ñ Ð¾ÑладоÑнÑе пÑоÑедÑÑÑ, пÑÑаÑÑиеÑÑ Ð²ÑвеÑÑи неÑÑандаÑÑнÑй пÑÑÑ, ÑабоÑали ожидаемÑм обÑазом. Ðоле methods должно ÑказÑваÑÑ Ð½Ð° (обÑÑно ÑÑаÑиÑеÑки ÑазмеÑÑннÑй) обÑекÑ, ÑеализÑÑÑий ÑÑебÑемÑе меÑÐ¾Ð´Ñ Ð½ÐµÑÑандаÑÑного пÑÑи (на даннÑй Ð¼Ð¾Ð¼ÐµÐ½Ñ ÑÑо два меÑода, подÑобнее опиÑаннÑе ниже).
ÐÑÐ¾Ð²Ð°Ð¹Ð´ÐµÑ Ð½ÐµÑÑандаÑÑного ÑканиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð¼Ð¾Ð¶ÐµÑ Ñакже ÑеализоваÑÑ Ð¿ÑÑи Ñоединений. Ðак и Ð´Ð»Ñ Ð±Ð°Ð·Ð¾Ð²ÑÑ
оÑноÑений, Ñакой пÑÑÑ Ð´Ð¾Ð»Ð¶ÐµÐ½ вÑдаваÑÑ ÑÐ¾Ñ Ð¶Ðµ ÑезÑлÑÑаÑ, какой бÑл Ð±Ñ Ð¿Ð¾Ð»ÑÑен обÑÑнÑм Ñоединением, коÑоÑое он заменÑеÑ. ÐÐ»Ñ ÑÑого пÑÐ¾Ð²Ð°Ð¹Ð´ÐµÑ ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ð´Ð¾Ð»Ð¶ÐµÐ½ ÑÑÑановиÑÑ ÑледÑÑÑий обÑабоÑÑик, а заÑем внÑÑÑи ÑÑнкÑии-обÑабоÑÑика ÑоздаÑÑ Ð¿ÑÑи CustomPath Ð´Ð»Ñ Ð¾ÑноÑÐµÐ½Ð¸Ñ ÑоединениÑ.
typedef void (*set_join_pathlist_hook_type) (PlannerInfo *root,
RelOptInfo *joinrel,
RelOptInfo *outerrel,
RelOptInfo *innerrel,
JoinType jointype,
JoinPathExtraData *extra);
extern PGDLLIMPORT set_join_pathlist_hook_type set_join_pathlist_hook;ÐÑÐ¾Ñ Ð¾Ð±ÑабоÑÑик бÑÐ´ÐµÑ Ð²ÑзÑваÑÑÑÑ Ð¼Ð½Ð¾Ð³Ð¾ÐºÑаÑно Ð´Ð»Ñ Ð¾Ð´Ð½Ð¾Ð³Ð¾ оÑноÑÐµÐ½Ð¸Ñ ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ñ ÑазнÑми ÑоÑеÑаниÑми внÑÑÑÐµÐ½Ð½Ð¸Ñ Ð¸ внеÑÐ½Ð¸Ñ Ð¾ÑноÑений; задаÑа обÑабоÑÑика â минимизиÑоваÑÑ Ð¿Ñи ÑÑом дÑблиÑÑÑÑиеÑÑ Ð¾Ð¿ÐµÑаÑии.
56.1.1. ÐбÑабоÑÑики пÑÑи неÑÑандаÑÑного ÑканиÑованиÑ
Plan *(*PlanCustomPath) (PlannerInfo *root,
RelOptInfo *rel,
CustomPath *best_path,
List *tlist,
List *clauses,
List *custom_plans); ÐÑеобÑазÑÐµÑ Ð½ÐµÑÑандаÑÑнÑй пÑÑÑ Ð² законÑеннÑй план. ÐозвÑаÑаемÑм знаÑением обÑÑно бÑÐ´ÐµÑ Ð¾Ð±ÑÐµÐºÑ CustomScan, коÑоÑÑй ÑÑÐ¾Ñ Ð¾Ð±ÑабоÑÑик должен ÑазмеÑÑиÑÑ Ð² памÑÑи и иниÑиализиÑоваÑÑ. Ðа подÑобноÑÑÑми обÑаÑиÑеÑÑ Ðº РазделÑ 56.2.
void (*TextOutCustomPath) (StringInfo str,
const CustomPath *node); ÐÑдаÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑнÑÑ Ð¸Ð½ÑоÑмаÑиÑ, когда Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð³Ð¾ неÑÑандаÑÑного Ñзла вÑзÑваеÑÑÑ nodeToString. ÐÑÐ¾Ñ Ð¾Ð±ÑабоÑÑик ÑвлÑеÑÑÑ Ð½ÐµÐ¾Ð±ÑзаÑелÑнÑм. Так как nodeToString авÑомаÑиÑеÑки вÑÐ²Ð¾Ð´Ð¸Ñ Ð²Ñе Ð¿Ð¾Ð»Ñ ÑÑÑÑкÑÑÑÑ, коÑоÑÑе она видиÑ, вклÑÑÐ°Ñ custom_private, ÑÑÐ¾Ñ Ð¾Ð±ÑабоÑÑик полезен, ÑолÑко еÑли обÑÐµÐºÑ CustomPath на Ñамом деле внедÑÑн в ÑаÑÑиÑеннÑÑ ÑÑÑÑкÑÑÑÑ, ÑодеÑжаÑÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑнÑе полÑ.