Thread: How to access array elements via PL/pgSQL trigger?
I have a (partial) schema as shown below. When I attempt to insert a row from a Tcl script, I get the following error from the script: NOTICE: plpgsql: ERROR during compile of exam_statistics_fixup near line 4 ERROR: parse error at or near "[" insert into exam (type, school_id, year, population, level) values ('ELA', 4, 1999, 'GE', '{ 7,87,208,73 }') This is running with PostgreSQL 7.1.3 on both client and server. It looks like I don't understand something about PL/pgSQL functions and arrays, but I can't find any examples in the documentation or anything in the TODO list that would indicate there should be a problem. So what *am* I missing? NB: remove the "references" constraints, and you should be able to run this example in isolation from the rest of my database. create table exam ( type varchar(4) references exam_type_lookup (type), school_id int references school(id), year numeric(4) not null, population varchar(3) not null, total numeric(4), level numeric(4)[], levelpct numeric(5,2)[] ); create unique index uk_exam on exam (school_id, year, type, population); create index idx_exam_1 on exam (school_id); comment on column exam.type is 'Type of exam'; comment on column exam.year is 'Year in which the exam was performed'; comment on column exam.level is 'Number of students performing at the particular level'; comment on column exam.population is 'SE - Special Education, GE - General'; create function exam_statistics_fixup () returns opaque AS ' begin -- Force derived columns to be consistent with new data. new.total := new.level[1] + new.level[2] + new.level[3] + new.level[4]; new.levelpct[1] := 100 * new.level[1] / new.total; new.levelpct[2] := 100 * new.level[2] / new.total; new.levelpct[3] := 100 * new.level[3] / new.total; new.levelpct[4] := 100 * new.level[4] / new.total; return new; end; ' language 'plpgsql'; create trigger exam_biur before insert or update on exam for each row execute procedure exam_statistics_fixup(); roland -- PGP Key ID: 66 BC 3B CD Roland B. Roberts, PhD RL Enterprises roland@rlenter.com 76-15 113th Street, Apt 3B roland@astrofoto.org Forest Hills, NY 11375
Roland Roberts <roland@astrofoto.org> writes: > I have a (partial) schema as shown below. When I attempt to insert a > row from a Tcl script, I get the following error from the script: > NOTICE: plpgsql: ERROR during compile of exam_statistics_fixup near line 4 > ERROR: parse error at or near "[" Most likely this error is not coming from plpgsql, but from the core SQL parser spitting up on some transformed query that plpgsql tried to feed it. It'll be educational to set the debug level to 2 or more (in a fresh backend) and retry the failing query. That should cause the postmaster log to accumulate the queries being sent down to the SQL parser. My first thought is that plpgsql may not support the syntax arrayvar[subscript] := something but I've not tried it. regards, tom lane
>>>>> "Tom" == Tom Lane <tgl@sss.pgh.pa.us> writes: Tom> Most likely this error is not coming from plpgsql, but from Tom> the core SQL parser spitting up on some transformed query Tom> that plpgsql tried to feed it. It'll be educational to set Tom> the debug level to 2 or more (in a fresh backend) and retry Tom> the failing query. That should cause the postmaster log to Tom> accumulate the queries being sent down to the SQL parser. I'll try bumping up the debug level tomorrow morning when I'm awake enough to know what I'm doing.... Tom> My first thought is that plpgsql may not support the syntax Tom> arrayvar[subscript] := something Tom> but I've not tried it. But line 4 (where it *says* the error is located) reads new.total := new.level[1] + ... ; (which might be a variation of the same thing). roland -- PGP Key ID: 66 BC 3B CD Roland B. Roberts, PhD RL Enterprises roland@rlenter.com 76-15 113th Street, Apt 3B roland@astrofoto.org Forest Hills, NY 11375
Okay, I've re-executed the query after setting debug_level = 2 and restarting the postmaster to use a log file. Here is an extract from the log starting from my connect up to the first aborted insert on the "exam" table. All of the activity up to that point is correct (i.e., the previous duplicate key errors). DEBUG: connection: host=192.168.2.50 user=roland database=psr DEBUG: InitPostgres DEBUG: StartTransactionCommand DEBUG: query: select getdatabaseencoding() DEBUG: ProcessQuery DEBUG: CommitTransactionCommand DEBUG: StartTransactionCommand DEBUG: query: insert into district (number, borough) values (22, 'BKLN') DEBUG: ProcessQuery ERROR: Cannot insert a duplicate key into unique index district_pkey DEBUG: AbortCurrentTransaction DEBUG: StartTransactionCommand DEBUG: query: insert into school (number, district, level) values (312, 22, 'PS') DEBUG: ProcessQuery ERROR: Cannot insert a duplicate key into unique index uk_school DEBUG: AbortCurrentTransaction DEBUG: StartTransactionCommand DEBUG: query: select id from school where number=312 and district=22 and level='PS' DEBUG: ProcessQuery DEBUG: CommitTransactionCommand DEBUG: StartTransactionCommand DEBUG: query: update school set name = 'BERGEN BEACH SCHOOL' where id = 4 DEBUG: ProcessQuery DEBUG: query: SELECT oid FROM ONLY "school_level_lookup" WHERE "id" = $1 FOR UPDATE OF "school_level_lookup" DEBUG: query: SELECT oid FROM ONLY "district" WHERE "number" = $1 FOR UPDATE OF "district" DEBUG: CommitTransactionCommand DEBUG: StartTransactionCommand DEBUG: query: insert into exam (type, school_id, year, population, level) values ('ELA', 4, 1999, 'GE', '{ 7,87,208,73 }') DEBUG: ProcessQuery NOTICE: plpgsql: ERROR during compile of exam_statistics_fixup near line 4 ERROR: parse error at or near "[" DEBUG: AbortCurrentTransaction Does this tell you any more? Should I log this as a bug? (The bug form on the web site doesn't seem to be found right now...). roland -- PGP Key ID: 66 BC 3B CD Roland B. Roberts, PhD RL Enterprises roland@rlenter.com 76-15 113th Street, Apt 3B roland@astrofoto.org Forest Hills, NY 11375
Roland Roberts <roland@astrofoto.org> writes: > DEBUG: StartTransactionCommand > DEBUG: query: insert into exam (type, school_id, year, population, level) values ('ELA', 4, 1999, 'GE', '{ 7,87,208,73}') > DEBUG: ProcessQuery > NOTICE: plpgsql: ERROR during compile of exam_statistics_fixup near line 4 > ERROR: parse error at or near "[" > DEBUG: AbortCurrentTransaction Okay, so it's not coming from a passed-down query. I think my original guess is right: plpgsql doesn't support assignment to array elements. > Should I log this as a bug? "Missing feature" would be more like it. Postgres' array support is pretty weak in a lot of places, not only plpgsql. regards, tom lane
>>>>> "Tom" == Tom Lane <tgl@sss.pgh.pa.us> writes: >> Should I log this as a bug? Tom> "Missing feature" would be more like it. Postgres' array Tom> support is pretty weak in a lot of places, not only plpgsql. And time to redesign my tables... :-( roland -- PGP Key ID: 66 BC 3B CD Roland B. Roberts, PhD RL Enterprises roland@rlenter.com 76-15 113th Street, Apt 3B roland@astrofoto.org Forest Hills, NY 11375