Hacker News new | ask | show | jobs
by brendanyounger 886 days ago
On a syntax level, parsing, generating, and templating datalog is _much_ simpler than doing the same to SQL. DBT would never exist if every SQL database accepted datalog queries and SQL injection attacks would be rare to non-existent.

The more interesting answer is to think of datalog as making it easy to encode nearly all of your application logic as a bunch of self-referencing, incrementally updated, materialized views. Some examples:

  # view of Users table for currently logged in user
  LoggedInUserView(name, email, id) :- Users(id: 
  payload["userId"], name, email), Cookies(name: "login", payload).

  # view of Users for admin
  AdminUserView(name, email, id) :- Users(id, name, email), Cookies(name: "login", payload), payload["isAdmin"] = true.

  # posts a user can see
  PostsView(title, content, id) :- Posts(title, content, public: true).
  PostsView(title, content, id) :- Posts(title, content, author: payload["userId"]), Cookies(name: "login", payload).

And then you write your UI code to explicitly reference these derived views rather than manually wrapping an API around querying the Posts table and doing the filtering.

The examples above can be neatly replicated in Supabase or Postgraphile (the OG of auto-generated GraphQL over Postgres), but you can do a lot more with datalog as a language. The Hellerstein paper mentioned above is a good starting place.

1 comments

I can't really understand this without seeing the equivalent SQL as I don't understand datalog.

Is this SQL query similar to the first datalog query you listed? I apologize for how HN formatted the below and my lack of understanding for how to get around it.

Select u.name, u.email, u.id From Users u Join Cookies c on u.name = c.name

Almost. What I wrote is more like:

  create view LoggedInUserView as
  select u.id as id, u.name as name, u.email as email
  from Users u
  join Cookies c on c.name = 'login' and u.id = c.payload->>'userId';
where payload is a json blob. (Indent code by 2+ spaces.)

Most people wouldn't design their schema in a SQL database like this with a bunch of special-use relations/views, but datalog encourages you to do so since defining a new relation is the only means of abstraction. In effect, you've created an API endpoint similar to /api/auth/users and, what's more, you can use the LoggedInUserView in other rules to define new relations.