-
Notifications
You must be signed in to change notification settings - Fork 10
Changelog
cgnl edited this page Mar 28, 2026
·
8 revisions
For the full detailed changelog, see CHANGELOG.md.
-
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