Thread: Nested loops and $13

Nested loops and $13

From
Torbjörn Andersson
Date:
Hi,

I'm trying to write a function that duplicates information from two tables
and assigns them to a new contract. The relations are s_air_contract has
many s_air_fare which has many s_air_fare_s_airline_rt.

A nested loop seemed like a straightforward way to do it. First insert a new
air fare and then insert the dependant airlines. The code below generates
this error message:

safari=# SELECT func_air_fare_copy(31,76,'20021010','20011212',2,2);
ERROR:  parser: parse error at or near "$13"

I only use 6 variables so $13 has me stumped, ideas anyone??


Best regards,


Torbjörn Andersson
---------------------------------------------------
Embryo Communication      phone: +46 (0) 31-774 39 11(00)
Kungsgatan 7a             fax: +46 (0)31 774 07 80
S-411 19 Göteborg         mobile: 0708-30 70 04
Sweden                    home: http://www.embryo.se/       mail: torbjorn.andersson@embryo.se
---------------------------------------------------



--Code--------------

DROP FUNCTION func_air_fare_copy(int, int, date, date, int, int);
CREATE FUNCTION func_air_fare_copy(int, int, date, date, int, int)
RETURNS int AS'
DECLARE       v_contract_old ALIAS FOR $1;       v_contract_new ALIAS FOR $2;       v_from ALIAS FOR $3;       v_to
ALIASFOR $4;       v_person ALIAS FOR $5;       v_company ALIAS FOR $6;       v_number int := 0;       v_air_fare int
:=0;      row_air RECORD;       row_airline RECORD;
 
BEGIN
-- Insert one row into s_air_fare, get new id, insert airline and code.
FOR row_air IN       SELECT s_air_fare_id, dep__s_airport_code, dest__s_airport_code,
net, gross, gross_infant, gross_child, locked, info       FROM s_air_fare       WHERE s_air_contract_id =
v_contract_old
LOOP       -- insert air_fare       INSERT INTO s_air_fare       (s_air_contract_id, dep__s_airport_code,
dest__s_airport_code,
dep_from, dep_to, net, gross, gross_infant, gross_child, locked, info,
a_person_id, a_company_id)       VALUES       (v_contract_new, row_air.dep__s_airport_code,
row_air.dest__s_airport_code, v_from, v_to, row_air.net, row_air.gross,
row_air.gross_infant, row_air.gross_child, row_air.locked,       row_air.info, v_person. v_company);       v_air_fare =
(SELECT last_value FROM s_air_fare_s_air_fare_id_seq);       -- airlines and classes for the current row       FOR
row_airlineIN               SELECT s_airline_code, s_class               FROM s_air_fare_s_airline_rt
WHEREs_air_fare_id =  row_air.s_air_fare_id       LOOP               -- insert s_air_fare_s_airline_rt
INSERTINTO s_airfare_s_airline_rt VALUES(v_air_fare,
 
row_airline.s_airline_code, row_airline.s_class);       END LOOP;
v_number := v_number + 1;
END LOOP;
RETURN v_number;
END;
' LANGUAGE 'plpgsql';



Re: Nested loops and $13

From
Tom Lane
Date:
Torbjörn Andersson <tobbe@embryo.se> writes:
> safari=# SELECT func_air_fare_copy(31,76,'20021010','20011212',2,2);
> ERROR:  parser: parse error at or near "$13"

> I only use 6 variables so $13 has me stumped, ideas anyone??

The $13 is probably being inserted by plpgsql into one of the queries
that it feeds down to the main SQL parser, as a placeholder for one of
your plpgsql variables.  What this is telling you is that there's a
syntax error in one of the SQL queries, but unfortunately it's not
telling you much about exactly where.  Easiest way to isolate the
problem is to turn on query logging (set debug_print_query = true)
before you run the function for the first time; then look in the
postmaster log to see the passed-down queries.

BTW, I believe that 7.2 will provide a line number in the plpgsql
function in this sort of situation, which should help some.
        regards, tom lane


Re: Nested loops and $13

From
Torbjörn Andersson
Date:
Hi again,

