Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
12 changes: 11 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,22 @@ jobs:
- run: cargo test -p graphql-orm --no-default-features --features sqlite,field-case-pascal,argument-case-snake --test federation_entity_keys_case_features
- run: cargo check -p graphql-orm --no-default-features --features postgres
- run: cargo test -p graphql-orm --no-default-features --features postgres --test federation_entity_keys_postgres
- name: Execute runtime strings and binding identity on owned PostgreSQL
env:
CARGO_BUILD_JOBS: "2"
run: cargo test -p graphql-orm --locked --no-default-features --features postgres --test runtime_strings -- --include-ignored --test-threads=1
- name: Execute the private runtime string consumer on owned PostgreSQL
env:
CARGO_BUILD_JOBS: "2"
run: cargo test --manifest-path crates/graphql-orm/tests/fixtures/repository-aggregate-consumer/Cargo.toml --locked --no-default-features --features postgres --test runtime_strings -- --ignored --test-threads=1
- name: Execute the private runtime string consumer on owned SQLite
run: cargo run --manifest-path crates/graphql-orm/tests/fixtures/repository-aggregate-consumer/Cargo.toml --locked --no-default-features --features sqlite --example runtime_strings
- name: Execute host timestamps on owned PostgreSQL
run: cargo test -p graphql-orm --locked --no-default-features --features postgres --test host_timestamps -- --ignored --test-threads=1
- name: Execute the private PostgreSQL host timestamp consumer
run: cargo test --manifest-path crates/graphql-orm/tests/fixtures/repository-aggregate-consumer/Cargo.toml --locked --no-default-features --features postgres --test host_timestamps -- --ignored --test-threads=1
- run: cargo check -p graphql-orm --no-default-features --features mssql
- run: cargo test -p graphql-orm --no-default-features --features mssql --test federation_entity_keys_mssql
- run: cargo test -p graphql-orm --no-default-features --features mssql --test federation_entity_keys_mssql --test runtime_records --test query_ir
- run: cargo clippy -p graphql-orm --all-targets -- -D warnings
- run: RUSTDOCFLAGS="-D warnings" cargo doc -p graphql-orm -p graphql-orm-macros --no-deps

Expand Down
5 changes: 4 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -157,11 +157,14 @@ jobs:
cargo test -p graphql-orm --no-default-features --features postgres --test federation_entity_keys_postgres --locked
cargo test -p graphql-orm --no-default-features --features postgres --test projection_visibility --test cross_crate_relations_fixture --test repository_counts --locked
cargo test -p graphql-orm --no-default-features --features postgres --test grouped_aggregates_postgres --test portable_group_pages --test host_timestamps --locked -- --ignored --test-threads=1
cargo test -p graphql-orm --locked --no-default-features --features postgres --test runtime_strings -- --include-ignored --test-threads=1
cargo test --manifest-path crates/graphql-orm/tests/fixtures/repository-aggregate-consumer/Cargo.toml --locked --no-default-features --features postgres --test runtime_strings -- --ignored --test-threads=1
cargo run --manifest-path crates/graphql-orm/tests/fixtures/repository-aggregate-consumer/Cargo.toml --locked --no-default-features --features sqlite --example runtime_strings
cargo run --manifest-path crates/graphql-orm/tests/fixtures/repository-aggregate-consumer/Cargo.toml --locked --no-default-features --features sqlite --example policy_projections
cargo run --manifest-path crates/graphql-orm/tests/fixtures/repository-aggregate-consumer/Cargo.toml --locked --no-default-features --features sqlite --example complete_events
cargo test --manifest-path crates/graphql-orm/tests/fixtures/repository-aggregate-consumer/Cargo.toml --locked --no-default-features --features postgres --test portable_groups --test host_timestamps -- --ignored --test-threads=1
cargo check -p graphql-orm --no-default-features --features mssql --locked
cargo test -p graphql-orm --no-default-features --features mssql --test federation_entity_keys_mssql --locked
cargo test -p graphql-orm --no-default-features --features mssql --test federation_entity_keys_mssql --test runtime_records --test query_ir --locked
cargo clippy -p graphql-orm --all-targets --locked -- -D warnings
RUSTDOCFLAGS="-D warnings" cargo doc -p graphql-orm -p graphql-orm-macros --no-deps --locked

Expand Down
18 changes: 16 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: "Changelog"
kind: reference
status: active
owner: workspace-maintainers
last_reviewed: 2026-10-02
last_reviewed: 2026-10-06
review_by: 2027-02-01
supersedes: []
---
Expand All @@ -14,7 +14,21 @@ This file is the authoritative user-facing release chronology. The former
[release-notes ledger](docs/archive/2026/graphql-orm-release-notes.md) is retained
for historical context.

