Hi Jeremy,

Yes, I've used the ds = ds.filter approach as a workaround.  However,
if there are a number of attributes being added conditionally, then
the repeated dataset filters are less efficient than defining a hash
of attributes and calling filter once.

I believe your patch could be made more efficient.  You're using
Array.include to look for empty condition expressions, when the empty?
method should be a lot faster:

+      if cond.responds_to?(:empty?) && cond.empty?
+        clone
+      else

This would not match cond == [[]], but I don't know that filter should
honor that condition expression.  [], {}, and '' would all be empty
and result in a clone.

A more universally applicable way to implement this would be to fork
inside the filter_expr method:

  if expr?(:empty?) && expr.empty?
    return BOOL_TRUE # not sure how you get the true value for the
dataset's database, but insert it here
  end

Then a fork would not be necessary inside Dataset.filter:

      cond = filter_expr(cond, &block)  #=> BOOL_TRUE
      cond = SQL::BooleanExpression.new(:AND, @opts[clause], cond) if
@opts[clause]
      clone(clause => cond)  #=> where TRUE (1, 't', etc.)

Shawn

On Apr 10, 7:16 am, Jeremy Evans <[email protected]> wrote:
> On Apr 9, 1:57 pm, John Firebaugh <[email protected]> wrote:
>
> > I encounter this situation when I have an external datastructure and I need
> > to convert it to a filter hash, via inject({}) {...} or similar. With the
> > current API, I need to create an extra branch in my code to handle the empty
> > case.
>
> Are these cases where you wouldn't have access to the dataset?
> Because anything possible with a filter hash is going to be possible
> with individual filter calls:
>
>   ds = ds.filter(data.inject({}){|d, (k,v)| d[k] = v; d})
>   # vs.
>   ds = data.inject(ds){|d, (k,v)| d.filter(k=>v)}
>
> > I consider it a code smell when an API does not have a sensible behavior for
> > obvious boundary conditions in its input. This is of particular concern for
> > functions like filter that are commonly used in situations where the
> > arguments are not a static condition but built dynamically from runtime
> > input.
>
> Agreed.  Like I said, I'm certainly willing to consider this patch.
> The implementation isn't difficult and the performance hit is modest.
> Simply because I think there are generally better ways doesn't mean I
> think Sequel should violate the POLS.
>
> BTW, how do you think this should be handled?:
>
>   ds.filter(nil)
>
> That currently raises an error.  I think it should probably use WHERE
> NULL (there just isn't a when clause for nil), but I could see some
> people thinking filter(nil) should be the same as filter().
>
> Jeremy

-- 
You received this message because you are subscribed to the Google Groups 
"sequel-talk" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/sequel-talk?hl=en.

Reply via email to