Login | Register
My pages Projects Community openCollabNet

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Catacomb] bug: DASL search using the "like" operator fails with Internal Server Error (patch included)



In search.c, in the function parse_where(), in the big if/elseif dispatch that
handles the various operators, the code for the comparison operators (eq, lt,
gt, lte, gte, like) is almost identical, and is copy/pasted for each of them
separately. But, it looks like somebody forgot to update it for the "like"
operator (and also for "lte" and "gte").

The patch below fixes this problem, and also refactors the resulting 6 almost
identical copies of code into one chunk near the end of the function.

P.S. I'm not subscribed to this list, please CC me if you reply.

--
Makefiles not war





diff -urN catacomb-0.9.0-orig/search.c catacomb-0.9.0/search.c
--- catacomb-0.9.0-orig/search.c 2003-08-22 21:00:28.000000000 +0200
+++ catacomb-0.9.0/search.c 2003-10-20 04:29:12.000000000 +0200
@@ -590,6 +590,7 @@
   dead_prop_list ** dead_props)
 {
     char *op = NULL;
+    char *comp_op = NULL;
     dead_prop_list *tmp = NULL;

     op = apr_pstrdup(r->pool, cur_elem->name);
@@ -637,75 +638,50 @@
      return HTTP_BAD_REQUEST;
  }
     }
