- تبدأ Executable UDFs برنامجًا خارجيًا أو برنامجًا نصيًا (بايثون، Bash، إلخ)، وتُمرِّر إليه blocks من البيانات عبر STDIN / STDOUT. استخدمها لدمج التعليمات البرمجية أو الأدوات الحالية دون الحاجة إلى إعادة تجميع ClickHouse. وهي تفرض overhead أعلى لكل استدعاء مقارنةً بالخيارات التي تعمل داخل العملية، لذا فهي الأنسب للمنطق الأثقل أو عند الحاجة إلى runtime مختلف.
- تُعرَّف SQL UDFs باستخدام
CREATE FUNCTIONبالكامل ضمن SQL. وتُضمَّن/تُوسَّع داخل query plan (من دون حدٍّ فاصل على مستوى العملية)، مما يجعلها lightweight ومثالية لإعادة استخدام منطق expression أو تبسيط columns المحسوبة المعقدة. - تُشغِّل Experimental WebAssembly UDFs تعليمات برمجية مُجمَّعة إلى WebAssembly داخل sandbox ضمن server process. وهي توفّر overhead أقل لكل استدعاء مقارنةً بالبرامج التنفيذية الخارجية، مع عزل أفضل من الامتدادات native، مما يجعلها مناسبة للخوارزميات المخصّصة المكتوبة بلغات يمكنها الاستهداف إلى WASM (مثل C/C++/Rust).
- تتيح Experimental driver-based executable UDFs لـ operator يوفّره المشغّل أن يحوّل مقطع شيفرة مُقدَّمًا في
CREATE FUNCTION ... ENGINE = DriverName(...) AS '...'إلى executable UDF عند وقت إنشاء الدالة (على سبيل المثال، عن طريق تجميعه). وهي تستند إلى executable UDFs وتتطلب إعداد driver على جانب server.
الدوال المعرّفة من قبل المستخدم القابلة للتنفيذ
في ClickHouse Cloud، تكون UDFs القابلة للتنفيذ متاحة ضمن الإصدار التجريبي العام، ويتم إنشاؤها عبر واجهة مستخدم Cloud Console. راجع الدوال المعرّفة من قبل المستخدم في Cloud للاطلاع على سير العمل الخاص بـ Cloud.
user_defined_executable_functions_config.
يتضمن تكوين الدالة الإعدادات التالية:
يجب أن يقرأ الأمر الوسائط من
STDIN وأن يكتب النتيجة إلى STDOUT. ويجب أن يعالج الأمر الوسائط على نحو تكراري. أي إنه بعد معالجة دفعة من الوسائط، يجب أن ينتظر الدفعة التالية.
الدوال المعرّفة من قبل المستخدم القابلة للتنفيذ
أمثلة
UDF من برنامج نصي مضمن
test_function_sum يدويًا مع ضبط execute_direct على القيمة 0 باستخدام إعدادات XML أو YAML.
- XML
- YAML
الملف
test_function.xml (/etc/clickhouse-server/test_function.xml مع إعدادات المسار الافتراضية)./etc/clickhouse-server/test_function.xml
Query
Result
UDF من برنامج نصي بايثون
STDIN ويُرجعها كسلسلة نصية.
أنشئ test_function باستخدام تهيئة XML أو YAML.
- XML
- YAML
الملف
test_function.xml (/etc/clickhouse-server/test_function.xml مع إعدادات المسار الافتراضية)./etc/clickhouse-server/test_function.xml
أنشئ ملف البرنامج النصي
test_function.py داخل مجلد user_scripts (/var/lib/clickhouse/user_scripts/test_function.py مع إعدادات المسار الافتراضية).
Query
Result
اقرأ قيمتين من STDIN وأعِد مجموعهما على شكل كائن JSON
test_function_sum_json باستخدام وسيطات مُسمّاة وتنسيق JSONEachRow، وذلك باستخدام تهيئة XML أو YAML.
- XML
- YAML
الملف
test_function.xml (/etc/clickhouse-server/test_function.xml مع إعدادات المسار الافتراضية)./etc/clickhouse-server/test_function.xml
أنشئ ملف البرنامج النصي
test_function_sum_json.py داخل المجلد user_scripts (/var/lib/clickhouse/user_scripts/test_function_sum_json.py مع إعدادات المسار الافتراضية).
Query
Result
استخدام المعلمات في إعداد command
command (يعمل هذا فقط مع الدوال المعرّفة من قبل المستخدم من النوع executable).
ويتطلب ذلك أيضًا الخيار execute_direct لضمان عدم وجود ثغرة ناتجة عن توسيع وسيطات الصدفة.
- XML
- YAML
ملف
test_function_parameter_python.xml (/etc/clickhouse-server/test_function_parameter_python.xml مع إعدادات المسار الافتراضية)./etc/clickhouse-server/test_function_parameter_python.xml
أنشئ ملف البرنامج النصي
test_function_parameter_python.py داخل المجلد user_scripts (/var/lib/clickhouse/user_scripts/test_function_parameter_python.py مع إعدادات المسار الافتراضية).
Query
Result
UDF من برنامج نصي shell
- XML
- YAML
ملف
test_function_shell.xml (/etc/clickhouse-server/test_function_shell.xml باستخدام إعدادات المسار الافتراضية)./etc/clickhouse-server/test_function_shell.xml
أنشئ ملف البرنامج النصي
test_shell.sh داخل المجلد user_scripts (/var/lib/clickhouse/user_scripts/test_shell.sh باستخدام إعدادات المسار الافتراضية).
/var/lib/clickhouse/user_scripts/test_shell.sh
Query
Result
معالجة الأخطاء
تقييم تعبيرات الوسائط
&& و || و ?:.
في ClickHouse، تُقيَّم وسائط الدوال (المعاملات) دائمًا.
ويرجع ذلك إلى أن أجزاءً كاملة من الأعمدة تُقيَّم دفعةً واحدة، بدلًا من حساب كل صف على حدة.
تنفيذ الدوال في معالجة الاستعلامات الموزعة
SELECT f(sum(g(x))) FROM distributed_table GROUP BY h(y),
- إذا كان
distributed_tableيحتوي على shardين على الأقل، فستُنفَّذ الدالتان ‘g’ و ‘h’ على الخوادم البعيدة، بينما تُنفَّذ الدالة ‘f’ على الخادم الطالب. - إذا كان
distributed_tableيحتوي على shard واحد فقط، فستُنفَّذ جميع الدوال ‘f’ و ‘g’ و ‘h’ على خادم هذا الـ shard.
hostName، التي تُرجع اسم الخادم الذي تعمل عليه، بحيث يمكن تنفيذ GROUP BY حسب الخوادم في استعلام SELECT.
إذا كانت دالة في استعلام ما تُنفَّذ على الخادم الطالب، لكنك تحتاج إلى تنفيذها على الخوادم البعيدة، فيمكنك تغليفها داخل الدالة التجميعية ‘any’ أو إضافتها إلى مفتاح في GROUP BY.
دوال SQL المعرفة من قبل المستخدم
دوال WebAssembly المعرّفة من قبل المستخدم
البدء السريع
مزيد من المعلومات
الدوال المعرّفة من قبل المستخدم القابلة للتنفيذ المعتمدة على برامج التشغيل
هذه ميزة تجريبية قد تتغيّر مستقبلاً بطرق قد لا تكون متوافقة مع الإصدارات السابقة. فعِّلها باستخدام إعداد الخادم
allow_experimental_executable_udf_drivers.ENGINE = DriverName(...)، يشغّل ClickHouse الأمر create_command الخاص ببرنامج التشغيل، مع تمرير توقيع الدالة ومحتوى الشيفرة إليه. بعد ذلك، يترجم برنامج التشغيل هذا المحتوى أو يعالجه بطريقة أخرى، ثم يطبع إعدادات دالة معرّفة من قبل المستخدم قابلة للتنفيذ، ليقوم ClickHouse بعدها بتخزينها وتحميلها.
يتيح ذلك للمسؤولين توفير طريقة آمنة ومحدودة للمستخدمين لتعريف دوال بلغة برمجة كيفما كانت (على سبيل المثال، C بعد ترجمتها داخل حاوية معزولة) من دون منحهم إمكانية الوصول إلى ملفات تهيئة الخادم أو نظام الملفات. وتظل مجموعة برامج التشغيل المتاحة خاضعة بالكامل لسيطرة المشغّل.
تمكين برامج التشغيل
-
عيّن خيار Experimental في إعدادات الخادم:
-
وجّه
user_defined_executable_function_drivers_configإلى ملف configuration واحد أو أكثر لبرامج التشغيل (مع دعم نمطglob)، واضبط اختياريًاdynamic_user_defined_executable_functions_path، وهو الدليل الذي تُخزَّن فيه ملفات configuration المُولَّدة الخاصة بـ UDFs القابلة للتنفيذ:
SYSTEM RELOAD CONFIG، لذلك يمكن إضافة برامج التشغيل أو تعديلها أو إزالتها دون إعادة تشغيل الخادم.
إعداد برنامج التشغيل
<driver> في المستوى الأعلى. الحقول التالية مدعومة:
مثال على إعداد برنامج التشغيل:
بروتوكول استدعاء برنامج التشغيل
CREATE FUNCTION، يُستدعى create_command بعد ضبط متغيرات env المهيأة، مع تمرير الوسيطات التالية:
--name <function_name>--return <return_type>(إذا وُجد بندRETURNS)--args <signature>(إذا وُجد بندARGUMENTS)، حيث يمثّل التوقيع قائمة الوسيطات المعلنة، مثلx UInt8, y DateTime--<key> <value>لكل وسيط engine مُعلن وممرَّر فيENGINE = DriverName(key = value)
AS) إلى الإدخال القياسي للأمر. ويجب أن يطبع الأمر تهيئة UDF executable إلى المخرج القياسي. ويُكتشَف format تلقائيًا: فإذا بدأ المخرج بـ < عُدّ XML، وإلا عُدّ YAML. ويجب أن يطابق اسم الدالة المعرَّفة في التهيئة المُولَّدة الاسم الذي يجري إنشاؤه. وإذا أنهى create_command التنفيذ بحالة غير صفرية، يفشل statement مع Exception تتضمن رمز الخروج والخطأ القياسي لبرنامج التشغيل.
ويُستدعى drop_command، عند وجوده، بالطريقة نفسها (ولكن من دون متن شيفرة على stdin) عند حذف الدالة.
إنشاء function
create_command الخاص ببرنامج التشغيل، ويكتب التهيئة الناتجة إلى dynamic_user_defined_executable_functions_path، ثم يكتشفها مُحمِّل UDF التنفيذي الحالي. بعد ذلك يمكن استدعاء الدالة مثل أي دالة أخرى.
حذف دالة
DROP FUNCTION الأمر drop_command الخاص ببرنامج التشغيل (إن وُجد)، ويزيل التهيئة الديناميكية المُنشأة ودليل العمل الخاص بكل دالة، ويُعيد تحميل مُحمِّل UDF التنفيذي، ويزيل الاستعلام المحفوظ.
الاستمرارية وإعادة التشغيل
ATTACH FUNCTION ... في دليل كائنات SQL المعرَّفة من قبل المستخدم، بحيث تبقى الدالة بعد إعادة تشغيل الخادم. عند بدء التشغيل، تُحمَّل التهيئات المُولَّدة في dynamic_user_defined_executable_functions_path مباشرةً من دون إعادة تشغيل برنامج التشغيل. وإذا لم تكن لعبارة ATTACH FUNCTION المحفوظة تهيئة مُولَّدة مطابقة (على سبيل المثال، إذا فُقد الدليل الديناميكي)، فستُعاد تشغيل برنامج التشغيل لإعادة إنشائها.
القيود
- هذه الميزة تجريبية ولا تتاح إلا عند تفعيل
allow_experimental_executable_udf_drivers. - الدوال المستندة إلى برامج التشغيل غير مدعومة مع التخزين المُكرَّر للدوال المعرّفة من قبل المستخدم (
ON CLUSTERو<user_defined_zookeeper_path>)، لأن الاستعلام الأصلي فقط هو الذي يُكرَّر، وليس الملفات الناتجة. - تؤدي عملية
RESTOREلدالة مستندة إلى برنامج تشغيل جرى أخذ نسخة احتياطية لها إلى الاحتفاظ بالاستعلام، لكنها لا تعيد تشغيل برنامج التشغيل؛ إذ تُطبَّق التهيئة المُولَّدة وتُحفَظ لاحقًا أثناء استرداد إعادة التشغيل.
مثال على برامج تشغيل C
programs/server/user_defined_executable_function_drivers_config.d/، وهي تُترجم جسم دالة بلغة C وتُشغّله. وهذه مجرد أمثلة ولا تُثبَّت عبر الحزم:
DockerC- يترجم الشيفرة ويشغّلها داخل حاويات Docker معزولة (--network=none --read-only --cap-drop=ALL --security-opt=no-new-privileges، بالإضافة إلى حدود الذاكرة/CPU/PID)، ويُنتج UDF من النوعexecutable_pool.GVisorC- نسخة بديلة تشغّل الملف التنفيذي المترجم ضمن بيئة التشغيل gVisorrunsc.UnsafeC- يترجم الشيفرة ويشغّلها مباشرة على المضيف من دون sandbox. وكما يوحي الاسم، فهو لا يوفّر أي عزل، وهو مخصّص فقط للبيئات الموثوقة ولأغراض الاختبار.