Login | Register
My pages Projects Community openCollabNet

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

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



Hi Ivan,

Thank you for tracking down this bug! We'll take a look at this code right
away -- seems to me it should be integrated quickly.

Kai Pan, could you please take the lead on integrating this patch? Thanks!

- Jim

> -----Original Message-----
> From: catacomb-bounces@webdav.org
> [mailto:catacomb-bounces@webdav.org]On Behalf Of Ivan Todoroski
> Sent: Sunday, October 19, 2003 8:31 PM
> To: catacomb@webdav.org
> Subject: [Catacomb] bug: DASL search using the "like" operator
> fails withInternal 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;
>
>
>
> _______________________________________________
> Catacomb mailing list
> Catacomb@webdav.org
> http://mailman.webdav.org/mailman/listinfo/catacomb