Repository navigation
Changelog
cgnl edited this page Oct 9, 2026
·
10 revisions
Regular release: complete changelog and downloads.
- PostgreSQL transaction/reconnect, migration/export and SQLite ABI fixes.
- FTS rebuilds preserve source metadata; SQLite backing tables, skipped spellfix statements and temporary tokenizers use the appropriate engine.
- Native eight-lane acceptance workflow with 100 restart cycles and 5h50 soak.
- Real Big Buck Bunny and The Beverly Hillbillies S01E01/E02 scan, streaming, byte-range, full audio/video decoding and recovery checks.
- Linux/macOS release bundles with SHA256 files; README and wiki refreshed.
The complete native matrix/soak is unfinished; fixture downloads on some GitHub runners return HTTP 403. Local native full movie/TV playback and recovery passed. This regular release does not claim complete native production certification. Stability Testing records the scope and remaining gates.
The latest published release is v1.3.20. Consult its release notes for the shipped changes. Native acceptance of the new stability candidate is still pending; this page does not certify the existing release for the new Plex/PG matrix.
-
92% unsafe reduction — raw pointer dereferences 806→59. Internal functions use safe
&mut PgStmt/&mut PgConnectionreferences. Business logic is Rust-safe; unsafe confined to FFI boundary. -
PgStmt Vec-based allocation — inline
[T; 1024]arrays replaced withVec<T>that grow on-demand. 0-param SELECT uses 540 bytes (was 88KB). Allocated viaBox::new(), freed via Drop. -
Rust Mutex on PgStmt —
pthread_mutex_treplaced withstd::sync::Mutex<()>. -
138 functions de-FFI'd — removed
#[no_mangle] extern "C"from Rust-only functions. - 55 safe orig_sqlite3 accessors — macro-generated wrappers encapsulate static mut reads.
- Memory leak fix (1.8GB→59MB) — PGresult leak in re-execution path, transaction control routing mismatch (BEGIN/COMMIT sent to PG instead of skipped), cached_result ref_count not released on stmt free.
- 3 deadlocks eliminated — connection mutex self-deadlock, ABBA deadlock (stmt→LOGGER), connection mutex convoy.
- 11 data races fixed — atomic counters/flags, seqlock on crash buffers, OnceLock for lazy config, eager hook resolution, AtomicPtr for fishhook linked list.
-
Stack overflow fix — all large allocations use
vec![].into_boxed_slice()for Plex's 544K worker threads. - Performance — browse 500 items 37% faster (PQcancel fast path, conditional type validation, lazy log macros).
-
Clippy clean — zero warnings with
-D warnings.
- 100% Rust shim runtime — all C interpose/runtime code eliminated. The shim compiles entirely from Rust into a single static library linked into the dylib/so. No C object files remain.
-
Module split — monolithic Rust files split into focused submodules:
db_interpose_column/,db_interpose_common/,db_interpose_step/,db_interpose_prepare/,pg_client/,pg_statement/, and 15+ other module directories. -
Fixed: connection mutex self-deadlock —
PgConnection.mutexchanged fromPTHREAD_MUTEX_DEFAULTtoPTHREAD_MUTEX_RECURSIVE, fixing self-deadlock whenensure_pg_result_for_metadatacallsresolve_column_tables_implon the same connection. -
Fixed: connection mutex convoy —
ensure_pg_result_for_metadatanow releases the connection mutex before callingresolve_column_tables, preventing thread convoy effects. -
Fixed: ABBA deadlock (stmt/LOGGER) — logging calls removed from inside stmt/conn mutex scopes. Logger uses
try_lockwith stderr fallback. -
Fixed: stack overflow — thread-local text buffers (512KB) heap-allocated via
Box::new()for Plex's 544K worker stacks. - Fixed: rusqlite 0.32 compat — tests updated for API changes.
- Total: 712 tests passing
-
SQL translator fully migrated to Rust — entire SQLite→PostgreSQL translation pipeline now runs on Rust's
sqlparser-rsAST engine. C translator removed. 525 Rust tests. - PG modules migrated to hybrid C/Rust — all 7 backend modules (pg_config, pg_logging, pg_client, pg_statement, pg_query_cache, pg_mem_telemetry, shim_alloc) now have core logic in Rust with thin C shims. ~550 C tests across 25 suites.
-
C SQL translator removed —
sql_tr_*.c,sql_translator.c, and all related Makefile objects deleted. - Docker and CI builds updated for Rust — Dockerfiles, build_shim_musl.sh, and GitHub Actions workflows install Rust toolchain and build the sql-translator staticlib.
-
Git repository size reduced — removed accidentally committed
rust/sql-translator/target/from history. Repo went from 243MB to 60MB. - Total: 1,075+ tests (525 Rust + ~550 C)
-
Fixed: Connection isolation during streaming —
resolve_column_tables()andpreload_decltype_cache()no longer corrupt streaming connections; use alternate pool connections instead -
Fixed: Pool acquisition skips
streaming_activeconnections (fast path + PHASE 1) -
Fixed:
PQcancelbefore all 6 drain loops to prevent hangs -
Added:
streaming_activeflag onpg_connection_twith full lifecycle management - Added: Dummy shadow statement fallback for failed READ prepares (no shadow SQLite dependency)
-
Added: DDL
IF NOT EXISTSinjection for shadow SQLite schema operations - Added: 37 new tests (connection isolation + shadow fallback). Total: 798 tests, 24 suites
-
Added: Single-row streaming mode (
PQsetSingleRowMode) for READ queries — row-by-row instead of full result fetch - Fixed: SQL translation bugs (placeholder counting, string quoting, upsert without column list)
- Fixed: Removed SyncCollections COMPAT skips — eliminates 223 LPE errors at startup
- Root causes already resolved in v0.9.23, making the skips unnecessary
-
Fixed: JSON
->>operator rewritten correctly for Plex v1.43 -
Fixed:
instr()→STRPOS()translation - Fixed: Migration CSV truncation for large TEXT fields (Python bridge)
-
Added:
migrate_table.py, truncated JSON detection indoctor.sh
-
Added: Optional memory telemetry (
PLEX_PG_MEM_TELEMETRY=1) - Confirmed: Shim allocates only 14KB total under normal load
-
Fixed: Statement cleanup leak — bind values freed across all
MAX_PARAMSslots - Added: 2 regression tests for parameter slot cleanup
-
Fixed: 142-221
LPE: only library URIs are allowederrors per startup (server:// → library:// rewrite) -
Fixed:
std::bad_caston/library/metadata/<id>and/relatedendpoints - Added: 13 URI rewrite tests
-
Refactored: Extracted
db_interpose_value.c— all 7sqlite3_value_*functions in separate module (column.c: 2065 → 1769 lines)
-
Fixed: macOS
sqlite3_column_decltypenot intercepted (missing from fishhook rebindings) - Fixed: Linux decltype wrapper bypassed SOCI type mapping
- Fixed: macOS fallback only loaded ~11 of ~60 symbols
-
Added:
common_load_sqlite_symbols()— shared dlsym loading for both platforms -
Added:
platform_backtrace.c— unified backtrace module (~300 lines dedup removed) - Added: 66 new platform parity tests (764 total, 23 suites)
- Added: GitHub Actions unit test pipeline — 657 tests run on every push and PR
- Added: ~160 new unit tests for SQL translator and upsert (540 -> 698 total)
-
Added:
ci-testMakefile target for CI-safe test subset - Fixed: 3 SQL translator bugs found by new tests (upsert schema prefix, case booleans fast-path, datetime type fast-path)
-
Fixed: Linux/GCC test portability (stack tests,
ptrdiff_t,__cxa_demangleskip)
-
Fixed: Block junk metadata inserts with both
library_section_idandmetadata_typeNULL -
Fixed:
schema_migrationsON CONFLICT DO NOTHINGto prevent UNIQUE violation crash - Fixed: Placeholder translator only tracks single-quote strings, not double-quote identifiers
- Fixed: Duplicate assignment dedup handles backtick-quoted columns
- Added: NULLS FIRST ordering for GROUP BY queries (SOCI compatibility)
- Fixed: Auto-reconnect PostgreSQL after connection loss or restart
- Retry once after 500ms if pool returns NULL, fallback to fresh
PQconnectdbifPQresetfails
- Changed: macOS shim dylib installed into Plex.app bundle
- Scanner uses
@loader_pathfor portableLC_LOAD_DYLIB - Server wrapper simplified, no more placeholder sed or auto-build
-
Fix: Linux
Received unexpected async signal 17crash loops underLD_PRELOAD - Fix: Added Linux passthrough mode for non-server/scanner child processes
-
Fix: Docker init now syncs SQLite shadow
schema_migrationsfrom PostgreSQL (prevents migration reruns) -
Changed:
docker-compose.standalone.ymldefault log level toERROR -
Validation: Linux scanner path tested (
Plex Media Scannerstarts with shim)
-
Fix:
make installon Linux no longer tries to build macOS-onlyfishhook.c -
Added:
Dockerfile.standaloneforplexinc/pms-dockerusers -
Added:
scripts/doctor.sh— checks and fixes schema + data integrity -
Added:
scripts/migrate_pg_to_sqlite.sh— export back to SQLite (beta) - Closes #4, #5
- Fix: Excessive logging causing 34+ GB/day disk writes, system freeze, and kernel panic
- Debug/trace statements were firing at ERROR level on every query
-
Fix: Stack overflow from circular
parent_idreferences - Fix: ORDER BY syntax error in GROUP BY translation
- Added: Database triggers to prevent circular parent references
-
Fix: Kernel panic from
fflush(NULL)deadlock with log mutex - Fix: SOCI "Null value not allowed for this type" exceptions (HTTP 500)
- Added: Full blobs.db PostgreSQL support (thumbnails, artwork, posters)
- Fix: TOCTOU race condition — PQstatus crashes from connection state changes
- Fix: Infinite recursion loops in pool cleanup
-
Fix: Timeline 500 error —
sqlite3_last_insert_rowid()wrong database handle
-
Fix: TV shows HTTP 500 — SOCI
std::bad_castwith BIGINT aggregates
- Fix: Transaction handling — BEGIN/COMMIT/ROLLBACK now executed on PostgreSQL
-
Fix: Connection mismatch in
lastval()— wrong sequence values