-    else if (apr_strnatcmp(op, "eq") == 0) {
- if (cur_elem->first_child &&
-     cur_elem->first_child->first_child &&
-     cur_elem->first_child->first_child->name &&
-     cur_elem->first_child->next &&
-     cur_elem->first_child->next->first_cdata.first->text) {
-     if (is_dead_prop(cur_elem->first_child->first_child)) {
-  tmp = (dead_prop_list *) apr_pcalloc(r->pool, sizeof(*tmp));
-  tmp->next = *dead_props;
-  tmp->prop = apr_pstrdup(r->pool,
-     cur_elem->first_child->first_child->
-     name);
-  *dead_props = tmp;
-  sctx->where_cond = apr_pstrcat(r->pool, sctx->where_cond,
-            tmp->prop, "_t.name = '",
-            tmp->prop, "' AND ", tmp->prop,
-            "_t.value = '",
-            cur_elem->first_child->next->
-            first_cdata.first->text, "' ",
-            NULL);
-     }
-     else {
-  sctx->where_cond = apr_pstrcat(r->pool, sctx->where_cond,
-            cur_elem->first_child->
-            first_child->name, " = '",
-            cur_elem->first_child->next->
-            first_cdata.first->text, "' ",
-            NULL);
-     }
- }
- else {
-     return HTTP_BAD_REQUEST;
- }
-    }
-    else if (apr_strnatcmp(op, "lt") == 0) {
- if (cur_elem->first_child &&
-     cur_elem->first_child->first_child &&
-     cur_elem->first_child->first_child->name &&
-     cur_elem->first_child->next &&
-     cur_elem->first_child->next->first_cdata.first->text) {
-     if (is_dead_prop(cur_elem->first_child->first_child)) {
-  tmp = (dead_prop_list *) apr_pcalloc(r->pool, sizeof(*tmp));
-  tmp->next = *dead_props;
-  tmp->prop = apr_pstrdup(r->pool,
-     cur_elem->first_child->first_child->
-     name);
-  *dead_props = tmp;
-  sctx->where_cond = apr_pstrcat(r->pool, sctx->where_cond,
-            tmp->prop, "_t.name = '",
-            tmp->prop, "' AND ", tmp->prop,
-            "_t.value < '",
-            cur_elem->first_child->next->
-            first_cdata.first->text, "' ",
-            NULL);
-     }
-     else {
-  sctx->where_cond = apr_pstrcat(r->pool, sctx->where_cond,
-            cur_elem->first_child->
-            first_child->name, " < '",
-            cur_elem->first_child->next->
-            first_cdata.first->text, "' ",
-            NULL);
-     }
- }
- else {
-     return HTTP_BAD_REQUEST;
- }
-    }
-    else if (apr_strnatcmp(op, "gt") == 0) {
+    else if (apr_strnatcmp(op, "eq") == 0)
+ comp_op = "=";
+    else if (apr_strnatcmp(op, "lt") == 0)
+ comp_op = "<";
+    else if (apr_strnatcmp(op, "gt") == 0)
+ comp_op = ">";
+    else if (apr_strnatcmp(op, "lte") == 0)
+ comp_op = "<=";
+    else if (apr_strnatcmp(op, "gte") == 0)
+ comp_op = ">=";
+    else if (apr_strnatcmp(op, "like") == 0)
+ comp_op = "like";
+    /* According to the spec, the isdefined operator is optional. We'll
+       need to implement contains, however...
+
+       } else if (apr_strnatcmp(op, "isdefined") == 0) {
+
+       } else if (apr_strnatcmp(op, "contains") == 0) {
+     */
+    else if (apr_strnatcmp(op, "contains") == 0) { // By PK
+        const char *contains_value = cur_elem->first_cdata.first->text;
+
+ /*Get rid of eol*/
+        if ( contains_value[0] == ' ' )
+     contains_value++;
+ if ( contains_value[0] == '\r' || contains_value[0] == '\n' )
+     contains_value++;
+ if ( contains_value[0] == '\n' )
+     contains_value++;
+
+        /* Get rid of the leading 'EOL' sent by cadaver. FIX cadaver & FIX ME
*/
+ if (strncmp(contains_value, "EOL", 3) == 0)
+     contains_value += 3;
+
+        if (cur_elem->first_cdata.first->text) {
+            sctx->where_cond = apr_pstrcat(r->pool, sctx->where_cond,
+                   " MATCH (textcontent) AGAINST ('",
+                   contains_value ,
+     "')", NULL);
+        }
+    }
+
+    /* Handle the comparison operator (if encountered) */
+    if (comp_op) {
  if (cur_elem->first_child &&
      cur_elem->first_child->first_child &&
      cur_elem->first_child->first_child->name &&
@@ -721,7 +697,7 @@
   sctx->where_cond = apr_pstrcat(r->pool, sctx->where_cond,
             tmp->prop, "_t.name = '",
             tmp->prop, "' AND ", tmp->prop,
-            "_t.value > '",
+            "_t.value ", comp_op, " '",
             cur_elem->first_child->next->
             first_cdata.first->text, "' ",
             NULL);
@@ -729,7 +705,7 @@
      else {
   sctx->where_cond = apr_pstrcat(r->pool, sctx->where_cond,
             cur_elem->first_child->
-            first_child->name, " > '",
+            first_child->name, " ", comp_op, " '",
             cur_elem->first_child->next->
             first_cdata.first->text, "' ",
             NULL);
@@ -739,110 +715,7 @@
      return HTTP_BAD_REQUEST;
  }
     }
-    else if (apr_strnatcmp(op, "lte") == 0) {
- if (cur_elem->first_child &&
-     cur_elem->first_child->first_child &&
-     cur_elem->first_child->first_child->name &&
-     cur_elem->first_child->next &&
-     cur_elem->first_child->next->first_cdata.first->text) {
-     if (is_dead_prop(cur_elem->first_child->first_child)) {
-  tmp = (dead_prop_list *) apr_pcalloc(r->pool, sizeof(*tmp));
-  tmp->next = *dead_props;
-  tmp->prop = apr_pstrdup(r->pool,
-     cur_elem->first_child->first_child->
-     name);
-  *dead_props = tmp;
-     }
-     sctx->where_cond = apr_pstrcat(r->pool, sctx->where_cond,
-        cur_elem->first_child->
-        first_child->name, " <= '",
-        cur_elem->first_child->next->
-        first_cdata.first->text, "' ",
-        NULL);
- }
- else {
-     return HTTP_BAD_REQUEST;
- }
-    }
-    else if (apr_strnatcmp(op, "gte") == 0) {
- if (cur_elem->first_child &&
-     cur_elem->first_child->first_child &&
-     cur_elem->first_child->first_child->name &&
-     cur_elem->first_child->next &&
-     cur_elem->first_child->next->first_cdata.first->text) {
-     if (is_dead_prop(cur_elem->first_child->first_child)) {
-  tmp = (dead_prop_list *) apr_pcalloc(r->pool, sizeof(*tmp));
-  tmp->next = *dead_props;
-  tmp->prop = apr_pstrdup(r->pool,
-     cur_elem->first_child->first_child->
-     name);
-  *dead_props = tmp;
-     }
-     sctx->where_cond = apr_pstrcat(r->pool, sctx->where_cond,
-        cur_elem->first_child->
-        first_child->name, " >= '",
-        cur_elem->first_child->next->
-        first_cdata.first->text, "' ",
-        NULL);
- }
- else {
-     return HTTP_BAD_REQUEST;
- }
-    }
-    else if (apr_strnatcmp(op, "like") == 0) {
- if (cur_elem->first_child &&
-     cur_elem->first_child->first_child &&
-     cur_elem->first_child->first_child->name &&
-     cur_elem->first_child->next &&
-     cur_elem->first_child->next->first_cdata.first->text) {
-     if (is_dead_prop(cur_elem->first_child->first_child)) {
-  tmp = (dead_prop_list *) apr_pcalloc(r->pool, sizeof(*tmp));
-  tmp->next = *dead_props;
-  tmp->prop = apr_pstrdup(r->pool,
-     cur_elem->first_child->first_child->
-     name);
-  *dead_props = tmp;
-     }
-     sctx->where_cond = apr_pstrcat(r->pool, sctx->where_cond,
-        cur_elem->first_child->
-        first_child->name, " like '",
-        cur_elem->first_child->next->
-        first_cdata.first->text, "'",
-        NULL);
- }
- else {
-     return HTTP_BAD_REQUEST;
- }
- /* According to the spec, the isdefined operator is optional. We'll
-    need to implement contains, however...
-
-    } else if (apr_strnatcmp(op, "isdefined") == 0) {

-    } else if (apr_strnatcmp(op, "contains") == 0) {
-  */
-    }
-    else if (apr_strnatcmp(op, "contains") == 0) { // By PK
-        const char *contains_value = cur_elem->first_cdata.first->text;
-
- /*Get rid of eol*/
-        if ( contains_value[0] == ' ' )
-     contains_value++;
- if ( contains_value[0] == '\r' || contains_value[0] == '\n' )
-     contains_value++;
- if ( contains_value[0] == '\n' )
-     contains_value++;
-
-        /* Get rid of the leading 'EOL' sent by cadaver. FIX cadaver & FIX ME
*/
- if (strncmp(contains_value, "EOL", 3) == 0)
-     contains_value += 3;
-
-        if (cur_elem->first_cdata.first->text) {
-            sctx->where_cond = apr_pstrcat(r->pool, sctx->where_cond,
-                   " MATCH (textcontent) AGAINST ('",
-                   contains_value ,
-     "')", NULL);
-        }
-    }
     sctx->where_cond = apr_pstrcat(r->pool, sctx->where_cond, ")", NULL);

     return HTTP_OK;