-- SETOF as list {{{
create or replace
function a_list (name text, value integer, count integer)
    returns setof a_type
    language plpythonu
as $$
    assert args[0] == name
    assert args[1] == value
    assert args[2] == count

    # return as list
    return [ { 'name': name, 'value': value } ]*count
$$;

select * from a_list(null, null, 0);
select a_list('list', null, 1);
select * from a_list(null, 1, 2);
select a_list('list', 1, 3);
-- }}}


-- SETOF as iterator {{{
create or replace
function a_iter (name text, value integer, count integer)
    returns setof a_type
    language plpythonu
as $$
    assert args[0] == name
    assert args[1] == value
    assert args[2] == count

    # create iterator class that produces tuple(name, value)
    class producer:
        def __init__ (self, name, value, count):
            self.name = name
            self.value = value
            self.count = count
            self.index = 0

        def __iter__ (self):
            return self

        def next (self):
            if self.index == self.count:
                raise StopIteration
            self.index += 1
            return { 'name': self.name, 'value': self.value }

    # return iterator object
    return producer(name, value, count)
$$;

select * from a_iter(null, null, 0);
select a_iter('iter', null, 1);
select * from a_iter(null, 2, 2);
select a_iter('iter', 2, 3);
-- }}}


-- SETOF as generator {{{
create or replace
function a_gen (name text, value integer, count integer)
    returns setof a_type
    language plpythonu
as $$
    assert args[0] == name
    assert args[1] == value
    assert args[2] == count

    # run as generator
    for i in range(count):
       yield { 'name': name, 'value': value }
$$;

select * from a_gen(null, null, 0);
select a_gen('gen', null, 1);
select * from a_gen(null, 3, 2);
select a_gen('gen', 3, 3);
-- }}}
