docs(python-udf): CPython 3.14 runtime, init + flush hooks, package install grammar, and UDF runtime gates - #664
Open
yokofly wants to merge 4 commits into
Open
docs(python-udf): CPython 3.14 runtime, init + flush hooks, package install grammar, and UDF runtime gates#664yokofly wants to merge 4 commits into
yokofly wants to merge 4 commits into
Conversation
… the removal of bundled packages Timeplus Enterprise 3.3.1 upgrades the embedded interpreter from CPython 3.10 to 3.14 free-threaded (cp314t) and stops shipping any third-party Python packages — only the stdlib, pip and truststore remain. - py-udf.md: replace the ~40-entry built-in library list with the clean environment it actually is; add the python_requirements declarative package sync, a free-threading concurrency section (shared globals in imported modules are no longer GIL-protected), and an upgrade guide. - sql-system-python-packages.md: correct the runtime version, note cp314t wheel compatibility and local-install durability, and document python_requirements as the declarative alternative. - sql-create-function.md: correct the runtime version. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
✅ Deploy Preview for elastic-elion-a958b6 ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
Python UDF init hooks (init_function_name / init_function_parameters / named_collection) shipped in the same v3.3.1 release as the CPython 3.14 migration but were not documented anywhere. - py-udf.md: new 'Initialization hook' section covering the hook contract (called once at module load, before a UDAF class is constructed), the single-string parameter convention, the named collection variant that keeps secrets out of SHOW CREATE FUNCTION, and the resolution/ACL rules. - sql-create-function.md: document the three supported Python UDF settings, which the syntax blocks previously left as a bare 'SETTINGS ...'. - named-collection.md: list Python UDF init parameters under Supported Usage and add a worked example. Behavior verified against 99150_python_udf_init_named_collection.sh and 99121_python_udf_init_named_collection_acl.sh. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
flush_function_name shipped in v3.3.1 (proton-enterprise 4a7f2b6a, "support flush hook in python external stream sink" #12183) alongside the CPython 3.14 migration, but was documented nowhere. - shared/python-external-stream.md: add flush_fn to the DDL skeleton and flush_function_name to the SETTINGS block, a settings bullet, and a new lifecycle step — the sequence previously went straight from the entry function to deinit. - shared/python-external-stream-write.md: new 'Flushing buffered writes' section with a batching-sink example, plus the contract (zero-arg, sink-only, called on every checkpoint and once before deinit, missing name fails the INSERT at runtime rather than at CREATE). - sql-create-external-stream.md: add the setting to the Python syntax block with its own version note, since the page's blanket 3.2.2+ line does not hold for it. Behavior verified against src/CPython/PythonModuleSession.cpp, src/Storages/ExternalStream/Python/PythonSink.cpp and 99177_external_python_stream_flush.sql. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…e gates Two features that shipped before 3.3.1 and were never documented. SYSTEM INSTALL PYTHON PACKAGE grammar (v3.1.2, proton-enterprise aa38eeb0 #11494) — only the 'pkg' and 'pkg' 'version' forms were documented, so the REQUIREMENTS / INDEX_URL / EXTRA_INDEX_URL clauses looked nonexistent: - sql-system-python-packages.md: new 'Installing from requirements text' and 'Private package indexes' sections covering the line rules, the rejection of pip options inside the text, the 1024-line cap, http(s) URL validation, and the fact that a REQUIREMENTS batch appears in system.python_package_tasks under package_name 'requirements.txt'. Also a compatibility note: these statements use a newer cluster request format, so every node must be on 3.1.2+. - py-udf.md: the two most useful forms inline, pointing at the reference. UDF runtime gates (v3.2.1, proton-enterprise fb17e0b9 #11752): - py-udf.md: new 'Turning the runtime off' section for enable_python_udf — applied by SYSTEM RELOAD CONFIG, gates creation only (existing UDFs keep running), and read per-node rather than replicated. - server_config.md: both flags as config items. - js-udf.md: one line for enable_javascript_udf. Note: config.yaml describes these flags as rejecting creation *and execution*, but ensureUDFIsEnabled is only reached from the two creation paths (InterpreterCreateFunctionQuery, UDFHandler), which is also all 99145_udf_runtime_enable_flags.sh asserts. The docs say creation-only. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Documents the Python UDF and Python external stream features that shipped without docs. The bulk is Timeplus Enterprise 3.3.1 — which upgraded the embedded interpreter from CPython 3.10 to 3.14 free-threaded (
cp314t) and stopped bundling third-party packages — plus two older features (3.1.2, 3.2.1) that were never written up and are backfilled here.Four commits, each independently reviewable:
83048e8c82bdca0cfeed5e4afca61. CPython 3.14 free-threaded runtime (
83048e8)The docs still described the 3.10 environment and listed ~40 bundled packages that no longer exist.
docs/py-udf.mdnumpy,requests,openai,pydantic,proton-driver,timeplus-neutrino, …) with the clean environment it actually is, plus a warning that any UDF importing one of the old bundled packages now fails withModuleNotFoundError.python_requirements— the declarative S3requirements.txtpackage sync (poll interval, credential chain, pip index overrides, install-only reconcile semantics). This is the path for ephemeral compute nodes, where a localSYSTEM INSTALLdoes not survive a reschedule.sys.modulesacross threads and races. Includes the measured loss (8 concurrent queries × 5000 increments finished near 18,000/40,000 unprotected, exactly 40,000 with athreading.Lock) and a locking example.bin/andlib/(the startup ABI guard rejects a GIL runtime), reinstall the packages your UDFs import, check forcp314twheels, audit shared mutable state, and roll back via a data-folder copy.docs/sql-system-python-packages.mdcp314twheel-compatibility and install-durability caveats.python_requirementssection as the declarative alternative, cross-linked topy-udf.docs/sql-create-function.mddocs/named-collection.md2. Python UDF init hooks + named collections (
c82bdca)Init hooks (
init_function_name/init_function_parameters/named_collection,ceaea40d939d, #12198) shipped in the same v3.3.1 release but were documented nowhere —sql-create-function.mdshowed a bareSETTINGS ...with no list of what is accepted.py-udf.md— new Initialization hook section: the hook runs once at module load, before the first call and before a UDAF class is constructed; parameters are passed as a single string (JSON by convention);named_collectionreads the collection'sinit_function_parameterskey so the value stays out ofSHOW CREATE FUNCTION, unlike inlineinit_function_parameters. Documents the rules — the two parameter sources are mutually exclusive, both requireinit_function_name, creation needs theNAMED COLLECTIONprivilege (and returnsACCESS_DENIEDwhether or not the collection exists, so it does not leak which collections are defined), a collection without the key means a zero-arg call, values resolve at module-load time so rotating a collection does not reach running materialized views, and a failed hook discards the module so a later call retries.sql-create-function.md— a settings table for the three Python-only settings, plus an example.3. Python external stream sink flush hook (
0cfeed5)flush_function_nameshipped in v3.3.1 (4a7f2b6a, #12183) alongside the CPython migration, and was documented nowhere. Python external streams had a documented ctor (init) and dtor (deinit), but nothing about flushing — so a batching sink had no discoverable way to avoid losing buffered rows.shared/python-external-stream.md— addedflush_fnto the DDL skeleton andflush_function_nameto the SETTINGS block, a settings bullet, and a new lifecycle step. The lifecycle sequence previously went straight from the entry function to deinit.shared/python-external-stream-write.md— new Flushing buffered writes section with a batching-sink example (init opens the buffer → write collects → flush posts → deinit clears), plus the contract: zero-arg, return value ignored, sink-only (never called on a read), invoked on every checkpoint and once before deinit on close, and a missing function name fails the INSERT withUDF_INTERNAL_ERRORat runtime — unlikeinit_function_parameters, it is not validated atCREATEtime.sql-create-external-stream.md— added the setting to the Python syntax block with its own version note, since the page's blanket "3.2.2+" line does not hold for it.4. Package install grammar + UDF runtime gates (
e4afca6)Two features that shipped before 3.3.1 and were never documented.
SYSTEM INSTALL PYTHON PACKAGEgrammar — v3.1.2 (aa38eeb0, #11494)Only the
'pkg'and'pkg' 'version'forms were documented, so theREQUIREMENTS/INDEX_URL/EXTRA_INDEX_URLclauses looked nonexistent.index_urlappeared only as a YAML comment inside thepython_requirementsblock, which made it look like a config-file-only capability.sql-system-python-packages.md— new Installing from requirements text and Private package indexes sections: one package spec per line, blank/#lines skipped, pip options inside the text rejected (-r nested.txt,--index-url …) with a pointer to the clauses, the 1024-line cap,REQUIREMENTScannot be combined with a version literal, http(s)-only URL validation that runs before any node invokes pip, and the non-obvious bit — aREQUIREMENTSbatch is a single row insystem.python_package_tasksunderpackage_name = 'requirements.txt', not one row per package. Plus a compatibility note: these statements are dispatched with a newer cluster request format, so every node must be on 3.1.2+.py-udf.md— the two most useful forms inline, pointing at the reference page.UDF runtime gates — v3.2.1 (
fb17e0b9, #11752)py-udf.md— new Turning the runtime off section forenable_python_udf: applied bySYSTEM RELOAD CONFIGwith no restart, exact error text, enforced on the REST endpoint too, and the two things that trip people up — it gates creation only (existing UDFs keep running, package management is unaffected), and it is read from each node's own config rather than replicated cluster-wide.server_config.md—enable_python_udfandenable_javascript_udfas config items, so they are findable from the config reference.js-udf.md— one line forenable_javascript_udf, since the flag is symmetric.One deliberate divergence from the source:
programs/server/config.yamldescribes these flags as rejecting creation and execution, butensureUDFIsEnabledis only reached from the two creation paths (InterpreterCreateFunctionQuery,UDFHandler), which is also all99145_udf_runtime_enable_flags.shasserts. The docs say creation-only. The server-side comment looks like the thing that needs fixing.Verification
yarn buildpasses with no broken-link or broken-anchor warnings.99150_python_udf_init_named_collection.shand99121_python_udf_init_named_collection_acl.sh.99177_external_python_stream_flush.sql,src/CPython/PythonModuleSession.cppandsrc/Storages/ExternalStream/Python/PythonSink.cpp.99124_python_package_requirements_syntax.sh,src/Parsers/ParserSystemQuery.cppandsrc/CPython/PythonPackage.cpp.99145_udf_runtime_enable_flags.shandsrc/Functions/UserDefined/UserDefinedFunctionFactory.cpp.contrib/cpythonat 3.14.6,--enable-python-free-threadedinrelease_build.yml, thepip+truststore-onlydist-packagesstaging,PythonRequirementsReconcilerandprograms/server/config.yaml.Not included
enterprise-v3.3.mdrelease-notes page — the repo currently stops atenterprise-v3.2.md, and writing 3.3 release notes needs the full changelog. Nothing here links to/enterprise-v3.3, so the build stays clean. Worth a follow-up.python()/python_query()table function (TableFunctionPythonQuery) is registered in the engine but has no test coverage, and the only related test has itsRETURNS TABLEUDF case commented out asserverError UNSUPPORTED. It looks unfinished, so it is left undocumented rather than guessed at.🤖 Generated with Claude Code