<docbook><section><title>VOSResFilterDETAPI</title><programlisting>--  
--  $Id: DET_ResFilter.sql,v 1.1 2007/03/26 14:37:37 source Exp $
--
--  This file is part of the OpenLink Software Virtuoso Open-Source (VOS)
--  project.
--  
--  Copyright (C) 1998-2006 OpenLink Software
--  
--  This project is free software; you can redistribute it and/or modify it
--  under the terms of the GNU General Public License as published by the
--  Free Software Foundation; only version 2 of the License, dated June 1991.
--  
--  This program is distributed in the hope that it will be useful, but
--  WITHOUT ANY WARRANTY; without even the implied warranty of
--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
--  General Public License for more details.
--  
--  You should have received a copy of the GNU General Public License along
--  with this program; if not, write to the Free Software Foundation, Inc.,
--  51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
--  

use DB
;

create function &quot;ResFilter_DAV_AUTHENTICATE&quot; (in id any, in what char(1), in req varchar, in auth_uname varchar, in auth_pwd varchar, in auth_uid integer)
{
  declare rfc_spath varchar;
  declare rfc_list_cond, rfc_del_action any;
  declare spath_id integer;
  -- dbg_obj_princ (&#39;ResFilter_DAV_AUTHENTICATE (&#39;, id, what, req, auth_uname, auth_pwd, auth_uid, &#39;)&#39;);
  rfc_spath := null;
  if (DAV_HIDE_ERROR (&quot;ResFilter_GET_CONDITION&quot; (id[1], rfc_spath, rfc_list_cond, rfc_del_action)) is null)
    return -1;
  if (not (&#39;110&#39; like req))
    return -13; -- Internals of ResFilter are not executable.
  if (&#39;C&#39; = what)
    {
      spath_id := DAV_SEARCH_ID (rfc_spath, &#39;C&#39;);
      return DAV_AUTHENTICATE (spath_id, &#39;C&#39;, req, auth_uname, auth_pwd, auth_uid);
    }
  if (&#39;R&#39; = what)
    {
      return DAV_AUTHENTICATE (id [2], &#39;R&#39;, req, auth_uname, auth_pwd, auth_uid);
    }
  return -14;
}
;


create function &quot;ResFilter_NORM&quot; (in value any) returns varchar
{
  value := blob_to_string (value);
  if ((&#39;&#39; = value) or (193 &lt;&gt; value[0]))
    return value;
  value := deserialize (value)[1];
  if (isstring (value))
    return value;
  return cast (xml_tree_doc(value) as varchar);
}
;


create function &quot;ResFilter_ENCODE_FILTER&quot; (in filt any) returns varchar
{
  if (193 &lt;&gt; __tag (filt))
    signal (&#39;.....&#39;, &#39;Invalid filter passed to ResFilter_ENCODE_FILTER&#39;);
  filt := serialize (filt);
  filt[0] := 2;
  return filt;
}
;


create function &quot;ResFilter_DECODE_FILTER&quot; (in value any) returns any
{
  value := blob_to_string (value);
  if ((&#39;&#39; = value) or (value[0] &lt;&gt; 2))
    signal (&#39;.....&#39;, &#39;Invalid filter serialization passed to ResFilter_DECODE_FILTER&#39;);
  value [0] := 193;
  return deserialize (value);
}
;


create function &quot;ResFilter_GET_CONDITION&quot; (in detcol_id integer, out rfc_spath varchar, out rfc_list_cond any, out rfc_del_action any)
{
  -- dbg_obj_princ (&#39;ResFilter_GET_CONDITION (&#39;, detcol_id, &#39;...)&#39;);
  whenever not found goto nf;
  if (isarray (detcol_id))
    return -20;
  select &quot;ResFilter_NORM&quot; (PROP_VALUE) into rfc_spath from WS.WS.SYS_DAV_PROP where PROP_NAME = &#39;virt:ResFilter-SearchPath&#39; and PROP_PARENT_ID = detcol_id and PROP_TYPE = &#39;C&#39;;
  select &quot;ResFilter_DECODE_FILTER&quot; (PROP_VALUE) into rfc_list_cond from WS.WS.SYS_DAV_PROP where PROP_NAME = &#39;virt:ResFilter-ListCond&#39; and PROP_PARENT_ID = detcol_id and PROP_TYPE = &#39;C&#39;;
  select &quot;ResFilter_DECODE_FILTER&quot; (PROP_VALUE) into rfc_del_action from WS.WS.SYS_DAV_PROP where PROP_NAME = &#39;virt:ResFilter-DelAction&#39; and PROP_PARENT_ID = detcol_id and PROP_TYPE = &#39;C&#39;;
  return 0;
nf:
  return -1;
}
;


create procedure &quot;ResFilter_FIT_INTO_CONDITION&quot; (in id any, in what char (1), inout rfc_list_cond any, in auth_uid integer)
{
  -- dbg_obj_princ (&#39;ResFilter_FIT_INTO_CONDITION (&#39;, id, what, rfc_list_cond, auth_uid, &#39;)&#39;);
  declare has_rdf_preds integer;
  declare raw_filter any;
  has_rdf_preds := 0;
  raw_filter := get_keyword (&#39;&#39;, rfc_list_cond);
  foreach (any pred in raw_filter) do
    {
      declare propid integer;
      declare old_value, pred_name, pred_cmp varchar;
      pred_name := pred [0];
      pred_cmp := pred [1];
      if ((&#39;PROP_VALUE&#39; = pred_name) and (&#39;=&#39; = pred_cmp))
        {
          if (isarray (id))
            {
              call (cast (id[0] as varchar) || &#39;_DAV_PROP_SET&#39;)(id, what, pred[3], pred[2], 1, auth_uid);
	      goto next_pred;
            }
	  whenever not found goto ins_prop;
	  select p.PROP_ID, &quot;ResFilter_NORM&quot; (p.PROP_VALUE) into propid, old_value from WS.WS.SYS_DAV_PROP p, WS.WS.SYS_DAV_RES r where p.PROP_NAME = pred[3] and p.PROP_PARENT_ID = id and p.PROP_TYPE = what and r.RES_ID = id;
	  if (old_value &lt;&gt; pred[2])
	    update WS.WS.SYS_DAV_PROP set PROP_VALUE = pred[2] where PROP_ID = propid;
	  goto next_pred;
ins_prop:
	  propid := WS.WS.GETID (&#39;P&#39;);
	  insert replacing WS.WS.SYS_DAV_PROP (PROP_ID, PROP_NAME, PROP_VALUE, PROP_PARENT_ID, PROP_TYPE)
          values (propid, pred[3], pred[2], id, what);
	  goto next_pred;
	}
      if ((&#39;PROP_VALUE&#39; = pred_name) and (&#39;&lt;&gt;&#39; = pred_cmp))
        {
          if (isarray (id))
            {
              call (cast (id[0] as varchar) || &#39;_DAV_PROP_REMOVE&#39;)(id, what, pred[3], 1, auth_uid);
	      goto next_pred;
            }
	  whenever not found goto next_pred;
	  select p.PROP_ID into propid from WS.WS.SYS_DAV_PROP p, WS.WS.SYS_DAV_RES r where p.PROP_NAME = pred[3] and p.PROP_PARENT_ID = id and p.PROP_TYPE = what and r.RES_ID = id and &quot;ResFilter_NORM&quot; (p.PROP_VALUE) = pred[2];
	  delete from WS.WS.SYS_DAV_PROP where PROP_ID = propid;
	  goto next_pred;
	}
      if ((&#39;PROP_NAME&#39; = pred_name) and (&#39;not_exists&#39; = pred_cmp))
        {
          if (isarray (id))
            {
              call (cast (id[0] as varchar) || &#39;_DAV_PROP_REMOVE&#39;)(id, what, pred[3], 1, auth_uid);
	      goto next_pred;
            }
	  whenever not found goto next_pred;
	  select p.PROP_ID into propid from WS.WS.SYS_DAV_PROP p, WS.WS.SYS_DAV_RES r where p.PROP_NAME = pred[2] and p.PROP_PARENT_ID = id and p.PROP_TYPE = what and r.RES_ID = id;
	  delete from WS.WS.SYS_DAV_PROP where PROP_ID = propid;
	  goto next_pred;
	}
      else if ((&#39;RDF_VALUE&#39; = pred_name) and ((&#39;=&#39; = pred_cmp) or (&#39;&lt;&gt;&#39; = pred_cmp)) and (5 = length (pred)) and (&#39;http://local.virt/DAV-RDF&#39; = pred [3]))
        {
	  has_rdf_preds := 1;
	  goto next_pred;
	}
      else if ((&#39;RDF_PRED&#39; = pred_name) and (&#39;not_exists&#39; = pred_cmp) and (4 = length (pred)) and (&#39;http://local.virt/DAV-RDF&#39; = pred [3]))
        {
	  has_rdf_preds := 1;
	  goto next_pred;
	}
      else
        {
          -- dbg_obj_princ (&#39;ResFilter_FIT_INTO_CONDITION has failed on &#39;, pred);
          signal (&#39;.....&#39;, &#39;Unsupported predicate in ResFilter_FIT_INTO_CONDITION&#39;);
        }
next_pred: ;
    }
  if (has_rdf_preds)
    {
      declare propid integer;
      declare old_prop, old_n3, acc_n3, new_n3, new_davxml any;
      declare top_path nvarchar;
      top_path := cast (DAV_SEARCH_PATH (id, what) as nvarchar);
      xte_nodebld_init (acc_n3);
      foreach (any pred in raw_filter) do
        {
	  declare pred_name, pred_cmp varchar;
          pred_name := pred [0];
	  pred_cmp := pred [1];
	  if ((&#39;RDF_VALUE&#39; = pred_name) and (&#39;=&#39; = pred_cmp))
    	    {
	      xte_nodebld_acc (acc_n3,
	        xte_node (
		  xte_head (&#39;N3&#39;, &#39;N3S&#39;, top_path, &#39;N3P&#39;, pred [4]),
		  pred [2] ) );
	    }
        }
      xte_nodebld_final (acc_n3, xte_head (&#39; root&#39;));
      acc_n3 := xml_tree_doc (acc_n3);
      old_n3 := null;
      propid := null;
      if (isarray (id))
        {
          old_prop := call (cast (id[0] as varchar) || &#39;_DAV_PROP_GET&#39;)(id, what, &#39;http://local.virt/DAV-RDF&#39;, auth_uid);
          if (DAV_HIDE_ERROR (old_prop) is null)
            {
              goto do_merge;
            }
          if (isentity (old_prop))
            {
	      old_n3 := xslt (&#39;http://local.virt/davxml2n3xml&#39;, old_prop);
              goto do_merge;
            }
          goto old_prop_found;
        }
      whenever not found goto do_merge;
      select p.PROP_ID, blob_to_string (p.PROP_VALUE) into propid, old_prop
      from WS.WS.SYS_DAV_PROP p, WS.WS.SYS_DAV_RES r
      where p.PROP_NAME = &#39;http://local.virt/DAV-RDF&#39; and p.PROP_PARENT_ID = id and p.PROP_TYPE = what and r.RES_ID = id;
      goto do_merge;
old_prop_found:
      old_prop := deserialize (cast (old_prop as varchar));
      old_n3 := xslt (&#39;http://local.virt/davxml2n3xml&#39;, xml_tree_doc (old_prop));
do_merge:
      new_n3 := DAV_RDF_MERGE (old_n3, acc_n3, null, -1);
      foreach (any pred in raw_filter) do
        {
	  declare pred_name, pred_cmp varchar;
          pred_name := pred [0];
	  pred_cmp := pred [1];
	  if ((&#39;RDF_PRED&#39; = pred_name) and (&#39;&lt;&gt;&#39; = pred_cmp))
    	    {
    	      new_n3 := XMLUpdate (new_n3, &#39;/N3[N3P=&#39; || WS.WS.STR_SQL_APOS (pred[4]) || &#39;][string (.) =&#39; || WS.WS.STR_SQL_APOS (pred[2]) || &#39;]&#39;, null);
	    }
	  else
	  if ((&#39;RDF_PRED&#39; = pred_name) and (&#39;not_exists&#39; = pred_cmp))
    	    {
    	      new_n3 := XMLUpdate (new_n3, &#39;/N3[N3P=&#39; || WS.WS.STR_SQL_APOS (pred[2]) || &#39;]&#39;, null);
	    }
        }
      new_davxml := DAV_RDF_PREPROCESS_RDFXML (new_n3, top_path, 1);
      if (isarray (id))
        {
          call (cast (id[0] as varchar) || &#39;_DAV_PROP_SET&#39;)(id, what, &#39;http://local.virt/DAV-RDF&#39;, new_davxml, 1, auth_uid);
          goto next_pred;
        }
      else if (propid is null)
        {
	  propid := WS.WS.GETID (&#39;P&#39;);
	  insert replacing WS.WS.SYS_DAV_PROP (PROP_ID, PROP_NAME, PROP_VALUE, PROP_PARENT_ID, PROP_TYPE)
          values (propid, &#39;http://local.virt/DAV-RDF&#39;, serialize (new_davxml), id, what);
	}
      else
	update WS.WS.SYS_DAV_PROP set PROP_VALUE = serialize (new_davxml) where PROP_ID = propid;
    }
}
;


create function &quot;ResFilter_MAKE_DEL_ACTION_FROM_CONDITION&quot; (inout rfc_list_cond any) returns any
{
  -- dbg_obj_princ (&#39;ResFilter_MAKE_DEL_ACTION_FROM_CONDITION (&#39;, rfc_list_cond, &#39;)&#39;);
  declare raw_filter, res any;
  res := vector ();
  raw_filter := get_keyword (&#39;&#39;, rfc_list_cond);
  foreach (any pred in raw_filter) do
    {
      declare propid integer;
      declare old_value, pred_name, pred_cmp varchar;
      pred_name := pred [0];
      pred_cmp := pred [1];
      if ((&#39;PROP_VALUE&#39; = pred_name) and (&#39;=&#39; = pred_cmp))
        {
          res := vector_concat (res, vector (vector (&#39;PROP_VALUE&#39;, &#39;&lt;&gt;&#39;, pred[2], pred [3])));
        }
      else if ((&#39;PROP_VALUE&#39; = pred_name) and (&#39;&lt;&gt;&#39; = pred_cmp))
        {
          res := vector_concat (res, vector (vector (&#39;PROP_VALUE&#39;, &#39;=&#39;, pred[2], pred [3])));
        }
      else if ((&#39;RDF_VALUE&#39; = pred_name) and (&#39;=&#39; = pred_cmp) and (5 = length (pred)) and (&#39;http://local.virt/DAV-RDF&#39; = pred [3]))
        {
          res := vector_concat (res, vector (vector (&#39;RDF_VALUE&#39;, &#39;&lt;&gt;&#39;, pred [2], &#39;http://local.virt/DAV-RDF&#39;, pred [4])));
        }
      else if ((&#39;RDF_VALUE&#39; = pred_name) and (&#39;&lt;&gt;&#39; = pred_cmp) and (5 = length (pred)) and (&#39;http://local.virt/DAV-RDF&#39; = pred [3]))
        {
          res := vector_concat (res, vector (vector (&#39;RDF_VALUE&#39;, &#39;=&#39;, pred [2], &#39;http://local.virt/DAV-RDF&#39;, pred [4])));
        }
      else return vector ();
    }
  return vector (&#39;&#39;, res);
}
;


create function &quot;ResFilter_LEAVE_CONDITION&quot; (in id integer, in what char (1), in rfc_del_action any, in auth_uid integer) returns integer
{
  &quot;ResFilter_FIT_INTO_CONDITION&quot; (id, what, rfc_del_action, auth_uid);
  return 0;
}
;


create function &quot;ResFilter_FNMERGE&quot; (in path any, in id any) returns varchar
{
  declare pairs any;
  declare res varchar;
  pairs := regexp_parse (&#39;^(.*[/])?([^/][^./]*)([^/]*)\044&#39;, path, 0);
  if (pairs is null)
    signal (&#39;.....&#39;, sprintf (&#39;Internal error: failed &quot;ResFilter_FNMERGE&quot; (%s, %d)&#39;, path, id));
  if (isinteger (id))
    return sprintf (&#39;%s -RfId%d%s&#39;, subseq (path, 0, pairs[5]), id, subseq (path, pairs[6]));
  id[0] := cast (id[0] as varchar);
  res := sprintf (&#39;%s -Rf%s%s&#39;,
    subseq (path, 0, pairs[5]),
    call (cast (id[0] as varchar) || &#39;_RF_ID2SUFFIX&#39;)(id, &#39;R&#39;),
    subseq (path, pairs[6]) );
  -- dbg_obj_princ (&#39;ResFilter_FNMERGE (&#39;, path, id, &#39;) returns &#39;, res);
  return res;
}
;


create procedure &quot;ResFilter_FNSPLIT&quot; (in path any, out colpath varchar, out orig_fnameext varchar, out id any)
{
  declare pairs any;
  declare fname, fext varchar;
  -- dbg_obj_princ (&#39;ResFilter_FNSPLIT (&#39;, path, &#39;)&#39;);
  pairs := regexp_parse (&#39;^(.*[/])?([^/][^./]*)([^/]*)\044&#39;, path, 0);
  if (pairs is null)
    signal (&#39;.....&#39;, sprintf (&#39;Internal error: failed &quot;ResFilter_FNSPLIT&quot; (%s)&#39;, path));
  colpath := subseq (path, 0, pairs[4]);
  fname := subseq (path, pairs[4], pairs[5]);
  fext := subseq (path, pairs[6], pairs[7]);
  -- dbg_obj_princ (&#39;ResFilter_FNSPLIT: colpath = &#39;, colpath, &#39;, fname = &#39;, fname, &#39;, fext = &#39;, fext);
  pairs := regexp_parse (&#39;^(.*) -RfId([1-9][0-9]*)\044&#39;, fname, 0);
  if (pairs is not null)
    {
      orig_fnameext := subseq (fname, pairs[2], pairs[3]) || fext;
      id := cast (subseq (fname, pairs[4], pairs[5]) as integer);
      -- dbg_obj_princ (&#39;ResFilter_FNSPLIT (&#39;, path, &#39;) decoded &#39;, colpath, orig_fnameext, id);
      return;
    }
  pairs := regexp_parse (&#39;^(.*) -Rf([A-Z][A-Za-z0-9]+)-([A-Za-z0-9~+-]*)\044&#39;, fname, 0);
  if (pairs is not null)
    {
      whenever sqlstate &#39;*&#39; goto oblom;
      orig_fnameext := subseq (fname, pairs[2], pairs[3]) || fext;
      id := call (subseq (fname, pairs[4], pairs[5]) || &#39;_RF_SUFFIX2ID&#39;)(subseq (fname, pairs[6], pairs[7]), &#39;R&#39;);
      -- dbg_obj_princ (&#39;ResFilter_FNSPLIT (&#39;, path, &#39;) decoded &#39;, colpath, orig_fnameext, id);
      return;
    }
oblom:
  orig_fnameext := fname || fext;
  id := null;
  -- dbg_obj_princ (&#39;ResFilter_FNSPLIT (&#39;, path, &#39;) decoded &#39;, colpath, orig_fnameext, id);
}
;


create function &quot;ResFilter_DAV_SEARCH_ID_IMPL&quot; (in detcol_id any, in path_parts any, in what char(1), inout rfc_spath varchar, inout rfc_list_cond any, inout rfc_del_action any) returns any
{
  declare colpath, orig_fnameext varchar;
  declare orig_id any;
  declare hitlist any;
  declare ext_cond any;
  -- dbg_obj_princ (&#39;ResFilter_DAV_SEARCH_ID (&#39;, detcol_id, path_parts, what, &#39;)&#39;);
  if (&#39;R&#39; &lt;&gt; what)
    return -1;
  if (not (isstring (rfc_spath)))
    {
      if (0 &gt; &quot;ResFilter_GET_CONDITION&quot; (detcol_id, rfc_spath, rfc_list_cond, rfc_del_action))
	{
	  -- dbg_obj_princ (&#39;broken filter - no items&#39;);
	  return -1;
	}
    }
  if (1 &lt;&gt; length(path_parts) or (&#39;&#39; = path_parts[0]))
    {
      -- dbg_obj_princ (&#39;not a resource right inside detcol - no items&#39;);
      return -1;
    }
  &quot;ResFilter_FNSPLIT&quot; (path_parts[0], colpath, orig_fnameext, orig_id);
  -- dbg_obj_princ (path_parts, colpath, orig_fnameext, orig_id, rfc_spath, rfc_list_cond, rfc_del_action);
  if (orig_id is null)
    {
      ext_cond := vector (vector (&#39;RES_NAME&#39;, &#39;=&#39;, orig_fnameext));
    }
  else
    {
      if (isinteger (orig_id))
        ext_cond := vector (vector (&#39;RES_NAME&#39;, &#39;=&#39;, orig_fnameext), vector (&#39;RES_ID&#39;, &#39;=&#39;, orig_id));
      else
        ext_cond := vector (vector (&#39;RES_NAME&#39;, &#39;=&#39;, orig_fnameext), vector (&#39;RES_ID_SERIALIZED&#39;, &#39;=&#39;, serialize (orig_id)));
    }
  ext_cond := vector (&#39;&#39;,
    vector_concat (ext_cond, get_keyword (&#39;&#39;, rfc_list_cond) ) );
  hitlist := DAV_DIR_FILTER_INT (rfc_spath, 1, ext_cond, null, null, http_dav_uid ());
  -- dbg_obj_princ (&#39;hitlist is &#39;, hitlist);
  if (length (hitlist) &lt;&gt; 1)
    return -1;
  return hitlist[0][4];
}
;


create function &quot;ResFilter_DAV_AUTHENTICATE_HTTP&quot; (in id any, in what char(1), in req varchar, in can_write_http integer, inout a_lines any, inout a_uname varchar, inout a_pwd varchar, inout a_uid integer, inout a_gid integer, inout _perms varchar) returns integer
{
  declare rc integer;
  declare puid, pgid, ruid, rgid integer;
  declare u_password, pperms varchar;
  declare allow_anon integer;
  if (length (req) &lt;&gt; 3)
    return -15;

  whenever not found goto nf_col_or_res;
  puid := http_dav_uid();
  pgid := coalesce (
    ( select G_ID from WS.WS.SYS_DAV_GROUP
      where G_NAME = &#39;ResFilter_&#39; || coalesce ((select COL_NAME from WS.WS.SYS_DAV_COL where COL_ID=id[1] and COL_DET=&#39;ResFilter&#39;), &#39;&#39;)
      ), puid+1);
  pperms := &#39;110100100NN&#39;;
  if ((what &lt;&gt; &#39;R&#39;) and (what &lt;&gt; &#39;C&#39;))
    return -14;
  allow_anon := WS.WS.PERM_COMP (substring (cast (pperms as varchar), 7, 3), req);
  if (a_uid is null)
    {
      if ((not allow_anon) or (&#39;&#39; &lt;&gt; WS.WS.FINDPARAM (a_lines, &#39;Authorization:&#39;)))
      rc := WS.WS.GET_DAV_AUTH (a_lines, allow_anon, can_write_http, a_uname, u_password, a_uid, a_gid, _perms);
      if (rc &lt; 0)
        return rc;
    }
  if (isinteger (a_uid))
    {
      if (a_uid &lt; 0)
	return a_uid;
     if (a_uid = 1) -- Anonymous FTP
	{
          a_uid := 0;
	  a_gid := 0;
	}
    }
  if (not DAV_CHECK_PERM (pperms, req, a_uid, a_gid, pgid, puid))
    return -13;

  if (isarray (id[2]))
    return -1;
  select RES_OWNER, RES_GROUP into ruid, rgid from WS.WS.SYS_DAV_RES where RES_ID = id[2];
  if (not DAV_CHECK_PERM (pperms, req, a_uid, a_gid, rgid, ruid))
    return -13;

  return a_uid;

nf_col_or_res:
  return -1;
}
;


create function &quot;ResFilter_DAV_GET_PARENT&quot; (in id any, in st char(1), in path varchar) returns any
{
  -- dbg_obj_princ (&#39;ResFilter_DAV_GET_PARENT (&#39;, id, st, path, &#39;)&#39;);
  if (st = &#39;R&#39;)
    return id [1];
  return -20;
}
;


create function &quot;ResFilter_DAV_COL_CREATE&quot; (in detcol_id any, in path_parts any, in permissions varchar, in uid integer, in gid integer, in auth_uid integer) returns any
{
  -- dbg_obj_princ (&#39;ResFilter_DAV_COL_CREATE (&#39;, detcol_id, path_parts, permissions, uid, gid, auth_uid, &#39;)&#39;);
  return -20;
}
;


create function &quot;ResFilter_DAV_COL_MOUNT&quot; (in detcol_id any, in path_parts any, in full_mount_path varchar, in mount_det varchar, in permissions varchar, in uid integer, in gid integer, in auth_uid integer) returns any
{
  -- dbg_obj_princ (&#39;ResFilter_DAV_COL_MOUNT (&#39;, detcol_id, path_parts, full_mount_path, mount_det, permissions, uid, gid, auth_uid, &#39;)&#39;);
  return -20;
}
;


create function &quot;ResFilter_DAV_COL_MOUNT_HERE&quot; (in parent_id any, in full_mount_path varchar, in permissions varchar, in uid integer, in gid integer, in auth_uid integer) returns any
{
  -- dbg_obj_princ (&#39;ResFilter_DAV_COL_MOUNT (&#39;, parent_id, full_mount_path, permissions, uid, gid, auth_uid, &#39;)&#39;);
  return -20;
}
;


create function &quot;ResFilter_DAV_DELETE&quot; (in detcol_id any, in path_parts any, in what char(1), in silent integer, in auth_uid integer) returns integer
{
  declare rc, orig_id integer;
  declare rfc_spath varchar;
  declare rfc_list_cond, rfc_del_action any;
  -- dbg_obj_princ (&#39;ResFilter_DAV_DELETE (&#39;, detcol_id, path_parts, what, silent, auth_uid, &#39;)&#39;);
  rfc_spath := null;
  orig_id := &quot;ResFilter_DAV_SEARCH_ID_IMPL&quot; (detcol_id, path_parts, what, rfc_spath, rfc_list_cond, rfc_del_action);
  if (orig_id &lt; 0)
    return orig_id;
  if (0 = length (rfc_del_action))
    return -20;
  return &quot;ResFilter_LEAVE_CONDITION&quot; (orig_id, what, rfc_del_action, auth_uid);
}
;

create function &quot;ResFilter_DAV_RES_UPLOAD&quot; (in detcol_id any, in path_parts any, inout content any, in type varchar, in permissions varchar, in uid integer, in gid integer, in auth_uid integer) returns any
{
  -- dbg_obj_princ (&#39;ResFilter_DAV_RES_UPLOAD (&#39;, detcol_id, path_parts, &#39;, [content], &#39;, type, permissions, uid, gid, auth_uid, &#39;)&#39;);
  return -20;
}
;


create function &quot;ResFilter_DAV_PROP_REMOVE&quot; (in id any, in st char(0), in propname varchar, in silent integer, in auth_uid integer) returns integer
{
  -- dbg_obj_princ (&#39;ResFilter_DAV_PROP_REMOVE (&#39;, id, st, propname, silent, auth_uid, &#39;)&#39;);
  if (st &lt;&gt; &#39;R&#39;)
    return -1;
  id := id[2];
  if (isarray (id))
    return call (cast (id[0] as varchar) || &#39;_DAV_PROP_REMOVE&#39;) (id, st, propname, silent, auth_uid);
  return DAV_PROP_REMOVE_RAW (id, st, propname, silent, auth_uid);
}
;


create function &quot;ResFilter_DAV_PROP_SET&quot; (in id any, in st char(0), in propname varchar, in propvalue any, in overwrite integer, in auth_uid integer) returns any
{
  declare pid integer;
  declare resv any;
  -- dbg_obj_princ (&#39;ResFilter_DAV_PROP_SET (&#39;, id, st, propname, propvalue, overwrite, auth_uid, &#39;)&#39;);
  if (st &lt;&gt; &#39;R&#39;)
    return -1;
  id := id[2];
  if (isarray (id))
    return call (cast (id[0] as varchar) || &#39;_DAV_PROP_SET&#39;) (id, st, propname, propvalue, overwrite, auth_uid);
  return DAV_PROP_SET_RAW (id, st, propname, propvalue, overwrite, auth_uid);
}
;


create function &quot;ResFilter_DAV_PROP_GET&quot; (in id any, in what char(0), in propname varchar, in auth_uid integer)
{
  declare ret varchar;
  -- dbg_obj_princ (&#39;ResFilter_DAV_PROP_GET (&#39;, id, what, propname, auth_uid, &#39;)&#39;);
  id := id[2];
  if (isarray (id))
    return call (cast (id[0] as varchar) || &#39;_DAV_PROP_GET&#39;) (id, what, propname, auth_uid);
  if (propname[0] = 58)
    return DAV_PROP_GET_INT (id, what, propname, 0, null, null, auth_uid);
  whenever not found goto no_prop;
  select blob_to_string (PROP_VALUE) into ret from WS.WS.SYS_DAV_PROP where PROP_NAME = propname and PROP_PARENT_ID = id and PROP_TYPE = what;
  return ret;

no_prop:
    return -11;
}
;


create function &quot;ResFilter_DAV_PROP_LIST&quot; (in id any, in what char(0), in propmask varchar, in auth_uid integer)
{
  declare ret any;
  -- dbg_obj_princ (&#39;ResFilter_DAV_PROP_LIST (&#39;, id, what, propmask, auth_uid, &#39;)&#39;);
  id := id[2];
  vectorbld_init (ret);
  for select PROP_NAME, PROP_VALUE from WS.WS.SYS_DAV_PROP where PROP_NAME like propmask and PROP_PARENT_ID = id and PROP_TYPE = what do {
      vectorbld_acc (ret, vector (PROP_NAME, blob_to_string (PROP_VALUE)));
    }
  vectorbld_final (ret);
  return ret;
}
;


create function &quot;ResFilter_DAV_DIR_SINGLE&quot; (in id any, in what char(0), in path any, in auth_uid integer) returns any
{
  -- dbg_obj_princ (&#39;ResFilter_DAV_DIR_SINGLE (&#39;, id, what, path, auth_uid, &#39;)&#39;);
  if (&#39;R&#39; &lt;&gt; what)
    return -1;
  for select RES_FULL_PATH, RES_ID, length (RES_CONTENT) as clen, RES_MOD_TIME,
    RES_PERMS, RES_GROUP, RES_OWNER, RES_CR_TIME, RES_TYPE, RES_NAME as r1_RES_NAME
  from WS.WS.SYS_DAV_RES r1
  where RES_ID = id[2]
  do
    {
      declare merged varchar;
      -- dbg_obj_princ (&#39;About to return in DAV_DIR_SINGLE: &#39;, r1_RES_NAME, RES_ID);
      if (regexp_parse (&#39;^([^/][^./]*) -Rf((Id[1-9][0-9]*)|([A-Z][A-Za-z0-9]+)-([A-Za-z0-9~+-]*))([.][^/]*)?\044&#39;, r1_RES_NAME, 0)) -- Suspicious names should be qualified
        {
          merged := &quot;ResFilter_FNMERGE&quot; (r1_RES_NAME, RES_ID);
        }
      else
        {
	  declare rfc_spath varchar;
	  declare rfc_list_cond, rfc_del_action varchar;
	  declare tmp_comp, namesakes any;
          declare namesakes_no integer;
	  if (0 &gt; &quot;ResFilter_GET_CONDITION&quot; (id[1], rfc_spath, rfc_list_cond, rfc_del_action))
	    {
	      -- dbg_obj_princ (&#39;broken filter - bad id in DIR_SINGLE&#39;);
	      return -1;
	    }
          tmp_comp := vector (&#39;&#39;,
            vector_concat (
              vector (vector (&#39;RES_NAME&#39;, &#39;=&#39;, r1_RES_NAME)),
              get_keyword (&#39;&#39;, rfc_list_cond) ) );
	  namesakes := DAV_DIR_FILTER_INT (rfc_spath, 1, tmp_comp, null, null, auth_uid);
	  namesakes_no := length (namesakes);
	  if (0 = namesakes_no)
	    return -1;
	  if (1 &lt; namesakes_no)
	    merged := &quot;ResFilter_FNMERGE&quot; (r1_RES_NAME, RES_ID);
	  else
	    merged := r1_RES_NAME;
        }
--                   0                                                       1    2     3
      return vector (DAV_CONCAT_PATH (DAV_SEARCH_PATH (id[1], &#39;C&#39;), merged), &#39;R&#39;, clen, RES_MOD_TIME,
--       4   5          6          7          8            9         10
	 id, RES_PERMS, RES_GROUP, RES_OWNER, RES_CR_TIME, RES_TYPE, merged);
    }
  return -1;
}
;


create function &quot;ResFilter_DAV_DIR_LIST&quot; (in detcol_id any, in path_parts any, in detcol_path varchar, in name_mask varchar, in recursive integer, in auth_uid integer) returns any
{
  declare rfc_spath varchar;
  declare rfc_list_cond, rfc_dec_action any;
  declare davpath, prev_raw_name varchar;
  declare res, itm, reps any;
  declare itm_ctr, itm_count, prev_is_patched integer;
  -- dbg_obj_princ (&#39;ResFilter_DAV_DIR_LIST (&#39;, detcol_id, path_parts, detcol_path, name_mask, recursive, auth_uid, &#39;)&#39;);
  if (0 &gt; &quot;ResFilter_GET_CONDITION&quot; (detcol_id, rfc_spath, rfc_list_cond, rfc_dec_action))
    {
      -- dbg_obj_princ (&#39;broken filter - no items&#39;);
      return vector();
    }
  if (1 &lt;&gt; length(path_parts) or (&#39;&#39; &lt;&gt; path_parts[0]))
    {
      -- dbg_obj_princ (&#39;nonempty path - no items&#39;);
      return vector();
    }
  if (&#39;%&#39; = name_mask)
    res := DAV_DIR_FILTER_INT (rfc_spath, 1, rfc_list_cond, null, null, auth_uid);
  else
    {
      declare tmp_cond any;
      tmp_cond := vector (&#39;&#39;,
        vector_concat (
          vector (vector (&#39;RES_NAME&#39;, &#39;like&#39;, name_mask)),
          get_keyword (&#39;&#39;, rfc_list_cond) ) );
      res := DAV_DIR_FILTER_INT (rfc_spath, 1, tmp_cond, null, null, auth_uid);
    }
  reps := dict_new ();
  itm_count := length (res);
  for (itm_ctr := 0; itm_ctr &lt; itm_count; itm_ctr := itm_ctr + 1)
    {
      declare rname varchar;
      declare orig_id integer;
      itm := res [itm_ctr];
      rname := itm [10];
      orig_id := itm[4];
      if (regexp_parse (&#39;^([^/][^./]*) -Rf((Id[1-9][0-9]*)|([A-Z][A-Za-z0-9]+)-([A-Za-z0-9~+-]*))([.][^/]*)?\044&#39;, rname, 0)) -- Suspicious names should be qualified
        res [itm_ctr][10] := rname := &quot;ResFilter_FNMERGE&quot; (rname, orig_id);
      dict_put (reps, rname, dict_get (reps, rname, 0) + 1);
    }
  for (itm_ctr := 0; itm_ctr &lt; itm_count; itm_ctr := itm_ctr + 1)
    {
      declare rname varchar;
      declare orig_id integer;
      itm := res [itm_ctr];
      rname := itm [10];
      orig_id := itm[4];
      res[itm_ctr][4] := vector (UNAME&#39;ResFilter&#39;, detcol_id, orig_id);
      if (dict_get (reps, rname, 0) &gt; 1) -- Suspicious names should be qualified
        res [itm_ctr][10] := rname := &quot;ResFilter_FNMERGE&quot; (rname, orig_id);
      res[itm_ctr][0] := DAV_CONCAT_PATH (detcol_path, rname);
    }
  return res;
}
;


create function &quot;ResFilter_DAV_DIR_FILTER&quot; (in detcol_id any, in path_parts any, in detcol_path varchar, inout compilation any, in recursive integer, in auth_uid integer) returns any
{
  declare rfc_spath varchar;
  declare rfc_list_cond, rfc_dec_action any;
  declare davpath, prev_raw_name varchar;
  declare res, itm, reps any;
  declare itm_ctr, itm_count, prev_is_patched integer;
  -- dbg_obj_princ (&#39;ResFilter_DAV_DIR_FILTER (&#39;, detcol_id, path_parts, detcol_path, compilation, recursive, auth_uid, &#39;)&#39;);
  if (0 &gt; &quot;ResFilter_GET_CONDITION&quot; (detcol_id, rfc_spath, rfc_list_cond, rfc_dec_action))
    {
      -- dbg_obj_princ (&#39;broken filter - no items&#39;);
      return vector();
    }
  if (1 &lt;&gt; length(path_parts) or (&#39;&#39; &lt;&gt; path_parts[0]))
    {
      -- dbg_obj_princ (&#39;nonempty path - no items&#39;);
      return vector();
    }
  if (0 = length (get_keyword (&#39;&#39;, compilation)))
    res := DAV_DIR_FILTER_INT (rfc_spath, 1, rfc_list_cond, null, null, auth_uid);
  else
    {
      declare tmp_cond any;
      tmp_cond := vector (&#39;&#39;,
        vector_concat (
          get_keyword (&#39;&#39;, compilation),
          get_keyword (&#39;&#39;, rfc_list_cond) ) );
      res := DAV_DIR_FILTER_INT (rfc_spath, 1, tmp_cond, null, null, auth_uid);
    }
  reps := dict_new ();
  itm_count := length (res);
  for (itm_ctr := 0; itm_ctr &lt; itm_count; itm_ctr := itm_ctr + 1)
    {
      declare rname varchar;
      declare orig_id integer;
      itm := res [itm_ctr];
      rname := itm [10];
      orig_id := itm[4];
      if (regexp_parse (&#39;^([^/][^./]*) -Rf((Id[1-9][0-9]*)|([A-Z][A-Za-z0-9]+)-([A-Za-z0-9~+-]*))([.][^/]*)?\044&#39;, rname, 0)) -- Suspicious names should be qualified
        res [itm_ctr][10] := rname := &quot;ResFilter_FNMERGE&quot; (rname, orig_id);
      dict_put (reps, rname, dict_get (reps, rname, 0) + 1);
    }
  for (itm_ctr := 0; itm_ctr &lt; itm_count; itm_ctr := itm_ctr + 1)
    {
      declare rname varchar;
      declare orig_id integer;
      itm := res [itm_ctr];
      rname := itm [10];
      orig_id := itm[4];
      res[itm_ctr][4] := vector (UNAME&#39;ResFilter&#39;, detcol_id, orig_id);
      if (dict_get (reps, rname, 0) &gt; 1) -- Suspicious names should be qualified
        res [itm_ctr][10] := rname := &quot;ResFilter_FNMERGE&quot; (rname, orig_id);
      res[itm_ctr][0] := DAV_CONCAT_PATH (detcol_path, rname);
    }
  return res;
}
;


create function &quot;ResFilter_DAV_SEARCH_ID&quot; (in detcol_id any, in path_parts any, in what char(1)) returns any
{
  declare rfc_spath varchar;
  declare rfc_list_cond, rfc_del_action any;
  declare orig_id integer;
  -- dbg_obj_princ (&#39;ResFilter_DAV_SEARCH_ID (&#39;, detcol_id, path_parts, what, &#39;)&#39;);
  rfc_spath := null;
  orig_id := &quot;ResFilter_DAV_SEARCH_ID_IMPL&quot; (detcol_id, path_parts, what, rfc_spath, rfc_list_cond, rfc_del_action);
  if (orig_id &lt; 0)
    return orig_id;
  return vector (UNAME&#39;ResFilter&#39;, detcol_id, orig_id);
}
;


create function &quot;ResFilter_DAV_SEARCH_PATH&quot; (in id any, in what char(1)) returns any
{
  -- dbg_obj_princ (&#39;ResFilter_DAV_SEARCH_PATH (&#39;, id, what, &#39;)&#39;);
  return coalesce ((select RES_FULL_PATH from WS.WS.SYS_DAV_RES where RES_ID = id[2]), null);
}
;


create function &quot;ResFilter_DAV_RES_UPLOAD_COPY&quot; (in detcol_id any, in path_parts any, in source_id any, in what char(1), in overwrite integer, in permissions varchar, in uid integer, in gid integer, in auth_uid integer) returns any
{
  declare rfc_spath varchar;
  declare rfc_list_cond, rfc_del_action any;
  declare rc integer;
  -- dbg_obj_princ (&#39;ResFilter_DAV_RES_UPLOAD_COPY (&#39;, detcol_id, path_parts, source_id, what, overwrite, permissions, uid, gid, auth_uid, &#39;)&#39;);
  if (0 &gt; &quot;ResFilter_GET_CONDITION&quot; (detcol_id, rfc_spath, rfc_list_cond, rfc_del_action))
    {
      -- dbg_obj_princ (&#39;broken filter - no items&#39;);
      return -2;
    }
  if (0 = length (rfc_del_action))
    return -20;
  if (1 &lt;&gt; length (path_parts))
    return -2;
  if (&#39;R&#39; &lt;&gt; what)
    return -2;
  if (&#39;&#39; = path_parts[0])
    return -2;
  if (isinteger (source_id) and
     exists (select 1 from WS.WS.SYS_DAV_RES
         where RES_ID = source_id and RES_NAME = path_parts[0] and (RES_FULL_PATH between rfc_spath and DAV_COL_PATH_BOUNDARY (rfc_spath)) ) )
    {
      &quot;ResFilter_FIT_INTO_CONDITION&quot; (source_id, what, rfc_list_cond, auth_uid);
    }
  else
    {
      declare new_full_path varchar;
      new_full_path := DAV_CONCAT_PATH (rfc_spath, path_parts[0]);
      rc := DAV_COPY_INT (DAV_SEARCH_PATH (source_id, what), new_full_path, overwrite, permissions,
         coalesce ((select U_NAME from WS.WS.SYS_DAV_USER where U_ID = uid), &#39;&#39;),
         coalesce ((select G_NAME from WS.WS.SYS_DAV_GROUP where G_ID = gid), &#39;&#39;),
         null, null, 0);
      if (DAV_HIDE_ERROR (rc) is null)
        return rc;
      source_id := DAV_SEARCH_ID (new_full_path, what);
      if (DAV_HIDE_ERROR (source_id) is null)
        return source_id;
      &quot;ResFilter_FIT_INTO_CONDITION&quot; (source_id, what, rfc_list_cond, auth_uid);
    }
  return 1;
}
;


create function &quot;ResFilter_DAV_RES_UPLOAD_MOVE&quot; (in detcol_id any, in path_parts any, in source_id any, in what char(1), in overwrite integer, in auth_uid integer) returns any
{
  declare rfc_spath varchar;
  declare rfc_list_cond, rfc_del_action any;
  declare rc integer;
  -- dbg_obj_princ (&#39;ResFilter_DAV_RES_UPLOAD_MOVE (&#39;, detcol_id, path_parts, source_id, what, overwrite, auth_uid, &#39;)&#39;);
  if (0 &gt; &quot;ResFilter_GET_CONDITION&quot; (detcol_id, rfc_spath, rfc_list_cond, rfc_del_action))
    {
      -- dbg_obj_princ (&#39;broken filter - no items&#39;);
      return -2;
    }
  if (0 = length (rfc_del_action))
    return -20;
  if (1 &lt;&gt; length (path_parts))
    return -2;
  if (&#39;R&#39; &lt;&gt; what)
    return -2;
  if (&#39;&#39; = path_parts[0])
    return -2;
  if (isinteger (source_id) and
    exists (select 1 from WS.WS.SYS_DAV_RES
        where RES_ID = source_id and RES_NAME = path_parts[0] and (RES_FULL_PATH between rfc_spath and DAV_COL_PATH_BOUNDARY (rfc_spath))))
    {
      &quot;ResFilter_FIT_INTO_CONDITION&quot; (source_id, what, rfc_list_cond, auth_uid);
    }
  else
    {
      declare new_full_path varchar;
      new_full_path := DAV_CONCAT_PATH (rfc_spath, path_parts[0]);
      rc := DAV_MOVE_INT (DAV_SEARCH_PATH (source_id, what), new_full_path, overwrite, null, null, 0, 1);
      if (DAV_HIDE_ERROR (rc) is null)
        return rc;
      source_id := DAV_SEARCH_ID (new_full_path, what);
      if (DAV_HIDE_ERROR (source_id) is null)
        return source_id;
      &quot;ResFilter_FIT_INTO_CONDITION&quot; (source_id, what, rfc_list_cond, auth_uid);
    }
  return 1;
}
;


create function &quot;ResFilter_DAV_RES_CONTENT&quot; (in id any, inout content any, out type varchar, in content_mode integer) returns integer
{
  -- dbg_obj_princ (&#39;ResFilter_DAV_RES_CONTENT (&#39;, id, &#39;, [content], [type], &#39;, content_mode, &#39;)&#39;);
  declare cont any;
  if ((content_mode = 0) or (content_mode = 2))
    select RES_CONTENT, RES_TYPE into content, type from WS.WS.SYS_DAV_RES where RES_ID = id[2];
  else if (content_mode = 1)
    select http (RES_CONTENT, content), RES_TYPE into cont, type from WS.WS.SYS_DAV_RES where RES_ID = id[2];
  else if (content_mode = 3)
    select http (RES_CONTENT), RES_TYPE into cont, type from WS.WS.SYS_DAV_RES where RES_ID = id[2];
  return id[2];
}
;


create function &quot;ResFilter_DAV_SYMLINK&quot; (in detcol_id any, in path_parts any, in source_id any, in what char(1), in overwrite integer, in uid integer, in gid integer, in auth_uid integer) returns any
{
  -- dbg_obj_princ (&#39;ResFilter_DAV_SYMLINK (&#39;, detcol_id, path_parts, source_id, overwrite, uid, gid, auth_uid, &#39;)&#39;);
  return -20;
}
;


create function &quot;ResFilter_DAV_LOCK&quot; (in path any, in id any, in type char(1), inout locktype varchar, inout scope varchar, in token varchar, inout owner_name varchar, inout owned_tokens varchar, in depth varchar, in timeout_sec integer, in auth_uid integer) returns any
{
  declare rc, u_token, new_token varchar;
  -- dbg_obj_princ (&#39;ResFilter_DAV_LOCK (&#39;, path, id, type, locktype, scope, token, owner_name, owned_tokens, depth, timeout_sec, auth_uid, &#39;)&#39;);
  if (&#39;R&#39; &lt;&gt; type)
    return -20;
  if (DAV_HIDE_ERROR (id) is null)
    return -20;
  if (isarray (id))
    return DAV_LOCK_INT (path, id[2], type, locktype, scope, token, owner_name, owned_tokens, depth, timeout_sec, null, null, auth_uid);
  return -20;
}
;


create function &quot;ResFilter_DAV_UNLOCK&quot; (in id any, in type char(1), in token varchar, in auth_uid integer)
{
  -- dbg_obj_princ (&#39;ResFilter_DAV_UNLOCK (&#39;, id, type, token, auth_uid, &#39;)&#39;);
  if (isarray (id))
    id := id [2];
  return DAV_UNLOCK_INT (id, type, token, null, null, auth_uid);
}
;


create function &quot;ResFilter_DAV_IS_LOCKED&quot; (inout id any, inout type char(1), in owned_tokens varchar) returns integer
{
  declare rc integer;
  declare orig_id any;
  declare orig_type char(1);
  -- dbg_obj_princ (&#39;ResFilter_DAV_IS_LOCKED (&#39;, id, type, owned_tokens, &#39;)&#39;);
  orig_id := id;
  id := orig_id[2];
  rc := DAV_IS_LOCKED_INT (id, type, owned_tokens);
  if (rc &lt;&gt; 0)
    return rc;
  id := orig_id[1];
  orig_type := type;
  type := &#39;C&#39;;
  rc := DAV_IS_LOCKED_INT (id, type, owned_tokens);
  if (rc &lt;&gt; 0)
    return rc;
  id := orig_id;
  type := orig_type;
  return 0;
}
;


create function &quot;ResFilter_DAV_LIST_LOCKS&quot; (in id any, in type char(1), in recursive integer) returns any
{
  declare res any;
  -- dbg_obj_princ (&#39;ResFilter_DAV_LIST_LOCKS&quot; (&#39;, id, type, recursive);
  id := id[2];
  if (isarray (id))
    return call (cast (id[0] as varchar) || &#39;_DAV_LIST_LOCKS&#39;) (id, type, recursive);
  res := vector();
  for select LOCK_TYPE, LOCK_SCOPE, LOCK_TOKEN, LOCK_TIMEOUT, LOCK_OWNER, LOCK_OWNER_INFO
    from WS.WS.SYS_DAV_LOCK where LOCK_PARENT_ID = id and LOCK_PARENT_TYPE = type do {
      res := vector_concat (res, vector (vector (LOCK_TYPE, LOCK_SCOPE, LOCK_TOKEN, LOCK_TIMEOUT, LOCK_OWNER, LOCK_OWNER_INFO)));
    }
  return res;
}
;


create function &quot;ResFilter_CONFIGURE&quot; (in col any, in search_path varchar, in filter any) returns integer
{
  declare rc integer;
  declare colname varchar;
  declare compilation, del_act any;
  compilation := vector (&#39;&#39;, filter);
  rc := DAV_DIR_FILTER_INT (search_path, 1, compilation, null, null, http_dav_uid ());
  if (isinteger (rc))
    return rc;
  if (not isinteger (col))
    return -20;
  colname := DAV_SEARCH_PATH (col, &#39;C&#39;);
  if (not (isstring (colname)))
    return -23;
  rc := DAV_SEARCH_ID (search_path, &#39;C&#39;);
  if (DAV_HIDE_ERROR (rc) is null)
    return rc;
  if (search_path &lt;&gt; DAV_SEARCH_PATH (rc, &#39;C&#39;))
    return -2;
  if (search_path between colname and (colname || &#39;\255\255\255\255&#39;))
    return -28;
  rc := DAV_PROP_SET_INT (colname, &#39;virt:ResFilter-SearchPath&#39;, search_path, null, null, 0, 1, 1);
  if (DAV_HIDE_ERROR (rc) is null)
    return rc;
  rc := DAV_PROP_SET_INT (colname, &#39;virt:ResFilter-ListCond&#39;, &quot;ResFilter_ENCODE_FILTER&quot; (compilation), null, null, 0, 1, 1);
  if (DAV_HIDE_ERROR (rc) is null)
    return rc;
  del_act := &quot;ResFilter_MAKE_DEL_ACTION_FROM_CONDITION&quot; (compilation);
  -- dbg_obj_princ (&#39;ResFilter_CONFIGURE has made del_action &#39;, del_act, &#39; from &#39;, compilation);
  rc := DAV_PROP_SET_INT (colname, &#39;virt:ResFilter-DelAction&#39;, &quot;ResFilter_ENCODE_FILTER&quot; (del_act), null, null, 0, 1, 1);
  if (DAV_HIDE_ERROR (rc) is null)
    return rc;
  update WS.WS.SYS_DAV_COL set COL_DET=&#39;ResFilter&#39; where COL_ID=col;
  return 0;
}
;

</programlisting></section></docbook>