ts-safeql / safeql

Validate and auto-generate TypeScript types from raw SQL queries in PostgreSQL.
https://safeql.dev
MIT License
1.35k stars 22 forks source link

Aliasing limitations on non-nullabilities constraints #273

Closed bbenezech closed 1 month ago

bbenezech commented 2 months ago

Hello dear maintainer,

This is what I have this morning with @ts-safeql/eslint-plugin@3.4.5 and libpg-query@15.0.2 on PG-14

select count(1) => { count: string }select count(1) as count => { count: string }select count(1) as count2 => { count2: unknown } 👻

select count(1)::int => {count: number}select count(1)::int as count => {count: number}select count(1)::int as count2 => {count2: number | null} 👻

select pid from pg_stat_activity => { pid: number | null }select pid from pg_stat_activity where pid IS NOT NULL => { pid: number }select pid from pg_stat_activity psa where pid IS NOT NULL => { pid: number }select pid from pg_stat_activity psa where psa.pid IS NOT NULL => { pid: number | null } 👻 select psa.pid from pg_stat_activity psa where psa.pid IS NOT NULL => { pid: number | null } 👻

Not exactly sure which failures are known limitations and which ones are unexpected? Would you like me to have a go at one of these cases?

Newbie012 commented 2 months ago

I'm not getting these results. there are test cases for most of these cases. can you share a reproduction?

karlhorky commented 2 months ago

I'm starting to confirm (this is like the count2 example):

// 💥 Query has incorrect type annotation.
//  Expected: { x: number }[]
//    Actual: { x: number | null }[]
await sql<{ x: number }[]>`
  SELECT
    count(1)::int AS x
`;

select count(1)::int as count2 => {count2: number | null} 👻

Newbie012 commented 2 months ago

fixed in @ts-safeql/eslint-plugin@3.4.6

bbenezech commented 2 months ago

I can confirm

select count(1) as count2 is now ✅ select count(1)::int as count2 is now ✅ select pid from pg_stat_activity psa where psa.pid IS NOT NULL is now ✅

But select psa.pid from pg_stat_activity psa where psa.pid IS NOT NULL is still 👻 { pid: number | null }

BTW select psa.pid from pg_stat_activity psa where pid IS NOT NULL is ✅ select pid from pg_stat_activity psa where pid IS NOT NULL is ✅