Thread: BUG #6673: Value out of range for type integer when adding WHERE clause
BUG #6673: Value out of range for type integer when adding WHERE clause
From
mfork00@yahoo.com
Date:
The following bug has been logged on the website: Bug reference: 6673 Logged by: Michael Fork Email address: mfork00@yahoo.com PostgreSQL version: 9.1.3 Operating system: Scientific Linux release 6.2 (Carbon) Description:=20=20=20=20=20=20=20=20 The following query and plan executes as expected ++++++++++++++++++++++++++++++++++++++++++++++ springboard_v2=3D# explain SELECT (SELECT number FROM dblink('dbname=3Dcard= ', 'SELECT number FROM mint.card WHERE id =3D ' || card_id) AS card (number TEXT)) AS card_number, mdn, created_at FROM (SELECT trail.parsecardidfromreferencecode(reference_code)::integer AS card_id, mdn, created_at FROM trail.event INNER JOIN trail.activation_event ON activation_event.id =3D event.activation_id INNER JOIN trail.credit_event ON event.id =3D credit_event.id WHERE created_at >=3D 'YESTERDAY' AND created_= at < 'TODAY' and outcome =3D 'SUCCESSFUL' AND type =3D 'CREDIT' AND method =3D '= CARD') AS event LEFT OUTER JOIN (SELECT id FROM dblink('dbname=3Dcard', 'SELECT id FROM mint.card WHERE used_at >=3D ''YESTERDAY'' AND used_at < ''TODAY'' AND state =3D ''REPLENISHED''') AS card (id integer)) AS card ON event.card_id = =3D card.id; =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20 QUERY PLAN ---------------------------------------------------------------------------= ---------------------------------------------------------------------------= ---------------------------- Merge Right Join (cost=3D339861.85..473494.95 rows=3D12660 width=3D37) Merge Cond: (card.id =3D ((trail.parsecardidfromreferencecode(trail.event.reference_code))::integer)) -> Sort (cost=3D59.83..62.33 rows=3D1000 width=3D4) Sort Key: card.id -> Function Scan on dblink card (cost=3D0.00..10.00 rows=3D1000 width=3D4) -> Sort (cost=3D339802.01..339808.34 rows=3D2532 width=3D37) Sort Key: ((trail.parsecardidfromreferencecode(trail.event.reference_code))::integer) -> Nested Loop (cost=3D0.00..339658.88 rows=3D2532 width=3D37) -> Nested Loop (cost=3D0.00..312285.68 rows=3D2694 width= =3D30) -> Index Scan using idx_event_created_at on event=20 (cost=3D0.00..17550.96 rows=3D15644 width=3D34) Index Cond: ((created_at >=3D '2012-06-01 00:00:00-04'::timestamp with time zone) AND (created_at < '2012-06-02 00:00:00-04'::timestamp with time zone)) Filter: ((outcome =3D 'SUCCESSFUL'::text) AND (t= ype =3D 'CREDIT'::text)) -> Index Scan using credit_event_pkey on credit_event= =20 (cost=3D0.00..18.83 rows=3D1 width=3D4) Index Cond: (id =3D trail.event.id) Filter: (method =3D 'CARD'::text) -> Index Scan using activation_event_pkey on activation_event (cost=3D0.00..10.15 rows=3D1 width=3D15) Index Cond: (id =3D trail.event.activation_id) SubPlan 1 -> Function Scan on dblink card (cost=3D0.27..10.27 rows=3D1000 width=3D32) ++++++++++++++++++++++++++++++++++++++++++++++ However, the following query, which is just the above query with 'WHERE card.id IS NULL' tacked on to the end fails with an integer out of range.= =20 Important to know is that parsecardidfromreferencecode will return a valid integer ONLY for the rows matching the WHERE clause. However, I cannot see how adding the WHERE clause causes that error. ++++++++++++++++++++++++++++++++++++++++++++++ springboard_v2=3D# explain SELECT (SELECT number FROM dblink('dbname=3Dcard= ', 'SELECT number FROM mint.card WHERE id =3D ' || card_id) AS card (number TEXT)) AS card_number, mdn, created_at FROM (SELECT trail.parsecardidfromreferencecode(reference_code)::integer AS card_id, mdn, created_at FROM trail.event INNER JOIN trail.activation_event ON activation_event.id =3D event.activation_id INNER JOIN trail.credit_event ON event.id =3D credit_event.id WHERE created_at >=3D 'YESTERDAY' AND created_= at < 'TODAY' and outcome =3D 'SUCCESSFUL' AND type =3D 'CREDIT' AND method =3D '= CARD') AS event LEFT OUTER JOIN (SELECT id FROM dblink('dbname=3Dcard', 'SELECT id FROM mint.card WHERE used_at >=3D ''YESTERDAY'' AND used_at < ''TODAY'' AND state =3D ''REPLENISHED''') AS card (id integer)) AS card ON event.card_id = =3D card.id WHERE card.id IS NULL;; =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20 QUERY PLAN ---------------------------------------------------------------------------= ---------------------------------------------------------------------------= ---------------------- Nested Loop (cost=3D22.50..209968.44 rows=3D1266 width=3D37) -> Nested Loop (cost=3D22.50..183286.35 rows=3D1347 width=3D30) -> Hash Anti Join (cost=3D22.50..35918.99 rows=3D7822 width=3D34) Hash Cond: ((trail.parsecardidfromreferencecode(trail.event.reference_code))::integer = =3D card.id) -> Index Scan using idx_event_created_at on event=20 (cost=3D0.00..17550.96 rows=3D15644 width=3D34) Index Cond: ((created_at >=3D '2012-06-01 00:00:00-04'::timestamp with time zone) AND (created_at < '2012-06-02 00:00:00-04'::timestamp with time zone)) Filter: ((outcome =3D 'SUCCESSFUL'::text) AND (type = =3D 'CREDIT'::text)) -> Hash (cost=3D10.00..10.00 rows=3D1000 width=3D4) -> Function Scan on dblink card (cost=3D0.00..10.00 rows=3D1000 width=3D4) -> Index Scan using credit_event_pkey on credit_event=20 (cost=3D0.00..18.83 rows=3D1 width=3D4) Index Cond: (id =3D trail.event.id) Filter: (method =3D 'CARD'::text) -> Index Scan using activation_event_pkey on activation_event=20 (cost=3D0.00..10.15 rows=3D1 width=3D15) Index Cond: (id =3D trail.event.activation_id) SubPlan 1 -> Function Scan on dblink card (cost=3D0.27..10.27 rows=3D1000 width=3D32) =09=20 ERROR: value "1338523218442" is out of range for type integer
mfork00@yahoo.com writes: > However, the following query, which is just the above query with 'WHERE > card.id IS NULL' tacked on to the end fails with an integer out of range. > Important to know is that parsecardidfromreferencecode will return a valid > integer ONLY for the rows matching the WHERE clause. However, I cannot see > how adding the WHERE clause causes that error. It looks like the planner has chosen to do the joins in a different order here; the join to activation_event is now done last, so that the value of the function might be needed for rows it was not needed for otherwise. This could have occurred in the other version of the query too; it's all about relative row counts. Why don't you cast to bigint rather than integer, seeing that the function is evidently quite capable of returning a bigint value? If you really must use a join condition involving a function that can fail for some inputs, possibly the best solution is to mark the function volatile so that the planner will avoid rearranging stuff that uses it. This might do some considerable damage to the overall quality of the plan though. regards, tom lane