only use extended join-clause if some variable is TRUE I am working with Postgis (extension to postgres) where there are several different geometry-types, i.e. 'polygons', 'points' 'linestrings', and multi-variants of these.
I am trying to create a function which should only use extra join-clauses if the geometry-type is a (multi)-polygon.
in all cases, with all geometrytypes, the join should look like this:
--drop function if exists test_return(geometry, double precision);
CREATE OR REPLACE FUNCTION test_return(
      PAR_geom                      geometry
     ,PAR_tolerance                 double precision DEFAULT 0.0000001
) RETURNS setof geometry
AS $$
DECLARE
    VAR_main_id int;
BEGIN

CASE ST_GeometryType(PAR_geom)
WHEN 'ST_LineString'  THEN
    VAR_main_id = 0;
WHEN 'ST_Polygon', 'ST_MultiLineString', 'ST_MultiPoint'  THEN
    VAR_main_id = 1;
WHEN 'ST_MultiPolygon' THEN 
    VAR_main_id = 2;
ELSE 
    raise EXCEPTION 'this function does not work on single-points';
END CASE;

return query
with repeated_pts as (
select (st_dumppoints(PAR_geom)).path, (st_dumppoints(PAR_geom)).geom 
where st_npoints(st_snaptogrid(PAR_geom, PAR_tolerance)) &lt;&gt; st_npoints(PAR_geom)
)   

select b.geom from 
repeated_pts a
inner join
repeated_pts b
on 

--- Here is how it should behave for all geometry-types---
a.path[1:VAR_main_id] = b.path[1:VAR_main_id] 
and 
a.path[array_upper(a.path, 1)]&lt; b.path[array_upper(b.path, 1)] 
and 
st_dwithin(a.geom, b.geom, PAR_tolerance);
    END;
$$
LANGUAGE plpgsql;

In case its a (multi)-polygon, i want to extend the join-clause with additional join-clauses:
and
  
(
(
a.path[VAR_main_id] = 1 and 
a.path[array_upper(a.path, 1)] &gt; 1 and 
b.path[array_upper(b.path, 1)] &gt; 1
)
or
(
a.path[VAR_main_id] &gt; 1 and 
b.path[array_upper(b.path, 1)] &lt;= 4 
)
)

Is there a smart way to do this?
I know its possible to insert the query into a case-when-then structure like this:
case 
when st_geometrytype(PAR_geom) in ('ST_MultiPolygon', 'ST_Polygon')
then --- run query with additional join-clause -- 

else 
-- run query WITHOUT the extra join-clause --
end case;

however, this structure requires I write the first part of the query twice - is there a way to avoid this?
In case its a (multi)-polygon, I want to extend the join-clause with additional join-clauses:

What you ask for can be achieved with plain boolean logic in the JOIN clause. Append:
AND ((st_geometrytype(PAR_geom) IN ('ST_MultiPolygon', 'ST_Polygon')) IS NOT TRUE

  OR a.path[VAR_main_id] = 1
 AND a.path[array_upper(a.path, 1)] &gt; 1
 AND b.path[array_upper(b.path, 1)] &gt; 1

  OR a.path[VAR_main_id] &gt; 1
 AND b.path[array_upper(b.path, 1)] &lt;= 4 
)

Meaning, either the type is not among the listed ones ('ST_MultiPolygon', 'ST_Polygon'), or the following conditions have to be met.
Operator precedence makes AND bind before OR, so we need no additional parentheses.
The function might look like this:
CREATE OR REPLACE FUNCTION test_return(par_geom      geometry
                                     , par_tolerance float8 = 0.0000001)
  RETURNS SETOF geometry
  LANGUAGE plpgsql AS
$func$
DECLARE
   var_main_id int;
BEGIN
   CASE ST_GeometryType(par_geom)
   WHEN 'ST_LineString'  THEN
       var_main_id = 0;
   WHEN 'ST_Polygon', 'ST_MultiLineString', 'ST_MultiPoint'  THEN
       var_main_id = 1;
   WHEN 'ST_MultiPolygon' THEN 
       var_main_id = 2;
   ELSE 
       RAISE EXCEPTION 'this function does not work on single-points';
   END CASE;

   RETURN QUERY
   WITH repeated_pts AS (
      SELECT d.path, d.geom 
      FROM   st_dumppoints(par_geom) d  -- evaluate once
      WHERE  st_npoints(st_snaptogrid(par_geom, par_tolerance)) &lt;&gt; st_npoints(par_geom)
   )   
   SELECT b.geom
   FROM   repeated_pts a
   JOIN   repeated_pts b ON a.path[1:var_main_id] = b.path[1:var_main_id] 
                        AND a.path[array_upper(a.path, 1)] &lt; b.path[array_upper(b.path, 1)] 
                        AND st_dwithin(a.geom, b.geom, par_tolerance)
                        -- append here!
                        AND ((st_geometrytype(PAR_geom) IN ('ST_MultiPolygon', 'ST_Polygon')) IS NOT TRUE

                          OR a.path[VAR_main_id] = 1
                         AND a.path[array_upper(a.path, 1)] &gt; 1
                         AND b.path[array_upper(b.path, 1)] &gt; 1

                          OR a.path[VAR_main_id] &gt; 1
                         AND b.path[array_upper(b.path, 1)] &lt;= 4 
                        );
END
$func$

Might be possible to simplify further. I lack insight.