Skip to content

Commit d547072

Browse files
authored
test(postgrest): add partitionned tables computed field tests (#1808)
1 parent ca4eda3 commit d547072

File tree

5 files changed

+283
-2
lines changed

5 files changed

+283
-2
lines changed

packages/core/postgrest-js/test/db/00-schema.sql

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,13 @@ CREATE TABLE public.messages (
5959
ALTER TABLE public.messages REPLICA IDENTITY FULL; -- Send "previous data" to supabase
6060
COMMENT ON COLUMN public.messages.data IS 'For unstructured data and prototyping.';
6161

62+
-- USERS AUDIT
63+
CREATE TABLE public.users_audit (
64+
id bigint GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
65+
created_at timestamptz DEFAULT now(),
66+
previous_value bigint
67+
);
68+
6269
-- SELF REFERENCING TABLE
6370
CREATE TABLE public.collections (
6471
id bigint GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
@@ -357,3 +364,40 @@ ROWS 1
357364
AS $$
358365
SELECT * FROM public.user_profiles WHERE username = user_row.username LIMIT 1;
359366
$$;
367+
368+
-- Function that return the created_ago computed field
369+
CREATE OR REPLACE FUNCTION "public"."created_ago" ("public"."users_audit") RETURNS numeric LANGUAGE "sql"
370+
SET
371+
"search_path" TO ''
372+
AS $_$
373+
SELECT ROUND(EXTRACT(EPOCH FROM (NOW() - $1.created_at)));
374+
$_$;
375+
376+
-- Create a partitioned table for testing computed fields on partitioned tables
377+
CREATE TABLE public.events (
378+
id bigint generated by default as identity,
379+
created_at timestamptz default now(),
380+
event_type text,
381+
data jsonb,
382+
primary key (id, created_at)
383+
) partition by range (created_at);
384+
385+
-- Create partitions for the events table
386+
CREATE TABLE public.events_2024 PARTITION OF public.events
387+
FOR VALUES FROM ('2024-01-01') TO ('2025-01-01');
388+
389+
CREATE TABLE public.events_2025 PARTITION OF public.events
390+
FOR VALUES FROM ('2025-01-01') TO ('2026-01-01');
391+
392+
-- Insert some test data
393+
INSERT INTO public.events (created_at, event_type, data)
394+
VALUES
395+
('2024-06-15', 'login', '{"user": "alice"}'),
396+
('2025-03-20', 'logout', '{"user": "bob"}');
397+
398+
-- Function that returns computed field for partitioned table
399+
CREATE OR REPLACE FUNCTION "public"."days_since_event" ("public"."events") RETURNS numeric LANGUAGE "sql"
400+
SET
401+
"search_path" TO '' AS $_$
402+
SELECT ROUND(EXTRACT(EPOCH FROM (NOW() - $1.created_at)) / 86400);
403+
$_$;

packages/core/postgrest-js/test/db/01-dummy-data.sql

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,4 +119,13 @@ VALUES
119119
(5, 3), -- Booking for Beachfront Inn
120120
(6, 1), -- Third booking for Sunset Resort
121121
(7, NULL), -- Another booking with no hotel
122-
(8, 4); -- Booking for hotel with null name
122+
(8, 4); -- Booking for hotel with null name
123+
124+
-- Insert users audit
125+
INSERT INTO public.users_audit (id, previous_value)
126+
VALUES
127+
(1, 42),
128+
(2, 42),
129+
(3, 42),
130+
(4, 42),
131+
(5, 42);

packages/core/postgrest-js/test/db/docker-compose.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ services:
3939
POSTGRES_USER: postgres
4040
POSTGRES_PASSWORD: postgres
4141
pgmeta:
42-
image: supabase/postgres-meta:v0.92.0
42+
image: supabase/postgres-meta:v0.93.1
4343
ports:
4444
- '8080:8080'
4545
environment:

packages/core/postgrest-js/test/embeded_functions_join.test.ts

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1225,4 +1225,137 @@ describe('embeded functions select', () => {
12251225
expectType<TypeEqual<typeof result, typeof expected>>(true)
12261226
ExpectedSchema.parse(res.data)
12271227
})
1228+
1229+
// test select the created_ago embeded function
1230+
test('select the created_ago embeded function', async () => {
1231+
const res = await postgrest.from('users_audit').select('id, created_ago')
1232+
expect(res).toMatchInlineSnapshot(`
1233+
Object {
1234+
"count": null,
1235+
"data": Array [
1236+
Object {
1237+
"created_ago": 7,
1238+
"id": 1,
1239+
},
1240+
Object {
1241+
"created_ago": 7,
1242+
"id": 2,
1243+
},
1244+
Object {
1245+
"created_ago": 7,
1246+
"id": 3,
1247+
},
1248+
Object {
1249+
"created_ago": 7,
1250+
"id": 4,
1251+
},
1252+
Object {
1253+
"created_ago": 7,
1254+
"id": 5,
1255+
},
1256+
],
1257+
"error": null,
1258+
"status": 200,
1259+
"statusText": "OK",
1260+
}
1261+
`)
1262+
let result: Exclude<typeof res.data, null>
1263+
const ExpectedSchema = z.array(
1264+
z.object({
1265+
id: z.number(),
1266+
created_ago: z.number().nullable(),
1267+
})
1268+
)
1269+
let expected: z.infer<typeof ExpectedSchema>
1270+
expectType<TypeEqual<keyof (typeof expected)[number], keyof (typeof result)[number]>>(true)
1271+
expectType<TypeEqual<typeof result, typeof expected>>(true)
1272+
ExpectedSchema.parse(res.data)
1273+
const use_rpc_call = await postgrest.rpc('created_ago', {
1274+
// @ts-expect-error - id is not a parameter of the created_ago function
1275+
id: 1,
1276+
})
1277+
expect(use_rpc_call).toMatchInlineSnapshot(`
1278+
Object {
1279+
"count": null,
1280+
"data": null,
1281+
"error": Object {
1282+
"code": "PGRST202",
1283+
"details": "Searched for the function public.created_ago with parameter id or with a single unnamed json/jsonb parameter, but no matches were found in the schema cache.",
1284+
"hint": null,
1285+
"message": "Could not find the function public.created_ago(id) in the schema cache",
1286+
},
1287+
"status": 404,
1288+
"statusText": "Not Found",
1289+
}
1290+
`)
1291+
let result_rpc: Exclude<typeof use_rpc_call.data, null>
1292+
expectType<
1293+
TypeEqual<
1294+
typeof result_rpc,
1295+
{
1296+
error: true
1297+
} & 'the function public.created_ago with parameter or with a single unnamed json/jsonb parameter, but no matches were found in the schema cache'
1298+
>
1299+
>(true)
1300+
})
1301+
// Test the days_since_event embeded function over partitioned table
1302+
test('select the days_since_event embeded function over partitioned table', async () => {
1303+
const res = await postgrest.from('events').select('id, days_since_event')
1304+
expect(res).toMatchInlineSnapshot(`
1305+
Object {
1306+
"count": null,
1307+
"data": Array [
1308+
Object {
1309+
"days_since_event": 500,
1310+
"id": 1,
1311+
},
1312+
Object {
1313+
"days_since_event": 222,
1314+
"id": 2,
1315+
},
1316+
],
1317+
"error": null,
1318+
"status": 200,
1319+
"statusText": "OK",
1320+
}
1321+
`)
1322+
let result: Exclude<typeof res.data, null>
1323+
const ExpectedSchema = z.array(
1324+
z.object({
1325+
id: z.number(),
1326+
days_since_event: z.number().nullable(),
1327+
})
1328+
)
1329+
let expected: z.infer<typeof ExpectedSchema>
1330+
expectType<TypeEqual<keyof (typeof expected)[number], keyof (typeof result)[number]>>(true)
1331+
expectType<TypeEqual<typeof result, typeof expected>>(true)
1332+
ExpectedSchema.parse(res.data)
1333+
const use_rpc_call = await postgrest.rpc('days_since_event', {
1334+
// @ts-expect-error - id is not a parameter of the days_since_event function
1335+
id: 1,
1336+
})
1337+
expect(use_rpc_call).toMatchInlineSnapshot(`
1338+
Object {
1339+
"count": null,
1340+
"data": null,
1341+
"error": Object {
1342+
"code": "PGRST202",
1343+
"details": "Searched for the function public.days_since_event with parameter id or with a single unnamed json/jsonb parameter, but no matches were found in the schema cache.",
1344+
"hint": null,
1345+
"message": "Could not find the function public.days_since_event(id) in the schema cache",
1346+
},
1347+
"status": 404,
1348+
"statusText": "Not Found",
1349+
}
1350+
`)
1351+
let result_rpc: Exclude<typeof use_rpc_call.data, null>
1352+
expectType<
1353+
TypeEqual<
1354+
typeof result_rpc,
1355+
{
1356+
error: true
1357+
} & 'the function public.days_since_event with parameter or with a single unnamed json/jsonb parameter, but no matches were found in the schema cache'
1358+
>
1359+
>(true)
1360+
})
12281361
})

packages/core/postgrest-js/test/types.generated.ts

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,70 @@ export type Database = {
275275
}
276276
Relationships: []
277277
}
278+
events: {
279+
Row: {
280+
created_at: string
281+
data: Json | null
282+
event_type: string | null
283+
id: number
284+
days_since_event: number | null
285+
}
286+
Insert: {
287+
created_at?: string
288+
data?: Json | null
289+
event_type?: string | null
290+
id?: number
291+
}
292+
Update: {
293+
created_at?: string
294+
data?: Json | null
295+
event_type?: string | null
296+
id?: number
297+
}
298+
Relationships: []
299+
}
300+
events_2024: {
301+
Row: {
302+
created_at: string
303+
data: Json | null
304+
event_type: string | null
305+
id: number
306+
}
307+
Insert: {
308+
created_at?: string
309+
data?: Json | null
310+
event_type?: string | null
311+
id: number
312+
}
313+
Update: {
314+
created_at?: string
315+
data?: Json | null
316+
event_type?: string | null
317+
id?: number
318+
}
319+
Relationships: []
320+
}
321+
events_2025: {
322+
Row: {
323+
created_at: string
324+
data: Json | null
325+
event_type: string | null
326+
id: number
327+
}
328+
Insert: {
329+
created_at?: string
330+
data?: Json | null
331+
event_type?: string | null
332+
id: number
333+
}
334+
Update: {
335+
created_at?: string
336+
data?: Json | null
337+
event_type?: string | null
338+
id?: number
339+
}
340+
Relationships: []
341+
}
278342
hotel: {
279343
Row: {
280344
id: number
@@ -488,6 +552,25 @@ export type Database = {
488552
}
489553
Relationships: []
490554
}
555+
users_audit: {
556+
Row: {
557+
created_at: string | null
558+
id: number
559+
previous_value: number | null
560+
created_ago: number | null
561+
}
562+
Insert: {
563+
created_at?: string | null
564+
id?: number
565+
previous_value?: number | null
566+
}
567+
Update: {
568+
created_at?: string | null
569+
id?: number
570+
previous_value?: number | null
571+
}
572+
Relationships: []
573+
}
491574
}
492575
Views: {
493576
active_users: {
@@ -589,6 +672,18 @@ export type Database = {
589672
error: true
590673
} & 'the function public.blurb_message with parameter or with a single unnamed json/jsonb parameter, but no matches were found in the schema cache'
591674
}
675+
created_ago: {
676+
Args: { '': Database['public']['Tables']['users_audit']['Row'] }
677+
Returns: {
678+
error: true
679+
} & 'the function public.created_ago with parameter or with a single unnamed json/jsonb parameter, but no matches were found in the schema cache'
680+
}
681+
days_since_event: {
682+
Args: { '': Database['public']['Tables']['events']['Row'] }
683+
Returns: {
684+
error: true
685+
} & 'the function public.days_since_event with parameter or with a single unnamed json/jsonb parameter, but no matches were found in the schema cache'
686+
}
592687
function_returning_row: {
593688
Args: never
594689
Returns: {

0 commit comments

Comments
 (0)