pgsql/update_tables_0.5.x-0.6-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
   481 CREATE OR REPLACE FUNCTION postfix_virtual_alias_map(
   481 CREATE OR REPLACE FUNCTION postfix_virtual_alias_map(
   482     IN localpart varchar, IN the_domain varchar)
   482     IN localpart varchar, IN the_domain varchar)
   483     RETURNS SETOF recipient_destination
   483     RETURNS SETOF recipient_destination
   484 AS $$
   484 AS $$
   485     DECLARE
   485     DECLARE
       
   486         recordc recipient_destination;
   486         record recipient_destination;
   487         record recipient_destination;
       
   488         catchall_cursor refcursor;
   487         recipient varchar(320) := localpart || '@' || the_domain;
   489         recipient varchar(320) := localpart || '@' || the_domain;
   488         did bigint := (SELECT gid FROM domain_name WHERE domainname=the_domain);
   490         did bigint := (SELECT gid FROM domain_name WHERE domainname=the_domain);
   489     BEGIN
   491     BEGIN
   490         FOR record IN
   492         FOR record IN
   491             SELECT recipient, destination
   493             SELECT recipient, destination
   493              WHERE gid = did
   495              WHERE gid = did
   494                AND address = localpart
   496                AND address = localpart
   495             LOOP
   497             LOOP
   496                 RETURN NEXT record;
   498                 RETURN NEXT record;
   497             END LOOP;
   499             END LOOP;
       
   500 
   498         IF NOT FOUND THEN
   501         IF NOT FOUND THEN
   499             -- First, we have to check existing mailboxes and
   502             -- There is no matching virtual_alias. If there are no catchall
   500             -- return identity if one exists
   503             -- records for this domain, we can just return NULL since Postfix
   501             FOR record IN
   504             -- will then later consult mailboxes/relocated itself. But if
   502                 SELECT recipient, recipient as destination
   505             -- there is a catchall destination, then it would take precedence
   503                   FROM users
   506             -- over mailboxes/relocated, which is not what we want. Therefore,
   504                  WHERE gid = did
   507             -- we must first find out if the query is for an existing mailbox
   505                    AND local_part = localpart
   508             -- or relocated entry and return the identity mapping if that is
   506                 UNION SELECT recipient, recipient as destination
   509             -- the case
   507                   FROM relocated
   510             OPEN catchall_cursor FOR
   508                  WHERE gid = did
   511                 SELECT recipient, destination
   509                    AND address = localpart
   512                   FROM catchall
   510                 LOOP
   513                  WHERE gid = did;
   511                     RETURN NEXT record;
   514             FETCH NEXT FROM catchall_cursor INTO recordc;
   512                 END LOOP;
   515 
   513             -- Only now can we think about catchalls...
   516             IF recordc IS NOT NULL THEN
   514             IF NOT FOUND THEN
   517                 -- Since there are catchall records for this domain
       
   518                 -- check the mailbox and relocated records and return identity
       
   519                 -- if a matching record exists.
   515                 FOR record IN
   520                 FOR record IN
   516                     SELECT recipient, destination
   521                     SELECT recipient, recipient as destination
   517                       FROM catchall
   522                       FROM users
   518                     WHERE gid = did
   523                     WHERE gid = did
       
   524                       AND local_part = localpart
       
   525                     UNION SELECT recipient, recipient as destination
       
   526                       FROM relocated
       
   527                     WHERE gid = did
       
   528                       AND address = localpart
   519                     LOOP
   529                     LOOP
   520                         RETURN NEXT record;
   530                         RETURN NEXT record;
   521                     END LOOP;
   531                     END LOOP;
       
   532 
       
   533                 IF NOT FOUND THEN
       
   534                     -- There were no records found for mailboxes/relocated,
       
   535                     -- so now we can actually iterate the cursor and populate
       
   536                     -- the return set
       
   537                     LOOP
       
   538                         RETURN NEXT recordc;
       
   539                         FETCH NEXT FROM catchall_cursor INTO recordc;
       
   540                         EXIT WHEN recordc IS NULL;
       
   541                     END LOOP;
       
   542                 END IF;
   522             END IF;
   543             END IF;
       
   544             CLOSE catchall_cursor;
   523         END IF;
   545         END IF;
   524         RETURN;
   546         RETURN;
   525     END;
   547     END;
   526 $$ LANGUAGE plpgsql STABLE
   548 $$ LANGUAGE plpgsql STABLE
   527 RETURNS NULL ON NULL INPUT
   549 RETURNS NULL ON NULL INPUT