Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 17 additions & 15 deletions src/lib/sql/functions.sql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,21 +44,23 @@ with functions as (
? `(
SELECT STRING_AGG(type_oid::text, ' ') FROM (
SELECT (
split_args.arr[
array_length(
split_args.arr,
1
)
]::regtype::oid
) AS type_oid FROM (
SELECT STRING_TO_ARRAY(
UNNEST(
ARRAY[${props.args}]
),
' '
) AS arr
) AS split_args
) args
CASE
-- Unnamed multi-word SQL types (and single-token types) cast as-is.
-- Taking only the last space-separated token breaks these
-- ("double precision" -> "precision").
WHEN arg ~* '^(timestamp|time)( with| without) time zone(\\[\\])?$'
OR arg ~* '^double precision(\\[\\])?$'
OR arg ~* '^character varying(\\[\\])?$'
OR arg ~* '^bit varying(\\[\\])?$'
OR position(' ' in arg) = 0
THEN arg::regtype
-- Named args: drop the parameter name (first token) and cast the rest.
ELSE substring(arg from position(' ' in arg) + 1)::regtype
END
)::oid AS type_oid FROM (
SELECT UNNEST(ARRAY[${props.args}]) AS arg
) AS args
) resolved
)`
: "''"
} AND`
Expand Down
25 changes: 25 additions & 0 deletions test/lib/functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -531,3 +531,28 @@ test('retrieve function by args filter - function with no arguments', async () =
})
expect(res.error).toBeNull()
})

test('create and retrieve function with multi-word argument types', async () => {
const created = await pgMeta.functions.create({
name: 'test_multiword_arg',
schema: 'public',
args: ['x double precision', 'ts timestamp with time zone'],
definition: 'select x',
return_type: 'double precision',
language: 'sql',
behavior: 'STABLE',
security_definer: false,
})
expect(created.error).toBeNull()
expect(created.data?.name).toBe('test_multiword_arg')

const byTypes = await pgMeta.functions.retrieve({
schema: 'public',
name: 'test_multiword_arg',
args: ['double precision', 'timestamp with time zone'],
})
expect(byTypes.error).toBeNull()
expect(byTypes.data?.id).toBe(created.data!.id)

await pgMeta.functions.remove(created.data!.id)
})