NULLs and composite types
От | Dean Gibson (DB Administrator) |
---|---|
Тема | NULLs and composite types |
Дата | |
Msg-id | 52A9010D.3070202@ultimeth.com обсуждение исходный текст |
Ответы |
Re: NULLs and composite types
(David Johnston <polobo@yahoo.com>)
|
Список | 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 по дате отправления: