Skip to content

Commit 7dcc826

Browse files
committed
Fix Issue 1329 - agtype_to_int4 crash (apache#1339)
Fixed issue 1329 where `agtype_to_int`<8,4,2> and `agtype_to_int4_array` crashed due to not properly checking input. As these functions take "any" input, the input has to be properly checked before casting it to a specific type. The input section assumed it was agtype, which caused crashes for non-agtypes. The functions `agtype_to_int`<8,4,2> will convert non-agtypes into agtype. However, there were no regression tests for this. The functions `agtype_to_int`<8,4,2> will convert non-agtypes to agtype ints but, did not for their string equivs. Meaning, passing a ('true') or ('3.14') would fail but, passing a (true) or (3.14) would not. This has been corrected for all 3 functions. TODO - The function `agtype_to_int4_array` only takes agtype, currently, and we should consider allowing it to take "any" types. Added regression tests. Added missing regression tests. Conflicts: regress/expected/agtype.out regress/expected/expr.out src/backend/utils/adt/agtype.c
1 parent e0c1b93 commit 7dcc826

File tree

5 files changed

+727
-73
lines changed

5 files changed

+727
-73
lines changed

regress/expected/agtype.out

+316-8
Original file line numberDiff line numberDiff line change
@@ -2216,6 +2216,91 @@ SELECT agtype_to_int8(agtype_in('false'));
22162216
0
22172217
(1 row)
22182218

2219+
-- should return SQL NULL
2220+
SELECT agtype_to_int8(agtype_in('null'));
2221+
agtype_to_int8
2222+
----------------
2223+
2224+
(1 row)
2225+
2226+
SELECT agtype_to_int8(NULL);
2227+
agtype_to_int8
2228+
----------------
2229+
2230+
(1 row)
2231+
2232+
-- non agtype input
2233+
SELECT agtype_to_int8(1);
2234+
agtype_to_int8
2235+
----------------
2236+
1
2237+
(1 row)
2238+
2239+
SELECT agtype_to_int8(3.14);
2240+
agtype_to_int8
2241+
----------------
2242+
3
2243+
(1 row)
2244+
2245+
SELECT agtype_to_int8(3.14::numeric);
2246+
agtype_to_int8
2247+
----------------
2248+
3
2249+
(1 row)
2250+
2251+
SELECT agtype_to_int8('3');
2252+
agtype_to_int8
2253+
----------------
2254+
3
2255+
(1 row)
2256+
2257+
SELECT agtype_to_int8(true);
2258+
agtype_to_int8
2259+
----------------
2260+
1
2261+
(1 row)
2262+
2263+
SELECT agtype_to_int8(false);
2264+
agtype_to_int8
2265+
----------------
2266+
0
2267+
(1 row)
2268+
2269+
SELECT agtype_to_int8('3.14');
2270+
agtype_to_int8
2271+
----------------
2272+
3
2273+
(1 row)
2274+
2275+
SELECT agtype_to_int8('true');
2276+
agtype_to_int8
2277+
----------------
2278+
1
2279+
(1 row)
2280+
2281+
SELECT agtype_to_int8('false');
2282+
agtype_to_int8
2283+
----------------
2284+
0
2285+
(1 row)
2286+
2287+
-- should fail
2288+
SELECT agtype_to_int8('neither');
2289+
ERROR: invalid input syntax for type agtype
2290+
DETAIL: Expected agtype value, but found "neither".
2291+
CONTEXT: agtype data, line 1: neither
2292+
SELECT agtype_to_int8('NaN');
2293+
ERROR: bigint out of range
2294+
SELECT agtype_to_int8('Inf');
2295+
ERROR: bigint out of range
2296+
SELECT agtype_to_int8(NaN);
2297+
ERROR: column "nan" does not exist
2298+
LINE 1: SELECT agtype_to_int8(NaN);
2299+
^
2300+
SELECT agtype_to_int8(Inf);
2301+
ERROR: column "inf" does not exist
2302+
LINE 1: SELECT agtype_to_int8(Inf);
2303+
^
22192304
--
22202305
-- Test boolean to integer cast
22212306
--
@@ -2231,14 +2316,8 @@ SELECT agtype_to_int4(agtype_in('false'));
22312316
0
22322317
(1 row)
22332318

2234-
SELECT agtype_to_int4(agtype_in('null'));
2235-
agtype_to_int4
2236-
----------------
2237-
2238-
(1 row)
2239-
22402319
--
2241-
-- Test agtype to integer cast
2320+
-- Test agtype to integer4 cast
22422321
--
22432322
SELECT agtype_to_int4(agtype_in('1'));
22442323
agtype_to_int4
@@ -2260,11 +2339,228 @@ SELECT agtype_to_int4(agtype_in('1.444::numeric'));
22602339

22612340
-- These should all fail
22622341
SELECT agtype_to_int4(agtype_in('"string"'));
2263-
ERROR: invalid input syntax for integer: "string"
2342+
ERROR: invalid input syntax for type agtype
2343+
DETAIL: Expected agtype value, but found "string".
2344+
CONTEXT: agtype data, line 1: string
22642345
SELECT agtype_to_int4(agtype_in('[1, 2, 3]'));
22652346
ERROR: cannot cast agtype array to type int
22662347
SELECT agtype_to_int4(agtype_in('{"int":1}'));
22672348
ERROR: cannot cast agtype object to type int
2349+
-- should return SQL NULL
2350+
SELECT agtype_to_int4(agtype_in('null'));
2351+
agtype_to_int4
2352+
----------------
2353+
2354+
(1 row)
2355+
2356+
SELECT agtype_to_int4(NULL);
2357+
agtype_to_int4
2358+
----------------
2359+
2360+
(1 row)
2361+
2362+
-- non agtype input
2363+
SELECT agtype_to_int4(1);
2364+
agtype_to_int4
2365+
----------------
2366+
1
2367+
(1 row)
2368+
2369+
SELECT agtype_to_int4(3.14);
2370+
agtype_to_int4
2371+
----------------
2372+
3
2373+
(1 row)
2374+
2375+
SELECT agtype_to_int4(3.14::numeric);
2376+
agtype_to_int4
2377+
----------------
2378+
3
2379+
(1 row)
2380+
2381+
SELECT agtype_to_int4('3');
2382+
agtype_to_int4
2383+
----------------
2384+
3
2385+
(1 row)
2386+
2387+
SELECT agtype_to_int4(true);
2388+
agtype_to_int4
2389+
----------------
2390+
1
2391+
(1 row)
2392+
2393+
SELECT agtype_to_int4(false);
2394+
agtype_to_int4
2395+
----------------
2396+
0
2397+
(1 row)
2398+
2399+
SELECT agtype_to_int4('3.14');
2400+
agtype_to_int4
2401+
----------------
2402+
3
2403+
(1 row)
2404+
2405+
SELECT agtype_to_int4('true');
2406+
agtype_to_int4
2407+
----------------
2408+
1
2409+
(1 row)
2410+
2411+
SELECT agtype_to_int4('false');
2412+
agtype_to_int4
2413+
----------------
2414+
0
2415+
(1 row)
2416+
2417+
-- should error
2418+
SELECT agtype_to_int4('neither');
2419+
ERROR: invalid input syntax for type agtype
2420+
DETAIL: Expected agtype value, but found "neither".
2421+
CONTEXT: agtype data, line 1: neither
2422+
SELECT agtype_to_int4('NaN');
2423+
ERROR: integer out of range
2424+
SELECT agtype_to_int4('Inf');
2425+
ERROR: integer out of range
2426+
SELECT agtype_to_int4(NaN);
2427+
ERROR: column "nan" does not exist
2428+
LINE 1: SELECT agtype_to_int4(NaN);
2429+
^
2430+
SELECT agtype_to_int4(Inf);
2431+
ERROR: column "inf" does not exist
2432+
LINE 1: SELECT agtype_to_int4(Inf);
2433+
^
2434+
--
2435+
-- Test boolean to integer2 cast
2436+
--
2437+
SELECT agtype_to_int2(agtype_in('true'));
2438+
agtype_to_int2
2439+
----------------
2440+
1
2441+
(1 row)
2442+
2443+
SELECT agtype_to_int2(agtype_in('false'));
2444+
agtype_to_int2
2445+
----------------
2446+
0
2447+
(1 row)
2448+
2449+
--
2450+
-- Test agtype to integer2 cast
2451+
--
2452+
SELECT agtype_to_int2(agtype_in('1'));
2453+
agtype_to_int2
2454+
----------------
2455+
1
2456+
(1 row)
2457+
2458+
SELECT agtype_to_int2(agtype_in('1.45'));
2459+
agtype_to_int2
2460+
----------------
2461+
1
2462+
(1 row)
2463+
2464+
SELECT agtype_to_int2(agtype_in('1.444::numeric'));
2465+
agtype_to_int2
2466+
----------------
2467+
1
2468+
(1 row)
2469+
2470+
-- These should all fail
2471+
SELECT agtype_to_int2(agtype_in('"string"'));
2472+
ERROR: invalid input syntax for type agtype
2473+
DETAIL: Expected agtype value, but found "string".
2474+
CONTEXT: agtype data, line 1: string
2475+
SELECT agtype_to_int2(agtype_in('[1, 2, 3]'));
2476+
ERROR: cannot cast agtype array to type int
2477+
SELECT agtype_to_int2(agtype_in('{"int":1}'));
2478+
ERROR: cannot cast agtype object to type int
2479+
-- should return SQL NULL
2480+
SELECT agtype_to_int2(agtype_in('null'));
2481+
agtype_to_int2
2482+
----------------
2483+
2484+
(1 row)
2485+
2486+
SELECT agtype_to_int2(NULL);
2487+
agtype_to_int2
2488+
----------------
2489+
2490+
(1 row)
2491+
2492+
-- non agtype input
2493+
SELECT agtype_to_int2(1);
2494+
agtype_to_int2
2495+
----------------
2496+
1
2497+
(1 row)
2498+
2499+
SELECT agtype_to_int2(3.14);
2500+
agtype_to_int2
2501+
----------------
2502+
3
2503+
(1 row)
2504+
2505+
SELECT agtype_to_int2(3.14::numeric);
2506+
agtype_to_int2
2507+
----------------
2508+
3
2509+
(1 row)
2510+
2511+
SELECT agtype_to_int2('3');
2512+
agtype_to_int2
2513+
----------------
2514+
3
2515+
(1 row)
2516+
2517+
SELECT agtype_to_int2(true);
2518+
agtype_to_int2
2519+
----------------
2520+
1
2521+
(1 row)
2522+
2523+
SELECT agtype_to_int2(false);
2524+
agtype_to_int2
2525+
----------------
2526+
0
2527+
(1 row)
2528+
2529+
SELECT agtype_to_int2('3.14');
2530+
agtype_to_int2
2531+
----------------
2532+
3
2533+
(1 row)
2534+
2535+
SELECT agtype_to_int2('true');
2536+
agtype_to_int2
2537+
----------------
2538+
1
2539+
(1 row)
2540+
2541+
SELECT agtype_to_int2('false');
2542+
agtype_to_int2
2543+
----------------
2544+
0
2545+
(1 row)
2546+
2547+
-- should error
2548+
SELECT agtype_to_int2('neither');
2549+
ERROR: invalid input syntax for type agtype
2550+
DETAIL: Expected agtype value, but found "neither".
2551+
CONTEXT: agtype data, line 1: neither
2552+
SELECT agtype_to_int2('NaN');
2553+
ERROR: smallint out of range
2554+
SELECT agtype_to_int2('Inf');
2555+
ERROR: smallint out of range
2556+
SELECT agtype_to_int2(NaN);
2557+
ERROR: column "nan" does not exist
2558+
LINE 1: SELECT agtype_to_int2(NaN);
2559+
^
2560+
SELECT agtype_to_int2(Inf);
2561+
ERROR: column "inf" does not exist
2562+
LINE 1: SELECT agtype_to_int2(Inf);
2563+
^
22682564
--
22692565
-- Test agtype to int[]
22702566
--
@@ -2286,6 +2582,18 @@ SELECT agtype_to_int4_array(agtype_in('["6","7",3.66]'));
22862582
{6,7,4}
22872583
(1 row)
22882584

2585+
-- should error
2586+
SELECT agtype_to_int4_array(bool('true'));
2587+
ERROR: argument must resolve to agtype
2588+
SELECT agtype_to_int4_array((1,2,3,4,5));
2589+
ERROR: argument must resolve to agtype
2590+
-- should return SQL NULL
2591+
SELECT agtype_to_int4_array(NULL);
2592+
agtype_to_int4_array
2593+
----------------------
2594+
2595+
(1 row)
2596+
22892597
--
22902598
-- Map Literal
22912599
--

0 commit comments

Comments
 (0)