## 0.39.0 - unreleased
## 0.39.1 - unreleased

Companion macros crate: `graphql-orm-macros` **0.39.1** (alignment only).

- Correct runtime SQLite `ends_with("")` to match every non-null string;
preserve case-sensitive literal, Unicode and SQL NULL semantics.
- Preserve repeated native PostgreSQL parameter identity at complete-statement
binding boundaries, including authenticated count/read pairs and transaction
reads/writes. Retain anonymous/mixed occurrence rebasing and static fragment
semantics; no public signature, cursor, schema or migration changes.
- Add owned SQLite/PostgreSQL execution, evaluator/page/count/RLS parity,
normalization and dependency-minimal external-consumer regressions. MSSQL
runtime capability gates remain unchanged; no live MSSQL claim is made.

## 0.39.0 - 2026-10-03

Companion macros crate: `graphql-orm-macros` **0.39.0**.

Expand Down
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ cynic-parser = { version = "=0.11.2", features = ["pretty"] }
futures = "0.3"
getrandom = "0.3"
graphql-composition = "=0.12.2"
graphql-orm = { path = "crates/graphql-orm", version = "0.39.0", default-features = false }
graphql-orm = { path = "crates/graphql-orm", version = "0.39.1", default-features = false }
graphql-orm-ai-tool-profiles = { path = "crates/graphql-orm-ai-tool-profiles", version = "0.15.0" }
graphql-orm-backup = { path = "crates/graphql-orm-backup", version = "0.7.2", default-features = false }
graphql-orm-operation-catalog = { path = "crates/graphql-orm-operation-catalog", version = "0.4.0" }
Expand Down
27 changes: 26 additions & 1 deletion MIGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: "Migration Guide"
kind: reference
status: active
owner: workspace-maintainers
last_reviewed: 2026-10-02
last_reviewed: 2026-10-06
review_by: 2027-02-01
supersedes: []
---
Expand All @@ -13,6 +13,31 @@ supersedes: []
`graphql-orm` is distributed from GitHub only. Use a reviewed full 40-character commit in `rev`;
neither the runtime nor macros crate is published to crates.io.

## Runtime string predicates and PostgreSQL binding (0.39.1)

Adopt aligned ORM/macros 0.39.1. No data migration, declaration change, GraphQL
SDL change, or cursor-format change is required. SQLite runtime empty suffixes
now match every non-null string, as empty prefixes already do. SQL NULL remains
unknown under comparisons and NOT; use an explicit null predicate to include it.

`PostgresBackend::normalize_sql` is a complete-statement binding boundary:
SQL using only native `$n` parameters retains each index and repeated identity.
A positive rebasing start adds `start_index - 1` to each native index. Previously,
repeated references were incorrectly allocated separate slots; out-of-order
indices were also renumbered. Callers must supply values for the actual native
slots, rather than relying on occurrence order. Ordinary generated static queries
already compose contiguous native indices and require no call-site edits.

Anonymous or mixed placeholder forms retain legacy occurrence-based rebasing;
mixed forms do not express shared native identity. `SqlDialect::normalize_sql`
retains static-fragment occurrence rebasing, including generated fragments with
arbitrary or restarted native labels. Do not use fragment rebasing on a complete
native statement whose repeated parameters share a bound value.

See [runtime string semantics, executable consumer and backend checks](docs/reference/graphql-orm/runtime-queries.md).
Runtime MSSQL remains unsupported before I/O. This independent query fix does
not implement the proposed runtime migration/mutation/dynamic GraphQL contracts.

## Repository host timestamps (0.39.0)

Adopt aligned ORM/macros 0.39.0. Existing declarations require no edits and keep
Expand Down
2 changes: 1 addition & 1 deletion crates/graphql-orm-macros/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "graphql-orm-macros"
version = "0.39.0"
version = "0.39.1"
edition = "2024"
authors = ["Toby Martin"]
description = "Procedural macros for async-graphql and ORM-backed entities, relations, and CRUD operations."
Expand Down
9 changes: 6 additions & 3 deletions crates/graphql-orm-macros/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: "graphql-orm-macros"
kind: reference
status: active
owner: graphql-orm-macros-maintainers
last_reviewed: 2026-10-02
last_reviewed: 2026-10-06
review_by: 2027-02-01
supersedes: []
---
Expand All @@ -16,19 +16,22 @@ macro/runtime versions aligned:

