There's no DSL that will map into postgresql's NULLS [LAST | FIRST] in order_by clause
There is a DSL that will map into postgresql's NULLS [LAST | FIRST] in order_by clause
While we don't have this in the DSL, it can be easily achieved with fragments:
from f in Foo, order_by: [asc: fragment("? NULLS LAST", f.bar)]
You could also create a simple macro wrapper to make it easier, if you use this a lot:
defmacro nulls_last(field) do
quote do
fragment("? NULLS LAST", unquote(field))
end
end
from f in Foo, order_by: [asc: nulls_last(f.bar)]
I'm not sure we should add this to the DSL.
/cc @josevalim
@michalmuskala is the nulls_last per field? If so I think your solution is beautiful and perfectly fine.
I use a fragment in hex_web https://github.com/hexpm/hex_web/blob/86eb0a71ad2322b329dba6197f91b6aa59abed5e/web/models/package.ex#L165
@josevalim yes, it's per field.
I had the snipper ready, because I wrote it in one of my projects just yesterday 馃槃
@michalmuskala Your fragment example helped me, but I had to modify it slightly (I'm using Ecto 2.1.4 - maybe that matters?).
I'm using order_by: [fragment("? DESC NULLS LAST", foo.bar], which produces SQL ORDER BY foo."bar" DESC NULLS LAST as it should.
If I do order_by: [desc: fragment("? NULLS LAST", f.bar)], it causes a SQL syntax error because the generated SQL is ORDER BY foo."bar" NULLS LAST DESC. The DESC must come before NULLS LAST.
Yes, you're right. I think it never worked as it's described there.
I guess we could support it in ecto using order_by: [desc_nulls_last: foo, asc_nulls_first: bar], I'm not 100% sure we want to add this to ecto itself, though
I don't think it's necessary. I mostly wanted to leave a breadcrumb for myself, for the next time I Google this. :)
Most helpful comment
@michalmuskala Your fragment example helped me, but I had to modify it slightly (I'm using Ecto 2.1.4 - maybe that matters?).
I'm using
order_by: [fragment("? DESC NULLS LAST", foo.bar], which produces SQLORDER BY foo."bar" DESC NULLS LASTas it should.If I do
order_by: [desc: fragment("? NULLS LAST", f.bar)], it causes a SQL syntax error because the generated SQL isORDER BY foo."bar" NULLS LAST DESC. TheDESCmust come beforeNULLS LAST.