BUG #14609: ON CONSTRAINT (aka UPSERT) code fails when excluded.<columname> used in calculation.

From: paul(dot)coyne(at)diridium(dot)com
To: pgsql-bugs(at)postgresql(dot)org
Subject: BUG #14609: ON CONSTRAINT (aka UPSERT) code fails when excluded.<columname> used in calculation.
Date: 2017-03-31 21:10:11
Message-ID: 20170331211011.2690.61348@wrigleys.postgresql.org
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

The following bug has been logged on the website:

Bug reference: 14609
Logged by: Paul Coyne
Email address: paul(dot)coyne(at)diridium(dot)com
PostgreSQL version: 9.5.6
Operating system: Ubuntu 14.04 (and later)
Description:

Table:

CREATE TABLE public.test
(
id bigint NOT NULL DEFAULT nextval('test_id_seq'::regclass),
patient_id bigint,
site_code character varying,
mrn character varying,
sendingfacility character varying(50),
CONSTRAINT test_pkey PRIMARY KEY (id),
CONSTRAINT test_site_code_mrn_key UNIQUE (site_code, mrn)
)
WITH (
OIDS=FALSE
);

CREATE INDEX index_test_on_patient_id
ON public.test
USING btree
(patient_id);

CREATE UNIQUE INDEX index_test_on_site_code_and_mrn
ON public.test
USING btree
(site_code COLLATE pg_catalog."default", mrn COLLATE
pg_catalog."default");

SP:

CREATE OR REPLACE FUNCTION public.sp_test_upsert_with_coalesce(
p_sendingfacility character varying DEFAULT NULL::character varying,
p_site_code character varying DEFAULT NULL::character varying,
p_mrn character varying DEFAULT NULL::character varying)
RETURNS bigint AS
$BODY$
/* BEGIN */
INSERT INTO test(
sendingfacility,
site_code,
mrn
)
VALUES (
NULLIF(p_sendingfacility,''),
p_site_code,
p_mrn
)
ON CONFLICT ON CONSTRAINT test_site_code_mrn_key
DO UPDATE
SET sendingfacility =
NULLIF(COALESCE(NULLIF(p_sendingfacility,''),excluded.sendingfacility),'""')
WHERE excluded.mrn = p_mrn and excluded.site_code = p_site_code
RETURNING id;
/* END; */
$BODY$
LANGUAGE sql VOLATILE
COST 100;

SQL to Run:

select sp_test_upsert_with_coalesce('ABC','1','DEF')
select * from test -- returns 1,,1,DEF,ABC
select sp_test_upsert_with_coalesce('DEF','1','DEF')
select * from test -- returns 1,,1,DEF,DEF
select sp_test_upsert_with_coalesce('','1','DEF')
select * from test -- returns 1,,1,DEF,, -- ERROR: blank parameter
should not be written to DB based on SP
-- if
'excluded.sendingfacility' is changed to test.sendingfacility, the code
works

Can excluded.variablename be used in a calculation? It appears to have the
value NULL in the formula.

The actual code applies to healthcare HL7 messages where by most fields
follow this logic:

If I sent you a value for variable A, store it.
If I send you an empty string for variable A, keep what I sent you before
If I send you "", clear out the variable A
If I send you a new value for for variable A, store it.

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message Peter Geoghegan 2017-03-31 21:54:30 Re: BUG #14609: ON CONSTRAINT (aka UPSERT) code fails when excluded.<columname> used in calculation.
Previous Message Tom Lane 2017-03-31 19:49:26 Re: BUG #14608: no index scan with NOT IN and ENUM