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