Skip to content

Commit 8b3d822

Browse files
authored
Infer input types from json_populate_recordset and friends (#14)
* initial implementation to infer input types from json_populate_recordset and friends * make json_populate_record detection more robust * handle JSON.t stringification properly so arrays can be handled * add another example + fix types * generated
1 parent f8884e1 commit 8b3d822

33 files changed

+1906
-339
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
# main
22

3+
- Make sure `JSON.t` is properly stringified so JSON arrays can be passed to params expecting `JSON.t` without them being confused for regular Postgres arrays.
34
- Auto-escape all ReScript keywords in generated record field names.
45
- Add automatic parsing of PostgreSQL check constraints to generate ReScript polyvariant types for enumeration-style constraints. Supports both `column IN (value1, value2, ...)` and `column = ANY (ARRAY[value1, value2, ...])` patterns with string and integer values.
56
- Add top-level literal inference for SELECT queries. When a query returns literal values with aliases (e.g., `SELECT 'success' as status, 42 as code`), PgTyped now automatically infers specific polyvariant types like `[#"success"]` and `[#42]` instead of generic `string` and `int` types. This provides better type safety and autocompletion. Also works with UNION queries where literals are consistent across all branches.
7+
- Add support for PostgreSQL JSON population functions (`json_populate_record`, `json_populate_recordset`, `jsonb_populate_record`, `jsonb_populate_recordset`, `json_to_record`, `jsonb_to_recordset`). This supports efficient bulk operations.
68
- Remove dependency on `@rescript/core` since it's not really used.
79

810
# 2.6.0

RESCRIPT.md

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,75 @@ let books = await client->GetBooksByStatus.many({
170170

171171
This feature works seamlessly with both separate SQL files and SQL-in-ReScript modes.
172172

173+
## JSON Population Functions
174+
175+
`pgtyped-rescript` provides support for PostgreSQL's JSON population functions, enabling type-safe conversion between JSON data and database records.
176+
177+
### Supported Functions
178+
179+
- **`json_populate_record`** - Converts a JSON object to a PostgreSQL record
180+
- **`json_populate_recordset`** - Converts a JSON array to a set of PostgreSQL records
181+
- **`jsonb_populate_record`** - Binary JSON variant of `json_populate_record`
182+
- **`jsonb_populate_recordset`** - Binary JSON variant of `json_populate_recordset`
183+
- **`json_to_record`** - Converts JSON to a record with explicit column definitions
184+
- **`jsonb_to_recordset`** - Converts JSONB array to records with explicit column definitions
185+
186+
### Usage Examples
187+
188+
**Bulk insert with `json_populate_recordset`:**
189+
190+
```sql
191+
/* @name bulkInsertBooks */
192+
INSERT INTO books (name, author_id, categories, rank)
193+
SELECT
194+
event.name,
195+
event.author_id,
196+
event.categories,
197+
event.rank
198+
FROM json_populate_recordset(null::books, :books!) as event
199+
RETURNING *;
200+
```
201+
202+
**Update single record with `json_populate_record`:**
203+
204+
```sql
205+
/* @name updateBookFromJson */
206+
UPDATE books
207+
SET (name, author_id, categories, rank) = (
208+
SELECT
209+
r.name,
210+
r.author_id,
211+
r.categories,
212+
r.rank
213+
FROM json_populate_record(null::books, :bookData!) as r
214+
)
215+
WHERE id = :bookId!
216+
RETURNING *;
217+
```
218+
219+
**Example:**
220+
221+
```rescript
222+
let bulkInsert = %sql.many(`
223+
INSERT INTO books (name, author_id, categories, rank)
224+
SELECT
225+
event.name,
226+
event.author_id,
227+
event.categories,
228+
event.rank
229+
FROM json_populate_recordset(null::books, :books!) as event
230+
RETURNING *
231+
`)
232+
233+
// Usage with full type safety
234+
let newBooks = await client->bulkInsert({
235+
books: [
236+
{name: "Book 1", author_id: 1, categories: ["fiction"], rank: 1},
237+
{name: "Book 2", author_id: 2, categories: ["sci-fi"], rank: 2}
238+
]
239+
})
240+
```
241+
173242
## Literal Type Inference
174243

175244
`pgtyped-rescript` automatically infers specific polyvariant types for literal values in your SQL queries, providing enhanced type safety and better development experience.

0 commit comments

Comments
 (0)