Skip to content

Tags: sqliteai/sqlite-sync-dev

Tags

0.9.202

Toggle 0.9.202's commit message
fix: update schema hash on extension version change

When upgrading from an older version, the schema hash algorithm may
differ. Call cloudsync_update_schema_hash before updating the stored
version to ensure hash compatibility across synced devices.

0.9.201

Toggle 0.9.201's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
refactor: move all savepoint management from shared layer to platform…

… wrappers (#17)

* refactor: move all savepoint management from shared layer to platform wrappers

Move database_begin_savepoint, database_commit_savepoint, and
database_rollback_savepoint calls out of cloudsync_begin_alter and
cloudsync_commit_alter (shared CRDT logic) into the platform-specific
wrappers in cloudsync_sqlite.c and cloudsync_postgresql.c.

This fixes the PostgreSQL "subtransaction left non-empty SPI stack"
warning by ensuring SPI_connect() is called before the savepoint
boundary, and creates architectural symmetry where shared code is
pure business logic and all transaction management lives in platform
wrappers.

0.9.200

Toggle 0.9.200's commit message
fix(ci): remove artifact size increase check to be less than 5% from …

…previous release

0.9.118

Toggle 0.9.118's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
Dev (#14)

* fix(network): cloudsync_network_check_changes must not return the nrows value in case of error

`SELECT cloudysnc_network_check_changes();` was returning "Runtime error: 0" in case of error response from the cloudsync microservice instead of the real error message

* feat(rls): add complete support for RLS with batch merge in cloudsync_payload_apply

* Feat/add support for status endpoint (#10)

* feat(network): add support for new status endpoint

* refactor(network): structured JSON responses for sync functions. 
Example: {"send":{"status":"synced","localVersion":5,"serverVersion":5},"receive":{"rows":3,"tables":["tasks"]}}

* Feat/network support for multi org cloudsync (#11)

* Disable notnull prikey constraints (#12)

* The cloudsync extension now enforces NULL primary key rejection at runtime (any write with a NULL PK returns an error), so the explicit NOT NULL constraint on primary key  columns is no longer a schema requirement

* test: add null primary key rejection tests for SQLite and PostgreSQL

* docs: remove NOT NULL requirement from primary key definitions

The extension now enforces NULL primary key rejection at runtime, so
the explicit NOT NULL constraint on PK columns is no longer a schema
requirement. Replace the "must be NOT NULL" guidance with a note about
runtime enforcement.

* docs: add first draft of PERFORMANCE.md and CHANGELOG.md

* fix(postgresql): resolve commit_alter crash and BYTEA handling in column_text

Guard savepoint commit/rollback against missing subtransactions to prevent
segfault in autocommit mode. Add BYTEA support to database_column_text so encoded PKs are readable during refill_metatable after ALTER TABLE.
Enable alter table sync test (31).

* test: new alter table test for postgres

* feat: update endpoints to use databaseMangedId for /v2/cloudsync api
* feat(network)!: replace URL connection string with a UUID (managedDatabaseId)

BREAKING CHANGE: cloudsync_network_init now accepts a UUID string instead of the previous URL string. URL connection strings are no longer accepted. The managed database identifier returned by the CloudSync service when a new database is registered for sync. For SQLiteCloud projects, this value can be obtained from the project's OffSync page on the dashboard.

* docs: update docs for the new managedDatabaseId arg for cloudsync_network_init

* docs(examples): update example for the new managedDatabaseId arg for cloudsync_network_init

0.9.112

Toggle 0.9.112's commit message
fix(sqlite): PRIVATE functions used inside triggers require SQLITE_IN…

…NOCUOUS

... otherwise the cloudsync_init function returns this error:
table_add_stmts error: 1 unsafe use of cloudsync_is_sync()
Runtime error: An error occurred while adding test_sync table information to global context (unsafe use of cloudsync_is_sync()) (21)

0.9.111

Toggle 0.9.111's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
Fix 35 bugs and bump version to 0.9.111 (#9)

* Fix 35 bugs across CloudSync SQLite/PostgreSQL sync extension

Comprehensive audit identified and fixed 35 bugs (1 CRITICAL, 7 HIGH,
18 MEDIUM, 9 LOW) across the entire codebase. All 84 SQLite tests and
26 PostgreSQL tests pass with 0 failures and 0 memory leaks.

## src/cloudsync.c (13 fixes)

- [HIGH] Guard NULL db_version_stmt in cloudsync_dbversion_rerun —
  set db_version = CLOUDSYNC_MIN_DB_VERSION and return 0 when stmt
  is NULL, preventing NULL dereference after schema rebuild failure
- [MEDIUM] Add early return for NULL stmt in dbvm_execute to prevent
  crash when called with uninitialized statement pointer
- [MEDIUM] Change (bool)dbvm_count() to (dbvm_count() > 0) in
  table_pk_exists — prevents negative return values being cast to
  true, giving false positive "pk exists" results
- [MEDIUM] Add NULL check on database_column_text result in
  cloudsync_refill_metatable before calling strlen — prevents crash
  on corrupted or empty column data
- [MEDIUM] Route early returns in cloudsync_payload_apply through
  goto cleanup so CLEANUP callback and vm finalize always run —
  prevents resource leaks and callback contract violation
- [MEDIUM] Change return false to goto abort_add_table when
  ROWIDONLY rejected — ensures table_free runs on the partially
  allocated table, preventing memory leak
- [MEDIUM] Initialize *persistent = false at top of
  cloudsync_colvalue_stmt — prevents use of uninitialized value
  when table_lookup returns NULL
- [LOW] Add NULL check on database_column_blob in merge_did_cid_win
  — prevents memcmp with NULL pointer on corrupted cloudsync table
- [LOW] Handle partial failure in table_add_to_context_cb — clean
  up col_name, col_merge_stmt, col_value_stmt at index on error
  instead of leaving dangling pointers
- [LOW] Remove unused pragma_checked field from cloudsync_context
- [LOW] Change pointer comparison to strcmp in cloudsync_set_schema
  — pointer equality missed cases where different string pointers
  had identical content
- [LOW] Fix cloudsync_payload_get NULL check: blob == NULL (always
  false for char** arg) changed to *blob == NULL
- [LOW] Pass extra meta_ref args to SQL_CLOUDSYNC_UPSERT_COL_INIT_OR_BUMP_VERSION
  mprintf call to match updated PostgreSQL format string

## src/sqlite/cloudsync_sqlite.c (5 fixes)

- [HIGH] Split DEFAULT_FLAGS into FLAGS_PURE (SQLITE_UTF8 |
  SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC) and FLAGS_VOLATILE
  (SQLITE_UTF8). Pure functions: cloudsync_version, cloudsync_pk_encode,
  cloudsync_pk_decode. All others volatile — fixes cloudsync_uuid()
  returning identical values within the same query when SQLite cached
  deterministic results
- [HIGH] Fix realloc inconsistency in dbsync_update_payload_append:
  on second realloc failure, state was inconsistent (new_values
  resized, old_values not, capacity not updated). Both reallocs now
  checked before updating pointers and capacity
- [MEDIUM] Move payload->count++ after all database_value_dup NULL
  checks in dbsync_update_payload_append — prevents count increment
  when allocation failed, which would cause use-after-free on cleanup
- [MEDIUM] Add dbsync_update_payload_free(payload) before 3 early
  returns in dbsync_update_final — prevents memory leak of entire
  aggregate payload on error paths
- [MEDIUM] Clean up partial database_value_dup allocations on OOM in
  dbsync_update_payload_append — free dup'd values at current index
  when count is not incremented to prevent leak

## src/sqlite/database_sqlite.c (6 fixes)

- [MEDIUM] Replace fixed 4096-byte trigger WHEN clause buffers with
  dynamic cloudsync_memory_mprintf — prevents silent truncation for
  tables with long filter expressions
- [MEDIUM] Check cloudsync_memory_mprintf return for NULL before
  storing in col_names[] in database_build_trigger_when — prevents
  strlen(NULL) crash in filter_is_column under OOM
- [LOW] Use consistent PRId64 format with (int64_t) cast for schema
  hash in database_check_schema_hash and database_update_schema_hash
  — prevents format string mismatch on platforms where uint64_t and
  int64_t have different printf specifiers
- [LOW] Fix DEBUG_DBFUNCTION using undeclared variable 'table'
  instead of 'table_name' in database_create_metatable (line 568)
  and database_create_triggers (line 782) — compile error when
  debug macros enabled
- [LOW] Remove dead else branch in database_pk_rowid — unreachable
  code after sqlite3_prepare_v2 success check

## src/sqlite/sql_sqlite.c (1 fix)

- [MEDIUM] Change %s to %q in SQL_INSERT_SETTINGS_STR_FORMAT —
  prevents SQL injection via malformed setting key/value strings

## src/dbutils.c (1 fix)

- [MEDIUM] Change snprintf to cloudsync_memory_mprintf for settings
  insert using the new %q format — ensures proper SQL escaping

## src/utils.c (1 fix)

- [MEDIUM] Fix integer overflow in cloudsync_blob_compare:
  (int)(size1 - size2) overflows for large size_t values, changed
  to (size1 > size2) ? 1 : -1

## src/network.c (1 fix)

- [MEDIUM] Remove trailing semicolon from savepoint name
  "cloudsync_logout_savepoint;" — semicolon in name caused
  savepoint/release mismatch

## src/postgresql/sql_postgresql.c (1 fix)

- [CRITICAL] Replace EXCLUDED.col_version with %s.col_version
  (table reference) in SQL_CLOUDSYNC_UPSERT_COL_INIT_OR_BUMP_VERSION
  — PostgreSQL EXCLUDED refers to the proposed INSERT row (always
  col_version=1), not the existing row. This caused col_version to
  never increment correctly on conflict, breaking CRDT merge logic

## src/postgresql/cloudsync_postgresql.c (4 fixes)

- [HIGH] Change PG_RETURN_INT32(rc) to PG_RETURN_BOOL(rc == DBRES_OK)
  in pg_cloudsync_terminate — SQL declaration returns BOOLEAN but code
  returned raw integer, causing protocol mismatch
- [HIGH] Copy blob data with palloc+memcpy before databasevm_reset in
  cloudsync_col_value, and fix PG_RETURN_CSTRING to PG_RETURN_BYTEA_P
  — reset invalidates SPI tuple memory, causing use-after-free; wrong
  return type caused type mismatch with SQL declaration
- [MEDIUM] Use palloc0 instead of cloudsync_memory_alloc+memset in
  aggregate context — palloc0 is lifetime-safe in PG aggregate memory
  context; cloudsync_memory_alloc uses wrong allocator
- [MEDIUM] Free SPI_tuptable in all paths of get_column_oid — prevents
  SPI tuple table leak on early return

## src/postgresql/database_postgresql.c (3 fixes)

- [MEDIUM] Use sql_escape_identifier for table_name/schema in CREATE
  INDEX — prevents SQL injection via specially crafted table names
- [MEDIUM] Use sql_escape_literal for table_name in trigger WHEN
  clause — prevents SQL injection in trigger condition
- [LOW] Use SPI_getvalue instead of DatumGetName for type safety in
  database_pk_names — DatumGetName assumes Name type which may not
  match the actual column type from information_schema

## test/unit.c (3 new tests)

- do_test_blob_compare_large_sizes: verifies overflow fix for large
  size_t values in cloudsync_blob_compare
- do_test_deterministic_flags: verifies cloudsync_uuid() returns
  different values in same query (non-deterministic flag working)
- do_test_schema_hash_consistency: verifies int64 hash format
  roundtrip through cloudsync_schema_versions table

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Bump version to 0.9.111

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Update .gitignore

0.9.110

Toggle 0.9.110's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
Merge pull request #8 from sqliteai/dev

release version 0.9.110

- fix/schema-hash
- fix/bind-column-value-parameters-also-if-null
- feat/sync-filter

0.9.101

Toggle 0.9.101's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
perf(postgres): use SQL template casting for non-PK column types (#4)

* perf(postgres): use SQL template casting for non-PK column types

Refactor type conversion for non-PK columns to use SQL template casting ($n::typename) instead of per-value SPI_execute_with_args("SELECT $1::typename") calls. This matches the pattern already used for primary key columns.

Changes:
  - sql_postgresql.c: Add format_type() lookup and $n::coltype casting to SQL_BUILD_UPSERT_PK_AND_COL for non-PK column values
  - cloudsync_postgresql.c: Simplify cloudsync_decode_bytea_to_pgvalue() to return base types only (INT8, FLOAT8, TEXT, BYTEA) without SPI casting
  - cloudsync_postgresql.c: Remove lookup_column_type_oid() function
  - Add test 19 (19_uuid_pk_with_unmapped_cols.sql) covering UUID PK with unmapped non-PK types (JSONB, UUID, INET, CIDR) and all CRUD operations: INSERT, UPDATE non-PK, UPDATE mapped cols, DELETE, RESURRECT, UPDATE PK

Performance benefit: Eliminates one SPI_execute call per non-PK column value during payload application, reducing overhead for unmapped PostgreSQL types.

* test(postgres): new tests

0.9.100

Toggle 0.9.100's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
feat: add support for UUID primary keys in PG (#3)

* Fix for PG UUID used as PK

* build(postgres): update test target for the current test files

* docs(docs/postgresql/CLIENT.md): clarify primary key requirements for PostgreSQL and SQLite, added support for UUID primary keys

* test(claude): add custom command for claude code to run sqlite-to-pg tests for the specified table schema

---------

Co-authored-by: Marco Bambini <marco@creolabs.com>

0.9.99

Toggle 0.9.99's commit message
feat: support to https connection string and JWT token