59.3. ÐпоÑнÑе ÑÑнкÑии B-деÑевÑев
Ðак показано в ТаблиÑе 36.8, btree опÑеделÑÐµÑ Ð¾Ð´Ð½Ñ Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼ÑÑ Ð¸ две необÑзаÑелÑнÑÑ Ð¾Ð¿Ð¾ÑнÑÑ ÑÑнкÑии.
ÐÐ»Ñ Ð²ÑеÑ
комбинаÑий Ñипов даннÑÑ
, Ð´Ð»Ñ ÐºÐ¾ÑоÑÑÑ
ÑемейÑÑво опеÑаÑоÑов btree пÑедоÑÑавлÑÐµÑ Ð¾Ð¿ÐµÑаÑоÑÑ ÑÑавнениÑ, оно должно пÑедоÑÑавлÑÑÑ Ð¾Ð¿Ð¾ÑнÑÑ ÑÑнкÑÐ¸Ñ ÑÑÐ°Ð²Ð½ÐµÐ½Ð¸Ñ Ð² pg_amproc Ñ Ð½Ð¾Ð¼ÐµÑом 1 и c amproclefttype/amprocrighttype, ÑавнÑми Ð»ÐµÐ²Ð¾Ð¼Ñ Ð¸ пÑÐ°Ð²Ð¾Ð¼Ñ ÑÐ¸Ð¿Ñ ÑÑÐ°Ð²Ð½ÐµÐ½Ð¸Ñ (Ñо еÑÑÑ Ñем же Ñипам даннÑÑ
, Ñ ÐºÐ¾ÑоÑÑми ÑооÑвеÑÑÑвÑÑÑие опеÑаÑоÑÑ Ð·Ð°ÑегиÑÑÑиÑÐ¾Ð²Ð°Ð½Ñ Ð² pg_amop). ÐÑа ÑÑнкÑÐ¸Ñ ÑÑÐ°Ð²Ð½ÐµÐ½Ð¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° пÑинимаÑÑ Ð´Ð²Ð° оÑлиÑнÑÑ
Ð¾Ñ NULL знаÑÐµÐ½Ð¸Ñ A и B и возвÑаÑаÑÑ Ð·Ð½Ð°Ñение int32, коÑоÑое бÑÐ´ÐµÑ < 0, 0 или > 0, когда A < B, A = B или A > B, ÑооÑвеÑÑÑвенно. РезÑлÑÑÐ°Ñ NULL не допÑÑкаеÑÑÑ: вÑе знаÑÐµÐ½Ð¸Ñ Ñипа даннÑÑ
Ð´Ð¾Ð»Ð¶Ð½Ñ Ð±ÑÑÑ ÑÑавнимÑми.
ÐÑли ÑÑавниваемÑе знаÑÐµÐ½Ð¸Ñ Ð¸Ð¼ÐµÑÑ ÑоÑÑиÑÑемÑй Ñип даннÑÑ
, опоÑной ÑÑнкÑии ÑÑÐ°Ð²Ð½ÐµÐ½Ð¸Ñ Ð±ÑÐ´ÐµÑ Ð¿ÐµÑедан OID ÑооÑвеÑÑÑвÑÑÑего пÑавила ÑоÑÑиÑовки ÑеÑез ÑÑандаÑÑнÑй меÑ
анизм PG_GET_COLLATION().
ÐополниÑелÑно ÑемейÑÑво опеÑаÑоÑов btree Ð¼Ð¾Ð¶ÐµÑ Ð¿ÑедоÑÑавиÑÑ ÑÑнкÑии поддеÑжки ÑоÑÑиÑовки, коÑоÑÑе ÑегиÑÑÑиÑÑÑÑÑÑ Ð¿Ð¾Ð´ номеÑом опоÑной ÑÑнкÑии 2. ÐÑи ÑÑнкÑии позволÑÑÑ ÑеализовÑваÑÑ ÑÑÐ°Ð²Ð½ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ñелей ÑоÑÑиÑовки гоÑаздо ÑÑÑекÑивнее, Ñем ÑÑо возможно пÑи пÑÑмолинейном вÑзове ÑÑнкÑии поддеÑжки ÑÑавнениÑ. ÐадейÑÑвованнÑе в ÑÑом пÑогÑаммнÑе инÑеÑÑейÑÑ Ð¾Ð¿ÑÐµÐ´ÐµÐ»ÐµÐ½Ñ Ð² src/include/utils/sortsupport.h.
ÐополниÑелÑно ÑемейÑÑво опеÑаÑоÑов btree Ð¼Ð¾Ð¶ÐµÑ Ð¿ÑедоÑÑавиÑÑ Ð¾Ð¿Ð¾ÑнÑе ÑÑнкÑии in_range, коÑоÑÑе ÑегиÑÑÑиÑÑÑÑÑÑ Ð¿Ð¾Ð´ номеÑом 3. Ðни не иÑполÑзÑÑÑÑÑ Ð² Ñ
оде опеÑаÑий Ñ Ð¸Ð½Ð´ÐµÐºÑом btree; вмеÑÑо ÑÑого они ÑаÑÑиÑÑÑÑ ÑеманÑÐ¸ÐºÑ ÑемейÑÑва опеÑаÑоÑов, ÑÑÐ¾Ð±Ñ Ð¾Ð½Ð¾ могло поддеÑживаÑÑ Ð¾ÐºÐ¾Ð½Ð½Ñе пÑÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ RANGE ÑмеÑение PRECEDING и RANGE ÑмеÑение FOLLOWING (Ñм. ÐодÑаздел 4.2.8). Ðо ÑÑÑи они пÑедоÑÑавлÑÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑнÑÑ Ð¸Ð½ÑоÑмаÑиÑ, позволÑÑÑÑÑ Ð´Ð¾Ð±Ð°Ð²Ð»ÑÑÑ Ð¸Ð»Ð¸ вÑÑиÑаÑÑ ÑмеÑение в ÑооÑвеÑÑÑвии Ñ Ð¿Ð¾ÑÑдком ÑоÑÑиÑовки, пÑинÑÑÑм в ÑемейÑÑве.
ФÑнкÑÐ¸Ñ in_range должна имеÑÑ ÑигнаÑÑÑÑ
in_range(знаÑениеtype1,базаtype1,ÑмеÑениеtype2,вÑÑиÑаниеbool,менÑÑеbool) returns bool
ÐнаÑение и база Ð´Ð¾Ð»Ð¶Ð½Ñ Ð±ÑÑÑ Ð¾Ð´Ð½Ð¾Ð³Ð¾ Ñипа даннÑÑ
, и ÑÑÐ¾Ñ Ñип должен поддеÑживаÑÑÑÑ ÑемейÑÑвом опеÑаÑоÑов (Ñо еÑÑÑ ÑÑо должен бÑÑÑ Ñип, Ð´Ð»Ñ ÐºÐ¾ÑоÑого ÑеализÑеÑÑÑ ÑоÑÑиÑовка). Ðднако ÑмеÑение Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð´ÑÑгого Ñипа, коÑоÑÑй никаким дÑÑгим обÑазом не поддеÑживаеÑÑÑ Ð´Ð°Ð½Ð½Ñм ÑемейÑÑвом. ÐапÑимеÑ, вÑÑÑоенное ÑемейÑÑво time_ops пÑедоÑÑавлÑÐµÑ ÑÑнкÑиÑ, Ð´Ð»Ñ ÐºÐ¾ÑоÑой ÑмеÑение Ð¸Ð¼ÐµÐµÑ Ñип interval. СемейÑÑво Ð¼Ð¾Ð¶ÐµÑ Ð¿ÑедоÑÑавлÑÑÑ ÑÑнкÑии in_range Ð´Ð»Ñ Ð»ÑбÑÑ
из ÑвоиÑ
поддеÑживаемÑÑ
Ñипов и одного или неÑколÑкиÑ
Ñипов ÑмеÑений. ÐÐ°Ð¶Ð´Ð°Ñ ÑÑнкÑÐ¸Ñ in_range должна ÑегиÑÑÑиÑоваÑÑÑÑ Ð² pg_amproc Ñ Ð¿Ð¾Ð»ÐµÐ¼ amproclefttype, ÑавнÑм type1, и amprocrighttype, ÑавнÑм type2.
СÑÑÑ Ð´ÐµÐ¹ÑÑÐ²Ð¸Ñ ÑÑнкÑии in_range завиÑÐ¸Ñ Ð¾Ñ Ð´Ð²ÑÑ
логиÑеÑкиÑ
Ñлагов. Ðна должна пÑибавиÑÑ Ð¸Ð»Ð¸ вÑÑеÑÑÑ Ð¸Ð· Ð±Ð°Ð·Ñ ÑмеÑение, а заÑем ÑÑавниÑÑ Ð·Ð½Ð°Ñение Ñ ÑезÑлÑÑаÑом ÑледÑÑÑим обÑазом:
еÑли
!вÑÑиÑаниеи!менÑÑе, возвÑаÑаеÑÑÑзнаÑение>=(база+ÑмеÑение)еÑли
!вÑÑиÑаниеименÑÑе, возвÑаÑаеÑÑÑзнаÑение<=(база+ÑмеÑение)еÑли
вÑÑиÑаниеи!менÑÑе, возвÑаÑаеÑÑÑзнаÑение>=(база-ÑмеÑение)еÑли
вÑÑиÑаниеименÑÑе, возвÑаÑаеÑÑÑзнаÑение<=(база-ÑмеÑение)
ÐÑежде Ñем делаÑÑ ÑÑо, ÑÑнкÑÐ¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° пÑовеÑиÑÑ Ð·Ð½Ð°Ðº ÑмеÑÐµÐ½Ð¸Ñ Ð¸, еÑли оно оÑÑиÑаÑелÑное, вÑдаÑÑ Ð¾ÑÐ¸Ð±ÐºÑ ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE (22013) Ñ ÑекÑÑом оÑибки «invalid preceding or following size in window function» (невеÑÐ½Ð°Ñ Ð¿ÑедÑеÑÑвÑÑÑÐ°Ñ Ð¸Ð»Ð¸ поÑледÑÑÑÐ°Ñ Ð²ÐµÐ»Ð¸Ñина в оконной ÑÑнкÑии). (ÐÑо ÑÑебÑеÑÑÑ ÑÑандаÑÑом SQL, но неÑÑандаÑÑнÑе ÑемейÑÑва опеÑаÑоÑов могÑÑ Ð¿ÑоигноÑиÑоваÑÑ Ð´Ð°Ð½Ð½Ð¾Ðµ огÑаниÑение, Ñак как оно не неÑÑÑ Ð±Ð¾Ð»ÑÑой ÑмÑÑловой нагÑÑзки.) ÐÑовеÑка ÑÑого ÑÑÐµÐ±Ð¾Ð²Ð°Ð½Ð¸Ñ Ð´ÐµÐ»ÐµÐ³Ð¸ÑÑеÑÑÑ ÑÑнкÑии in_range, ÑÑÐ¾Ð±Ñ ÐºÐ¾Ð´Ñ ÑдÑа не ÑÑебовалоÑÑ Ð¿Ð¾Ð½Ð¸Ð¼Ð°ÑÑ, ÑÑо ознаÑÐ°ÐµÑ Â«Ð¼ÐµÐ½ÑÑе нÑлÑ» Ð´Ð»Ñ Ð¿ÑоизволÑного Ñипа даннÑÑ
.
ÐÑоме Ñого, ÑÑнкÑии in_range, еÑли ÑÑо пÑакÑиÑно, могÑÑ Ð½Ðµ вÑдаваÑÑ Ð¾ÑибкÑ, когда опеÑаÑÐ¸Ñ Ð±Ð°Ð·Ð° + ÑмеÑение или база - ÑмеÑение пÑÐ¸Ð²Ð¾Ð´Ð¸Ñ Ðº пеÑеполнениÑ. ÐÑавилÑнÑй ÑезÑлÑÑÐ°Ñ ÑÑÐ°Ð²Ð½ÐµÐ½Ð¸Ñ Ð¼Ð¾Ð¶Ð½Ð¾ полÑÑиÑÑ, даже еÑли ÑÑо знаÑение вÑÑ
Ð¾Ð´Ð¸Ñ Ð·Ð° гÑаниÑÑ Ð´Ð¾Ð¿ÑÑÑимого диапазона ÑÑого Ñипа даннÑÑ
. ÐамеÑÑÑе, ÑÑо еÑли Ð´Ð»Ñ Ñипа даннÑÑ
опÑÐµÐ´ÐµÐ»ÐµÐ½Ñ Ñакие понÑÑиÑ, как «беÑконеÑноÑÑÑ» и «NaN», могÑÑ Ð¿Ð¾ÑÑебоваÑÑÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑнÑе меÑÑ Ð´Ð»Ñ Ð¾Ð±ÐµÑпеÑÐµÐ½Ð¸Ñ ÑоглаÑованноÑÑи ÑезÑлÑÑаÑов in_range Ñ Ð¾Ð±ÑÑнÑм поÑÑдком ÑоÑÑиÑовки данного ÑемейÑÑва опеÑаÑоÑов.
РезÑлÑÑаÑÑ ÑÑнкÑии in_range Ð´Ð¾Ð»Ð¶Ð½Ñ ÑооÑвеÑÑÑвоваÑÑ Ð¿Ð¾ÑÑÐ´ÐºÑ ÑоÑÑиÑовки, ÑÑÑÐ°Ð½Ð°Ð²Ð»Ð¸Ð²Ð°ÐµÐ¼Ð¾Ð¼Ñ ÑемейÑÑвом опеÑаÑоÑов. ТоÑнее говоÑÑ, пÑи лÑбÑÑ
ÑикÑиÑованнÑÑ
аÑгÑменÑаÑ
ÑмеÑение и вÑÑиÑание ÑпÑаведливо:
ÐÑли
in_rangeÑменÑÑе= true возвÑаÑÐ°ÐµÑ true Ð´Ð»Ñ Ð½ÐµÐºÐ¾ÑоÑогознаÑениÑ1ибазÑ, true должно возвÑаÑаÑÑÑÑ Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾Ð·Ð½Ð°ÑениÑ2<=знаÑениÑ1Ñ Ñой жебазой.ÐÑли
in_rangeÑменÑÑе= true возвÑаÑÐ°ÐµÑ false Ð´Ð»Ñ Ð½ÐµÐºÐ¾ÑоÑогознаÑениÑ1ибазÑ, false должно возвÑаÑаÑÑÑÑ Ð´Ð»Ñ Ð»ÑбогознаÑениÑ2>=знаÑениÑ1Ñ Ñой жебазой.ÐÑли
in_rangeÑменÑÑе= true возвÑаÑÐ°ÐµÑ true Ð´Ð»Ñ Ð½ÐµÐºÐ¾ÑоÑогознаÑениÑибазÑ1, true должно возвÑаÑаÑÑÑÑ Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð¹Ð±Ð°Ð·Ñ2>=базе1Ñ Ñем жезнаÑением.ÐÑли
in_rangeÑменÑÑе= true возвÑаÑÐ°ÐµÑ false Ð´Ð»Ñ Ð½ÐµÐºÐ¾ÑоÑогознаÑениÑибазÑ1, false должно возвÑаÑаÑÑÑÑ Ð´Ð»Ñ Ð»ÑбойбазÑ2<=базе1Ñ Ñем жезнаÑением.
ÐналогиÑнÑе ÑÑвеÑÐ¶Ð´ÐµÐ½Ð¸Ñ Ñ Ð¿ÑоÑивоположнÑми ÑÑловиÑми Ð´Ð¾Ð»Ð¶Ð½Ñ Ð²ÑполнÑÑÑÑÑ Ð¿Ñи менÑÑе = false.
ÐÑли ÑпоÑÑдоÑиваемÑй Ñип (type1) ÑвлÑеÑÑÑ ÑоÑÑиÑÑемÑм, ÑÑнкÑии in_range бÑÐ´ÐµÑ Ð¿ÐµÑедан OID ÑооÑвеÑÑÑвÑÑÑего пÑавила ÑоÑÑиÑовки ÑеÑез ÑÑандаÑÑнÑй меÑ
анизм PG_GET_COLLATION().
ФÑнкÑии in_range не Ð´Ð¾Ð»Ð¶Ð½Ñ Ð¾Ð±ÑабаÑÑваÑÑ NULL в аÑгÑменÑаÑ
и обÑÑно помеÑаÑÑÑÑ ÐºÐ°Ðº ÑÑÑогие.