```toml
[dependencies]
graphql-orm = { git = "https://github.com/Dastari/graphql-orm.git", rev = "<reviewed-full-40-character-commit-sha>", version = "0.39.0", default-features = false, features = ["sqlite"] }
graphql-orm = { git = "https://github.com/Dastari/graphql-orm.git", rev = "<reviewed-full-40-character-commit-sha>", version = "0.39.1", default-features = false, features = ["sqlite"] }
```

Direct use is supported for tooling that needs the macro package:

```toml
graphql-orm-macros = { git = "https://github.com/Dastari/graphql-orm.git", rev = "<reviewed-full-40-character-commit-sha>", version = "0.39.0", default-features = false, features = ["sqlite"] }
graphql-orm-macros = { git = "https://github.com/Dastari/graphql-orm.git", rev = "<reviewed-full-40-character-commit-sha>", version = "0.39.1", default-features = false, features = ["sqlite"] }
```

The direct dependency still requires a compatible `graphql-orm` runtime in the
consumer crate because generated code refers to `::graphql_orm`. The macros do
not connect to a database, run migrations, host GraphQL, or authorize requests.

Version 0.39.1 aligns with the runtime string/binding correction; generated
static fragment rebasing, inputs, GraphQL SDL and timestamp behavior are unchanged.

## Public macros

| Item | Purpose |
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions crates/graphql-orm/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "graphql-orm"
version = "0.39.0"
version = "0.39.1"
edition = "2024"
description = "Runtime support crate for graphql-orm-macros"
license = "MIT"
Expand Down Expand Up @@ -68,7 +68,7 @@ futures = "0.3"
geo = { version = "0.33", optional = true, default-features = false }
geo-types = { version = "0.7", optional = true }
geojson = { version = "1", optional = true, default-features = true }
graphql-orm-macros = { path = "../graphql-orm-macros", version = "0.39.0", default-features = false }
graphql-orm-macros = { path = "../graphql-orm-macros", version = "0.39.1", default-features = false }
graphql-orm-operation-catalog = { workspace = true }
rust_decimal = { workspace = true }
serde = { version = "1", features = ["derive"] }
Expand Down
5 changes: 3 additions & 2 deletions crates/graphql-orm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: "graphql-orm"
kind: reference
status: active
owner: graphql-orm-maintainers
last_reviewed: 2026-10-02
last_reviewed: 2026-10-06
review_by: 2027-02-01
supersedes: []
---
Expand All @@ -29,7 +29,7 @@ backend:

```toml
[dependencies]
graphql-orm = { git = "https://github.com/Dastari/graphql-orm.git", rev = "<reviewed-full-40-character-commit-sha>", version = "0.39.0", default-features = false, features = ["sqlite"] }
graphql-orm = { git = "https://github.com/Dastari/graphql-orm.git", rev = "<reviewed-full-40-character-commit-sha>", version = "0.39.1", default-features = false, features = ["sqlite"] }
```

This unpublished package has no docs.rs release. Use this Git README and the
Expand Down Expand Up @@ -163,6 +163,7 @@ enforce row/field/database limits appropriate to the application.
- [Entities and relations](../../docs/reference/graphql-orm/entities-and-relations.md)
- [Typed grouped aggregates](../../docs/reference/graphql-orm/typed-aggregates.md)
- [Federation entities, keys, and operation roots](../../docs/reference/graphql-orm/federation.md)
- [Runtime predicates and keyset reads](../../docs/reference/graphql-orm/runtime-queries.md)
- [Runtime writes and repository operations](../../docs/reference/graphql-orm/runtime-and-writes.md)
- [Schema management](../../docs/reference/graphql-orm/schema-management.md)
- [Strict authorization](../../docs/reference/graphql-orm/strict-authorization.md)
Expand Down
13 changes: 12 additions & 1 deletion crates/graphql-orm/src/graphql/orm/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,19 @@ pub trait OrmBackend: Copy + Clone + Send + Sync + 'static {
Self::DIALECT.placeholder(index)
}

/// Normalize a complete statement at the driver binding boundary.
///
/// PostgreSQL statements using only native `$n` parameters preserve their
/// indices and repeated identity; rebasing adds `start_index - 1` to each
/// index. Anonymous or mixed placeholder forms retain legacy occurrence
/// rebasing. [`SqlDialect::normalize_sql`] separately rebases static query
/// fragments by occurrence, before their ordered values are composed.
fn normalize_sql(sql: &str, start_index: usize) -> String {
Self::DIALECT.normalize_sql(sql, start_index)
if Self::DIALECT == DatabaseBackend::Postgres {
super::dialect::normalize_postgres_statement(sql, start_index)
} else {
Self::DIALECT.normalize_sql(sql, start_index)
}
}
}

Expand Down
Loading
Loading