NULLs and composite types
| От | Dean Gibson (DB Administrator) |
|---|---|
| Тема | NULLs and composite types |
| Дата | |
| Msg-id | 52A9010D.3070202@ultimeth.com обсуждение исходный текст |
| Ответы |
Re: NULLs and composite types
|
| Список | pgsql-sql |
PostgreSQL 9.0.2 (CentOS 4.4):<br /><br /> I think the crux of my problem is:<br /><br /> SELECT ROW( NULL, NULL) IS
NULL; -- returns TRUE<br /><br /> SELECT COALESCE( ROW( NULL, NULL), ROW( 1,2 )); -- returns "(,)"<br /><br />
Manifestation:<br/><br /> I have a composite type:<br /><br /> CREATE TYPE "BaseTypes"."GeoPosition"
AS(<br/> latitude FLOAT,<br /> longitude FLOAT<br /> );<br /><br /> For the problem at
hand,I have two tables (say named A and B) which each declare a field thusly:<br /><br /> ...<br /> location"
"BaseTypes"."GeoPosition",<br/> ...<br /><br /> I also have a PL/pqSQL TRIGGER (BEFORE INSERT) that intercepts
INSERTsto table A generated elsewhere, and depending on a bunch of stuff, may:<br /><br /><ol><li>Change values in NEW
fields.<li>Usinga CURSOR, go find a related record in table A and update that instead (and RETURN NULL from the TRIGGER
procedure),or just RETURN NEW.<li>Before RETURNing, the TRIGGER procedure may also INSERT or UPDATE a related record in
tableB.</ol><p>This has all worked beautifully for three years, until I added the above "location" variable to tables A
andB. At the beginning of the TRIGGER procedure, I have:<br /><p> IF (NEW.location).latitude IS NULL
OR (NEW.location).longitude IS NULL THEN<br /> NEW.location := NULL;<br />
END IF;<br /><p>My intent is to make sure that "location" never has the value "ROW( NULL, NULL)", mainly
forsubsequent rendering in a web page.<br /><p>This works in making sure that table A never has the above value.
However,when I INSERT or UPDATE the related record in table B, somehow the fully "NULL" value for "location" gets
"corrupted"into "ROW( NULL, NULL)". I've spent the better part of a day trying to figure this out, with statements
like("record_row" comes from a row captured in a CURSOR SELECT statement from table A):<br /><p>
IF (record_row.location).latitude IS NULL OR (record_row.location).longitude IS NULL THEN<br />
record_row.location := NULL;<br /> END IF;<br />
IF record_row.location = ROW( NULL, NULL )::"GeoPosition" THEN<br />
RAISE LOG 'Debug 1';<br /> END IF;<br /><p>These are six
successivelines, and yet the RAISE statement is frequently executed.<br /><p>Right now I get rid of the problem by
manually(and frequently) executing the following statement:<br /><p>UPDATE "A" SET location = NULL WHERE location =
ROW(NULL, NULL )::"GeoPosition";<br /><p>The above changes the "corrupted" lines correctly, and DOESN'T change lines
where"location" is already fully NULL.<br /><p>What's going on? I can provide more detail if requested. Of course, an
obviousworkaround is to use in a VIEW:<br /><p>... NULLIF( location, ROW( NULL, NULL )::"GeoPosition" ) ...<br /><p>but
I'dlike to know the cause.<br /><p>ps: I know the word "location" is "non-reserved", and if that's the problem, I can
changeit; it just means changing a bunch of other stuff, which I'd rather not do unless necessary.<p>-- Dean<br /><br
/><preclass="moz-signature" cols="72">--
Mail to my list address MUST be sent via the mailing list.
All other mail to my list address will bounce.</pre>
В списке pgsql-sql по дате отправления: