pgsql/update_tables_0.5.x-0.6.pgsql
branchv0.6.x
changeset 514 d863a44a6353
parent 512 821d3ffaaaca
child 515 09fa019bb330
equal deleted inserted replaced
513:557c4703986c 514:d863a44a6353
   459 CREATE OR REPLACE FUNCTION postfix_virtual_alias_map(
   459 CREATE OR REPLACE FUNCTION postfix_virtual_alias_map(
   460     IN localpart varchar, IN the_domain varchar)
   460     IN localpart varchar, IN the_domain varchar)
   461     RETURNS SETOF recipient_destination
   461     RETURNS SETOF recipient_destination
   462 AS $$
   462 AS $$
   463     DECLARE
   463     DECLARE
       
   464         recordc recipient_destination;
   464         record recipient_destination;
   465         record recipient_destination;
       
   466         catchall_cursor refcursor;
   465         recipient varchar(320) := localpart || '@' || the_domain;
   467         recipient varchar(320) := localpart || '@' || the_domain;
   466         did bigint := (SELECT gid FROM domain_name WHERE domainname=the_domain);
   468         did bigint := (SELECT gid FROM domain_name WHERE domainname=the_domain);
   467     BEGIN
   469     BEGIN
   468         FOR record IN
   470         FOR record IN
   469             SELECT recipient, destination
   471             SELECT recipient, destination
   471              WHERE gid = did
   473              WHERE gid = did
   472                AND address = localpart
   474                AND address = localpart
   473             LOOP
   475             LOOP
   474                 RETURN NEXT record;
   476                 RETURN NEXT record;
   475             END LOOP;
   477             END LOOP;
       
   478 
   476         IF NOT FOUND THEN
   479         IF NOT FOUND THEN
   477             -- First, we have to check existing mailboxes and
   480             -- There is no matching virtual_alias. If there are no catchall
   478             -- return identity if one exists
   481             -- records for this domain, we can just return NULL since Postfix
   479             FOR record IN
   482             -- will then later consult mailboxes/relocated itself. But if
   480                 SELECT recipient, recipient as destination
   483             -- there is a catchall destination, then it would take precedence
   481                   FROM users
   484             -- over mailboxes/relocated, which is not what we want. Therefore,
   482                  WHERE gid = did
   485             -- we must first find out if the query is for an existing mailbox
   483                    AND local_part = localpart
   486             -- or relocated entry and return the identity mapping if that is
   484                 UNION SELECT recipient, recipient as destination
   487             -- the case
   485                   FROM relocated
   488             OPEN catchall_cursor FOR
   486                  WHERE gid = did
   489                 SELECT recipient, destination
   487                    AND address = localpart
   490                   FROM catchall
   488                 LOOP
   491                  WHERE gid = did;
   489                     RETURN NEXT record;
   492             FETCH NEXT FROM catchall_cursor INTO recordc;
   490                 END LOOP;
   493 
   491             -- Only now can we think about catchalls...
   494             IF recordc IS NOT NULL THEN
   492             IF NOT FOUND THEN
   495                 -- Since there are catchall records for this domain
       
   496                 -- check the mailbox and relocated records and return identity
       
   497                 -- if a matching record exists.
   493                 FOR record IN
   498                 FOR record IN
   494                     SELECT recipient, destination
   499                     SELECT recipient, recipient as destination
   495                       FROM catchall
   500                       FROM users
   496                     WHERE gid = did
   501                     WHERE gid = did
       
   502                       AND local_part = localpart
       
   503                     UNION SELECT recipient, recipient as destination
       
   504                       FROM relocated
       
   505                     WHERE gid = did
       
   506                       AND address = localpart
   497                     LOOP
   507                     LOOP
   498                         RETURN NEXT record;
   508                         RETURN NEXT record;
   499                     END LOOP;
   509                     END LOOP;
       
   510 
       
   511                 IF NOT FOUND THEN
       
   512                     -- There were no records found for mailboxes/relocated,
       
   513                     -- so now we can actually iterate the cursor and populate
       
   514                     -- the return set
       
   515                     LOOP
       
   516                         RETURN NEXT recordc;
       
   517                         FETCH NEXT FROM catchall_cursor INTO recordc;
       
   518                         EXIT WHEN recordc IS NULL;
       
   519                     END LOOP;
       
   520                 END IF;
   500             END IF;
   521             END IF;
       
   522             CLOSE catchall_cursor;
   501         END IF;
   523         END IF;
   502         RETURN;
   524         RETURN;
   503     END;
   525     END;
   504 $$ LANGUAGE plpgsql STABLE
   526 $$ LANGUAGE plpgsql STABLE
   505 RETURNS NULL ON NULL INPUT
   527 RETURNS NULL ON NULL INPUT