ينشئ معالج HTTP مخصصًا مُعرّفًا باستخدام SQL، دون تحرير ملف تهيئة الخادم. تُعد المعالجات المُعرّفة باستخدام SQL بديلًا عن معالجات واجهة HTTP المستندة إلى التهيئة.
ينشئ معالجًا بالـ name المحدد. يُستخدم الاسم لإدارة المعالجات باستخدام استعلامات SQL، وفي الرسائل التشخيصية، ولترتيب المعالجات.
PROTOCOL — اختياري. إذا حُدِّد اسم بروتوكول، فلن يكون المعالج نشطًا إلا للبروتوكول القابل للتركيب المحدد. وإلا، يكون المعالج نشطًا على جميع نقاط نهاية HTTP: منافذ http/https المضمّنة وكل مستمع بروتوكول قابل للتركيب من نوع HTTP. يختار PROTOCOL ANY صراحةً هذا السلوك الافتراضي الأخير؛ وفي ALTER HANDLER يزيل تقييد بروتوكول تم تعيينه سابقًا. يمكن الإشارة إلى بروتوكول يحمل الاسم الحرفي any باستخدام علامات الاقتباس الخلفية: PROTOCOL `any` .
URL — إلزامي. يمكن أن يكون URL مطابقًا تمامًا، أو URL PREFIX، أو URL REGEXP. بالنسبة إلى عناوين URL المطابقة تمامًا والبادئات، يُتحقق من عدم الالتباس عند الإنشاء أو التعديل، ويُرفع استثناء عند وجود التباس. أما بالنسبة إلى regexp، فلا يمكن التحقق من الالتباس. تجري مطابقة URL دون سلسلة الاستعلام ? ومُعرّف الجزء #. تُطابق URL PREFIX كمسار أساسي عند حدّ مقطع مسار، وبنفس دلالات قاعدة url_prefix الخاصة بـالمعالجات المحددة في التهيئة: يطابق URL PREFIX '/api/v1' كلاً من /api/v1 و/api/v1/ و/api/v1/write، ولكن ليس /api/v1beta. تُتجاهل الشرطة المائلة الختامية / في البادئة، لذا يتصرف '/api/v1/' و'/api/v1' بالطريقة نفسها.
METHODS — اختياري. قائمة طرق HTTP المسموح بها. افتراضيًا، تكون الطريقة الوحيدة هي GET. الطرق المدعومة هي GET وPOST وPUT وDELETE. يُسمح للطرق المُعدِّلة POST وPUT وDELETE بتشغيل استعلامات تعدّل البيانات، بينما تُنفذ الطرق الآمنة مثل GET وHEAD دائمًا في وضع readonly. لذلك، يجب أن يسمح المعالج الذي ينفذ استعلامًا يغيّر البيانات، مثل INSERT أو DDL، بطريقة مُعدِّلة واحدة على الأقل؛ إذ إن إنشاء معالج كهذا باستخدام طرق للقراءة فقط، مثل GET الافتراضية، يرفع استثناءً. تُعد الاستعلامات التي تستمر آثارها الجانبية رغم وضع readonly حالة خاصة: فلـBACKUP وRESTORE آثار جانبية دائمة، وتغيّر العبارات المعدِّلة للجلسة SET وSET ROLE وUSE وBEGIN TRANSACTION وCOMMIT وROLLBACK وSET TRANSACTION SNAPSHOT حالة الجلسة أو المعاملة التي تستمر عبر الطلبات عند استخدام session_id، كما ينشئ CREATE TEMPORARY TABLE / CREATE TEMPORARY VIEW كائنًا يعيش ضمن الجلسة؛ ومع ذلك، لا يحظر وضع readonly للطرق الآمنة أيًا منها. كذلك لا يحظر وضع readonly تعديلات جدول مؤقت موجود، لذا تُعامل الاستعلامات التي قد تستهدف جدولًا كهذا بالطريقة نفسها: INSERT الذي لا يكون جدول الهدف فيه مؤهلاً باسم قاعدة بيانات (إذ قد يُحل الاسم غير المؤهل إلى جدول مؤقت للجلسة)، وDROP TEMPORARY TABLE، وDROP TABLE / TRUNCATE TABLE لجدول غير مؤهل باسم قاعدة بيانات، وALTER لجدول غير مؤهل باسم قاعدة بيانات (ALTER TEMPORARY TABLE هي العبارة نفسها). لا يمكن أبدًا أن يكون الهدف المؤهل باسم قاعدة بيانات جدولًا مؤقتًا، لذا لا تخضع هذه الاستعلامات لهذه القاعدة. يتطلب HTTP أن تكون الطرق الآمنة خالية من الآثار الجانبية (يُخدَم المعالج المعلن لـGET أيضًا لطلب HEAD، حيث يُحجب جسم الاستجابة ويكون الأثر غير مرئي). لذلك، يجب أن يسرد المعالج الذي ينفذ استعلامًا كهذا الطرق المُعدِّلة فقط؛ إذ إن إنشاؤه أو تعديله ليشمل طريقة آمنة يرفع استثناءً. تُفحَص العبارات المركبة من الداخل: بالنسبة إلى statement1 PARALLEL WITH statement2 ... وEXECUTE AS <user> <statement>، تنطبق القواعد أعلاه على العبارات المضمّنة، لأنها هي التي تُنفذ (كل منها ضمن نسخة من سياق المعالج، تحتفظ بوضع readonly). يجعل EXECUTE AS <user> المجرد الجلسة بأكملها تعمل كمستخدم آخر، لذا يُعدّ في حد ذاته معدِّلًا للجلسة. بالإضافة إلى ذلك، يجب أن يسمح أي معالج EXECUTE AS، سواء كان مجردًا أو يغلّف عبارة، بطريقة مُعدِّلة واحدة على الأقل: إذ يتطلب انتحال الهوية امتياز IMPERSONATE، الذي يمنعه وضع readonly للطرق الآمنة.
TYPE — اختياري. النوع الوحيد المدعوم حاليًا هو query.
AS — استعلام SQL الذي سيشغّله هذا المعالج. يمكن أن يتضمن الاستعلام معاملات. يُحلَّل الاستعلام للتحقق من صحته النحوية عند إنشاء المعالج أو تعديله، لكنه لا يخضع للتحليل الدلالي؛ فعلى سبيل المثال، قد لا تكون الجداول التي يشير إليها الاستعلام موجودة عند إنشاء المعالج. ينتمي البند FORMAT والبنود المشابهة إلى الاستعلام، لا إلى عبارة CREATE/ALTER بأكملها. ويمكن وضع الاستعلام بين قوسين لإزالة الالتباس. يجب ألا يحتوي استعلام INSERT على بيانات مضمنة بعد البند VALUES أو FORMAT؛ إذ يؤدي إنشاء مثل هذا المعالج أو تعديله إلى إطلاق استثناء، لأن الحمولة المضمنة لا يمكن حفظها في تعريف المعالج. ويُتوقع توفير البيانات في جسم طلب HTTP، أو احتسابها بواسطة INSERT ... SELECT. يجب أن يحدد الطلب الموجّه إلى معالج يقرأ استعلامه جسم الطلب — أي INSERT يأخذ بياناته من الجسم، أو استعلام يستخدم المعامل _request_body — طوله: يُرد على طلب غير مُجزّأ لا يحتوي على رأس Content-Length بالرمز 411 Length Required، إذ سيُقرأ الجسم لولا ذلك حتى نهاية الدفق، وسيُعامل الاتصال المنقطع على أنه طلب مكتمل. ويجب أيضًا أن تكون كل طريقة لمثل هذا المعالج حاملة لجسم طلب (POST أو PUT أو DELETE)؛ إذ يؤدي إنشاؤه باستخدام طريقة آمنة في البند METHODS، مثل GET الافتراضية، إلى إطلاق استثناء، لأن الطريقة الآمنة لا تتضمن أبدًا جسم طلب، وسيقرأ الاستعلام جسمًا فارغًا دون تنبيه. كما أن GET المُعلنة تُخدَم كذلك لطلبات HEAD، لذا فإن مزج الطرق الآمنة مع الطرق الحاملة للجسم سيُبقي تلك الاستدعاءات قابلة للوصول. لا يقرأ INSERT ... SELECT جسم الطلب، إذ تأتي بياناته من SELECT، ولذلك لا تنطبق عليه هذه المتطلبات، إلا إذا كان SELECT الخاص به يقرأ من دالة الجدول input التي تُغذّى من جسم الطلب. يجب أن يكون استعلام INSERT الذي يقرأ الجسم هو استعلام المعالج نفسه: تشغّل EXECUTE AS وPARALLEL WITH العبارات التي تغلفانها دون جسم الطلب، لذا يُرفض تغليف استعلام بها عند الإنشاء بدلًا من تجاهل كل عملية رفع بصمت. كذلك، يجب ألا يستخدم الاستعلام الذي يقرأ الجسم المعامل _request_body: فهناك جسم طلب واحد، وربط _request_body يستهلكه قبل أن يقرأ الاستعلام بيانات الإدخال، لذا يُرفض مثل هذا المعالج عند الإنشاء بدلًا من فقدان كل عملية رفع بصمت — استخدم إما إدخال الجسم الخاص بالاستعلام أو _request_body، وليس كليهما. لا تنطبق هذه المتطلبات على المعالجات التي لا تقرأ الجسم؛ إذ يُتجاهل جسم الطلب الموجّه إليها ولا يُلحق أبدًا باستعلام المعالج. يُعاد تحليل نص الاستعلام المخزن بواسطة الخادم بعمق محلل وتراجعات غير محدودة كلما أُعيد تحميل المعالج أو استدعاؤه، لذا يظل المعالج الذي أُنشئ ضمن جلسة رُفعت فيها قيمتا max_parser_depth / max_parser_backtracks قابلًا للتحميل والاستدعاء ضمن حدود الجلسة العادية.
تكون للمعالجات المعرَّفة في تهيئة الخادم أولوية على المعالجات المعرَّفة في SQL. وتُطابَق المعالجات المعرَّفة في SQL بالترتيب المعجمي لأسمائها.
تُمرَّر معلمات الاستعلامات المُعلَّمة، كما هو الحال في المعالجات المُعرَّفة في التهيئة، من خلال:
- معلمات HTTP URL في سلسلة الاستعلام، باستخدام اصطلاح
param_<name> (مثلًا، يربط ?param_id=42 {id:Type})؛
- مجموعات الالتقاط المُسمّاة في
URL REGEXP (مثلًا، يربط URL REGEXP '/users/(?P<id>\d+)' {id:Type})؛
- حقول النموذج في نص الطلب، للمعالج الذي يعرّف استعلامه معلمات: إذ يربط نص
application/x-www-form-urlencoded (مثلًا curl -d 'param_id=42') وحقول نص multipart/form-data معلمات {name:Type} بالطريقة نفسها التي تربط بها معلمات URL، وذلك في طرق POST وPUT وDELETE التي تحمل نص طلب. إذا وُجدت معلمة في كلٍّ من URL والنص، فتُؤخذ قيمتها من URL. تستهلك طبقة المعالج النص الذي يُحلَّل كنموذج، ولا يُمرَّر إلى الاستعلام كبيانات INSERT. يتلقى المعالج الذي يقتصر استخدامه للنص على _request_body النص الخام بدلًا من تحليله كنموذج؛ أما المعالج الذي يعرّف _request_body إلى جانب معلمات أخرى، فيتلقى كليهما، إذ تُحفَظ نسخة من النص الخام غير المُحلَّل في _request_body (رهناً بـ http_max_request_param_data_size) قبل تحليل النص كنموذج.
تُطبَّق ترويسات HTTP القياسية لـ ClickHouse (مثل X-ClickHouse-Database وX-ClickHouse-User وX-ClickHouse-Key) كالمعتاد عند استدعاء معالج.
يمكن استخدام الدالتين currentHandler وcurrentRequestURL لتخصيص سلوك الاستعلام وفقًا للمعالج المستدعى وURL الطلب.
تتطلب أوامر CREATE HANDLER وDROP HANDLER وALTER HANDLER امتيازات CREATE HANDLER وDROP HANDLER وALTER HANDLER، على التوالي.
تتطلب قراءة جدول system.handlers امتياز SHOW HANDLERS. وتُحجب الأسرار التي قد تكون مضمنة في استعلام المعالج فيه، ما لم يكن المستخدم مخولًا أيضًا بعرض الأسرار (راجع system.handlers).
لا يتطلب استدعاء المعالج أي امتياز منفصل، لكن تُتحقق الامتيازات كالمعتاد عند تنفيذ الاستعلام، وتعمل المصادقة بالطريقة المعتادة. لحصر الوصول إلى استعلامات معيّنة، أنشئ VIEW مع SQL SECURITY DEFINER وعرّف معالجًا ينفّذ SELECT من ذلك العرض.
تُحفَظ المعالجات في مساحة تخزين محلية أو من نوع Keeper، على غرار المجموعات المسماة، وتُهيَّأ في قسم query_rules_storage ضمن ملف التهيئة:
عند استخدام تخزين Keeper، تُزامَن المعالجات تلقائيًا بين جميع النسخ المتماثلة، لذا فإن عبارة ON CLUSTER الصريحة غير ضرورية، وستؤدي إلى محاولة كل نسخة متماثلة إنشاء المعالج نفسه. فعّل الإعداد ignore_on_cluster_for_replicated_handler_queries لكي تتجاهل أوامر CREATE وALTER وDROP HANDLER عبارة ON CLUSTER عندما يكون التخزين مُكرّرًا، على غرار ignore_on_cluster_for_replicated_named_collections_queries.
يستبدل المعالج بمعالج جديد. لا يمكن أن يتضمن استعلام ALTER سوى مجموعة فرعية من العبارات؛ إذ يمكن استخدامه، على سبيل المثال، لتغيير URL أو الاستعلام فقط. تحتفظ العبارات غير المحددة بقيمها السابقة. يزيل PROTOCOL ANY قيد بروتوكول قائمًا، مما يعيد تفعيل المعالج على جميع نقاط نهاية HTTP.
يحذف المعالج الذي يحمل الاسم المحدد.
يسرد جدول system.handlers جميع المعالجات المعرّفة باستخدام SQL. ويسجّل جدول system.query_log اسم المعالج ومسار طلب HTTP (من دون سلسلة الاستعلام) لكل استعلام في العمودين http_handler_name وhttp_request_url.
معالج مُعامَل يستخدم URL بتعبير نمطي:
تندرج CREATE HANDLER ضمن عائلة عبارات CREATE، وهي مرتبطة بـ ALTER وDROP. آخر تعديل في ٢٧ أغسطس ٢٠٢٦