hauleth

hauleth

Interest check in query functions

I am working on big update to my ecto_function library. It is inspired by Nx support for defn functions, and my thought was “well, why not, check if it will be possible to do something similar for DB queries”. It seems that it is more or less possible:

defq clamp(val) do
  cond do
    val < 0 -> 0
    val > 1 -> 1
    true -> val
  end
end

Which when used like:

from e in "entires",
  select: clamp(e.value)

Will be translated to:

SELECT
  CASE
  WHEN e.value < 0 THEN 0
  WHEN e.value > 1 THEN 1
  ELSE e.value
  END
FROM entries e

This may be useful when one would like to move more computation to the DB where sometimes it may make more sense (move your computation to your data instead of moving data to your computation).

Question is whether there will be will for such constructs and whether community will find something like that useful.

There is already working PoC on the GitHub

https://github.com/hauleth/ecto_function/pull/4

But I would live to get some more insights before I dig more into it.

First Post!

kelvinst

kelvinst

I really like all these libs that make devs lives easier. I have some concerns with this approach though:

  1. It’s not very explicit. I mean, having just the letter q by the end of def does not make it very clear that this is a macro that is going to magically turn your elixir code into an Ecto.Query
  2. Magic is normally hard to customize. I can see myself using your library for simple queries and falling back to Ecto’s default query builder for more complex stuff. But some people really like to push the limits of what you initially intended for the lib (specially people that do not have much experience with magic), so that can backfire to a lot of unexpected results.

Anyway, I liked your idea and I might even give it a try on one of my livestream side projects in the future (if it ever makes to a final version of your lib) :smiley:

Most Liked

hauleth

hauleth

Actually it doesn’t change it into Ecto.Query, it changes it into macro that produces fragment/1.

defq clamp(val) do
  cond do
    val < 0 -> 0
    val > 1 -> 1
    true -> val
  end
end

Will expand to:

defmacro clamp(val) do
  quote do
    fragment(
      "CASE WHEN ? THEN ? WHEN ? THEN ? ELSE ? END",
      unquote(val) < 0, 0,
      unquote(val) > 1, 1,
      unquote(val)
    )
  end
end

As shown above it is meant to be used within regular Ecto.Query queries, it will just provide a way to define more complex queries without manually writing fragments.

Last Post!

kelvinst

kelvinst

I see. My concern still applies though. By looking at the code, it only feels like that is going to run a condition and return a plain value, but instead, the code is magically turned into a fragment.

I’m not saying that no one should use it because of that though, just saying that one might want to be careful with the amount of logic put on these functions, as something might not work exactly as expected.

Also, have you ever checked dynamic/2? Not sure if it wouldn’t actually make sense to use that one instead of fragments.

Where Next?

Popular in Announcing Top

Hal9000
Here is my first stab at this. README pasted below. https://github.com/Hal9000/elixir_random Comments and critiques are welcome. Thank...
New
KronicDeth
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine) This is a plugin that adds support for Elixir to JetBrains IntelliJ...
289 36820 110
New
josevalim
EDIT: since Ecto 3.0 final version is out, this post was amended to use the final versions in the instructions below. Hi everyone, We a...
New
maltoe
Hello! Came here to announce ChromicPDF, a pet project PDF generator I’ve been working on for the past few months. Why another PDF gener...
New
aesmail
Hello guys, I have finally made it. I created an admin interface for a framework. It’s been on my todo list for years and with the curre...
New
kevinlang
Hey all, We have made an Ecto3 Adapter for SQLite3, ecto_sqlite3! We have successfully on-boarded the full suite of integration tests (...
New
martinthenth
Hello everybody :wave: Recently, some of my colleagues talked about database ids and uuids and their problems, and I remembered the pain...
New

Other popular topics Top

rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list. ...
New
JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
hariharasudhan94
Lets say I have map like this fetching from my database %{"_id" =&gt; #BSON.ObjectId&lt;58eb1a7a9ad169198c3dXXXX&gt;, "email" =&gt; ...
New
axelson
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!) This post collects co...
239 49266 226
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New

We're in Beta

About us Mission Statement