OK, so I've defined a grammar for string_expr, which means the following currently works: CREATE FUNCTION foo_raise_loop(text) RETURNS text AS ' DECLARE a ALIAS FOR $1; i integer; myrec RECORD; BEGIN i:=0; FOR myrec IN SELECT * FROM colours LOOP i:=i+1; RAISE NOTICE a || '' : '' || '' colour % is '' || myrec.c_name || ''.'', i, myrec.c_id; END LOOP; RETURN ''done''::text; END;' LANGUAGE 'plpgsql'; SELECT foo_raise_loop('Looping (%)'); Which produces (note the % nr Looping gets evaluated): NOTICE: Looping (1) : colour 1 is red. NOTICE: Looping (2) : colour 2 is green. NOTICE: Looping (3) : colour 3 is blue. What you haven't got are: brackets, casts, function calls, other operators (can't do i+1). I'm going to be out of town for a few days then busy for a couple of weeks. Throw in a week to debug,document and apply against CVS and we're into August. So - do you want it with current functionality or should I press on? - Richard Huxton ---------------------------(end of broadcast)--------------------------- TIP 2: you can get off all lists at once with the unregister command (send "unregister YourEmailAddressHere" to [EMAIL PROTECTED])