pgsql/create_tables-dovecot-1.2.x.pgsql
branchv0.6.x
changeset 514 d863a44a6353
parent 512 821d3ffaaaca
child 515 09fa019bb330
equal deleted inserted replaced
513:557c4703986c 514:d863a44a6353
   584 CREATE OR REPLACE FUNCTION postfix_virtual_alias_map(
   584 CREATE OR REPLACE FUNCTION postfix_virtual_alias_map(
   585     IN localpart varchar, IN the_domain varchar)
   585     IN localpart varchar, IN the_domain varchar)
   586     RETURNS SETOF recipient_destination
   586     RETURNS SETOF recipient_destination
   587 AS $$
   587 AS $$
   588     DECLARE
   588     DECLARE
       
   589         recordc recipient_destination;
   589         record recipient_destination;
   590         record recipient_destination;
       
   591         catchall_cursor refcursor;
   590         recipient varchar(320) := localpart || '@' || the_domain;
   592         recipient varchar(320) := localpart || '@' || the_domain;
   591         did bigint := (SELECT gid FROM domain_name WHERE domainname=the_domain);
   593         did bigint := (SELECT gid FROM domain_name WHERE domainname=the_domain);
   592     BEGIN
   594     BEGIN
   593         FOR record IN
   595         FOR record IN
   594             SELECT recipient, destination
   596             SELECT recipient, destination
   596              WHERE gid = did
   598              WHERE gid = did
   597                AND address = localpart
   599                AND address = localpart
   598             LOOP
   600             LOOP
   599                 RETURN NEXT record;
   601                 RETURN NEXT record;
   600             END LOOP;
   602             END LOOP;
       
   603 
   601         IF NOT FOUND THEN
   604         IF NOT FOUND THEN
   602             -- First, we have to check existing mailboxes and
   605             -- There is no matching virtual_alias. If there are no catchall
   603             -- return identity if one exists
   606             -- records for this domain, we can just return NULL since Postfix
   604             FOR record IN
   607             -- will then later consult mailboxes/relocated itself. But if
   605                 SELECT recipient, recipient as destination
   608             -- there is a catchall destination, then it would take precedence
   606                   FROM users
   609             -- over mailboxes/relocated, which is not what we want. Therefore,
   607                  WHERE gid = did
   610             -- we must first find out if the query is for an existing mailbox
   608                    AND local_part = localpart
   611             -- or relocated entry and return the identity mapping if that is
   609                 UNION SELECT recipient, recipient as destination
   612             -- the case
   610                   FROM relocated
   613             OPEN catchall_cursor FOR
   611                  WHERE gid = did
   614                 SELECT recipient, destination
   612                    AND address = localpart
   615                   FROM catchall
   613                 LOOP
   616                  WHERE gid = did;
   614                     RETURN NEXT record;
   617             FETCH NEXT FROM catchall_cursor INTO recordc;
   615                 END LOOP;
   618 
   616             -- Only now can we think about catchalls...
   619             IF recordc IS NOT NULL THEN
   617             IF NOT FOUND THEN
   620                 -- Since there are catchall records for this domain
       
   621                 -- check the mailbox and relocated records and return identity
       
   622                 -- if a matching record exists.
   618                 FOR record IN
   623                 FOR record IN
   619                     SELECT recipient, destination
   624                     SELECT recipient, recipient as destination
   620                       FROM catchall
   625                       FROM users
   621                     WHERE gid = did
   626                     WHERE gid = did
       
   627                       AND local_part = localpart
       
   628                     UNION SELECT recipient, recipient as destination
       
   629                       FROM relocated
       
   630                     WHERE gid = did
       
   631                       AND address = localpart
   622                     LOOP
   632                     LOOP
   623                         RETURN NEXT record;
   633                         RETURN NEXT record;
   624                     END LOOP;
   634                     END LOOP;
       
   635 
       
   636                 IF NOT FOUND THEN
       
   637                     -- There were no records found for mailboxes/relocated,
       
   638                     -- so now we can actually iterate the cursor and populate
       
   639                     -- the return set
       
   640                     LOOP
       
   641                         RETURN NEXT recordc;
       
   642                         FETCH NEXT FROM catchall_cursor INTO recordc;
       
   643                         EXIT WHEN recordc IS NULL;
       
   644                     END LOOP;
       
   645                 END IF;
   625             END IF;
   646             END IF;
       
   647             CLOSE catchall_cursor;
   626         END IF;
   648         END IF;
   627         RETURN;
   649         RETURN;
   628     END;
   650     END;
   629 $$ LANGUAGE plpgsql STABLE
   651 $$ LANGUAGE plpgsql STABLE
   630 RETURNS NULL ON NULL INPUT
   652 RETURNS NULL ON NULL INPUT