> ## Documentation Index
> Fetch the complete documentation index at: https://clickhouse.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

> توثيق CREATE HANDLER

# CREATE HANDLER

ينشئ معالج HTTP مخصصًا مُعرّفًا باستخدام SQL، دون تحرير ملف تهيئة الخادم. تُعد المعالجات المُعرّفة باستخدام SQL بديلًا عن [معالجات واجهة HTTP](/docs/ar/concepts/features/interfaces/http) المستندة إلى التهيئة.

<div id="syntax">
  ## الصياغة
</div>

```sql theme={null}
CREATE HANDLER [IF NOT EXISTS] name [ON CLUSTER cluster]
[PROTOCOL protocol_name|ANY]
URL [PREFIX|REGEXP] '/path'
[METHODS (GET, POST)]
[TYPE query]
AS [SELECT|INSERT|...] ...
```

ينشئ معالجًا بالـ `name` المحدد. يُستخدم الاسم لإدارة المعالجات باستخدام استعلامات SQL، وفي الرسائل التشخيصية، ولترتيب المعالجات.

<div id="clauses">
  ## عبارات SQL
</div>

* `PROTOCOL` — اختياري. إذا حُدِّد اسم بروتوكول، فلن يكون المعالج نشطًا إلا للبروتوكول [القابل للتركيب](/docs/ar/concepts/features/configuration/server-config/composable-protocols) المحدد. وإلا، يكون المعالج نشطًا على جميع نقاط نهاية HTTP: منافذ `http`/`https` المضمّنة وكل مستمع [بروتوكول قابل للتركيب](/docs/ar/concepts/features/configuration/server-config/composable-protocols) من نوع HTTP. يختار `PROTOCOL ANY` صراحةً هذا السلوك الافتراضي الأخير؛ وفي `ALTER HANDLER` يزيل تقييد بروتوكول تم تعيينه سابقًا. يمكن الإشارة إلى بروتوكول يحمل الاسم الحرفي `any` باستخدام علامات الاقتباس الخلفية: ``PROTOCOL `any` ``.
* `URL` — إلزامي. يمكن أن يكون URL مطابقًا تمامًا، أو `URL PREFIX`، أو `URL REGEXP`. بالنسبة إلى عناوين URL المطابقة تمامًا والبادئات، يُتحقق من عدم الالتباس عند الإنشاء أو التعديل، ويُرفع استثناء عند وجود التباس. أما بالنسبة إلى regexp، فلا يمكن التحقق من الالتباس. تجري مطابقة URL دون سلسلة الاستعلام `?` ومُعرّف الجزء `#`. تُطابق `URL PREFIX` كمسار أساسي عند حدّ مقطع مسار، وبنفس دلالات قاعدة `url_prefix` الخاصة بـ[المعالجات المحددة في التهيئة](/docs/ar/concepts/features/interfaces/http): يطابق `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` قابلًا للتحميل والاستدعاء ضمن حدود الجلسة العادية.

<div id="priority">
  ## priority
</div>

تكون للمعالجات المعرَّفة في تهيئة الخادم أولوية على المعالجات المعرَّفة في SQL. وتُطابَق المعالجات المعرَّفة في SQL بالترتيب المعجمي لأسمائها.

<div id="parameters">
  ## المعلمات
</div>

تُمرَّر معلمات الاستعلامات المُعلَّمة، كما هو الحال في المعالجات المُعرَّفة في التهيئة، من خلال:

* معلمات 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`](/docs/ar/reference/functions/regular-functions/other-functions#currentHandler) و[`currentRequestURL`](/docs/ar/reference/functions/regular-functions/other-functions#currentRequestURL) لتخصيص سلوك الاستعلام وفقًا للمعالج المستدعى وURL الطلب.

<div id="access-control">
  ## التحكم في الوصول
</div>

تتطلب أوامر `CREATE HANDLER` و`DROP HANDLER` و`ALTER HANDLER` امتيازات `CREATE HANDLER` و`DROP HANDLER` و`ALTER HANDLER`، على التوالي.

تتطلب قراءة جدول [`system.handlers`](/docs/ar/reference/system-tables/handlers) امتياز `SHOW HANDLERS`. وتُحجب الأسرار التي قد تكون مضمنة في استعلام المعالج فيه، ما لم يكن المستخدم مخولًا أيضًا بعرض الأسرار (راجع [`system.handlers`](/docs/ar/reference/system-tables/handlers)).

لا يتطلب استدعاء المعالج أي امتياز منفصل، لكن تُتحقق الامتيازات كالمعتاد عند تنفيذ الاستعلام، وتعمل المصادقة بالطريقة المعتادة. لحصر الوصول إلى استعلامات معيّنة، أنشئ [`VIEW` مع `SQL SECURITY DEFINER`](/docs/ar/reference/statements/create/view#sql_security) وعرّف معالجًا ينفّذ SELECT من ذلك العرض.

<div id="storage">
  ## التخزين
</div>

تُحفَظ المعالجات في مساحة تخزين محلية أو من نوع Keeper، على غرار [المجموعات المسماة](/docs/ar/concepts/features/configuration/server-config/named-collections)، وتُهيَّأ في قسم `query_rules_storage` ضمن ملف التهيئة:

```xml theme={null}
<query_rules_storage>
    <type>local</type> <!-- or zookeeper -->
    <path>/var/lib/clickhouse/handlers/</path>
</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`.

<div id="alter-handler">
  ## ALTER HANDLER
</div>

```sql theme={null}
ALTER HANDLER name
[PROTOCOL protocol_name|ANY]
[URL [PREFIX|REGEXP] '/path']
[METHODS (GET, POST)]
[TYPE query]
[AS SELECT ...]
```

يستبدل المعالج بمعالج جديد. لا يمكن أن يتضمن استعلام `ALTER` سوى مجموعة فرعية من العبارات؛ إذ يمكن استخدامه، على سبيل المثال، لتغيير URL أو الاستعلام فقط. تحتفظ العبارات غير المحددة بقيمها السابقة. يزيل `PROTOCOL ANY` قيد بروتوكول قائمًا، مما يعيد تفعيل المعالج على جميع نقاط نهاية HTTP.

<div id="drop-handler">
  ## معالج DROP
</div>

```sql theme={null}
DROP HANDLER [IF EXISTS] name
```

يحذف المعالج الذي يحمل الاسم المحدد.

<div id="introspection">
  ## الاستبطان
</div>

يسرد جدول [`system.handlers`](/docs/ar/reference/system-tables/handlers) جميع المعالجات المعرّفة باستخدام SQL. ويسجّل جدول [`system.query_log`](/docs/ar/reference/system-tables/query_log) اسم المعالج ومسار طلب HTTP (من دون سلسلة الاستعلام) لكل استعلام في العمودين `http_handler_name` و`http_request_url`.

<div id="example">
  ## مثال
</div>

```sql theme={null}
CREATE HANDLER my_handler URL '/my_handler' AS SELECT version();
```

```bash theme={null}
$ curl 'http://localhost:8123/my_handler'
```

معالج مُعامَل يستخدم URL بتعبير نمطي:

```sql theme={null}
CREATE HANDLER get_user URL REGEXP '/users/(?P<id>\d+)' AS SELECT * FROM users WHERE id = {id:UInt64};
```

```bash theme={null}
$ curl 'http://localhost:8123/users/42'
```

<div id="related-statements">
  ## العبارات ذات الصلة
</div>

تندرج `CREATE HANDLER` ضمن عائلة عبارات `CREATE`، وهي مرتبطة بـ `ALTER` و`DROP`.
