create type flat_sal_pay AS (name text, quarter integer, pay_by_quarter integer); create or replace function flatten_sal_emp_pay() returns setof flat_sal_pay AS $$ DECLARE r flat_sal_pay; qtrdims integer; q text; BEGIN select into qtrdims array_upper(pay_by_quarter,1) from sal_emp; FOR r in select name, idx.i, pay_by_quarter[idx.i] from sal_emp, generate_series(1,qtrdims) idx(i) order by name; LOOP RETURN NEXT r; END LOOP; RETURN; END; $$ language 'plpgsql'; create type flat_sched AS (name text, i integer, j integer, schedule_item text); create or replace function flatten_sal_emp_sched() returns setof flat_sched AS $$ DECLARE r flat_sched; itemdims integer; elemdims integer; q text; BEGIN select into itemdims max(array_upper(schedule,1)) from sal_emp; select into elemdims max(array_upper(schedule,2)) from sal_emp; FOR r in select name, idx.i, idx2.j, schedule[idx.i][idx2.j] from sal_emp, generate_series(1,itemdims) idx(i), generate_series(1,elemdims) idx2(j) order by name LOOP RETURN NEXT r; END LOOP; RETURN; END; $$ language 'plpgsql';