Found the error. It was a typo in this line:
row_air.info, v_person. v_company);
Should be v_person, v_company. Strange error message though.

Anyways, after correcting I get this:
safari=# SELECT func_air_fare_copy(31,76,'20021010','20011212',2,2);
ERROR:  Attribute 's_air_fare_id' is of type 'int4' but expression is of
type 'bpchar'       You will need to rewrite or cast the expression

I use s_air_fare_id on two occasions. Once in the SELECT that creates the
recordset for the outer loop. Here it is the primary key of s_air_fare.
Then in the WHERE clause for the recordset of the inner loop where it is the
foreign key from s_air_fare_s_airline_rt referencing s_air_fare.

In neither case should there be any need for casting. The record row_air has
the datatypes of the original table and when I later use it in the WHERE
clause I compare two integers. Probably I'm missing something here.....

Best Regards


Torbjörn Andersson
---------------------------------------------------
Embryo Communication      phone: +46 (0) 31-774 39 11(00)
Kungsgatan 7a             fax: +46 (0)31 774 07 80
S-411 19 Göteborg         mobile: 0708-30 70 04
Sweden                    home: http://www.embryo.se/       mail: torbjorn.andersson@embryo.se
---------------------------------------------------


--Code----------------
DROP FUNCTION func_air_fare_copy(int, int, date, date, int, int);
CREATE FUNCTION func_air_fare_copy(int, int, date, date, int, int)
RETURNS int AS'
DECLARE       v_contract_old ALIAS FOR $1;       v_contract_new ALIAS FOR $2;       v_from ALIAS FOR $3;       v_to
ALIASFOR $4;       v_person ALIAS FOR $5;       v_company ALIAS FOR $6;       v_number int := 0;       v_air_fare int
:=0;      row_air RECORD;       row_airline RECORD;
 
BEGIN
-- Insert one row into s_air_fare, get new id, insert airline and code.
FOR row_air IN       SELECT s_air_fare_id, dep__s_airport_code, dest__s_airport_code,
net, gross, gross_infant, gross_child, locked, info       FROM s_air_fare       WHERE s_air_contract_id =
v_contract_old
LOOP       -- insert air_fare       INSERT INTO s_air_fare       (s_air_contract_id, dep__s_airport_code,
dest__s_airport_code,
dep_from, dep_to, net, gross, gross_infant, gross_child, locked, info,
a_person_id, a_company_id)       VALUES       (v_contract_new, row_air.dep__s_airport_code,
row_air.dest__s_airport_code, v_from, v_to, row_air.net, row_air.gross,
row_air.gross_infant, row_air.gross_child, row_air.locked,       row_air.info, v_person, v_company);       SELECT  INTO
v_air_farelast_value FROM
 
s_air_fare_s_air_fare_id_seq;
       -- airlines and classes for the current row       FOR row_airline IN               SELECT s_airline_code,
s_class              FROM s_air_fare_s_airline_rt afart               WHERE afart.s_air_fare_id =
row_air.s_air_fare_id      LOOP               -- insert s_air_fare_s_airline_rt               INSERT INTO
s_air_fare_s_airline_rtVALUES(v_air_fare,
 
row_airline.s_airline_code, row_airline.s_class);       END LOOP;
v_number := v_number + 1;
END LOOP;
RETURN v_number;
END;
' LANGUAGE 'plpgsql';




Re: Nested loops and $13

From
Torbjörn Andersson
Date:
>  Easiest way to isolate the
> problem is to turn on query logging (set debug_print_query = true)
> before you run the function for the first time; then look in the
> postmaster log to see the passed-down queries.

Thanks Tom, I didn't know about that one. And it helped me to find two other
errors as well....

Best Regards

Torbjörn Andersson
---------------------------------------------------
Embryo Communication      phone: +46 (0) 31-774 39 11(00)
Kungsgatan 7a             fax: +46 (0)31 774 07 80
S-411 19 Göteborg         mobile: 0708-30 70 04
Sweden                    home: http://www.embryo.se/       mail: torbjorn.andersson@embryo.se
---------------------------------------------------
"Att idag tänka annorlunda än igår skiljer den vise från den envise." — John
Steinbeck