Skip to content

Changelog

cgnl edited this page Mar 28, 2026 · 8 revisions

Changelog

For the full detailed changelog, see CHANGELOG.md.

v1.2.0 (2026-03-28)

  • 92% unsafe reduction — raw pointer dereferences 806→59. Internal functions use safe &mut PgStmt / &mut PgConnection references. Business logic is Rust-safe; unsafe confined to FFI boundary.
  • PgStmt Vec-based allocation — inline [T; 1024] arrays replaced with Vec<T> that grow on-demand. 0-param SELECT uses 540 bytes (was 88KB). Allocated via Box::new(), freed via Drop.
  • Rust Mutex on PgStmt — pthread_mutex_t replaced with std::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.

v1.1.0 (2026-03-26)

  • 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.mutex changed from PTHREAD_MUTEX_DEFAULT to PTHREAD_MUTEX_RECURSIVE, fixing self-deadlock when ensure_pg_result_for_metadata calls resolve_column_tables_impl on the same connection.
  • Fixed: connection mutex convoy — ensure_pg_result_for_metadata now releases the connection mutex before calling resolve_column_tables, preventing thread convoy effects.
  • Fixed: ABBA deadlock (stmt/LOGGER) — logging calls removed from inside stmt/conn mutex scopes. Logger uses try_lock with 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

v1.0.0 (2026-02-22)

  • SQL translator fully migrated to Rust — entire SQLite→PostgreSQL translation pipeline now runs on Rust's sqlparser-rs AST 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)

v0.9.29 (2026-02-16)

  • Fixed: Connection isolation during streaming — resolve_column_tables() and preload_decltype_cache() no longer corrupt streaming connections; use alternate pool connections instead
  • Fixed: Pool acquisition skips streaming_active connections (fast path + PHASE 1)
  • Fixed: PQcancel before all 6 drain loops to prevent hangs
  • Added: streaming_active flag on pg_connection_t with full lifecycle management
  • Added: Dummy shadow statement fallback for failed READ prepares (no shadow SQLite dependency)
  • Added: DDL IF NOT EXISTS injection for shadow SQLite schema operations
  • Added: 37 new tests (connection isolation + shadow fallback). Total: 798 tests, 24 suites

v0.9.28 (2026-02-15)

  • 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)

v0.9.27 (2026-02-14)

  • Fixed: Removed SyncCollections COMPAT skips — eliminates 223 LPE errors at startup
  • Root causes already resolved in v0.9.23, making the skips unnecessary

v0.9.26 (2026-02-13)

  • 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 in doctor.sh

v0.9.25 (2026-02-12)

  • Added: Optional memory telemetry (PLEX_PG_MEM_TELEMETRY=1)
  • Confirmed: Shim allocates only 14KB total under normal load

v0.9.24 (2026-02-12)

  • Fixed: Statement cleanup leak — bind values freed across all MAX_PARAMS slots
  • Added: 2 regression tests for parameter slot cleanup

v0.9.23 (2026-02-10)

  • Fixed: 142-221 LPE: only library URIs are allowed errors per startup (server:// → library:// rewrite)
  • Fixed: std::bad_cast on /library/metadata/<id> and /related endpoints
  • Added: 13 URI rewrite tests

v0.9.22 (2026-02-09)

  • Refactored: Extracted db_interpose_value.c — all 7 sqlite3_value_* functions in separate module (column.c: 2065 → 1769 lines)

v0.9.21 (2026-02-09)

  • Fixed: macOS sqlite3_column_decltype not 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)

v0.9.20 (2026-02-09)

  • 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-test Makefile 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_demangle skip)

v0.9.19 (2026-02-09)

  • Fixed: Block junk metadata inserts with both library_section_id and metadata_type NULL
  • Fixed: schema_migrations ON CONFLICT DO NOTHING to 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)

v0.9.18 (2026-02-09)

  • Fixed: Auto-reconnect PostgreSQL after connection loss or restart
  • Retry once after 500ms if pool returns NULL, fallback to fresh PQconnectdb if PQreset fails

v0.9.17 (2026-02-09)

  • Changed: macOS shim dylib installed into Plex.app bundle
  • Scanner uses @loader_path for portable LC_LOAD_DYLIB
  • Server wrapper simplified, no more placeholder sed or auto-build

v0.9.14 (2026-02-08)

  • Fix: Linux Received unexpected async signal 17 crash loops under LD_PRELOAD
  • Fix: Added Linux passthrough mode for non-server/scanner child processes
  • Fix: Docker init now syncs SQLite shadow schema_migrations from PostgreSQL (prevents migration reruns)
  • Changed: docker-compose.standalone.yml default log level to ERROR
  • Validation: Linux scanner path tested (Plex Media Scanner starts with shim)

v0.9.13 (2026-02-07)

  • Fix: make install on Linux no longer tries to build macOS-only fishhook.c
  • Added: Dockerfile.standalone for plexinc/pms-docker users
  • 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

v0.9.12 (2026-02-06)

  • 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

v0.9.11 (2026-02-04)

  • Fix: Stack overflow from circular parent_id references
  • Fix: ORDER BY syntax error in GROUP BY translation
  • Added: Database triggers to prevent circular parent references

v0.9.10 (2026-02-02)

  • Fix: Kernel panic from fflush(NULL) deadlock with log mutex
  • Fix: SOCI "Null value not allowed for this type" exceptions (HTTP 500)

v0.9.8 (2026-01-30)

  • Added: Full blobs.db PostgreSQL support (thumbnails, artwork, posters)

v0.9.4 (2026-01-25)

  • Fix: TOCTOU race condition — PQstatus crashes from connection state changes

v0.9.3 (2026-01-24)

  • Fix: Infinite recursion loops in pool cleanup

v0.9.2 (2026-01-20)

  • Fix: Timeline 500 error — sqlite3_last_insert_rowid() wrong database handle

v0.8.12 (2026-01-13)

  • Fix: TV shows HTTP 500 — SOCI std::bad_cast with BIGINT aggregates

v0.8.10 (2026-01-12)

  • Fix: Transaction handling — BEGIN/COMMIT/ROLLBACK now executed on PostgreSQL
  • Fix: Connection mismatch in lastval() — wrong sequence values