Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
202 commits
Select commit Hold shift + click to select a range
5ef8b72
refactor(udf): replace legacy Python service with Arrow runtime
iamlinjunhong Sep 9, 2026
ce1c5cc
fix(udf): tighten runtime naming and lifecycle
iamlinjunhong Sep 9, 2026
bbb368f
fix(udf): rename Python adapter and fence duplicate calls
iamlinjunhong Sep 9, 2026
d9d37f0
fix(udf): close remaining Python worker contracts
iamlinjunhong Sep 9, 2026
7f3fb06
fix(udf): align SQL selection and system account fences
iamlinjunhong Sep 9, 2026
35e4073
test(udf): add Python cases to CI BVT
iamlinjunhong Sep 9, 2026
9f0e60d
chore(udf): remove stale Python service ignore rules
iamlinjunhong Sep 9, 2026
de5e734
ci(udf): harden Python BVT build fallback
iamlinjunhong Sep 9, 2026
ee9b4da
test(udf): run Python cases in ordinary BVT
iamlinjunhong Sep 9, 2026
24ce9c6
test(udf): expand Python boundary BVT coverage
iamlinjunhong Sep 9, 2026
693d090
test(udf): cover null multi-argument calls
iamlinjunhong Sep 9, 2026
e72ae50
fix(udf): close Python execution and type contracts
iamlinjunhong Sep 9, 2026
5e0e2ad
fix(udf): separate active and terminal reservations
iamlinjunhong Sep 9, 2026
0c44e0e
test(udf): update decimal normalization baseline
iamlinjunhong Sep 9, 2026
a6ec69d
fix(udf): harden handler response ownership
iamlinjunhong Sep 9, 2026
7a149c8
refactor(udf): clarify execution sequence ownership
iamlinjunhong Sep 9, 2026
bd60a90
fix(udf): encode UUID width in the ABI fingerprint
iamlinjunhong Sep 9, 2026
37f85dc
fix(udf): close Python execution channel contracts
iamlinjunhong Sep 9, 2026
c83d402
fix(udf): close Python gateway response contracts
iamlinjunhong Sep 10, 2026
efb8e45
fix(udf): make Python runtime shutdown terminal
iamlinjunhong Sep 10, 2026
16b512d
fix(udf): close Python SQL and runtime contracts
iamlinjunhong Sep 10, 2026
f56e2c7
fix(udf): require complete Python type contracts
iamlinjunhong Sep 10, 2026
158d19b
fix(udf): enforce one-shot group state transitions
iamlinjunhong Sep 10, 2026
34332a3
fix(udf): reject late Flight completion controls
iamlinjunhong Sep 10, 2026
1dcb5fa
fix(udf): align Python JSON validation with SQL
iamlinjunhong Sep 10, 2026
4dbeb65
fix(udf): isolate Python handler environment
iamlinjunhong Sep 10, 2026
e5751d9
fix(udf): enforce complete Python routine bodies
iamlinjunhong Sep 10, 2026
0a689e3
fix(udf): reject non-finite handler deadlines
iamlinjunhong Sep 10, 2026
6b2b2bc
fix(udf): validate Python execution input shapes
iamlinjunhong Sep 10, 2026
4cf272d
fix(udf): validate Arrow physical descriptor limits
iamlinjunhong Sep 10, 2026
3eaea97
fix(udf): ignore null decimal payloads
iamlinjunhong Sep 10, 2026
c1d3ef0
fix(udf): honor SQL integer type equivalence
iamlinjunhong Sep 10, 2026
ffa97bf
fix(udf): reject duplicate invocation opens
iamlinjunhong Sep 10, 2026
fcbafe1
fix(udf): reject unknown control envelope fields
iamlinjunhong Sep 10, 2026
41670cb
fix(udf): reject duplicate control JSON fields
iamlinjunhong Sep 10, 2026
ed014fa
fix(udf): validate opens before ledger admission
iamlinjunhong Sep 10, 2026
a1045eb
fix(udf): enforce Python descriptor shape
iamlinjunhong Sep 10, 2026
e8781f4
fix(udf): reject Arrow bodies on control frames
iamlinjunhong Sep 10, 2026
2ac59e3
fix(udf): align Python fencing tuple validation
iamlinjunhong Sep 10, 2026
ce47f4e
fix(udf): reject empty Flight input frames
iamlinjunhong Sep 10, 2026
67ac30b
fix(udf): encode zero sequence control fields
iamlinjunhong Sep 10, 2026
c7319eb
fix(udf): enforce control field ownership
iamlinjunhong Sep 10, 2026
d0d45c9
fix(udf): preserve decimal64 signed range
iamlinjunhong Sep 10, 2026
4fed46e
fix(udf): reject nonstandard control JSON
iamlinjunhong Sep 10, 2026
7c06e18
fix(udf): preserve fencing tuple encoding
iamlinjunhong Sep 10, 2026
c83fc6b
fix(udf): validate IANA timezone identities
iamlinjunhong Sep 10, 2026
62fd4ba
fix(udf): validate input Arrow values
iamlinjunhong Sep 10, 2026
5dcd102
fix(udf): reject empty constant inputs
iamlinjunhong Sep 10, 2026
339dbc9
fix(udf): classify malformed worker frames
iamlinjunhong Sep 10, 2026
24b5e26
fix(udf): enforce descriptor value domains
iamlinjunhong Sep 10, 2026
6089a81
fix(udf): reject invalid control UTF-8
iamlinjunhong Sep 10, 2026
765853b
fix(udf): validate every Python input batch
iamlinjunhong Sep 10, 2026
374a779
feat(udf): implement long-term Python UDF execution
iamlinjunhong Sep 11, 2026
a7623cf
feat(udf): validate Python definitions before publication
iamlinjunhong Sep 11, 2026
c0ff348
fix(udf): read handler frames across pipe short reads
iamlinjunhong Sep 11, 2026
3873305
fix(udf): keep Arrow encoder cleanup retryable
iamlinjunhong Sep 11, 2026
5a7c322
fix(udf): finalize input before terminal success
iamlinjunhong Sep 11, 2026
a1b2b48
fix(udf): classify invalid handler buffers
iamlinjunhong Sep 11, 2026
e8c5655
fix(udf): reject trailing handler batch bytes
iamlinjunhong Sep 11, 2026
6bdea8c
fix(udf): validate Python handler bindings at create
iamlinjunhong Sep 11, 2026
dbf0432
fix(udf): validate empty and typed input boundaries
iamlinjunhong Sep 11, 2026
9f016b4
fix(udf): reject unsupported routine types before allocation
iamlinjunhong Sep 11, 2026
30b174a
fix(udf): enforce exact external routine selection domain
iamlinjunhong Sep 11, 2026
16ff997
fix(udf): transfer external expression result ownership
iamlinjunhong Sep 14, 2026
d646a41
fix(udf): verify frozen definitions before evaluating arguments
iamlinjunhong Sep 14, 2026
f9922a4
fix(udf): skip arguments outside the selected row domain
iamlinjunhong Sep 14, 2026
b7f4d77
fix(udf): preserve canonical JSON tokens across adapters
iamlinjunhong Sep 14, 2026
e87f361
fix(udf): avoid re-expanding shared routine query dependencies
iamlinjunhong Sep 14, 2026
b5a61f5
fix(udf): own handler pipes before subsequent allocations
iamlinjunhong Sep 14, 2026
d36fda6
docs(udf): describe CI workers without isolation claims
iamlinjunhong Sep 14, 2026
1a5ad6d
test(udf): cover canonical JSON through real Flight batches
iamlinjunhong Sep 14, 2026
69c2cc6
perf(udf): reduce scalar batch conversion overhead
iamlinjunhong Sep 14, 2026
e6378a6
refactor(udf): share scalar conversion contract
iamlinjunhong Sep 14, 2026
a5d55ff
perf(udf): trim handler process startup
iamlinjunhong Sep 14, 2026
0e528b5
perf(udf): trim bounded handler IPC frames
iamlinjunhong Sep 14, 2026
15a7431
perf(udf): avoid Arrow result stream copies
iamlinjunhong Sep 14, 2026
120c313
perf(udf): batch fixed-width input materialization
iamlinjunhong Sep 14, 2026
44c41b8
perf(udf): reuse variable-width input wrappers
iamlinjunhong Sep 14, 2026
6a4f0f8
fix(udf): guard empty variable-width inputs
iamlinjunhong Sep 14, 2026
4aece7d
perf(udf): reduce handler request copies
iamlinjunhong Sep 14, 2026
70c4fc0
refactor(udf): clarify varlena cache naming
iamlinjunhong Sep 14, 2026
99a88aa
fix(udf): handle vector inputs in batch sizing
iamlinjunhong Sep 14, 2026
588f307
perf(udf): reuse result headers during decode
iamlinjunhong Sep 14, 2026
33ca6ec
fix(udf): preserve Arrow metadata across input batches
iamlinjunhong Sep 14, 2026
c41b931
fix(udf): fence supervisor restart during close
iamlinjunhong Sep 14, 2026
237b884
fix(udf): require explicit Python invocation language
iamlinjunhong Sep 14, 2026
9d3f85a
fix(udf): require explicit Python definition language
iamlinjunhong Sep 14, 2026
fd896ef
fix(udf): validate final Python handler binding
iamlinjunhong Sep 14, 2026
6042725
fix(udf): fall back when handler group kill is denied
iamlinjunhong Sep 14, 2026
50f2139
fix(udf): include timezone data in runtime image
iamlinjunhong Sep 14, 2026
e2002b0
fix(udf): fail closed on broken liveness watches
iamlinjunhong Sep 14, 2026
ca5fa95
fix(udf): close gateway admission barrier
iamlinjunhong Sep 14, 2026
535368f
fix(udf): validate empty selection domains
iamlinjunhong Sep 14, 2026
5e05a94
fix(udf): reject noncanonical JSON results
iamlinjunhong Sep 14, 2026
50f5338
fix(udf): reject opaque text descriptors
iamlinjunhong Sep 14, 2026
8bbeabd
fix(udf): serialize admission with gateway close
iamlinjunhong Sep 14, 2026
d5060ad
fix(udf): enforce budget during handler writes
iamlinjunhong Sep 14, 2026
a147416
fix(udf): validate Python catalog signature before publish
iamlinjunhong Sep 14, 2026
7cc8105
fix(udf): refresh worker lease for readiness
iamlinjunhong Sep 14, 2026
fd4c006
fix(udf): validate temporal child validity
iamlinjunhong Sep 14, 2026
6dc2c84
fix(udf): scope worker group fences by account
iamlinjunhong Sep 15, 2026
3bfe379
fix(udf): scope gateway groups by account
iamlinjunhong Sep 15, 2026
ea89da9
fix(udf): reject noncanonical descriptor fields
iamlinjunhong Sep 15, 2026
2d63df3
fix(udf): bound worker fencing identities
iamlinjunhong Sep 15, 2026
b0af418
fix(udf): align Python security IDs with uint32
iamlinjunhong Sep 15, 2026
250f8d2
fix(udf): enforce required worker controls on encode
iamlinjunhong Sep 15, 2026
6cf4cfc
fix(udf): bound Python statement timestamps
iamlinjunhong Sep 15, 2026
30f5dce
fix(udf): bound Python descriptor integers
iamlinjunhong Sep 15, 2026
976b42e
fix(udf): verify runtime result production
iamlinjunhong Sep 15, 2026
f949104
fix(udf): reject boolean contract versions
iamlinjunhong Sep 15, 2026
5d48263
fix(udf): require canonical timezone kinds
iamlinjunhong Sep 15, 2026
8511e17
fix(udf): validate definition schema type
iamlinjunhong Sep 15, 2026
c4853e1
fix(udf): cancel exchanges during worker shutdown
iamlinjunhong Sep 15, 2026
c9afd5a
fix(udf): require canonical routine language
iamlinjunhong Sep 15, 2026
ecc3442
fix(udf): reject noncanonical plan languages
iamlinjunhong Sep 15, 2026
a4bff52
test(udf): inspect scoped gateway group fences
iamlinjunhong Sep 15, 2026
72b82c9
fix(udf): align gateway timeout with worker limit
iamlinjunhong Sep 15, 2026
37519fe
fix(udf): preserve large JSON number tokens
iamlinjunhong Sep 15, 2026
0e8f007
fix(udf): reject noncanonical routine language at bind
iamlinjunhong Sep 15, 2026
41cbc0a
fix(udf): enforce Arrow field nullability
iamlinjunhong Sep 15, 2026
865807c
fix(udf): require object invocation payload
iamlinjunhong Sep 15, 2026
caae2b4
fix(udf): reject cancelled worker actions
iamlinjunhong Sep 15, 2026
550a5ce
fix(udf): reject noncanonical catalog languages
iamlinjunhong Sep 15, 2026
61ab50a
fix(udf): validate module handler bindings
iamlinjunhong Sep 15, 2026
058a1e7
fix(udf): bound resolved artifact sources
iamlinjunhong Sep 15, 2026
a4264ee
fix(udf): align statement timestamp bounds
iamlinjunhong Sep 15, 2026
bed268c
fix(udf): handle bare except in handler validation
iamlinjunhong Sep 15, 2026
f00511d
fix(udf): bound artifact validation resolution
iamlinjunhong Sep 15, 2026
70606cf
fix(udf): inspect mapping pattern handler captures
iamlinjunhong Sep 15, 2026
04f3d70
fix(udf): stop cleanup reaper on worker shutdown errors
iamlinjunhong Sep 15, 2026
c79d2aa
fix(udf): reject null sql mode context
iamlinjunhong Sep 15, 2026
2e250bc
fix(udf): validate IANA zones at CN boundary
iamlinjunhong Sep 15, 2026
404f8d2
fix(udf): cap artifact store to wire contract
iamlinjunhong Sep 15, 2026
a7b507a
fix(udf): bound control JSON nesting
iamlinjunhong Sep 15, 2026
174150d
fix(udf): bound validation action JSON
iamlinjunhong Sep 15, 2026
c394a0a
fix(udf): reject sub-minute session offsets
iamlinjunhong Sep 15, 2026
31e26c3
fix(frontend): stabilize Python replace validation
iamlinjunhong Sep 15, 2026
5df3bf6
fix(frontend): reject incomplete Python identities
iamlinjunhong Sep 15, 2026
30171c0
fix(udf): cancel exchange before releasing admission
iamlinjunhong Sep 15, 2026
731385a
fix(udf): keep native Flight readers on RPC thread
iamlinjunhong Sep 15, 2026
88ad522
fix(udf): distinguish expected worker shutdown
iamlinjunhong Sep 15, 2026
0fc7d42
fix(udf): complete handler response frame writes
iamlinjunhong Sep 15, 2026
51f2f62
fix(udf): validate handler binding before loading
iamlinjunhong Sep 15, 2026
01618e6
fix(udf): kill handler groups before reaping leaders
iamlinjunhong Sep 15, 2026
2bc4185
fix(udf): reject stale result acknowledgements
iamlinjunhong Sep 15, 2026
fdd6467
fix(udf): close Docker contract gaps
iamlinjunhong Sep 15, 2026
d6ed6ad
refactor(udf): centralize logical type mapping
iamlinjunhong Sep 15, 2026
ddc57d8
fix(udf): preserve legacy python heads on restore
iamlinjunhong Sep 16, 2026
a10a0b7
fix(udf): enforce descriptor validity at result boundaries
iamlinjunhong Sep 16, 2026
4e084f8
fix(udf): cancel gateway operations on close
iamlinjunhong Sep 16, 2026
6cbeb6f
fix(udf): reject incompatible vector descriptor casts
iamlinjunhong Sep 16, 2026
d22d9f8
fix(udf): bound handler response buffering
iamlinjunhong Sep 16, 2026
c586b4f
udf: add runtime status bridge and finish fencing
iamlinjunhong Sep 17, 2026
9ae2d0e
test: add Arrow compute correctness cases for Python UDF
iamlinjunhong Sep 18, 2026
f72c6ba
test: make Arrow sort null placement explicit
iamlinjunhong Sep 18, 2026
2c32ea4
test: cover null Arrow take indices
iamlinjunhong Sep 18, 2026
d373261
test: make Arrow arithmetic scalar type explicit
iamlinjunhong Sep 18, 2026
b57b9f8
test: make Arrow string options explicit
iamlinjunhong Sep 18, 2026
c38d8a7
test: make Arrow selection safety explicit
iamlinjunhong Sep 18, 2026
733429b
test: cover Arrow vector cardinality rejection
iamlinjunhong Sep 18, 2026
231a04a
test: distinguish Arrow string option semantics
iamlinjunhong Sep 18, 2026
7566103
test: bind Arrow scalar arguments to SQL types
iamlinjunhong Sep 18, 2026
06f17fe
docs: describe Arrow cardinality coverage
iamlinjunhong Sep 18, 2026
a7b17e9
test: clean up BVT service processes
iamlinjunhong Sep 18, 2026
9d113d6
test: reap BVT child services
iamlinjunhong Sep 18, 2026
a244b6c
test: wait for Python UDF capability handshake
iamlinjunhong Sep 18, 2026
ee611f1
test: cover Arrow take bounds errors
iamlinjunhong Sep 18, 2026
a35207c
test: verify Arrow sort index positions
iamlinjunhong Sep 18, 2026
8b420b9
test: cover Arrow float arithmetic
iamlinjunhong Sep 18, 2026
7708922
fix: preserve vector size during Python UDF binding
iamlinjunhong Sep 18, 2026
409733d
fix: keep BVT services alive for test runner
iamlinjunhong Sep 18, 2026
3bfcfa7
fix: clean BVT services after test completion
iamlinjunhong Sep 18, 2026
0149086
fix: harden BVT launcher argument handling
iamlinjunhong Sep 18, 2026
a157339
fix: freeze complete Arrow result frames
iamlinjunhong Sep 18, 2026
4d38f74
fix: verify BVT service liveness during startup
iamlinjunhong Sep 18, 2026
9bf61b6
docs: fix Python UDF BVT generation example
iamlinjunhong Sep 18, 2026
2d6e900
test: make compose worker readiness verify capabilities
iamlinjunhong Sep 18, 2026
4a85376
fix: clean BVT services on startup failure
iamlinjunhong Sep 18, 2026
fab4c59
ci: preserve BVT logs when setup fails
iamlinjunhong Sep 18, 2026
ee3ab5a
fix: avoid waiting on exited BVT processes
iamlinjunhong Sep 18, 2026
1a689a8
fix: keep handler quota ownership retryable
iamlinjunhong Sep 18, 2026
e7df36b
fix: degrade python runtime initialization failures
iamlinjunhong Sep 18, 2026
bab65ed
fix: clean up compose BVT services
iamlinjunhong Sep 18, 2026
6d703f4
test: execute scalar Python UDF BVT case
iamlinjunhong Sep 18, 2026
284a1d9
fix(udf): validate overload namespaces and cancel capability waits
iamlinjunhong Sep 20, 2026
83397d6
test(udf): supply NULL input for scalar control-flow assertion
iamlinjunhong Sep 20, 2026
ae740a8
fix(udf): preserve exact DROP and failed initialization ownership
iamlinjunhong Sep 20, 2026
61e962e
docs(udf): document execution and rollout scope for review
iamlinjunhong Sep 20, 2026
17bb262
fix(ci): add missing license headers for Python UDF files
iamlinjunhong Sep 20, 2026
2ac43e7
fix(udf): satisfy static checks and import ownership
iamlinjunhong Sep 20, 2026
39bfcd4
fix(ci): align Python UDF runtime dependencies
iamlinjunhong Sep 20, 2026
85032de
fix(udf): integrate concurrent CI contract repair
iamlinjunhong Sep 20, 2026
1d3f4c1
fix(udf): remove duplicate frontend import
iamlinjunhong Sep 20, 2026
98e9542
fix(udf): preserve Python UDF test dependencies
iamlinjunhong Sep 20, 2026
15ec92f
test(optools): isolate Python dependency probe in scheduler harness
iamlinjunhong Sep 21, 2026
da8fa82
test(bootstrap): preserve historical upgrade worker fixture
iamlinjunhong Sep 21, 2026
ae4e77a
test(udf): cover CI contracts and failure paths
iamlinjunhong Sep 23, 2026
8a86681
fix(optools): retain Python runtime loader path
iamlinjunhong Sep 23, 2026
1a26a2f
docs(udf): clarify test-stage acceptance scope
iamlinjunhong Sep 24, 2026
c6f9c76
docs(udf): approve current-stage design contract
iamlinjunhong Sep 24, 2026
632dc59
docs(udf): link design approval record
iamlinjunhong Sep 24, 2026
4ca2294
docs(udf): record current-stage design approvals
iamlinjunhong Sep 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,6 @@ node-*-data/
pkg/catalog/test/
pkg/config/system_vars.go
pkg/config/system_vars_test.go
pkg/udf/pythonservice/pyserver/udf/
pkg/udf/pythonservice/pyserver/__pycache__/
path_to_file
tester-log/
ut-report/
Expand Down
21 changes: 14 additions & 7 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,20 +35,27 @@ linters:
- $all
- '!$test'
- '!pkg/iceberg/adapter/iceberggo/**/*.go'
# Arrow IPC is isolated to the ingestion bridge and its external
# scan reader. Keep the dependency out of all other production
# packages, including the Iceberg-facing layers.
deny:
- pkg: github.com/apache/iceberg-go
desc: Iceberg dependency must stay behind pkg/iceberg/adapter/iceberggo
arrow-boundary:
list-mode: lax
files:
- $all
- '!$test'
- '!pkg/iceberg/adapter/iceberggo/**/*.go'
# Arrow belongs to the ingestion and external UDF boundaries.
# These owners do not also receive permission to import Iceberg.
- '!**/pkg/container/arrowbridge/*.go'
- '!**/pkg/sql/colexec/external/arrowio/*.go'
- '!**/pkg/sql/colexec/external/reader_arrow.go'
- '!**/pkg/sql/compile/compile.go'
- '!**/pkg/udf/python/*.go'
deny:
- pkg: github.com/apache/iceberg-go
desc: Iceberg dependency must stay behind pkg/iceberg/adapter/iceberggo
- pkg: github.com/apache/arrow-go
desc: Arrow dependency must not leak outside the Iceberg adapter
desc: Arrow dependency must stay behind an approved Arrow owner
- pkg: github.com/apache/arrow/go
desc: Arrow dependency must not leak outside the Iceberg adapter
desc: Arrow dependency must stay behind an approved Arrow owner
govet:
disable:
- fieldalignment
Expand Down
8 changes: 4 additions & 4 deletions cmd/mo-service/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ import (
"github.com/matrixorigin/matrixone/pkg/perfcounter"
"github.com/matrixorigin/matrixone/pkg/proxy"
"github.com/matrixorigin/matrixone/pkg/tnservice"
"github.com/matrixorigin/matrixone/pkg/udf/pythonservice"
"github.com/matrixorigin/matrixone/pkg/udf/python"
"github.com/matrixorigin/matrixone/pkg/util/debug/goroutine"
tomlutil "github.com/matrixorigin/matrixone/pkg/util/toml"
"github.com/matrixorigin/matrixone/pkg/version"
Expand Down Expand Up @@ -123,8 +123,8 @@ type Config struct {
CN cnservice.Config `toml:"cn"`
// ProxyConfig is the config of proxy.
ProxyConfig proxy.Config `toml:"proxy"`
// PythonUdfServerConfig is the config of python udf server
PythonUdfServerConfig pythonservice.Config `toml:"python-udf-server"`
// PythonUdfWorkerConfig is the config of the Python UDF worker.
PythonUdfWorkerConfig python.Config `toml:"python-udf-worker"`
// Observability parameters for the metric/trace
Observability config.ObservabilityParameters `toml:"observability"`

Expand Down Expand Up @@ -601,7 +601,7 @@ func (c *Config) mustGetServiceUUID() string {
case metadata.ServiceType_PROXY:
return c.ProxyConfig.UUID
case metadata.ServiceType_PYTHON_UDF:
return c.PythonUdfServerConfig.UUID
return c.PythonUdfWorkerConfig.UUID
}
panic("impossible")
}
Expand Down
37 changes: 27 additions & 10 deletions cmd/mo-service/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ import (
qclient "github.com/matrixorigin/matrixone/pkg/queryservice/client"
"github.com/matrixorigin/matrixone/pkg/sql/compile"
"github.com/matrixorigin/matrixone/pkg/tnservice"
"github.com/matrixorigin/matrixone/pkg/udf/pythonservice"
"github.com/matrixorigin/matrixone/pkg/udf/python"
"github.com/matrixorigin/matrixone/pkg/util/debug/goroutine"
"github.com/matrixorigin/matrixone/pkg/util/export"
"github.com/matrixorigin/matrixone/pkg/util/export/table"
Expand Down Expand Up @@ -300,7 +300,7 @@ func startService(
case metadata.ServiceType_LOG:
return startLogService(cfg, stopper, fs, shutdownC)
case metadata.ServiceType_PYTHON_UDF:
return startPythonUdfService(cfg, stopper)
return startPythonUdfWorker(cfg, stopper)
default:
panic("unknown service type")
}
Expand Down Expand Up @@ -738,8 +738,8 @@ func waitProxyFileServiceRetry(ctx context.Context, delay time.Duration) error {
}
}

// startPythonUdfService starts the python udf service.
func startPythonUdfService(cfg *Config, stopper *stopper.Stopper) error {
// startPythonUdfWorker starts the Python UDF worker.
func startPythonUdfWorker(cfg *Config, stopper *stopper.Stopper) error {
if err := waitClusterCondition(cfg.mustGetServiceUUID(), cfg.HAKeeperClient, waitHAKeeperRunning); err != nil {
return err
}
Expand All @@ -752,22 +752,39 @@ func startPythonUdfService(cfg *Config, stopper *stopper.Stopper) error {
finish(err)
})
}
err := stopper.RunNamedTask("python-udf-service", func(ctx context.Context) {
err := stopper.RunNamedTask("python-udf-worker", func(ctx context.Context) {
var closeErr error
defer func() { finishTask(closeErr) }()
roleCtx, cancelRole := serviceLifecycle.roleContext(ctx, serviceRolePython)
defer cancelRole()
s, err := pythonservice.NewService(cfg.PythonUdfServerConfig)
s, err := python.NewSupervisor(cfg.PythonUdfWorkerConfig)
if err != nil {
panic(err)
}
if err := s.Start(); err != nil {
panic(err)
}
<-roleCtx.Done()
if err := s.Close(); err != nil {
closeErr = err
logutil.GetGlobalLogger().Error("failed to close python udf service", zap.Error(err))
workerDone := s.Done()
select {
case <-roleCtx.Done():
if err := s.Close(); err != nil {
closeErr = err
logutil.GetGlobalLogger().Error("failed to close Python UDF worker", zap.Error(err))
}
case <-workerDone:
// A worker exit while the role is still running leaves CN with a
// configured but unusable Python runtime. Surface it as a fatal
// service event so the existing lifecycle supervisor drains CN
// before the worker dependency and does not accept partial service
// availability. A zero exit is still unexpected here.
if roleCtx.Err() == nil {
workerErr := s.Err()
if workerErr == nil {
workerErr = errors.New("process exited without an error")
}
closeErr = fmt.Errorf("python UDF worker exited unexpectedly: %w", workerErr)
serviceLifecycle.notifyFatal(closeErr)
}
}
})
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion docs/cn/stream_transport_fast_upload_plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Phase 0 — Protobuf / gRPC contract

New file `proto/datastream/v1/datastream.proto` (proto3, **not** gogoproto —
this proto is shared with Java, so use standard `protoc-gen-go` +
`protoc-gen-go-grpc`, same toolchain as `pkg/udf/udf.proto`, which is the
`protoc-gen-go-grpc`, using the repository's current protobuf toolchain, which is the
existing real-gRPC precedent in the repo; the main `proto/*.proto` files are
gogo-generated and Java-hostile).

Expand Down
112 changes: 112 additions & 0 deletions docs/design/python_udf.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# Python UDF implementation and rollout scope

This describes the implemented, owner-authorized external Python adapter and its
PR acceptance boundary. The relevant current-stage Catalog, SQL/planner,
migration/restore, Python ABI, Flight, and resource contracts are consolidated
in the [versioned current-stage design](python_udf_current_stage.md). Broader
long-term designs continue to inform future work; this page does not approve a
production tenant-isolation model.

## Owner-approved stage scope

On 2026-09-24, feature owner `iamlinjunhong` approved this PR for testing and
development-stage acceptance. The user guide and SQL examples are recorded in
[issue #28132](https://github.com/matrixorigin/matrixone/issues/28132#issuecomment-5748253137).
This PR does not claim production rollout, sandbox isolation, protection for
untrusted Python, or authenticated/TLS Flight transport. Those remain separate
production acceptance gates. Python stays disabled in generic launch and requires
explicit opt-in in the test/development configurations.

This stage decision is the feature owner's authorization for the current PR
scope; it is not a claim that Architecture, Security, SQL/Planner, Runtime,
Catalog, or Operator owners have approved the future production design.

## Execution and identity

CREATE/REPLACE validates Python syntax and the handler contract before publishing
a definition. The shared Catalog stores immutable typed revisions and complete
argument/return descriptors. Artifacts are digest-addressed, account-scoped and
published through FileService; worker execution receives the verified artifact
from CN. The worker needs no object-storage credentials or query-time package
installation. Old demo definitions are inert: explicitly recreate them using the
current DDL and SDK. Unknown definition, plan, Arrow, SDK or wire contracts fail
before user execution; no legacy fallback or automatic adapter is provided.

Planning resolves an exact FunctionRef and RoutineCall. Prepared/cache reuse
validates the selected revision and the complete overload namespace state; see
[routine namespace validation](routine_namespace_validation.md). Execution never
resolves a mutable latest revision. Clone and restore preserve supported catalog
contracts and republish Python artifacts for the destination account.

CN keeps native MO vectors. The expression framework dispatches typed Python calls
to ExternalRoutineEval; the parent evaluator owns argument evaluation, casts,
CASE/selection and NULL guards. The physical stage compacts selected rows,
admits bounded asynchronous work and scatters verified results, preserving empty
input, NULLs, zero arguments, nested calls and default VOLATILE semantics.

The Gateway is a CN library, not a separately deployed service. It connects to
Arrow Flight served by the Python worker. No second Flight daemon is required.
A worker creates bounded handler subprocesses; each handler/module can be reused
only within the invocation's bounded burst. It does not pool user heaps across
invocations. SCALAR handlers receive `(ctx, scalar...)`; VECTOR handlers receive
`(ctx, arrays...)` and use `ctx.num_rows` for output shape. Arrow field/schema
metadata comes from the trusted adapter, not handler-supplied identity.

## Completion and resources

K bounds active Gateway invocations, H bounds handler execution slots, and W=1
bounds stream batch progress. Admission, group/member state, terminal records and
per-account/per-owner quotas have independent owners and budgets. Protocol steps
include EndInput, InputConsumed, result ACK and Finish/FinishAck. Started work is
never transparently replayed. Cancellation and capability refresh waiters progress
independently; generation fences reject stale completions.

Process cleanup must cover both termination and reaping. Handler sessions own
pipes, child/watchdog processes and H/quota until cleanup succeeds; partial
initialization transfers a failed session to the same bounded pending-cleanup
owner. Linux containers run `/usr/bin/tini -- python -u worker.py`; init adopts
orphaned descendants after their handler leader exits. An Operator command override
must retain this init process. Native Supervisor launches rely on the host's init
(or an explicit subreaper in a container test harness).

## Enablement and deployment boundary

Generic launch keeps Python disabled. The explicit worker-enabled launch and
ordinary BVT entry point enable the unisolated adapter. See
[Python BVT and local launch](../../test/distributed/cases/udf_python/README.md).
Compose configures a separate worker endpoint for each CN. The `PYTHON_UDF`
mo-service role wraps a Go Supervisor; the standalone worker image runs Python
under init. These are different launch forms for the same Flight service.

Gateway and worker must match the current capability contract, including tzdata.
The worker image replaces its entire zoneinfo tree from the MO runtime base;
upgrading tzdata also changes the environment digest of definitions. Check existing
definitions before enabling an incompatible environment and explicitly rebuild
where required. Matching software version strings alone are not this check.

`enabled` and `allow-unisolated` are explicit gates. This implementation does not
provide sandbox isolation or authenticated/TLS Flight transport. Same-Pod Operator
configuration binds the worker to loopback and controls Pod composition; it does
not add broad CN ingress grants. External worker exposure needs a separately
approved security/deployment design. Worker availability is a Python execution
condition, not evidence of production tenant isolation.

## Verification and remaining scope

The regression suite covers scalar/vector Arrow computation, types and malformed
values, guarded SQL positions and DML atomicity, revision/overload invalidation,
exact-descriptor DROP and cross-account snapshot restore. Runtime tests cover
ACK/Finish, cancellation, quotas, initialization/cleanup failure, worker death,
stale events and real Flight consumers. Operator status wire fixtures pin the
producer/consumer error contract.

Linux PR validation uses the repository CGo wrapper, two CNs with distinct
Supervisor/worker endpoints, ordinary SQL/Python BVT, current worker image and
process-tree fault injection. Record the exact revision, selected tests, image
and terminal result with each run; unit or CNI echo tests are not complete
Operator rollout evidence.

Sandbox, production deployment approval, imported dependency environments and
W>1/cumulative ACK enablement remain separate work. W=1 measurements do not prove
that a wider window has no benefit. This PR is related to issue #28132 and does
not close that issue's broader isolated-runtime acceptance criteria.
Loading
Loading