cockroachdb / cockroachdb/cockroach

Rust sqlx v0.8.6 Test Failures Against CockroachDB v25.4.3

Open
#163,857 1 comment 0 reactions 0 assignees View on GitHub
C-bug
Dominant language
Go
Stars
32.5k
Forks
4.1k
PR merge metrics
PR metrics pending

Description

**Describe the problem**

Running the Rust [sqlx](https://github.com/launchbadge/sqlx) v0.8.6 integration
test suite against CockroachDB v25.4.3 results in 59 test failures and 2
cargo-ignored tests out of 208 total (147 pass). The failures fall into several
categories of PostgreSQL compatibility gaps.

**To Reproduce**

1. Start a single-node CockroachDB v25.4.3 cluster in insecure mode.
2. Create a database and user for the tests:
```sql
CREATE DATABASE IF NOT EXISTS sqlx;
CREATE USER IF NOT EXISTS postgres WITH CREATEDB CREATELOGIN CREATEROLE CANCELQUERY;
GRANT ALL ON DATABASE sqlx TO postgres;
SET CLUSTER SETTING sql.defaults.default_int_size = 4;
```
3. Clone sqlx v0.8.6:
```bash
git clone --branch v0.8.6 https://github.com/launchbadge/sqlx.git /tmp/sqlx
```
4. Run the postgres integration tests:
```bash
cd /tmp/sqlx && DATABASE_URL='postgresql://postgres@localhost:26257/sqlx?sslmode=disable' \
cargo test \
--features postgres,runtime-tokio,tls-none,_unstable-all-types \
--test postgres \
--test postgres-types \
--test postgres-describe \
--test postgres-error \
--test postgres-query-builder \
--no-fail-fast
```
5. Observe 59 failures across 4 of the 5 test targets (`postgres-query-builder`
passes entirely).

**Expected behavior**

All tests that exercise standard SQL and PostgreSQL wire-protocol features
supported by CockroachDB should pass. Tests that use genuinely unsupported
PostgreSQL extensions (LISTEN/NOTIFY, advisory locks, MACADDR, MONEY, etc.)
are expected to fail and belong on the blocklist.

**Environment:**
- CockroachDB version: v25.4.3
- Server OS: macOS Darwin 25.3.0 (arm64); also reproducible on Linux
- Client app: Rust sqlx v0.8.6 via `cargo test`

---

## Failure Categories

### 1. INT Type Mismatch (19 failures)

**Describe the problem**

CockroachDB returns `INT8` (OID 20) for integer literal expressions like
`SELECT 1 + 1` even when `sql.defaults.default_int_size = 4` is set. That
cluster setting only affects the default column type in `CREATE TABLE`
statements, not the inferred type of integer literals and arithmetic
expressions in queries.

sqlx strictly checks the wire-protocol type OID when decoding results. When a
Rust `i32` is expected (mapped to PostgreSQL `INT4`, OID 23), but CockroachDB
returns `INT8` (OID 20), sqlx rejects the value with a `ColumnDecode` error.

**To Reproduce**

```sql
-- CockroachDB returns INT8 for this expression even with default_int_size = 4
SELECT pg_typeof(1 + 1); -- returns 'bigint' (INT8)
```

```
Error: mismatched types; Rust type `i32` (as SQL type `INT4`) is not compatible with SQL type `INT8`
```

**Expected behavior**

Integer literal expressions should return `INT4` (OID 23) when
`sql.defaults.default_int_size = 4`, matching PostgreSQL's behavior where
`SELECT 1 + 1` returns `integer` (INT4).

**Additional data**

| Test | Rust Type | Expected SQL Type | Got |
|------|-----------|-------------------|-----|
| `it_connects` | `i32` | `INT4` | `INT8` |
| `it_maths` | `i32` | `INT4` | `INT8` |
| `it_can_query_scalar` | `i32` | `INT4` | `INT8` |
| `it_can_nest_map` | `i32` | `INT4` | `INT8` |
| `it_can_copy_in` | `i32` | `INT4` | `INT8` |
| `it_can_copy_out` | `i32` | `INT4` | `INT8` |
| `it_can_abort_copy_in` | `i32` | `INT4` | `INT8` |
| `it_can_work_with_failed_transactions` | `i32` | `INT4` | `INT8` |
| `it_can_recover_from_copy_in_empty_query` | `i32` | `INT4` | `INT8` |
| `it_can_recover_from_copy_in_invalid_params` | `i32` | `INT4` | `INT8` |
| `it_can_recover_from_copy_in_syntax_error` | `i32` | `INT4` | `INT8` |
| `it_can_recover_from_copy_in_to_missing_table` | `i32` | `INT4` | `INT8` |
| `test_select_expression` | `i32` | `INT4` | `INT8` |
| `test_invalid_query` | `i32` | `INT4` | `INT8` |
| `test_prepared_decode_type_num_tuple` | `i32` | `INT4` | `INT8` |
| `test_prepared_type_i16` | `i16` | `INT2` | `INT8` |
| `test_prepared_type_i32` | `i32` | `INT4` | `INT8` |
| `test_unprepared_type_i16` | `i16` | `INT2` | `INT8` |
| `test_unprepared_type_i32` | `i32` | `INT4` | `INT8` |

---

### 2. Missing Fixture Tables and Types (10 failures)

**Describe the problem**

sqlx tests rely on fixture SQL files that create tables (`tweet`, `products`)
and types (`status` enum, `inventory_item` composite type). These fixtures use
PostgreSQL-specific syntax that CockroachDB either does not support or silently
fails on during setup, causing downstream tests to fail with "relation/type does
not exist" errors.

The root cause is that the test fixture SQL (e.g., `CREATE TYPE status AS ENUM`,
composite type definitions, or table definitions referencing those types) uses
syntax that CockroachDB does not fully support, and the test harness does not
surface fixture-setup failures.

**To Reproduce**

```sql
-- These types/tables are expected by the tests but were never created:
SELECT * FROM tweet; -- ERROR: relation "tweet" does not exist
SELECT 'active'::status; -- ERROR: type "status" does not exist
```

**Expected behavior**

Fixture setup errors should either be surfaced clearly, or the fixtures should
use CockroachDB-compatible syntax.

**Additional data**

| Test | Missing Object | Error |
|------|----------------|-------|
| `it_can_prepare_then_execute` | relation `tweet` | relation "tweet" does not exist |
| `it_can_inspect_constraint_errors` | relation `products` | relation "products" does not exist |
| `it_describes_simple` | relation `tweet` | relation "tweet" does not exist |
| `it_describes_enum` | type `status` | type "status" does not exist |
| `it_describes_composite` | type `inventory_item` | type "inventory_item" does not exist |
| `it_fails_with_unique_violation` | relation `tweet` | relation "tweet" does not exist |
| `it_fails_with_begin_failed` | relation `tweet` | relation "tweet" does not exist |
| `test_describe_outer_join_nullable` | relation `tweet` | relation "tweet" does not exist |
| `test_pg_copy_chunked` | relation `products` | relation "products" does not exist |
| `test_multi_read_write` | fixture-dependent | unique\_id `1` vs `1151332600623661057` (suggests `unique_rowid()` vs PostgreSQL `SERIAL`) |

---

### 3. Unsupported Types: MACADDR, MONEY, INT4RANGE, NUMRANGE (12 failures)

**Describe the problem**

CockroachDB does not implement the PostgreSQL `MACADDR`, `MONEY`, `INT4RANGE`,
or `NUMRANGE` types. Tests that attempt to use these types fail with syntax
errors or unknown OID errors.

**To Reproduce**

```sql
SELECT '00:01:02:03:04:05'::macaddr;
-- ERROR: at or near "macaddr": syntax error: unimplemented: this syntax

SELECT 123.45::money;
-- ERROR: at or near "money": syntax error: unimplemented: this syntax

SELECT '(,)'::int4range;
-- ERROR: type "int4range" does not exist

SELECT '(1.3,2.4)'::numrange;
-- ERROR: type "numrange" does not exist
```

**Expected behavior**

These are known unsupported types. Tests should be on the blocklist.

**Additional data**

| Test | Type | Error |
|------|------|-------|
| `test_prepared_type_mac_address` | `MACADDR` | syntax error: unimplemented |
| `test_prepared_type_mac_address_vec` | `MACADDR[]` | syntax error: unimplemented |
| `test_unprepared_type_mac_address` | `MACADDR` | syntax error: unimplemented |
| `test_unprepared_type_mac_address_vec` | `MACADDR[]` | syntax error: unimplemented |
| `test_prepared_type_money` | `MONEY` | syntax error: unimplemented |
| `test_prepared_type_money_vec` | `MONEY[]` | syntax error: unimplemented |
| `test_prepared_type_int4range` | `INT4RANGE` | unknown oid type: 3904 |
| `test_unprepared_type_int4range` | `INT4RANGE` | type "int4range" does not exist |
| `test_prepared_type_numrange_bigdecimal` | `NUMRANGE` | unknown oid type: 3906 |
| `test_prepared_type_numrange_decimal` | `NUMRANGE` | unknown oid type: 3906 |
| `test_unprepared_type_numrange_bigdecimal` | `NUMRANGE` | type "numrange" does not exist |
| `test_unprepared_type_numrange_decimal` | `NUMRANGE` | type "numrange" does not exist |

---

### 4. CIDR IS NOT DISTINCT FROM Not Supported (4 failures)

**Describe the problem**

Tests for `INET`/`CIDR` types partially succeed (simple `INET` values pass) but
fail when the test reaches a `CIDR IS NOT DISTINCT FROM $1` expression.
CockroachDB does not support `IS NOT DISTINCT FROM` with the `CIDR` type.

**To Reproduce**

```sql
-- Works:
SELECT ('127.0.0.1'::inet IS NOT DISTINCT FROM '127.0.0.1'::inet);

-- Fails:
SELECT ('192.168'::cidr IS NOT DISTINCT FROM '192.168.0.0/24'::cidr);
-- ERROR: at or near "is": syntax error: unimplemented: this syntax
```

**Expected behavior**

`IS NOT DISTINCT FROM` should work with `CIDR` values the same way it does with
`INET`.

**Additional data**

| Test | Error |
|------|-------|
| `test_prepared_type_ipnet` | `at or near "is": syntax error: unimplemented` (on CIDR) |
| `test_prepared_type_ipnetwork` | `at or near "is": syntax error: unimplemented` (on CIDR) |
| `test_unprepared_type_ipnet` | `at or near "EOF": syntax error: unimplemented` (on CIDR) |
| `test_unprepared_type_ipnetwork` | `at or near "EOF": syntax error: unimplemented` (on CIDR) |

---

### 5. LISTEN/NOTIFY Not Supported (3 failures)

**Describe the problem**

CockroachDB does not implement PostgreSQL's `LISTEN`/`NOTIFY` pub-sub mechanism.

**To Reproduce**

```sql
LISTEN my_channel;
-- ERROR: at or near "listen": syntax error
```

**Expected behavior**

These are known unsupported features. Tests should be on the blocklist.

**Additional data**

| Test | Error |
|------|-------|
| `test_listener_cleanup` | `at or near "listen": syntax error` |
| `test_listener_try_recv_buffered` | `at or near "listen": syntax error` |
| `test_pg_listener_implements_acquire` | `at or near "listen": syntax error` |

---

### 6. Unsupported Built-in Functions (2 failures)

**Describe the problem**

CockroachDB does not implement `pg_notify()` or `pg_advisory_lock()`.

**To Reproduce**

```sql
SELECT pg_notify('chan', 'payload');
-- ERROR: unknown function: pg_notify()

SELECT pg_advisory_lock(1);
-- ERROR: unknown function: pg_advisory_lock()
```

**Expected behavior**

These are known unsupported functions. Tests should be on the blocklist.

**Additional data**

| Test | Missing Function |
|------|-----------------|
| `it_can_select_void` | `pg_notify()` |
| `test_advisory_locks` | `pg_advisory_lock()` |

---

### 7. Constraint Violation Error Classification Differences (3 failures)

**Describe the problem**

CockroachDB returns error codes that sqlx's `ErrorKind` mapping resolves to
`Other` instead of the specific PostgreSQL constraint violation kinds
(`NotNullViolation`, `ForeignKeyViolation`, `CheckViolation`). The tests
create tables inline and trigger constraint violations, but the error code or
structure returned by CockroachDB does not match what sqlx expects from
PostgreSQL.

**To Reproduce**

```sql
CREATE TABLE test_fk_parent (id INT PRIMARY KEY);
CREATE TABLE test_fk_child (id INT PRIMARY KEY, parent_id INT REFERENCES test_fk_parent(id));
INSERT INTO test_fk_child VALUES (1, 999);
-- CockroachDB returns this error, but sqlx classifies it as ErrorKind::Other
-- instead of ErrorKind::ForeignKeyViolation
```

**Expected behavior**

CockroachDB should return PostgreSQL-compatible error codes (SQLSTATE) for
constraint violations so that client libraries can correctly classify them:
- `23502` for NOT NULL violations
- `23503` for foreign key violations
- `23514` for check constraint violations

**Additional data**

| Test | Expected Kind | Got |
|------|---------------|-----|
| `it_fails_with_not_null_violation` | `NotNullViolation` | `Other` |
| `it_fails_with_foreign_key_violation` | `ForeignKeyViolation` | `Other` |
| `it_fails_with_check_violation` | `CheckViolation` | `Other` |

---

### 8. DEFERRABLE Constraints Not Supported (1 failure)

**Describe the problem**

CockroachDB does not support `DEFERRABLE` constraint syntax.

**To Reproduce**

```sql
CREATE TABLE test_defer (
id INT PRIMARY KEY,
CONSTRAINT u UNIQUE (id) DEFERRABLE INITIALLY DEFERRED
);
-- ERROR: at or near "deferrable": syntax error
```

**Expected behavior**

This is a known unsupported feature. The test should be on the blocklist.

**Additional data**

| Test | Error |
|------|-------|
| `test_error_handling_with_deferred_constraints` | `at or near "deferrable": syntax error` |

---

### 9. Domain Types / PL/pgSQL Not Supported (1 failure)

**Describe the problem**

The test uses a PL/pgSQL `DO $$ ... $$` block with `IF NOT EXISTS` logic to
create domain types within composite types, which CockroachDB does not support.

**To Reproduce**

```sql
DO $$ BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'my_domain') THEN
CREATE DOMAIN my_domain AS TEXT;
END IF;
END $$;
-- ERROR: at or near "if": syntax error: unimplemented: this syntax
```

**Expected behavior**

This is a known limitation of CockroachDB's PL/pgSQL support.

**Additional data**

| Test | Error |
|------|-------|
| `it_supports_domain_types_in_composite_domain_types` | `at or near "if": syntax error: unimplemented` |

---

### 10. Other Behavioral Differences (4 failures)

**Describe the problem**

Several tests fail due to subtle behavioral differences between CockroachDB and
PostgreSQL in error reporting, prepared statement lifecycle management, error
message content, and floating-point handling.

**Additional data**

| Test | Issue | Detail |
|------|-------|--------|
| `it_can_inspect_errors` | Error position not returned | Expected `Some(Original(8))`, got `None`. CockroachDB does not populate the `position` field in error responses. |
| `it_closes_statements_when_not_persistent_issue_3850` | Prepared statement count differs | Expected `1` open statement, got `0`. CockroachDB may handle prepared statement lifecycle differently. |
| `it_resolves_custom_types_in_anonymous_records` | Error message text differs | Test asserts error contains `"custom types in records are not fully supported yet"` but CockroachDB returns a different error message. |
| `test_prepared_type_f32` | Float32 round-trip precision | Value `9419.122` fails `IS NOT DISTINCT FROM` comparison after round-trip through `REAL` type. Likely a floating-point precision difference. |

---

### 11. Ignored by Cargo (2 tests)

**Describe the problem**

These tests are marked `#[ignore]` in the sqlx Rust source and are skipped by
`cargo test` unless `--include-ignored` is passed. They are not CockroachDB
compatibility failures. The roachtest harness treats "ignored" results as
failures when they appear in the blocklist.

| Test |
|------|
| `pool_smoke_test` |
| `copy_can_work_with_failed_transactions` |

---

## Additional context

The test was run via the CockroachDB roachtest framework using:

```bash
./bin/roachtest run rust-sqlx --local \
--cockroach=/opt/homebrew/Cellar/cockroach/25.4.3/bin/cockroach
```

The `postgres-query-builder` test target (9 tests) passes entirely. The
failures are concentrated in `postgres` (29/59), `postgres-types` (22/130),
`postgres-error` (5/6), and `postgres-describe` (3/5).

The single largest category is **INT type mismatch** (19 tests), which
represents a systemic issue where `sql.defaults.default_int_size = 4` does not
affect the type of integer literal expressions in query results.

Jira issue: CRDB-60507

Epic CRDB-19024

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.