v3: Typed JSON arrays use native-list handling for filters and null values
Maintainer thường phản hồi trong vòng 1 ngày
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức phù hợp với người mới
- 20/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Khá rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- postgresql, typescript
- Lĩnh vực
- databases
Hướng nghiên cứu
The payload names DataModelValidator.validateField, BaseCrudDialect's array dispatch, ZodSchemaFactory, BaseOperationHandler.processScalarFieldUpdateData, ResultProcessor and the FieldFilter conditional type; read those to separate custom JSON arrays from native SQL lists. Run the repro script against a disposable PostgreSQL database to confirm the four failures: the equality filter, the JsonNull filter, null reads, and the DbNull/JsonNull updates. Done means the equality filter returns the row, null and [] stay distinct, and both sentinel updates succeed while native-list behavior is unchanged.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Description and expected behavior
Custom-type arrays are stored as JSON, but several paths appear to handle them as native SQL/scalar lists. On 3.9.4, even equality filtering on a non-nullable Entry[] @json field fails. Nullable declarations, null reads/writes, and filter typings have related inconsistencies.
Expected:
- A JSON-array equality filter should compare the JSON value and return the matching row.
- Nullable custom JSON arrays should preserve
nullversus[], and accept the appropriateDbNull/JsonNulloperations and filter types. - Native SQL-list restrictions should remain unchanged.
Minimal reproduction
Create a fresh ESM project (package.json containing {"private":true,"type":"module"}), then install:
pnpm add @zenstackhq/[email protected] @zenstackhq/[email protected] @zenstackhq/[email protected] @zenstackhq/[email protected] [email protected] [email protected] [email protected]
Set DATABASE_URL to an empty disposable PostgreSQL database. The script creates an Example table there. Save the following files, then run:
pnpm exec zen generate --schema schema.zmodel
pnpm exec tsx repro.ts
schema.zmodel
datasource db {
provider = "postgresql"
}
type Entry {
label String
@@strict
}
model Example {
id Int @id
entries Entry[] @json
}
repro.ts
The first query uses the unmodified generated schema. Because the language currently rejects Entry[]?, the later nullable-runtime probes override only the generated field's optional metadata. This explicitly isolates runtime behavior from the language rejection; it is not required to reproduce the first equality-filter failure. tsx runs the script despite the separate TypeScript error described below.
import { ZenStackClient, DbNull, JsonNull } from '@zenstackhq/orm';
import { PostgresDialect } from '@zenstackhq/orm/dialects/postgres';
import { Pool } from 'pg';
import { schema } from './schema';
const pool = new Pool({ connectionString: process.env.DATABASE_URL, max: 1 });
const db = new ZenStackClient(schema, {
dialect: new PostgresDialect({ pool }),
validateInput: true,
});
async function show(name: string, run: () => Promise<unknown>) {
try { console.log(name, JSON.stringify(await run())); }
catch (error) { console.log(name, (error as Error).message); }
}
try {
await pool.query('CREATE TABLE "Example" (id integer PRIMARY KEY, entries jsonb)');
await db.example.create({ data: { id: 1, entries: [{ label: 'x' }] } });
await show('equals array', () => db.example.findMany({ where: { entries: { equals: [{ label: 'x' }] } } }));
// The language currently rejects Entry[]?. Override only optional metadata
// to isolate the runtime behavior of a nullable custom JSON array.
const optionalSchema = {
...schema,
models: {
...schema.models,
Example: {
...schema.models.Example,
fields: {
...schema.models.Example.fields,
entries: { ...schema.models.Example.fields.entries, optional: true as const },
},
},
},
};
const nullableDb = new ZenStackClient(optionalSchema, {
dialect: new PostgresDialect({ pool }),
validateInput: true,
});
await show('equals JsonNull', () => nullableDb.example.findMany({ where: { entries: { equals: JsonNull } } }));
await pool.query('INSERT INTO "Example" (id, entries) VALUES (2, NULL), (3, \'null\'::jsonb)');
await show('read SQL/JSON null', () => nullableDb.example.findMany({ where: { id: { in: [2, 3] } }, orderBy: { id: 'asc' } }));
await show('update DbNull', () => nullableDb.example.update({ where: { id: 1 }, data: { entries: DbNull } }));
await show('update JsonNull', () => nullableDb.example.update({ where: { id: 1 }, data: { entries: JsonNull } }));
} finally {
await pool.end();
}
Actual output
equals array Invariant failed: Array filter value must be an array
equals JsonNull Invalid findMany args for model "Example": Validation error: Invalid input: expected array, received JsonNullClass at "where.entries.equals"
read SQL/JSON null [{"id":2,"entries":[]},{"id":3,"entries":[]}]
update DbNull Invalid array update operation: __brand
update JsonNull Invalid array update operation: __brand
The first query should return [{"id":1,"entries":[{"label":"x"}]}]. The two null rows should have entries: null. Both null-sentinel updates should succeed for the nullable field.
Language rejection
Changing the field to entries Entry[]? @json and running zen generate fails with:
Optional lists are not supported. Use either `Type[]` or `Type?`
If rejecting nullable top-level custom JSON arrays is intentional, clarification would help; the non-nullable equality-filter failure above reproduces independently.
Filter typing
With TypeScript 6.0.3 (strict, skipLibCheck, moduleResolution: bundler), the nullableDb.example.findMany call with entries: { equals: JsonNull } also fails typecheck:
TS2740: Type 'JsonNullClass' is missing the following properties from type 'unknown[]': length, pop, push, concat, and 29 more.
Environment
- ZenStack: 3.9.4, stock npm packages, no patches
- PostgreSQL: 16.15
- Node.js: 22.14.0
- Package manager: pnpm 11.25.0
pg: 8.21.0; Zod: 4.5.4;tsx: 4.19.0- Direct
ZenStackClientwithvalidateInput: true; no plugins
Additional context
Related: #2411 addressed nullable custom-object JSON typings; this reproduction concerns custom-type arrays and also includes runtime failures.
The relevant 3.9.4 paths appear to be DataModelValidator.validateField, array dispatch in BaseCrudDialect and ZodSchemaFactory, BaseOperationHandler.processScalarFieldUpdateData, ResultProcessor, and the FieldFilter conditional type. They need to distinguish custom JSON arrays from native SQL lists. These observations are grouped here because they share that distinction; they can be split if preferred.
- Ngôn ngữ chính
- TypeScript
- Star
- 2.9k
- Fork
- 157
- Merge trung bình
- 2 ngày 46 phút
- Pull request đã merge (30 ngày)
- 17
Chuẩn bị môi trường
Dự án này không cung cấp dev container, Dockerfile hay hướng dẫn đóng góp, nên bạn cần tự thiết lập môi trường: hãy bắt đầu từ README và xem hướng dẫn đóng góp lần đầu của chúng tôi để biết các bước chung.
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của zenstackhq/zenstack
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
zenstackhq/zenstack#2873 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
`@default` on a field of a `@map`-ed enum emits the enum name as the column defaultCó thể đã có người làm @jkugsiya đã nhận 4 ngày trước. Đang mởruntime
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
zenstackhq/zenstack#2868 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
zenstackhq/zenstack#2694 · 3 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 68/100
zenstackhq/zenstack#2659 · 2 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
zenstackhq/zenstack#2542 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của zenstackhq/zenstack
Issue tương tự
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 77/100
TomerAberbach/profiler-md#733 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
bug priority: medium
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
brentspine/brents-toasts#143 ·
-
🐛 bug 🗺️ DB Models & Ops
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 83/100
LibreChat-AI/LibreChat#17214 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 67/100
Wavvon/Wavvon-clients#136 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 62/100
umami-software/umami#4637 ·
Maintainer thường phản hồi trong vòng 3 ngày