59.3. РаÑÑиÑÑемоÑÑÑ
SP-GiST пÑÐµÐ´Ð»Ð°Ð³Ð°ÐµÑ Ð¸Ð½ÑеÑÑÐµÐ¹Ñ Ñ Ð²ÑÑоким ÑÑовнем абÑÑÑакÑии и Ñаким обÑазом ÑÑебÑÐµÑ Ð¾Ñ ÑазÑабоÑÑика меÑода доÑÑÑпа ÑеализоваÑÑ ÑолÑко меÑодÑ, ÑпеÑиÑиÑнÑе Ð´Ð»Ñ ÐºÐ¾Ð½ÐºÑеÑного Ñипа даннÑÑ . ЯдÑо SP-GiST оÑвеÑÐ°ÐµÑ Ð·Ð° ÑÑÑекÑивнÑÑ ÑÑ ÐµÐ¼Ñ Ð¾Ð±ÑаÑений к диÑÐºÑ Ð¸ поиÑк в ÑÑÑÑкÑÑÑе деÑева, а Ñакже беÑÑÑ Ð½Ð° ÑÐµÐ±Ñ Ð·Ð°Ð±Ð¾ÑÑ Ð¾ паÑаллелÑном доÑÑÑпе и поддеÑжке жÑÑнала.
ÐоÑÑежи в лиÑÑÑÑÑ Ð´ÐµÑева SP-GiST ÑодеÑÐ¶Ð°Ñ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ Ñого же Ñипа даннÑÑ , ÑÑо и индекÑиÑÑемÑй ÑÑолбеÑ. Ðа веÑÑ Ð½ÐµÐ¼ ÑÑовне ÑÑи коÑÑежи ÑодеÑÐ¶Ð°Ñ Ð²Ñегда иÑÑ Ð¾Ð´Ð½Ð¾Ðµ индекÑиÑÑемое знаÑение даннÑÑ , но на более Ð½Ð¸Ð¶Ð½Ð¸Ñ Ð¼Ð¾Ð³ÑÑ ÑодеÑжаÑÑ ÑолÑко ÑокÑаÑÑнное пÑедÑÑавление, напÑимеÑ, ÑÑÑÑикÑ. Ð ÑÑом ÑлÑÑае опоÑнÑе ÑÑнкÑии клаÑÑа опеÑаÑоÑов Ð´Ð¾Ð»Ð¶Ð½Ñ ÑмеÑÑ Ð²Ð¾ÑÑÑанавливаÑÑ Ð¸ÑÑ Ð¾Ð´Ð½Ð¾Ðµ знаÑение, ÑобиÑÐ°Ñ ÐµÐ³Ð¾ из внÑÑÑÐµÐ½Ð½Ð¸Ñ ÐºÐ¾ÑÑежей, коÑоÑÑе нÑжно пÑойÑи Ð´Ð»Ñ Ð´Ð¾ÑÑÐ¸Ð¶ÐµÐ½Ð¸Ñ ÑÑÐ¾Ð²Ð½Ñ ÐºÐ¾Ð½ÐºÑеÑного лиÑÑа.
ÐнÑÑÑенние коÑÑежи ÑÑÑÑÐ¾ÐµÐ½Ñ Ñложнее, Ñак как они пÑедÑÑавлÑÑÑ Ñобой ÑоÑки ÑазвеÑÐ²Ð»ÐµÐ½Ð¸Ñ Ð² деÑеве поиÑка. ÐаждÑй внÑÑÑенний коÑÑеж ÑодеÑÐ¶Ð¸Ñ Ð½Ð°Ð±Ð¾Ñ Ð¸Ð· одного или неÑколÑÐºÐ¸Ñ Ñзлов, пÑедÑÑавлÑÑÑÐ¸Ñ Ð³ÑÑÐ¿Ð¿Ñ ÑÑ Ð¾Ð´Ð½ÑÑ Ð·Ð½Ð°Ñений лиÑÑÑев. Узел ÑодеÑÐ¶Ð¸Ñ Ð¾ÑвеÑвление, пÑиводÑÑее либо к дÑÑгомÑ, внÑÑÑÐµÐ½Ð½ÐµÐ¼Ñ ÐºÐ¾ÑÑÐµÐ¶Ñ Ð½Ð¸Ð¶Ð½ÐµÐ³Ð¾ ÑÑовнÑ, либо к коÑоÑÐºÐ¾Ð¼Ñ ÑпиÑÐºÑ ÐºÐ¾ÑÑежей в лиÑÑÑÑÑ , лежаÑÐ¸Ñ Ð² одной ÑÑÑаниÑе индекÑа. ÐÐ»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ Ñзла обÑÑно задаÑÑÑÑ Ð¼ÐµÑка, опиÑÑваÑÑÐ°Ñ ÐµÐ³Ð¾; напÑимеÑ, в пÑеÑикÑном деÑеве меÑкой Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¾ÑеÑедной Ñимвол в ÑÑÑоковом знаÑении. (С дÑÑгой ÑÑоÑонÑ, клаÑÑ Ð¾Ð¿ÐµÑаÑоÑов Ð¼Ð¾Ð¶ÐµÑ Ð¾Ð¿ÑÑкаÑÑ Ð¼ÐµÑки Ñзлов, еÑли он Ð¸Ð¼ÐµÐµÑ Ð´ÐµÐ»Ð¾ Ñ ÑикÑиÑованнÑм набоÑом Ñзлов во вÑÐµÑ Ð²Ð½ÑÑÑÐµÐ½Ð½Ð¸Ñ ÐºÐ¾ÑÑÐµÐ¶Ð°Ñ ; Ñм. ÐодÑаздел 59.4.2.) ÐополниÑелÑно внÑÑÑенний коÑÑеж Ð¼Ð¾Ð¶ÐµÑ Ñ ÑаниÑÑ Ð¿ÑеÑикÑ, опиÑÑваÑÑий вÑе его ÑленÑ. РпÑеÑикÑном деÑеве ÑÑо Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¾Ð±Ñий пÑеÑÐ¸ÐºÑ Ð²ÑÐµÑ Ð¿ÑедÑÑавленнÑÑ Ð½Ð¸Ð¶Ðµ ÑÑÑок. ÐнаÑением пÑеÑикÑа не обÑзаÑелÑно должен бÑÑÑ Ð¿ÑеÑикÑ, а могÑÑ Ð±ÑÑÑ Ð»ÑбÑе даннÑе, ÑÑебÑÑÑиеÑÑ ÐºÐ»Ð°ÑÑÑ Ð¾Ð¿ÐµÑаÑоÑов; напÑимеÑ, в деÑеве квадÑанÑов ÑÑо Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ ÑенÑÑалÑÐ½Ð°Ñ ÑоÑка, Ð¾Ñ ÐºÐ¾ÑоÑой оÑмеÑÑÑÑÑÑ ÑеÑÑÑе квадÑанÑа. Ð ÑÑом ÑлÑÑае внÑÑÑенний коÑÑеж деÑева квадÑанÑов бÑÐ´ÐµÑ Ñакже ÑодеÑжаÑÑ ÑеÑÑÑе Ñзла, ÑооÑвеÑÑÑвÑÑÑие квадÑанÑам вокÑÑг ÑÑой ÑенÑÑалÑной ÑоÑки.
ÐекоÑоÑÑе алгоÑиÑÐ¼Ñ Ð´ÐµÑевÑев ÑÑебÑÐµÑ Ð·Ð½Ð°Ð½Ð¸Ñ ÑÑÐ¾Ð²Ð½Ñ (или глÑбинÑ) ÑекÑÑего коÑÑежа, Ñак ÑÑо ÑдÑо SP-GiST даÑÑ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑÑ ÐºÐ»Ð°ÑÑам опеÑаÑоÑов конÑÑолиÑоваÑÑ ÑиÑло ÑÑовней пÑи ÑпÑÑке по деÑевÑ. Также имееÑÑÑ Ð¿Ð¾Ð´Ð´ÐµÑжка поÑагового воÑÑÑÐ°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¿ÑедÑÑавленного знаÑениÑ, когда ÑÑо ÑÑебÑеÑÑÑ, и пеÑедаÑи вниз дополниÑелÑнÑÑ Ð´Ð°Ð½Ð½ÑÑ (Ñак назÑваемÑÑ Ð¿ÐµÑÐµÑ Ð¾Ð´ÑÑÐ¸Ñ Ð·Ð½Ð°Ñений) пÑи ÑпÑÑке.
ÐÑимеÑание
ЯдÑо SP-GiST беÑÑÑ Ð½Ð° ÑÐµÐ±Ñ Ð·Ð°Ð±Ð¾ÑÑ Ð¾ знаÑениÑÑ NULL. ХоÑÑ Ð² индекÑÐ°Ñ SP-GiST не Ñ ÑанÑÑÑÑ Ð·Ð°Ð¿Ð¸Ñи Ð´Ð»Ñ NULL в индекÑиÑÑемÑÑ ÑÑолбÑÐ°Ñ , ÑÑо ÑкÑÑÑо Ð¾Ñ ÐºÐ¾Ð´Ð° клаÑÑа опеÑаÑоÑов; запиÑи индекÑов или ÑÑÐ»Ð¾Ð²Ð¸Ñ Ð¿Ð¾Ð¸Ñка Ñ NULL никогда не пеÑедаÑÑÑÑ Ð¼ÐµÑодам клаÑÑа опеÑаÑоÑов. (ÐÑедполагаеÑÑÑ, ÑÑо опеÑаÑоÑÑ SP-GiST ÑÑÑогие и не могÑÑ Ð²Ð¾Ð·Ð²ÑаÑаÑÑ Ð¿Ð¾Ð»Ð¾Ð¶Ð¸ÑелÑнÑй ÑезÑлÑÑÐ°Ñ Ð´Ð»Ñ Ð·Ð½Ð°Ñений NULL.) ÐоÑÑÐ¾Ð¼Ñ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ NULL здеÑÑ Ð±Ð¾Ð»ÑÑе обÑÑждаÑÑÑÑ Ð½Ðµ бÑдÑÑ.
ÐлаÑÑ Ð¾Ð¿ÐµÑаÑоÑов индекÑа Ð´Ð»Ñ SP-GiST должен пÑедоÑÑавиÑÑ ÑеализаÑии пÑÑи меÑодов. ÐÑе пÑÑÑ Ð¼ÐµÑодов Ð´Ð¾Ð»Ð¶Ð½Ñ Ð¿Ð¾ ÐµÐ´Ð¸Ð½Ð¾Ð¼Ñ ÑоглаÑÐµÐ½Ð¸Ñ Ð¿ÑинимаÑÑ Ð´Ð²Ð° аÑгÑменÑа internal, пеÑвÑм из коÑоÑÑÑ
бÑÐ´ÐµÑ ÑказаÑÐµÐ»Ñ Ð½Ð° ÑÑÑÑкÑÑÑÑ C, ÑодеÑжаÑÑÑ Ð²Ñ
однÑе знаÑÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð¾Ð¿Ð¾Ñного меÑода, а вÑоÑÑм â ÑказаÑÐµÐ»Ñ Ð½Ð° ÑÑÑÑкÑÑÑÑ C, в коÑоÑÑÑ Ð´Ð¾Ð»Ð¶Ð½Ñ Ð¿Ð¾Ð¼ÐµÑаÑÑÑÑ Ð²ÑÑ
однÑе знаÑениÑ. ЧеÑÑÑе из ÑÑиÑ
меÑодов Ð´Ð¾Ð»Ð¶Ð½Ñ Ð²Ð¾Ð·Ð²ÑаÑаÑÑ Ð¿ÑоÑÑо void, Ñак как иÑ
ÑезÑлÑÑаÑÑ Ð¿Ð¾Ð¼ÐµÑаÑÑÑÑ Ð² вÑÑ
однÑÑ ÑÑÑÑкÑÑÑÑ; однако leaf_consistent дополниÑелÑно возвÑаÑÐ°ÐµÑ ÑезÑлÑÑÐ°Ñ boolean. ÐÑи меÑÐ¾Ð´Ñ Ð½Ðµ Ð´Ð¾Ð»Ð¶Ð½Ñ Ð¼ÐµÐ½ÑÑÑ Ð½Ð¸ÐºÐ°ÐºÐ¸Ðµ Ð¿Ð¾Ð»Ñ Ð² иÑ
вÑ
однÑÑ
ÑÑÑÑкÑÑÑаÑ
. ÐÑÑ
Ð¾Ð´Ð½Ð°Ñ ÑÑÑÑкÑÑÑа вÑегда обнÑлÑеÑÑÑ Ð¿ÐµÑед вÑзовом полÑзоваÑелÑÑкого меÑода.
ÐолÑзоваÑÐµÐ»Ñ Ð´Ð¾Ð»Ð¶ÐµÐ½ опÑеделиÑÑ ÑледÑÑÑие пÑÑÑ Ð¼ÐµÑодов:
configÐозвÑаÑÐ°ÐµÑ ÑÑаÑиÑеÑкÑÑ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð¾ ÑеализаÑии индекÑа, вклÑÑÐ°Ñ OID Ñипов даннÑÑ Ð¿ÑеÑикÑа и меÑки Ñзла.
Ð SQL ÑÑа ÑÑнкÑÐ¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° обÑÑвлÑÑÑÑÑ Ñак:
CREATE FUNCTION my_config(internal, internal) RETURNS void ...
РпеÑвом аÑгÑменÑе пеÑедаÑÑÑÑ ÑказаÑÐµÐ»Ñ Ð½Ð° ÑÑÑÑкÑÑÑÑ
spgConfigInÑзÑка C, ÑодеÑжаÑие Ð²Ñ Ð¾Ð´Ð½Ñе даннÑе Ð´Ð»Ñ ÑÑнкÑии. Ðо вÑоÑом аÑгÑменÑе пеÑедаÑÑÑÑ ÑказаÑÐµÐ»Ñ Ð½Ð° ÑÑÑÑкÑÑÑÑspgConfigOutÑзÑка C, в коÑоÑÑÑ ÑÑнкÑÐ¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° помеÑÑиÑÑ ÑезÑлÑÑаÑ.typedef struct spgConfigIn { Oid attType; /* ÐндекÑиÑÑемÑй Ñип даннÑÑ */ } spgConfigIn; typedef struct spgConfigOut { Oid prefixType; /* Тип даннÑÑ Ð¿ÑеÑикÑа во внÑÑÑÐµÐ½Ð½Ð¸Ñ ÐºÐ¾ÑÑÐµÐ¶Ð°Ñ */ Oid labelType; /* Тип даннÑÑ Ð¼ÐµÑки Ñзла во внÑÑÑÐµÐ½Ð½Ð¸Ñ ÐºÐ¾ÑÑÐµÐ¶Ð°Ñ */ bool canReturnData; /* ÐлаÑÑ Ð¾Ð¿ÐµÑаÑоÑов Ð¼Ð¾Ð¶ÐµÑ Ð²Ð¾ÑÑÑановиÑÑ Ð¸ÑÑ Ð¾Ð´Ð½Ñе даннÑе */ bool longValuesOK; /* ÐлаÑÑ Ð¼Ð¾Ð¶ÐµÑ Ð¿ÑинимаÑÑ Ð·Ð½Ð°ÑениÑ, не ÑмеÑаÑÑиеÑÑ Ð½Ð° 1 ÑÑÑаниÑе */ } spgConfigOut;Ðоле
attTypeпеÑедаÑÑÑÑ Ð´Ð»Ñ Ð¿Ð¾Ð´Ð´ÐµÑжки полимоÑÑнÑÑ ÐºÐ»Ð°ÑÑов опеÑаÑоÑов; Ð´Ð»Ñ Ð¾Ð±ÑÑнÑÑ ÐºÐ»Ð°ÑÑов опеÑаÑоÑов Ñ ÑикÑиÑованнÑм Ñипом оно бÑÐ´ÐµÑ Ð²Ñегда ÑодеÑжаÑÑ Ð¾Ð´Ð½Ð¾ знаÑение и поÑÑÐ¾Ð¼Ñ ÐµÐ³Ð¾ можно пÑоÑÑо игноÑиÑоваÑÑ.ÐÐ»Ñ ÐºÐ»Ð°ÑÑов опеÑаÑоÑов, не иÑполÑзÑÑÑÐ¸Ñ Ð¿ÑеÑикÑÑ, в
prefixTypeможно ÑÑÑановиÑÑVOIDOID. ÐодобнÑм обÑазом, Ð´Ð»Ñ ÐºÐ»Ð°ÑÑов опеÑаÑоÑов, не иÑполÑзÑÑÑÐ¸Ñ Ð¼ÐµÑки Ñзлов, вlabelTypeÑоже можно ÑÑÑановиÑÑVOIDOID. ÐÑизнакcanReturnDataÑледÑÐµÑ ÑÑÑановиÑÑ, еÑли клаÑÑ Ð¾Ð¿ÐµÑаÑоÑов Ð¼Ð¾Ð¶ÐµÑ Ð²Ð¾ÑÑÑановиÑÑ Ð¸Ð·Ð½Ð°ÑалÑно пеÑеданное в Ð¸Ð½Ð´ÐµÐºÑ Ð·Ð½Ð°Ñение. ÐÑизнакlongValuesOKдолжен ÑÑÑанавливаÑÑÑÑ, ÑолÑко еÑлиattTypeпеÑеменной Ð´Ð»Ð¸Ð½Ñ Ð¸ клаÑÑ Ð¾Ð¿ÐµÑаÑоÑов Ð¼Ð¾Ð¶ÐµÑ ÑÑагменÑиÑоваÑÑ Ð´Ð»Ð¸Ð½Ð½Ñе знаÑениÑ, повÑоÑÑÑ ÑÑÑÑикÑÑ (Ñм. ÐодÑаздел 59.4.1).chooseÐÑбиÑÐ°ÐµÑ Ð¼ÐµÑод Ð´Ð»Ñ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ знаÑÐµÐ½Ð¸Ñ Ð²Ð¾ внÑÑÑенний коÑÑеж.
Ð SQL ÑÑа ÑÑнкÑÐ¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° обÑÑвлÑÑÑÑÑ Ñак:
CREATE FUNCTION my_choose(internal, internal) RETURNS void ...
РпеÑвом аÑгÑменÑе пеÑедаÑÑÑÑ ÑказаÑÐµÐ»Ñ Ð½Ð° ÑÑÑÑкÑÑÑÑ
spgChooseInÑзÑка C, ÑодеÑжаÑÑÑ Ð²Ñ Ð¾Ð´Ð½Ñе даннÑе Ð´Ð»Ñ ÑÑнкÑии. Ðо вÑоÑом аÑгÑменÑе пеÑедаÑÑÑÑ ÑказаÑÐµÐ»Ñ Ð½Ð° ÑÑÑÑкÑÑÑÑspgChooseOut, в коÑоÑÑÑ ÑÑнкÑÐ¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° помеÑÑиÑÑ ÑезÑлÑÑаÑ.typedef struct spgChooseIn { Datum datum; /* иÑÑ Ð¾Ð´Ð½Ð¾Ðµ знаÑение, коÑоÑое должно индекÑиÑоваÑÑÑÑ */ Datum leafDatum; /* ÑекÑÑее знаÑение, коÑоÑое должно ÑÐ¾Ñ ÑаниÑÑÑÑ Ð² лиÑÑе */ int level; /* ÑекÑÑий ÑÑÐ¾Ð²ÐµÐ½Ñ (наÑÐ¸Ð½Ð°Ñ Ñ Ð½ÑлÑ) */ /* ÐаннÑе из ÑекÑÑего внÑÑÑеннего коÑÑежа */ bool allTheSame; /* коÑÑеж Ñ Ð¿Ñизнаком вÑе-ÑавнÑ? */ bool hasPrefix; /* Ñ ÐºÐ¾ÑÑежа еÑÑÑ Ð¿ÑеÑикÑ? */ Datum prefixDatum; /* еÑли да, Ñо ÑÑо знаÑение пÑеÑикÑа */ int nNodes; /* ÑиÑло Ñзлов во внÑÑÑеннем коÑÑеже */ Datum *nodeLabels; /* знаÑÐµÐ½Ð¸Ñ Ð¼ÐµÑок Ñзлов (NULL, еÑли Ð¸Ñ Ð½ÐµÑ) */ } spgChooseIn; typedef enum spgChooseResultType { spgMatchNode = 1, /* ÑпÑÑÑиÑÑÑÑ Ð² ÑÑÑеÑÑвÑÑÑий Ñзел */ spgAddNode, /* добавиÑÑ Ñзел во внÑÑÑенний коÑÑеж */ spgSplitTuple /* ÑазделиÑÑ Ð²Ð½ÑÑÑенний коÑÑеж (измениÑÑ ÐµÐ³Ð¾ пÑеÑикÑ) */ } spgChooseResultType; typedef struct spgChooseOut { spgChooseResultType resultType; /* код дейÑÑвиÑ, Ñм. вÑÑе */ union { struct /* ÑезÑлÑÑаÑÑ Ð´Ð»Ñ spgMatchNode */ { int nodeN; /* ÑпÑÑÑиÑÑÑÑ Ðº ÑÑÐ¾Ð¼Ñ ÑÐ·Ð»Ñ (нÑмеÑаÑÐ¸Ñ Ñ 0) */ int levelAdd; /* Ñаг ÑвелиÑÐµÐ½Ð¸Ñ ÑÑÐ¾Ð²Ð½Ñ */ Datum restDatum; /* новое знаÑение лиÑÑа */ } matchNode; struct /* ÑезÑлÑÑаÑÑ Ð´Ð»Ñ spgAddNode */ { Datum nodeLabel; /* меÑка нового Ñзла */ int nodeN; /* кÑда вÑÑавлÑÑÑ ÐµÑ (нÑмеÑаÑÐ¸Ñ Ñ 0) */ } addNode; struct /* ÑезÑлÑÑаÑÑ Ð´Ð»Ñ spgSplitTuple */ { /* ÐнÑоÑмаÑÐ¸Ñ Ð´Ð»Ñ ÑоÑмиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ внÑÑÑеннего коÑÑежа веÑÑ Ð½ÐµÐ³Ð¾ ÑÑÐ¾Ð²Ð½Ñ Ñ Ð¾Ð´Ð½Ð¸Ð¼ доÑеÑним коÑÑежем */ bool prefixHasPrefix; /* коÑÑеж должен имеÑÑ Ð¿ÑеÑикÑ? */ Datum prefixPrefixDatum; /* еÑли да, его знаÑение */ int prefixNNodes; /* ÑиÑло Ñзлов */ Datum *prefixNodeLabels; /* Ð¸Ñ Ð¼ÐµÑки (или NULL, еÑли * меÑок неÑ) */ int childNodeN; /* Ñзел, коÑоÑÑй полÑÑÐ¸Ñ Ð´Ð¾ÑеÑний коÑÑеж */ /* ÐнÑоÑмаÑÐ¸Ñ Ð´Ð»Ñ ÑоÑмиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ внÑÑÑеннего коÑÑежа нижнего ÑÑÐ¾Ð²Ð½Ñ Ñо вÑеми ÑÑаÑÑми Ñзлами */ bool postfixHasPrefix; /* коÑÑеж должен имеÑÑ Ð¿ÑеÑикÑ? */ Datum postfixPrefixDatum; /* еÑли да, его знаÑение */ } splitTuple; } result; } spgChooseOut;Ð
datumзадаÑÑÑÑ Ð¸ÑÑ Ð¾Ð´Ð½Ð¾Ðµ знаÑение, коÑоÑое должно бÑÑÑ Ð²ÑÑавлено в индекÑ. ÐнаÑениеleafDatumизнаÑалÑно ÑÐ¾Ð²Ð¿Ð°Ð´Ð°ÐµÑ Ñdatum, но Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð´ÑÑгим на Ð½Ð¸Ð·ÐºÐ¸Ñ ÑÑовнÑÑ Ð´ÐµÑева, еÑли его изменÑÑ Ð¼ÐµÑодÑchooseилиpicksplit. Ðогда поиÑк меÑÑа Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð´Ð¾ÑÑÐ¸Ð³Ð°ÐµÑ ÑÑÑаниÑÑ ÑÑÐ¾Ð²Ð½Ñ Ð»Ð¸ÑÑа, в Ñоздаваемом коÑÑеже лиÑÑа бÑÐ´ÐµÑ ÑÐ¾Ñ Ñанено ÑекÑÑее знаÑениеleafDatum. ÐlevelзадаÑÑÑÑ ÑекÑÑий ÑÑÐ¾Ð²ÐµÐ½Ñ Ð²Ð½ÑÑÑеннего коÑÑежа, наÑÐ¸Ð½Ð°Ñ Ñ Ð½ÑÐ»Ñ Ð´Ð»Ñ ÑÑÐ¾Ð²Ð½Ñ ÐºÐ¾ÑнÑ. ÐÑизнакallTheSameÑÑÑанавливаеÑÑÑ, еÑли ÑекÑÑий внÑÑÑенний коÑÑеж ÑодеÑÐ¶Ð¸Ñ Ð½ÐµÑколÑко ÑавнознаÑнÑÑ Ñзлов (Ñм. ÐодÑаздел 59.4.3). ÐÑизнакhasPrefixÑÑÑанавливаеÑÑÑ, еÑли ÑекÑÑий внÑÑÑенний коÑÑеж ÑодеÑÐ¶Ð¸Ñ Ð¿ÑеÑикÑ; в ÑÑом ÑлÑÑае вprefixDatumзадаÑÑÑÑ ÐµÐ³Ð¾ знаÑение. ÐолеnNodesзадаÑÑ ÑиÑло доÑеÑÐ½Ð¸Ñ Ñзлов, ÑодеÑжаÑÐ¸Ñ ÑÑ Ð²Ð¾ внÑÑÑеннем коÑÑеже, аnodeLabelsпÑедÑÑавлÑÐµÑ Ð¼Ð°ÑÑив Ð¸Ñ Ð¼ÐµÑок, или NULL, еÑли меÑок Ñ Ð½Ð¸Ñ Ð½ÐµÑ.ФÑнкÑиÑ
chooseÐ¼Ð¾Ð¶ÐµÑ Ð¾Ð¿ÑеделиÑÑ, ÑооÑвеÑÑÑвÑÐµÑ Ð»Ð¸ новое знаÑение Ð¾Ð´Ð½Ð¾Ð¼Ñ Ð¸Ð· ÑÑÑеÑÑвÑÑÑÐ¸Ñ Ð´Ð¾ÑеÑÐ½Ð¸Ñ Ñзлов, или ÑÑо нÑжно добавиÑÑ Ð½Ð¾Ð²Ñй доÑеÑний Ñзел, или ÑÑо новое знаÑение не ÑоглаÑÑеÑÑÑ Ñ Ð¿ÑеÑикÑом коÑÑежа и внÑÑÑенний коÑÑеж нÑжно ÑазделиÑÑ, ÑÑÐ¾Ð±Ñ Ð¿Ð¾Ð»ÑÑиÑÑ Ð¼ÐµÐ½ÐµÐµ огÑаниÑиваÑÑий пÑеÑикÑ.ÐÑли новое знаÑение ÑооÑвеÑÑÑвÑÐµÑ Ð¾Ð´Ð½Ð¾Ð¼Ñ Ð¸Ð· ÑÑÑеÑÑвÑÑÑÐ¸Ñ Ð´Ð¾ÑеÑÐ½Ð¸Ñ Ñзлов, ÑÑÑановиÑе в
resultTypeзнаÑениеspgMatchNode. УÑÑановиÑе вnodeNÐ½Ð¾Ð¼ÐµÑ ÑÑого Ñзла в маÑÑиве Ñзлов (нÑмеÑаÑÐ¸Ñ Ð½Ð°ÑинаеÑÑÑ Ñ Ð½ÑлÑ). УÑÑановиÑе вlevelAddзнаÑение, на коÑоÑое должен ÑвелиÑиваÑÑÑÑ ÑÑÐ¾Ð²ÐµÐ½Ñ (level) пÑи ÑпÑÑке ÑеÑез ÑÑÐ¾Ñ Ñзел, либо оÑÑавÑÑе его нÑлевÑм, еÑли клаÑÑ Ð¾Ð¿ÐµÑаÑоÑов не оÑÑÐ»ÐµÐ¶Ð¸Ð²Ð°ÐµÑ ÑÑовни. УÑÑановиÑеrestDatum, ÑавнÑмdatum, еÑли клаÑÑ Ð¾Ð¿ÐµÑаÑоÑов не менÑÐµÑ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ Ð´Ð°Ð½Ð½ÑÑ Ð¾Ñ ÑÑÐ¾Ð²Ð½Ñ Ðº ÑледÑÑÑемÑ, а в пÑоÑивном ÑлÑÑае запиÑиÑе в него изменÑнное знаÑение, коÑоÑое должно иÑполÑзоваÑÑÑÑ Ð² каÑеÑÑвеleafDatumна ÑледÑÑÑем ÑÑовне.ÐÑли нÑжно добавиÑÑ Ð½Ð¾Ð²Ñй доÑеÑний Ñзел, ÑÑÑановиÑе в
resultTypeзнаÑениеspgAddNode. ÐnodeLabelзадайÑе меÑÐºÑ Ð´Ð»Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ Ñзла, а вnodeNпозиÑÐ¸Ñ (оÑÑÑиÑÑваемÑÑ Ð¾Ñ Ð½ÑлÑ), в коÑоÑÑÑ Ð´Ð¾Ð»Ð¶ÐµÐ½ вÑÑавлÑÑÑÑÑ Ñзел в маÑÑиве Ñзлов. ÐоÑле Ñого как Ñзел бÑÐ´ÐµÑ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½, ÑÑнкÑиÑchooseвÑзÑваеÑÑÑ Ñнова Ñ Ð¸Ð·Ð¼ÐµÐ½ÑннÑм внÑÑÑенним коÑÑежем; в ÑезÑлÑÑаÑе ÑÑого вÑзова должен бÑÑÑ Ð¿Ð¾Ð»ÑÑен ÑезÑлÑÑаÑspgMatchNode.ÐÑли новое знаÑение не ÑоглаÑÑеÑÑÑ Ñ Ð¿ÑеÑикÑом коÑÑежа, ÑÑÑановиÑе в
resultTypeзнаÑениеspgSplitTuple. ÐÑо дейÑÑвие пÑÐ¸Ð²Ð¾Ð´Ð¸Ñ Ðº пеÑемеÑÐµÐ½Ð¸Ñ Ð²ÑÐµÑ ÑÑÑеÑÑвÑÑÑÐ¸Ñ Ñзлов в новÑй внÑÑÑенний коÑÑеж нижнего ÑÑÐ¾Ð²Ð½Ñ Ð¸ замене ÑÑÑеÑÑвÑÑÑего внÑÑÑеннего коÑÑежа коÑÑежем, ÑодеÑжаÑим Ð¾Ð´Ð½Ñ ÑÑÑÐ»ÐºÑ Ð²Ð½Ð¸Ð· на новÑй внÑÑÑенний коÑÑеж. УÑÑановиÑе пÑизнакprefixHasPrefix, ÑÑÐ¾Ð±Ñ ÑказаÑÑ, должен ли новÑй веÑÑ Ð½Ð¸Ð¹ коÑÑеж имеÑÑ Ð¿ÑеÑикÑ, и еÑли да, задайÑе вprefixPrefixDatumзнаÑение пÑеÑикÑа. ÐÑо новое знаÑение пÑеÑикÑа должно бÑÑÑ Ð² доÑÑаÑоÑной меÑе менее огÑаниÑиваÑÑим, Ñем иÑÑ Ð¾Ð´Ð½Ð¾Ðµ, ÑÑÐ¾Ð±Ñ Ð² Ð¸Ð½Ð´ÐµÐºÑ Ð±Ñло пÑинÑÑо новое знаÑение. ÐапиÑиÑе вprefixNNodesÑиÑло ÑÑебÑÑÑÐ¸Ñ ÑÑ Ñзлов в новом коÑÑеже, а вprefixNodeLabelsâ ÑказаÑÐµÐ»Ñ Ð½Ð° вÑделеннÑй ÑеÑез palloc маÑÑив Ñ Ð¸Ñ Ð¼ÐµÑками или NULL, еÑли меÑки Ñзлов не нÑжнÑ. ÐамеÑÑÑе, ÑÑо обÑий ÑÐ°Ð·Ð¼ÐµÑ Ð½Ð¾Ð²Ð¾Ð³Ð¾ коÑÑежа веÑÑ Ð½ÐµÐ³Ð¾ ÑÑÐ¾Ð²Ð½Ñ Ð½Ðµ должен пÑевÑÑаÑÑ Ð¾Ð±Ñий ÑÐ°Ð·Ð¼ÐµÑ ÐºÐ¾ÑÑежа, коÑоÑÑй он замеÑаеÑ; ÑÑо огÑаниÑÐ¸Ð²Ð°ÐµÑ Ð´Ð»Ð¸Ð½Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ пÑеÑикÑа и новÑÑ Ð¼ÐµÑок. УÑÑановиÑе вchildNodeNÐ¸Ð½Ð´ÐµÐºÑ (наÑÐ¸Ð½Ð°Ñ Ñ Ð½ÑлÑ) Ñзла, коÑоÑÑй бÑÐ´ÐµÑ ÑÑÑлаÑÑÑÑ Ð½Ð° новÑй внÑÑÑенний коÑÑеж нижнего ÑÑовнÑ. УÑÑановиÑе пÑизнакpostfixHasPrefix, ÑÑÐ¾Ð±Ñ ÑказаÑÑ, должен ли новÑй внÑÑÑенний коÑÑеж нижнего ÑÑÐ¾Ð²Ð½Ñ Ð¸Ð¼ÐµÑÑ Ð¿ÑеÑикÑ, и еÑли да, задайÑе вpostfixPrefixDatumзнаÑение пÑеÑикÑа. СоÑеÑание ÑÑÐ¸Ñ Ð´Ð²ÑÑ Ð¿ÑеÑикÑов и меÑки Ñзла, ÑÑÑлаÑÑегоÑÑ Ð²Ð½Ð¸Ð·, (еÑли она еÑÑÑ) должно имеÑÑ Ñо же знаÑение, ÑÑо и иÑÑ Ð¾Ð´Ð½Ñй пÑеÑикÑ, Ñак как Ð½ÐµÑ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑи ни измениÑÑ Ð¼ÐµÑки Ñзлов, пеÑемеÑÑннÑÑ Ð² новÑй коÑÑеж нижнего ÑÑовнÑ, ни измениÑÑ ÐºÐ°ÐºÐ¸Ðµ-либо нижние запиÑи индекÑа. ÐоÑле Ñого как Ñзел ÑазделÑн, ÑÑнкÑиÑchooseбÑÐ´ÐµÑ Ð²Ñзвана Ñнова Ñ Ð·Ð°Ð¼ÐµÐ½ÑемÑм внÑÑÑенним коÑÑежем. ÐÑи ÑÑом вÑзове Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð²Ð¾Ð·Ð²ÑаÑÑн ÑезÑлÑÑаÑspgAddNode, еÑли Ð¿Ð¾Ð´Ñ Ð¾Ð´ÑÑий Ñзел не бÑл Ñоздан дейÑÑвиемspgSplitTuple. РконÑе конÑовchooseдолжна веÑнÑÑÑspgMatchNode, ÑÑÐ¾Ð±Ñ Ð¾Ð¿ÐµÑаÑÐ¸Ñ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¼Ð¾Ð³Ð»Ð° пеÑейÑи на ÑледÑÑÑий ÑÑовенÑ.picksplitÐÑбиÑаеÑ, как ÑоздаÑÑ Ð½Ð¾Ð²Ñй внÑÑÑенний коÑÑеж по набоÑÑ ÐºÐ¾ÑÑежей в лиÑÑÑÑÑ .
Ð SQL ÑÑа ÑÑнкÑÐ¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° обÑÑвлÑÑÑÑÑ Ñак:
CREATE FUNCTION my_picksplit(internal, internal) RETURNS void ...
РпеÑвом аÑгÑменÑе пеÑедаÑÑÑÑ ÑказаÑÐµÐ»Ñ Ð½Ð° ÑÑÑÑкÑÑÑÑ
spgPickSplitInÑзÑка C, ÑодеÑжаÑÑÑ Ð²Ñ Ð¾Ð´Ð½Ñе даннÑе Ð´Ð»Ñ ÑÑнкÑии. Ðо вÑоÑом аÑгÑменÑе пеÑедаÑÑÑÑ ÑказаÑÐµÐ»Ñ Ð½Ð° ÑÑÑÑкÑÑÑÑspgPickSplitOutÑзÑка C, в коÑоÑÑÑ ÑÑнкÑÐ¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° помеÑÑиÑÑ ÑезÑлÑÑаÑ.typedef struct spgPickSplitIn { int nTuples; /* ÑиÑло коÑÑежей в лиÑÑÑÑÑ */ Datum *datums; /* Ð¸Ñ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ (маÑÑив Ð´Ð»Ð¸Ð½Ñ nTuples) */ int level; /* ÑекÑÑий ÑÑÐ¾Ð²ÐµÐ½Ñ (оÑÑÑиÑÑÐ²Ð°Ñ Ð¾Ñ 0) */ } spgPickSplitIn; typedef struct spgPickSplitOut { bool hasPrefix; /* новÑй внÑÑÑенний коÑÑеж должен имеÑÑ Ð¿ÑеÑикÑ? */ Datum prefixDatum; /* еÑли да, его знаÑение */ int nNodes; /* ÑиÑло Ñзлов Ð´Ð»Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ внÑÑÑеннего коÑÑежа */ Datum *nodeLabels; /* Ð¸Ñ Ð¼ÐµÑки (или NULL, еÑли Ð¸Ñ Ð½ÐµÑ) */ int *mapTuplesToNodes; /* Ð½Ð¾Ð¼ÐµÑ Ñзла Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ коÑÑежа в лиÑÑе */ Datum *leafTupleDatums; /* знаÑениÑ, помеÑаемÑе в каждÑй новÑй коÑÑеж */ } spgPickSplitOut;Ð
nTuplesзадаÑÑÑÑ ÑиÑло пÑедоÑÑавленнÑÑ ÐºÐ¾ÑÑежей ÑÑÐ¾Ð²Ð½Ñ Ð»Ð¸ÑÑÑев, аdatumsâ маÑÑив Ð¸Ñ Ð·Ð½Ð°Ñений даннÑÑ . ÐlevelÑказÑваеÑÑÑ ÑекÑÑий ÑÑовенÑ, коÑоÑÑй Ð´Ð¾Ð»Ð¶Ð½Ñ ÑазделÑÑÑ Ð²Ñе коÑÑежи лиÑÑÑев, и коÑоÑÑй ÑÑÐ°Ð½ÐµÑ ÑÑовнем нового внÑÑÑеннего коÑÑежа.УÑÑановиÑе пÑизнак
hasPrefix, ÑÑÐ¾Ð±Ñ ÑказаÑÑ, должен ли новÑй внÑÑÑенний коÑÑеж имеÑÑ Ð¿ÑеÑикÑ, и еÑли да, задайÑе вprefixDatumзнаÑение пÑеÑикÑа. УÑÑановиÑе вnNodesколиÑеÑÑво Ñзлов, коÑоÑÑе бÑдÑÑ ÑодеÑжаÑÑÑÑ Ð²Ð¾ внÑÑÑеннем коÑÑеже, а вnodeLabelsâ маÑÑив знаÑений Ð¸Ñ Ð¼ÐµÑок либо NULL, еÑли Ñзлам не нÑÐ¶Ð½Ñ Ð¼ÐµÑки. ÐомеÑÑиÑе вmapTuplesToNodesÑказаÑÐµÐ»Ñ Ð½Ð° маÑÑив, назнаÑаÑÑий номеÑа Ñзлов (наÑÐ¸Ð½Ð°Ñ Ñ Ð½ÑлÑ) ÐºÐ°Ð¶Ð´Ð¾Ð¼Ñ ÐºÐ¾ÑÑÐµÐ¶Ñ Ð»Ð¸ÑÑа. ÐleafTupleDatumsпеÑедайÑе маÑÑив знаÑений, коÑоÑÑе Ð´Ð¾Ð»Ð¶Ð½Ñ Ð±ÑÑÑ ÑÐ¾Ñ ÑÐ°Ð½ÐµÐ½Ñ Ð² новÑÑ ÐºÐ¾ÑÑÐµÐ¶Ð°Ñ Ð»Ð¸ÑÑÑев (они бÑдÑÑ ÑовпадаÑÑ Ñо Ð²Ñ Ð¾Ð´Ð½Ñми знаÑениÑми (datums), еÑли клаÑÑ Ð¾Ð¿ÐµÑаÑоÑов не изменÑÐµÑ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ Ð¾Ñ ÑÑÐ¾Ð²Ð½Ñ Ðº ÑледÑÑÑемÑ). ÐамеÑÑÑе, ÑÑо ÑÑнкÑиÑpicksplitÑама должна вÑделиÑÑ Ð¿Ð°Ð¼ÑÑÑ, иÑполÑзÑÑ palloc, Ð´Ð»Ñ Ð¼Ð°ÑÑивовnodeLabels,mapTuplesToNodesиleafTupleDatums.ÐÑли пеÑедаÑÑÑÑ Ð½ÐµÑколÑко коÑÑежей лиÑÑÑев, ожидаеÑÑÑ, ÑÑо ÑÑнкÑиÑ
picksplitклаÑÑиÑиÑиÑÑÐµÑ Ð¸Ñ Ð¸ ÑÐ°Ð·Ð´ÐµÐ»Ð¸Ñ Ð½Ð° неÑколÑко Ñзлов; инаÑе нелÑÐ·Ñ Ð±ÑÐ´ÐµÑ ÑазнеÑÑи коÑÑежи лиÑÑÑев по ÑазнÑм ÑÑÑаниÑам, ÑÑо ÑвлÑеÑÑÑ ÐºÐ¾Ð½ÐµÑной ÑелÑÑ ÑÑой опеÑаÑии. Таким обÑазом, еÑлиpicksplitв иÑоге помеÑÐ°ÐµÑ Ð²Ñе коÑÑежи лиÑÑÑев в один Ñзел, ÑдÑо SP-GiST менÑÐµÑ ÑÑо ÑеÑение и ÑоздаÑÑ Ð²Ð½ÑÑÑенний коÑÑеж, в коÑоÑом коÑÑежи лиÑÑÑев ÑвÑзÑваÑÑÑÑ ÑлÑÑайнÑм обÑазом Ñ Ð½ÐµÑколÑкими Ñзлами Ñ Ð¾Ð´Ð¸Ð½Ð°ÐºÐ¾Ð²Ñми меÑками. Такой коÑÑеж помеÑаеÑÑÑ ÑлагомallTheSame, показÑваÑÑим, ÑÑо вÑе ÑÐ·Ð»Ñ ÑавнÑ. ФÑнкÑииchooseиinner_consistentÐ´Ð¾Ð»Ð¶Ð½Ñ ÑабоÑаÑÑ Ñ Ñакими внÑÑÑенними коÑÑежами оÑобÑм обÑазом. Ðа дополниÑелÑнÑми ÑведениÑми обÑаÑиÑеÑÑ Ðº ÐодÑазделÑ 59.4.3.picksplitÐ¼Ð¾Ð¶ÐµÑ Ð¿ÑименÑÑÑÑÑ Ðº Ð¾Ð´Ð½Ð¾Ð¼Ñ ÐºÐ¾ÑÑÐµÐ¶Ñ Ð½Ð° ÑÑовне лиÑÑÑев, ÑолÑко когда ÑÑнкÑиÑconfigÑÑÑановила вlongValuesOKзнаÑение true и бÑло пеÑедано Ð²Ñ Ð¾Ð´Ð½Ð¾Ðµ знаÑение, болÑÑее ÑÑÑаниÑÑ. Ð ÑÑом ÑлÑÑае ÑÐµÐ»Ñ Ð¾Ð¿ÐµÑаÑии â оÑделиÑÑ Ð¿ÑеÑÐ¸ÐºÑ Ð¸ полÑÑиÑÑ Ð½Ð¾Ð²Ð¾Ðµ, более коÑоÑкое знаÑение Ð´Ð»Ñ Ð»Ð¸ÑÑа. ÐÑÐ¾Ñ Ð²Ñзов бÑÐ´ÐµÑ Ð¿Ð¾Ð²ÑоÑÑÑÑÑÑ, пока знаÑение ÑÑÐ¾Ð²Ð½Ñ Ð»Ð¸ÑÑа не ÑменÑÑиÑÑÑ Ð½Ð°ÑÑолÑко, ÑÑÐ¾Ð±Ñ ÑмеÑÑиÑÑÑÑ Ð² ÑÑÑаниÑе. Ðа дополниÑелÑнÑми ÑведениÑми обÑаÑиÑеÑÑ Ðº ÐодÑазделÑ 59.4.1.inner_consistentÐозвÑаÑÐ°ÐµÑ Ð½Ð°Ð±Ð¾Ñ Ñзлов (веÑвей), по коÑоÑÑм надо пÑодолжаÑÑ Ð¿Ð¾Ð¸Ñк.
Ð SQL ÑÑа ÑÑнкÑÐ¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° обÑÑвлÑÑÑÑÑ Ñак:
CREATE FUNCTION my_inner_consistent(internal, internal) RETURNS void ...
РпеÑвом аÑгÑменÑе пеÑедаÑÑÑÑ ÑказаÑÐµÐ»Ñ Ð½Ð° ÑÑÑÑкÑÑÑÑ
spgInnerConsistentInÑзÑка C, ÑодеÑжаÑÑÑ Ð²Ñ Ð¾Ð´Ð½Ñе даннÑе Ð´Ð»Ñ ÑÑнкÑии. Ðо вÑоÑом аÑгÑменÑе пеÑедаÑÑÑÑ ÑказаÑÐµÐ»Ñ Ð½Ð° ÑÑÑÑкÑÑÑÑspgInnerConsistentOutÑзÑка C, в коÑоÑÑÑ ÑÑнкÑÐ¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° помеÑÑиÑÑ ÑезÑлÑÑаÑ.typedef struct spgInnerConsistentIn { ScanKey scankeys; /* маÑÑив опеÑаÑоÑов и иÑкомÑÑ Ð·Ð½Ð°Ñений */ int nkeys; /* длина маÑÑива */ Datum reconstructedValue; /* знаÑение, воÑÑÑановленное Ð´Ð»Ñ ÑодиÑÐµÐ»Ñ */ void *traversalValue; /* пеÑÐµÑ Ð¾Ð´ÑÑее знаÑение, ÑпеÑиÑиÑное Ð´Ð»Ñ ÐºÐ»Ð°ÑÑа опеÑаÑоÑов */ MemoryContext traversalMemoryContext; /* пеÑÐµÑ Ð¾Ð´ÑÑие знаÑÐµÐ½Ð¸Ñ Ð½Ñжно помеÑаÑÑ ÑÑда */ int level; /* ÑекÑÑий ÑÑÐ¾Ð²ÐµÐ½Ñ (оÑÑÑиÑÑваеÑÑÑ Ð¾Ñ Ð½ÑлÑ) */ bool returnData; /* нÑжно ли возвÑаÑаÑÑ Ð¸ÑÑ Ð¾Ð´Ð½Ñе даннÑе? */ /* ÐаннÑе из ÑекÑÑего внÑÑÑеннего коÑÑежа */ bool allTheSame; /* коÑÑеж Ñ Ð¿Ñизнаком вÑе-ÑавнÑ? */ bool hasPrefix; /* Ñ ÐºÐ¾ÑÑежа еÑÑÑ Ð¿ÑеÑикÑ? */ Datum prefixDatum; /* еÑли да, Ñо ÑÑо знаÑение пÑеÑикÑа */ int nNodes; /* ÑиÑло Ñзлов во внÑÑÑеннем коÑÑеже */ Datum *nodeLabels; /* знаÑÐµÐ½Ð¸Ñ Ð¼ÐµÑок Ñзлов (NULL, еÑли Ð¸Ñ Ð½ÐµÑ) */ } spgInnerConsistentIn; typedef struct spgInnerConsistentOut { int nNodes; /* ÑиÑло доÑеÑÐ½Ð¸Ñ Ñзлов, коÑоÑÑе нÑжно поÑеÑиÑÑ */ int *nodeNumbers; /* Ð¸Ñ Ð½Ð¾Ð¼ÐµÑа в маÑÑиве Ñзлов */ int *levelAdds; /* Ñаги ÑвелиÑÐµÐ½Ð¸Ñ ÑÑÐ¾Ð²Ð½Ñ Ð´Ð»Ñ ÑÑÐ¸Ñ Ñзлов */ Datum *reconstructedValues; /* ÑвÑзаннÑе воÑÑÑановленнÑе знаÑÐµÐ½Ð¸Ñ */ void **traversalValues; /* пеÑÐµÑ Ð¾Ð´ÑÑие знаÑениÑ, ÑпеÑиÑиÑнÑе Ð´Ð»Ñ ÐºÐ»Ð°ÑÑа опеÑаÑоÑов */ } spgInnerConsistentOut;ÐаÑÑив
scankeysдлинÑnkeysопиÑÑÐ²Ð°ÐµÑ ÑÑÐ»Ð¾Ð²Ð¸Ñ Ð¿Ð¾Ð¸Ñка по индекÑÑ. ÐÑи ÑÑÐ»Ð¾Ð²Ð¸Ñ Ð¾Ð±ÑединÑÑÑÑÑ Ð¾Ð¿ÐµÑаÑией Ð â Ð½Ð°Ð¹Ð´ÐµÐ½Ñ Ð´Ð¾Ð»Ð¶Ð½Ñ Ð±ÑÑÑ ÑолÑко Ñе запиÑи, коÑоÑÑе ÑдовлеÑвоÑÑÑÑ Ð²Ñем ÑÑловиÑм. (ÐамеÑÑÑе, ÑÑо Ñnkeys= 0 подÑазÑмеваеÑÑÑ, ÑÑо запÑоÑÑ ÑдовлеÑвоÑÑÑÑ Ð²Ñе запиÑи в индекÑе.) ÐбÑÑно ÑÑÑ ÑÑнкÑÐ¸Ñ Ð¸Ð½ÑеÑеÑÑÑÑ ÑолÑко полÑsk_strategyиsk_argumentв каждой запиÑи маÑÑива, в коÑоÑÑÑ Ð¾Ð¿ÑеделÑеÑÑÑ ÑооÑвеÑÑÑвенно индекÑиÑÑемÑй опеÑаÑÐ¾Ñ Ð¸ иÑкомое знаÑение. Ð ÑаÑÑноÑÑи, Ð½ÐµÑ Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾ÑÑи пÑовеÑÑÑÑsk_flags, ÑÑÐ¾Ð±Ñ ÑаÑпознаÑÑ NULL в иÑкомом знаÑении, Ñак как ÑдÑо SP-GiST оÑÑилÑÑÑÑÐµÑ Ñакие ÑÑловиÑ. ÐreconstructedValueпеÑедаÑÑÑÑ Ð·Ð½Ð°Ñение, воÑÑÑановленное Ð´Ð»Ñ ÑодиÑелÑÑкого коÑÑежа; ÑÑо Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ(Datum) 0на ÑÑовне коÑÐ½Ñ Ð¸Ð»Ð¸ еÑли ÑÑнкÑиÑinner_consistentне ÑÑÑановила знаÑение на пÑедÑдÑÑем ÑÑовне. ÐtraversalValueпеÑедаÑÑÑÑ ÑказаÑÐµÐ»Ñ Ð½Ð° пеÑÐµÑ Ð¾Ð´ÑÑие даннÑе, полÑÑеннÑе из пÑедÑдÑÑего вÑзоваinner_consistentÐ´Ð»Ñ ÑодиÑелÑÑкого коÑÑежа индекÑа, либо NULL на ÑÑовне коÑнÑ. ÐолеtraversalMemoryContextÑказÑÐ²Ð°ÐµÑ Ð½Ð° конÑекÑÑ Ð¿Ð°Ð¼ÑÑи, в коÑоÑом нÑжно ÑÐ¾Ñ ÑаниÑÑ Ð²ÑÑ Ð¾Ð´Ð½Ñе пеÑÐµÑ Ð¾Ð´ÑÑие даннÑе (Ñм. ниже). ÐlevelпеÑедаÑÑÑÑ ÑÑÐ¾Ð²ÐµÐ½Ñ ÑекÑÑего внÑÑÑеннего коÑÑежа (ÑÑÐ¾Ð²ÐµÐ½Ñ ÐºÐ¾ÑÐ½Ñ ÑÑиÑаеÑÑÑ Ð½ÑлевÑм). ФлагreturnDataÑÑÑанавливаеÑÑÑ, когда Ð´Ð»Ñ ÑÑого запÑоÑа нÑжно полÑÑиÑÑ Ð²Ð¾ÑÑÑановленнÑе даннÑе; ÑÑо возможно, ÑолÑко еÑли ÑÑнкÑиÑconfigÑÑÑановила пÑизнакcanReturnData. ÐÑизнакallTheSameÑÑÑанавливаеÑÑÑ, еÑли ÑекÑÑий внÑÑÑенний коÑÑеж Ð¸Ð¼ÐµÐµÑ Ð¿Ð¾Ð¼ÐµÑÐºÑ Â«Ð²Ñе-ÑавнÑ»; в ÑÑом ÑлÑÑае вÑе ÑÐ·Ð»Ñ Ð¸Ð¼ÐµÑÑ Ð¾Ð´Ð½Ñ Ð¼ÐµÑÐºÑ (еÑли имеÑÑ) и знаÑиÑ, либо вÑе они, либо никакой не ÑооÑвеÑÑÑвÑÐµÑ Ð·Ð°Ð¿ÑоÑÑ (Ñм. ÐодÑаздел 59.4.3). ÐÑизнакhasPrefixÑÑÑанавливаеÑÑÑ, еÑли ÑекÑÑий внÑÑÑенний коÑÑеж ÑодеÑÐ¶Ð¸Ñ Ð¿ÑеÑикÑ; в ÑÑом ÑлÑÑае вprefixDatumÐ½Ð°Ñ Ð¾Ð´Ð¸ÑÑÑ ÐµÐ³Ð¾ знаÑение. ÐnNodesзадаÑÑÑÑ ÑиÑло доÑеÑÐ½Ð¸Ñ Ñзлов, ÑодеÑжаÑÐ¸Ñ ÑÑ Ð²Ð¾ внÑÑÑеннем коÑÑеже, а вnodeLabelsâ маÑÑив Ð¸Ñ Ð¼ÐµÑок либо NULL, еÑли они не имеÑÑ Ð¼ÐµÑок.Ð
nNodesнÑжно запиÑаÑÑ ÑиÑло доÑеÑÐ½Ð¸Ñ Ñзлов, коÑоÑÑе поÑÑебÑеÑÑÑ Ð¿Ð¾ÑеÑиÑÑ Ð¿Ñи поиÑке, а вnodeNumbersâ маÑÑив Ð¸Ñ Ð¸Ð½Ð´ÐµÐºÑов. ÐÑли клаÑÑ Ð¾Ð¿ÐµÑаÑоÑов оÑÑÐ»ÐµÐ¶Ð¸Ð²Ð°ÐµÑ ÑÑовни, вlevelAddsнÑжно пеÑедаÑÑ Ð¼Ð°ÑÑив Ñ Ñагами ÑвелиÑÐµÐ½Ð¸Ñ ÑÑÐ¾Ð²Ð½Ñ Ð¿Ñи поÑеÑении каждого Ñзла. (ЧаÑÑо Ñаг бÑÐ´ÐµÑ Ð¾Ð´Ð½Ð¸Ð¼ Ð´Ð»Ñ Ð²ÑÐµÑ Ñзлов, но Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¸ по-дÑÑгомÑ, поÑÑÐ¾Ð¼Ñ Ð¿ÑименÑеÑÑÑ Ð¼Ð°ÑÑив.) ÐÑли поÑÑебовалоÑÑ Ð²Ð¾ÑÑÑановиÑÑ Ð·Ð½Ð°ÑениÑ, помеÑÑиÑе вreconstructedValuesÑказаÑÐµÐ»Ñ Ð½Ð° маÑÑив знаÑений, воÑÑÑановленнÑÑ Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ доÑеÑнего Ñзла, коÑоÑÑй нÑжно поÑеÑиÑÑ; в пÑоÑивном ÑлÑÑае оÑÑавÑÑеreconstructedValuesÑавнÑм NULL. ÐÑли желаÑелÑно пеÑедаÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑнÑе даннÑе («пеÑÐµÑ Ð¾Ð´ÑÑие знаÑениÑ») на нижние ÑÑовни пÑи поиÑке по деÑевÑ, помеÑÑиÑе вtraversalValuesÑказаÑÐµÐ»Ñ Ð½Ð° маÑÑив ÑооÑвеÑÑÑвÑÑÑÐ¸Ñ Ð¿ÐµÑÐµÑ Ð¾Ð´ÑÑÐ¸Ñ Ð·Ð½Ð°Ñений, по Ð¾Ð´Ð½Ð¾Ð¼Ñ Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ доÑеÑнего Ñзла, коÑоÑÑй нÑжно поÑеÑиÑÑ; в пÑоÑивном ÑлÑÑае оÑÑавÑÑе вtraversalValuesзнаÑение NULL. ÐамеÑÑÑе, ÑÑо ÑÑнкÑиÑinner_consistentÑама должна вÑделÑÑÑ Ð¿Ð°Ð¼ÑÑÑ, иÑполÑзÑÑ palloc, Ð´Ð»Ñ Ð¼Ð°ÑÑивовnodeNumbers,levelAdds,distances,reconstructedValuesиtraversalValuesв ÑекÑÑем конÑекÑÑе памÑÑи. Ðднако вÑÑ Ð¾Ð´Ð½Ñе пеÑÐµÑ Ð¾Ð´ÑÑие знаÑениÑ, на коÑоÑÑе ÑказÑÐ²Ð°ÐµÑ Ð¼Ð°ÑÑивtraversalValues, Ð´Ð¾Ð»Ð¶Ð½Ñ ÑазмеÑаÑÑÑÑ Ð² конÑекÑÑеtraversalMemoryContext. ÐÑи ÑÑом каждое пеÑÐµÑ Ð¾Ð´ÑÑее знаÑÐµÐ½Ð¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ð¾ ÑаÑполагаÑÑÑÑ Ð² оÑделÑном блоке памÑÑи palloc.leaf_consistentÐозвÑаÑÐ°ÐµÑ true, еÑли коÑÑеж лиÑÑа ÑдовлеÑвоÑÑÐµÑ Ð·Ð°Ð¿ÑоÑÑ.
Ð SQL ÑÑа ÑÑнкÑÐ¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° обÑÑвлÑÑÑÑÑ Ñак:
CREATE FUNCTION my_leaf_consistent(internal, internal) RETURNS bool ...
РпеÑвом аÑгÑменÑе пеÑедаÑÑÑÑ ÑказаÑÐµÐ»Ñ Ð½Ð° ÑÑÑÑкÑÑÑÑ
spgLeafConsistentInÑзÑка C, ÑодеÑжаÑÑÑ Ð²Ñ Ð¾Ð´Ð½Ñе даннÑе Ð´Ð»Ñ ÑÑнкÑии. Ðо вÑоÑом аÑгÑменÑе пеÑедаÑÑÑÑ ÑказаÑÐµÐ»Ñ Ð½Ð° ÑÑÑÑкÑÑÑÑspgLeafConsistentOutÑзÑка C, в коÑоÑÑÑ ÑÑнкÑÐ¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° помеÑÑиÑÑ ÑезÑлÑÑаÑ.typedef struct spgLeafConsistentIn { ScanKey scankeys; /* маÑÑив опеÑаÑоÑов и иÑкомÑÑ Ð·Ð½Ð°Ñений */ int nkeys; /* длина маÑÑива */ Datum reconstructedValue; /* знаÑение, воÑÑÑановленное Ð´Ð»Ñ ÑодиÑÐµÐ»Ñ */ void *traversalValue; /* пеÑÐµÑ Ð¾Ð´ÑÑее знаÑение, ÑпеÑиÑиÑное Ð´Ð»Ñ ÐºÐ»Ð°ÑÑа опеÑаÑоÑов */ int level; /* ÑекÑÑий ÑÑÐ¾Ð²ÐµÐ½Ñ (оÑÑÑиÑÑÐ²Ð°Ñ Ð¾Ñ Ð½ÑлÑ) */ bool returnData; /* нÑжно ли возвÑаÑаÑÑ Ð¸ÑÑ Ð¾Ð´Ð½Ñе даннÑе? */ Datum leafDatum; /* знаÑение в коÑÑеже лиÑÑа */ } spgLeafConsistentIn; typedef struct spgLeafConsistentOut { Datum leafValue; /* воÑÑÑановленнÑе иÑÑ Ð¾Ð´Ð½Ñе даннÑе, пÑи налиÑии */ bool recheck; /* true, еÑли опеÑаÑÐ¾Ñ Ð½Ñжно пеÑепÑовеÑиÑÑ */ } spgLeafConsistentOut;ÐаÑÑив
scankeysдлинÑnkeysопиÑÑÐ²Ð°ÐµÑ ÑÑÐ»Ð¾Ð²Ð¸Ñ Ð¿Ð¾Ð¸Ñка по индекÑÑ. ÐÑи ÑÑÐ»Ð¾Ð²Ð¸Ñ Ð¾Ð±ÑединÑÑÑÑÑ Ð¾Ð¿ÐµÑаÑией Ð â запÑоÑÑ ÑдовлеÑвоÑÑÑÑ ÑолÑко Ñе запиÑи в индекÑе, коÑоÑÑе ÑдовлеÑвоÑÑÑÑ Ð²Ñем ÑÑим ÑÑловиÑм. (ÐамеÑÑÑе, ÑÑо Ñnkeys= 0 подÑазÑмеваеÑÑÑ, ÑÑо запÑоÑÑ ÑдовлеÑвоÑÑÑÑ Ð²Ñе запиÑи в индекÑе.) ÐбÑÑно ÑÑÑ ÑÑнкÑÐ¸Ñ Ð¸Ð½ÑеÑеÑÑÑÑ ÑолÑко полÑsk_strategyиsk_argumentв каждой запиÑи маÑÑива, в коÑоÑÑÑ Ð¾Ð¿ÑеделÑÑÑÑÑ ÑооÑвеÑÑÑвенно индекÑиÑÑемÑй опеÑаÑÐ¾Ñ Ð¸ иÑкомое знаÑение. Ð ÑаÑÑноÑÑи, Ð½ÐµÑ Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾ÑÑи пÑовеÑÑÑÑsk_flags, ÑÑÐ¾Ð±Ñ ÑаÑпознаÑÑ NULL в иÑкомом знаÑении, Ñак как ÑдÑо SP-GiST оÑÑилÑÑÑÑÐµÑ Ñакие ÑÑловиÑ. ÐreconstructedValueпеÑедаÑÑÑÑ Ð·Ð½Ð°Ñение, воÑÑÑановленное Ð´Ð»Ñ ÑодиÑелÑÑкого коÑÑежа; ÑÑо Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ(Datum) 0на ÑÑовне коÑÐ½Ñ Ð¸Ð»Ð¸ еÑли ÑÑнкÑиÑinner_consistentне ÑÑÑановила знаÑение на пÑедÑдÑÑем ÑÑовне. ÐtraversalValueпеÑедаÑÑÑÑ ÑказаÑÐµÐ»Ñ Ð½Ð° пеÑÐµÑ Ð¾Ð´ÑÑие даннÑе, полÑÑеннÑе из пÑедÑдÑÑего вÑзоваinner_consistentÐ´Ð»Ñ ÑодиÑелÑÑкого коÑÑежа индекÑа, либо NULL на ÑÑовне коÑнÑ. ÐlevelпеÑедаÑÑÑÑ ÑÑÐ¾Ð²ÐµÐ½Ñ ÑекÑÑего внÑÑÑеннего коÑÑежа (ÑÑÐ¾Ð²ÐµÐ½Ñ ÐºÐ¾ÑÐ½Ñ ÑÑиÑаеÑÑÑ Ð½ÑлевÑм). ФлагreturnDataÑÑÑанавливаеÑÑÑ, когда Ð´Ð»Ñ ÑÑого запÑоÑа нÑжно полÑÑиÑÑ Ð²Ð¾ÑÑÑановленнÑе даннÑе; ÑÑо возможно, ÑолÑко еÑли ÑÑнкÑиÑconfigÑÑÑановила пÑизнакcanReturnData. ÐleafDatumпеÑедаÑÑÑÑ Ð·Ð½Ð°Ñение клÑÑа, запиÑанное в ÑекÑÑем коÑÑеже лиÑÑа.ÐÑа ÑÑнкÑÐ¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° веÑнÑÑÑ
true, еÑли коÑÑеж лиÑÑа ÑооÑвеÑÑÑвÑÐµÑ Ð·Ð°Ð¿ÑоÑÑ, илиfalseв пÑоÑивном ÑлÑÑае. Ð ÑлÑÑае положиÑелÑного ÑезÑлÑÑаÑа, еÑли в полеreturnDataпеÑеданоtrue, нÑжно помеÑÑиÑÑ Ð²leafValueзнаÑение, изнаÑалÑно пеÑеданное Ð´Ð»Ñ Ð¸Ð½Ð´ÐµÐºÑаÑии в ÑÑÐ¾Ñ ÐºÐ¾ÑÑеж. ÐÑоме Ñого, ÑлагÑrecheckможно пÑиÑвоиÑÑtrue, еÑли ÑооÑвеÑÑÑвие неÑоÑное, Ñак ÑÑо Ð´Ð»Ñ ÑÑÑÐ°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ ÑоÑного ÑезÑлÑÑаÑа пÑовеÑки нÑжно повÑоÑно пÑимениÑÑ Ð¾Ð¿ÐµÑаÑоÑ(Ñ) к акÑÑалÑÐ½Ð¾Ð¼Ñ ÐºÐ¾ÑÑÐµÐ¶Ñ Ð´Ð°Ð½Ð½ÑÑ .
ÐÑе опоÑнÑе меÑÐ¾Ð´Ñ SP-GiST обÑÑно вÑзÑваÑÑÑÑ Ð² кÑаÑковÑеменнÑÑ
конÑекÑÑаÑ
памÑÑи; Ñо еÑÑÑ CurrentMemoryContext ÑбÑаÑÑваеÑÑÑ Ð¿Ð¾Ñле обÑабоÑки каждого коÑÑежа. Таким обÑазом, можно не забоÑиÑÑÑÑ Ð¾Ð± оÑвобождении лÑбÑÑ
блоков памÑÑи, вÑделеннÑÑ
ÑÑнкÑией palloc. (ÐеÑод config ÑвлÑеÑÑÑ Ð¸ÑклÑÑением: в нÑм нÑжно не допÑÑкаÑÑ ÑÑеÑек памÑÑи. Ðо обÑÑно меÑод config не Ð´ÐµÐ»Ð°ÐµÑ Ð½Ð¸Ñего, кÑоме как пÑиÑÐ²Ð°Ð¸Ð²Ð°ÐµÑ ÐºÐ¾Ð½ÑÑанÑÑ Ð¿ÐµÑеданной ÑÑÑÑкÑÑÑе паÑамеÑÑов.)
ÐÑли индекÑиÑÑемÑй ÑÑÐ¾Ð»Ð±ÐµÑ Ð¸Ð¼ÐµÐµÑ ÑоÑÑиÑÑемÑй Ñип даннÑÑ
, пÑавило ÑоÑÑиÑовки индекÑа бÑÐ´ÐµÑ Ð¿ÐµÑедаваÑÑÑÑ Ð²Ñем опоÑнÑм меÑодам, иÑполÑзÑÑ ÑÑандаÑÑнÑй меÑ
анизм PG_GET_COLLATION().