<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
<title>Rad blog</title>
<link>https://www.radengine.dev/blog</link>
<description>Notes from building Rad: design and internals.</description>
<language>en</language>
<atom:link href="https://www.radengine.dev/rss.xml" rel="self" type="application/rss+xml" />
<item>
<title>Relational IR</title>
<link>https://www.radengine.dev/blog/relational-database-intermediate-representation</link>
<guid isPermaLink="true">https://www.radengine.dev/blog/relational-database-intermediate-representation</guid>
<pubDate>Thu, 16 Jul 2026 00:00:00 GMT</pubDate>
<dc:creator>Barnaby Keene</dc:creator>
<description>&lt;p&gt;Databases are essentially compilers that also happen to store stuff. Query languages &lt;em&gt;are languages&lt;/em&gt; just like C, Python, Go, etc. So they often follow a vaguely similar path: lexing, parsing, AST, optimisation, execution.&lt;/p&gt;
&lt;p&gt;The main difference is the last two bits: optimisation wants to make sure the query is as efficient as possible in terms of how much data is read, how much work needs to happen to shape it and what order to do things in. Then, execution is reading data from the source rather than performing computations. (I mean, yes it computes stuff but the main role is to read and unpack a data structure into something useful.)&lt;/p&gt;
&lt;div&gt;&lt;figure class=&quot;fig&quot;&gt;&lt;img src=&quot;https://www.radengine.dev/blog/diagrams/CompilerPipeline.png&quot; alt=&quot;Two aligned pipelines. A compiler: lex, parse, AST, optimise, codegen. A database: lex, parse, AST, plan, execute. The first three stages are identical; a dashed divider marks where the last two diverge — codegen versus execute.&quot; style=&quot;max-width:100%;height:auto&quot; /&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Programming language compilers are almost always implemented as &lt;strong&gt;layers&lt;/strong&gt;. Frontends, backends, intermediaries, and there&amp;#x27;s sometimes a story of &lt;strong&gt;interoperability&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Take C++ for example, you can compile a C++ program using something called LLVM, or &amp;quot;low level virtual machine&amp;quot;, the idea is there are too many computer architectures out there for one compiler team to target all of them so LLVM defines a middle ground: LLVM IR, &lt;strong&gt;intermediate representation&lt;/strong&gt;, which the LLVM program compiles to whatever architecture you want. This means all you have to do to write a C++ compiler* is lower your language to LLVM IR, then let LLVM do the rest for x86, Arm, Power PC, weird ones you&amp;#x27;ve never heard of, etc.&lt;/p&gt;
&lt;p&gt;In this world, C++ is a &amp;quot;frontend&amp;quot; to LLVM, and each architecture is a backend. It&amp;#x27;s a really neat system: Rust, Swift, Zig and many others use LLVM too!&lt;/p&gt;
&lt;div&gt;&lt;figure class=&quot;fig&quot;&gt;&lt;img src=&quot;https://www.radengine.dev/blog/diagrams/LLVMHourglass.png&quot; alt=&quot;An hourglass. On the left, four language front-ends — C++, Rust, Swift, Zig — all converge on a central LLVM IR box. From it, lines fan back out to four hardware back-ends: x86, Arm, PowerPC, RISC-V.&quot; style=&quot;max-width:100%;height:auto&quot; /&gt;&lt;figcaption&gt;LLVM&amp;#x27;s trick: define one IR in the middle. Write a front-end for it once and every back-end comes along for free.&lt;/figcaption&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;This makes it slightly easier to build a new language, it takes a lot of the work away from you so you can focus on the &lt;strong&gt;interesting&lt;/strong&gt; and &lt;strong&gt;innovative&lt;/strong&gt; things: syntax design, developer experience, target use-cases.&lt;/p&gt;
&lt;div class=&quot;callout&quot; role=&quot;note&quot;&gt;&lt;span class=&quot;callout__tag&quot; aria-hidden=&quot;true&quot;&gt;note&lt;/span&gt;&lt;div&gt;*Don&amp;#x27;t write a C++ compiler.&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;There are others too: The java world has JVM, and this has resulted in a neat little ecosystem of interoperable JVM languages like Scala, Kotlin, Clojure and even porting existing languages to run on the JVM such as Jython and Rhino! If you think the JVM is pretty neat and you want to make a language, you can target the JVM and not need to really worry too much about supporting x86, x86_64, Arm, and friends.&lt;/p&gt;
&lt;h2 id=&quot;databases&quot;&gt;Databases&lt;/h2&gt;
&lt;p&gt;Outside of the OLAP world, databases don&amp;#x27;t really do this. In the Apache ecosystem for big data, there&amp;#x27;s a really neat separation of storage formats and query engines, and sometimes: query interfaces (Flink is amazing for this!)&lt;/p&gt;
&lt;p&gt;There&amp;#x27;s no (popular) IR you can target if you want to play with building a new syntax for querying data. If you wanted to take a stab at creating something new, you kind of just have to build a whole database. Engines like Calcite, DataFusion, PostgreSQL and DuckDB all have their own internal representations, and Apache projects increasingly share formats like Substrait, but they&amp;#x27;re largely implementation details or interoperability layers. A lot more of this work is happening in the OLAP world, but OLTP is still fairly siloed.&lt;/p&gt;
&lt;p&gt;I highlighted a couple of words up there too, &lt;strong&gt;interesting&lt;/strong&gt; and &lt;strong&gt;innovative&lt;/strong&gt;. in 2024, some folks at Google released a paper, &lt;a href=&quot;https://research.google/pubs/sql-has-problems-we-can-fix-them-pipe-syntax-in-sql/&quot;&gt;SQL Has Problems. We Can Fix Them: Pipe Syntax In SQL&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I thought this was really neat, and a lot of others did too! It makes authoring SQL feel more composable and less restrictive in terms of the order of operations (like, why do I &lt;em&gt;really&lt;/em&gt; need to write LIMIT after ORDER, or GROUP BY after WHERE?)&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;SQL’s challenges start from its basic query syntax: SELECT ... FROM ... WHERE ... GROUP BY, etc. This operation order is rigid and arbitrary and doesn’t reflect the actual data flow, which starts with table scans in the FROM.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div&gt;&lt;figure class=&quot;fig&quot;&gt;&lt;img src=&quot;https://www.radengine.dev/blog/diagrams/ClauseOrder.png&quot; alt=&quot;Two rows of SQL clauses. As written: SELECT, FROM, WHERE, GROUP BY, ORDER BY, LIMIT. As run, following the data: FROM, WHERE, GROUP BY, SELECT, ORDER BY, LIMIT. Connector lines between the two rows cross; SELECT moves from first-written to fourth-run.&quot; style=&quot;max-width:100%;height:auto&quot; /&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;I&amp;#x27;d love to use it but I can&amp;#x27;t, none of the databases I use support it. Nothing in Postgres, MySQL, Flink or MSSQL. It&amp;#x27;s in Spark, and Spark is in the Apache world, so it would be neat to see it in Flink but it&amp;#x27;s unlikely to ever land in other databases. Adopting pipe syntax means every database vendor needs to independently modify its parser, grammar, tooling and documentation.&lt;/p&gt;
&lt;p&gt;Imagine instead that relational databases exposed a common, structured query representation rather than SQL text as their primary interface. A pipe-syntax frontend wouldn&amp;#x27;t need to be implemented N times by all the vendors. It could lower into that common representation, and any database speaking it could execute the result.&lt;/p&gt;
&lt;div&gt;&lt;figure class=&quot;fig&quot;&gt;&lt;img src=&quot;https://www.radengine.dev/blog/diagrams/SharedIR.png&quot; alt=&quot;Two panels. Left, labelled N times M: three query front-ends each connect directly to three separate database engines, a full mesh of nine lines. Right, labelled N plus M: the same three front-ends converge on one shared relational IR box, which fans out to three engines — far fewer connections.&quot; style=&quot;max-width:100%;height:auto&quot; /&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;h3 id=&quot;whats-actually-the-deal-with-sql&quot;&gt;What&amp;#x27;s actually the deal with SQL?&lt;/h3&gt;
&lt;p&gt;If you&amp;#x27;ve used more than one database, you know there are &lt;em&gt;dialects&lt;/em&gt; and this can be quite frustrating the more complex queries you write and features you use.&lt;/p&gt;
&lt;p&gt;SQL is also, to the surprise of many I tell, &lt;em&gt;not free&lt;/em&gt;. It&amp;#x27;s not an open standard like the wonderful W3 specs or IETF RFCs. No, it costs quite a bit of money to actually get the entire multi-document (about 11 docs I think?) spec, and it&amp;#x27;s thousands of pages long. As far as I know, no database on earth implements the full spec. Though, it&amp;#x27;s kind of designed that way, so you can pick and choose the relevant solution for your database.&lt;/p&gt;
&lt;p&gt;But, still, as as web developer, I think this is the only non-open/non-free standard (ish) we build on. Which could be one reason (of many) why there are so many dialects.&lt;/p&gt;
&lt;p&gt;It also moves slowly, as a design-by-committee businessy-enterprisey thing, I do find it interesting how the hobbyist/OSS community can choose FastAPI over Spring Boot, HTMX over ASP.NET WebForms, GCC over proprietary compilers but for OLTP databases it all leads back to SQL.&lt;/p&gt;
&lt;h3 id=&quot;we-all-hate-orms-eventually&quot;&gt;We all hate ORMs, eventually&lt;/h3&gt;
&lt;p&gt;Most dicussions around ORMs often devolve down to &amp;quot;ORMs bad&amp;quot;. With fair points too: they generate terrible queries and ruin your day. Why? Because an ORM is almost doing some of the same work as the database itself, just with a higher level language in the middle. But, to use compiler terms, ORMs almost feel like they are &lt;em&gt;raising&lt;/em&gt; only for the database to &lt;em&gt;lower&lt;/em&gt; again. A query goes from imperative code &lt;em&gt;upwards&lt;/em&gt; to human-friendly SQL then back downwards again through AST -&amp;gt; IR -&amp;gt; plan.&lt;/p&gt;
&lt;div&gt;&lt;figure class=&quot;fig&quot;&gt;&lt;img src=&quot;https://www.radengine.dev/blog/diagrams/AbstractionCurve.png&quot; alt=&quot;A line chart. The vertical axis is abstraction level; the horizontal axis steps through application code, SQL, query planner and physical plan. The ORM path rises from application code up to SQL — the highest point — then falls through the query planner down to the physical plan. The Rad path skips the SQL peak, descending gradually from application code straight to the physical plan.&quot; style=&quot;max-width:100%;height:auto&quot; /&gt;&lt;figcaption&gt;an emotional rollercoaster.&lt;/figcaption&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;They have to choose between exposing SQL&amp;#x27;s full expressiveness or providing a pleasant programming model. Most sit somewhere in the middle. ORMs don&amp;#x27;t, and shouldn&amp;#x27;t, have access to statistics about the underlying catalogs. But that means they can&amp;#x27;t easily make smarter decisions about query construction. And, even if they could, it would still be string-gluing of an rather complicated grammar.&lt;/p&gt;
&lt;p&gt;The database already knows how to bind names, infer types, optimise joins, estimate cardinalities and choose execution strategies. An ORM can&amp;#x27;t realistically compete with that, so it either generates best-effort SQL strings or asks the developer to write SQL anyway. In other words, we&amp;#x27;ve inserted another compiler frontend, whose only output format is a language designed for humans to explore data. It&amp;#x27;s all a little strange really.&lt;/p&gt;
&lt;p&gt;But ORMs aren&amp;#x27;t necessarily a problem, they&amp;#x27;re a symptom &lt;em&gt;and&lt;/em&gt; a desire path. It feels &lt;em&gt;nice&lt;/em&gt; to type &lt;code&gt;user.&lt;/code&gt; and see &lt;code&gt;id&lt;/code&gt;, &lt;code&gt;name&lt;/code&gt;, and &lt;code&gt;email&lt;/code&gt; pop up in your editor, it&amp;#x27;s genuinely a better interface into your already strongly typed data model. And even if you&amp;#x27;re not writing code by hand any more, strong types help coding agents immensely in their feedback loop while achieving a goal. In my own experience, I&amp;#x27;ve chosen ORMs at faster paced businesses purely because I could happily trade query speed for developer speed.&lt;/p&gt;
&lt;p&gt;And of course it didn&amp;#x27;t always go well. Prisma once tried to cleverly avoid a join and replace it with a correlated subquery, what Prisma didn&amp;#x27;t know is the left hand side returned over 20 thousand records, so its generated &lt;code&gt;where in (...)&lt;/code&gt; was just comically large. The question there isn&amp;#x27;t &amp;quot;why did you use an ORM you idiot!&amp;quot; it&amp;#x27;s &amp;quot;why did the ORM try to decide correlated subquery over join, surely that&amp;#x27;s the planners job?&amp;quot;. And that&amp;#x27;s the thing database engine authors have spent decades refining.&lt;/p&gt;
&lt;h2 id=&quot;where-rad-fits-in&quot;&gt;Where Rad fits in&lt;/h2&gt;
&lt;p&gt;Look, SQL isn&amp;#x27;t going away, and I&amp;#x27;ve grown to like it as I do a lot more OLAP work nowadays and it&amp;#x27;s genuinely a nice tool for expressing deeply complex aggregations, especially in streaming contexts with Flink!&lt;/p&gt;
&lt;p&gt;But I think that&amp;#x27;s sort of where I&amp;#x27;ve landed on this: SQL is fantastic as a language despite its quirks, especially when I&amp;#x27;m exploring and understanding unfamiliar data where you&amp;#x27;re typing queries into a UI looking for patterns and insights. Where I feel it falls flat is where you have a rigid business logic driven schema and rigid business logic driven code and crossing that boundary either means gluing strings or using an ORM.&lt;/p&gt;
&lt;p&gt;Prisma pioneered the idea of a code-generated ORM, it wasn&amp;#x27;t the first but it was the one that marketed the idea well and provided a fantastic developer experience around it. They had to build a sort of IR-like layer that glued the type-safe codegen to the schema and SQL generation.&lt;/p&gt;
&lt;p&gt;I think build tooling ontop of SQL can be a frustrating experience. The grammar is crazy huge, there are many dialects and it just &lt;em&gt;feels&lt;/em&gt; like the wrong direction. But there hasn&amp;#x27;t really been any other way to do it.&lt;/p&gt;
&lt;p&gt;This is what Rad is aiming to challenge and explore. To lower the integration surface by one level of abstraction. You don&amp;#x27;t talk to Rad with a human DSL, you talk to it using a relational Logical Intermediate Representation, or LIR. Any OLTP workload can be expressed in LIR, it gets passed directly to the planner which figures out how to efficiently retrieve the data in the shape you want.&lt;/p&gt;
&lt;h3 id=&quot;talk-is-cheap&quot;&gt;Talk is cheap&lt;/h3&gt;
&lt;p&gt;Enough yapping, here&amp;#x27;s some LIR.&lt;/p&gt;
&lt;p&gt;In SQL, you can grab a user and all their posts after the date:&lt;/p&gt;
&lt;pre class=&quot;shiki shiki-themes github-dark github-dark&quot; style=&quot;--shiki-light:#e1e4e8;--shiki-dark:#e1e4e8;--shiki-light-bg:#24292e;--shiki-dark-bg:#24292e&quot; tabindex=&quot;0&quot; icon=&quot;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992,3 3,3 h 3 v 11 c 0,0.564129 -0.435871,1 -1,1 H 6 C 5.4358712,21 5,20.564129 5,20 V 4 C 5,3.4358712 5.4358712,3 6,3 Z M 15,3.4140625 18.585937,7 H 16 C 15.435871,7 15,6.5641288 15,6 Z&amp;quot; fill=&amp;quot;currentColor&amp;quot; /&amp;gt;&amp;lt;/svg&amp;gt;&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#F97583;--shiki-dark:#F97583&quot;&gt;select&lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt; u&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;id&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;u&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;title&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#F97583;--shiki-dark:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt; users u&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#F97583;--shiki-dark:#F97583&quot;&gt;inner join&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt; posts p &lt;/span&gt;&lt;span style=&quot;--shiki-light:#F97583;--shiki-dark:#F97583&quot;&gt;on&lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt; p&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;user_id&lt;/span&gt;&lt;span style=&quot;--shiki-light:#F97583;--shiki-dark:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt; u&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;id&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#F97583;--shiki-dark:#F97583&quot;&gt;where&lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt; p&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;created_at&lt;/span&gt;&lt;span style=&quot;--shiki-light:#F97583;--shiki-dark:#F97583&quot;&gt; &amp;gt;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt; &amp;#x27;1974-01-01&amp;#x27;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We&amp;#x27;re grabbing users and their posts after a given date, but the natural result is flattened:&lt;/p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;u.id&lt;/th&gt;&lt;th&gt;u.name&lt;/th&gt;&lt;th&gt;p.title&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;Donald D. Chamberlin&lt;/td&gt;&lt;td&gt;SEQUEL: A Structured English Query Language&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Donald wrote a few papers, so without the date predicate his id and name would be repeated once for every matching post:&lt;/p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;u.id&lt;/th&gt;&lt;th&gt;u.name&lt;/th&gt;&lt;th&gt;p.title&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;Donald D. Chamberlin&lt;/td&gt;&lt;td&gt;SEQUEL: A Structured English Query Language&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;Donald D. Chamberlin&lt;/td&gt;&lt;td&gt;SQUARE: Specifying Queries as Relational Expressions&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;When exploring data this is fine, but if you&amp;#x27;re building an application that models this as a nested list of posts under the user, you have to untangle this.&lt;/p&gt;
&lt;p&gt;Rad, however, can express the same relationship while preserving the nested shape the application actually wants without sacrificing the relational algebraic semantics internally.&lt;/p&gt;
&lt;p&gt;What this looks like in Rad&amp;#x27;s IR is quite verbose, but remember, humans don&amp;#x27;t write LLVM IR by hand, so humans don&amp;#x27;t write this by hand either:&lt;/p&gt;
&lt;pre class=&quot;shiki shiki-themes github-dark github-dark&quot; style=&quot;--shiki-light:#e1e4e8;--shiki-dark:#e1e4e8;--shiki-light-bg:#24292e;--shiki-dark-bg:#24292e&quot; tabindex=&quot;0&quot; icon=&quot;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992,3 3,3 h 3 v 11 c 0,0.564129 -0.435871,1 -1,1 H 6 C 5.4358712,21 5,20.564129 5,20 V 4 C 5,3.4358712 5.4358712,3 6,3 Z M 15,3.4140625 18.585937,7 H 16 C 15.435871,7 15,6.5641288 15,6 Z&amp;quot; fill=&amp;quot;currentColor&amp;quot; /&amp;gt;&amp;lt;/svg&amp;gt;&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;  &amp;quot;nodes&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;    &amp;quot;users&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: { &lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;&amp;quot;kind&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;scan&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;&amp;quot;table&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;users&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;&amp;quot;scope&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;u&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt; },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;    &amp;quot;posts&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: { &lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;&amp;quot;kind&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;scan&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;&amp;quot;table&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;posts&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;&amp;quot;scope&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;p&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt; },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;    &amp;quot;mine&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;      &amp;quot;kind&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;filter&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;      &amp;quot;input&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;posts&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;      &amp;quot;predicate&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;        &amp;quot;kind&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;binary&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;        &amp;quot;op&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;and&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;        &amp;quot;left&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;          &amp;quot;kind&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;binary&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;          &amp;quot;op&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;eq&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;          &amp;quot;left&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: { &lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;&amp;quot;kind&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;col&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;&amp;quot;scope&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;p&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;&amp;quot;column&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;user_id&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt; },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;          &amp;quot;right&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: { &lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;&amp;quot;kind&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;col&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;&amp;quot;scope&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;u&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;&amp;quot;column&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;id&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;        },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;        &amp;quot;right&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;          &amp;quot;kind&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;binary&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;          &amp;quot;op&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;gt&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;          &amp;quot;left&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: { &lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;&amp;quot;kind&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;col&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;&amp;quot;scope&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;p&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;&amp;quot;column&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;created_at&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt; },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;          &amp;quot;right&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;            &amp;quot;kind&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;lit&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;            &amp;quot;value&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: { &lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;&amp;quot;type&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;int64&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;&amp;quot;value&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;126230400&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;          }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;      }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;    },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;    &amp;quot;post_objs&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;      &amp;quot;kind&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;project&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;      &amp;quot;input&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;mine&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;      &amp;quot;scope&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;po&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;      &amp;quot;fields&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;        {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;          &amp;quot;as&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;title&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;          &amp;quot;expr&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: { &lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;&amp;quot;kind&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;col&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;&amp;quot;scope&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;p&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;&amp;quot;column&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;title&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;        },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;        {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;          &amp;quot;as&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;created_at&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;          &amp;quot;expr&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: { &lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;&amp;quot;kind&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;col&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;&amp;quot;scope&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;p&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;&amp;quot;column&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;created_at&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;      ]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;    },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;    &amp;quot;sorted&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;      &amp;quot;kind&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;order&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;      &amp;quot;input&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;post_objs&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;      &amp;quot;terms&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;        { &lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;&amp;quot;expr&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: { &lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;&amp;quot;kind&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;col&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;&amp;quot;scope&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;po&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;&amp;quot;column&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;created_at&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt; } }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;      ]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;    },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;    &amp;quot;out&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;      &amp;quot;kind&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;project&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;      &amp;quot;input&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;users&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;      &amp;quot;scope&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;r&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;      &amp;quot;fields&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;        { &lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;&amp;quot;as&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;id&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;&amp;quot;expr&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: { &lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;&amp;quot;kind&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;col&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;&amp;quot;scope&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;u&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;&amp;quot;column&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;id&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt; } },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;        {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;          &amp;quot;as&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;name&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;          &amp;quot;expr&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: { &lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;&amp;quot;kind&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;col&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;&amp;quot;scope&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;u&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;&amp;quot;column&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;name&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;        },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;        { &lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;&amp;quot;as&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;posts&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;&amp;quot;expr&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: { &lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;&amp;quot;kind&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;array&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;&amp;quot;node&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;sorted&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt; } }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;      ]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;    },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;    &amp;quot;ordered&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;      &amp;quot;kind&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;order&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;      &amp;quot;input&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;out&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;      &amp;quot;terms&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: [{ &lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;&amp;quot;expr&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: { &lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;&amp;quot;kind&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;col&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;&amp;quot;scope&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;r&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;&amp;quot;column&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;id&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt; } }]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;  },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;  &amp;quot;root&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: { &lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;&amp;quot;node&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;ordered&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;&amp;quot;cardinality&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;many&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The result of this query is:&lt;/p&gt;
&lt;pre class=&quot;shiki shiki-themes github-dark github-dark&quot; style=&quot;--shiki-light:#e1e4e8;--shiki-dark:#e1e4e8;--shiki-light-bg:#24292e;--shiki-dark-bg:#24292e&quot; tabindex=&quot;0&quot; icon=&quot;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992,3 3,3 h 3 v 11 c 0,0.564129 -0.435871,1 -1,1 H 6 C 5.4358712,21 5,20.564129 5,20 V 4 C 5,3.4358712 5.4358712,3 6,3 Z M 15,3.4140625 18.585937,7 H 16 C 15.435871,7 15,6.5641288 15,6 Z&amp;quot; fill=&amp;quot;currentColor&amp;quot; /&amp;gt;&amp;lt;/svg&amp;gt;&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;[&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;  {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;    &amp;quot;id&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;    &amp;quot;name&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;Donald D. Chamberlin&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;    &amp;quot;posts&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;      {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;        &amp;quot;title&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#9ECBFF;--shiki-dark:#9ECBFF&quot;&gt;&amp;quot;SEQUEL: A Structured English Query Language&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;        &amp;quot;created_at&amp;quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#79B8FF;--shiki-dark:#79B8FF&quot;&gt;136598400&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;      }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;    ]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#E1E4E8;--shiki-dark:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;callout&quot; role=&quot;note&quot;&gt;&lt;span class=&quot;callout__tag&quot; aria-hidden=&quot;true&quot;&gt;note&lt;/span&gt;&lt;div&gt;&lt;p&gt;Sorry Raymond F. Boyce, you co-authored the paper too! But I didn&amp;#x27;t want to
complicate the example with a m2m junction table of authors...&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Now let&amp;#x27;s walk through what some of that means:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;It&amp;#x27;s a tree structure, which makes it really easy for machines to generate and edit. Relation nodes (operators) can reference other relation nodes as inputs while &amp;quot;scopes&amp;quot; are logical aliases to outputs, sort of like functions vs variable bindings. &lt;code&gt;&amp;quot;input&amp;quot;: &amp;quot;posts&amp;quot;&lt;/code&gt; / &lt;code&gt;&amp;quot;node&amp;quot;: &amp;quot;sorted&amp;quot;&lt;/code&gt; are edges into the &lt;code&gt;nodes&lt;/code&gt; map while &lt;code&gt;{ &amp;quot;scope&amp;quot;: &amp;quot;p&amp;quot;, ... }&lt;/code&gt; addresses a column by its relation alias.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Literals on the query path are self-describing. A &lt;code&gt;lit&lt;/code&gt; doesn&amp;#x27;t carry a bare JSON scalar, it&amp;#x27;s a tagged value &lt;code&gt;{ &amp;quot;type&amp;quot;: &amp;quot;int64&amp;quot;, &amp;quot;value&amp;quot;: &amp;quot;126230400&amp;quot; }&lt;/code&gt;. Numbers travel as strings so int64 keeps full precision on the wire. I&amp;#x27;m not set on JSON being the canonical format forever for this and other reasons, but it&amp;#x27;s a simple format for examples and development.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;many&lt;/code&gt; cardinality demands an explicit order. SQL returns an arbitrary order without &lt;code&gt;ORDER BY&lt;/code&gt;. Rad instead rejects an observable collection with no order (the binder error is literally &amp;quot;observable collections must not depend on the access path&amp;quot;). It&amp;#x27;s a determinism guarantee: the result can&amp;#x27;t silently change when the planner picks a different index, but it&amp;#x27;s also a developer experience feature. You pretty much always want to specify an order when pulling a list of things because the physical storage layer does not necessarily guarantee result order.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;&amp;quot;posts&amp;quot;: { &amp;quot;kind&amp;quot;: &amp;quot;array&amp;quot;, &amp;quot;node&amp;quot;: &amp;quot;sorted&amp;quot; }&lt;/code&gt; is a &lt;em&gt;crossing&lt;/em&gt;, it embeds a correlated subquery: &lt;code&gt;sorted&lt;/code&gt; filters &lt;code&gt;posts&lt;/code&gt; to &lt;code&gt;p.user_id = u.id&lt;/code&gt; (it reads the outer &lt;code&gt;u&lt;/code&gt; scope) and &lt;code&gt;created_at &amp;gt; 1974-01-01&lt;/code&gt;. &lt;code&gt;array&lt;/code&gt; renders those rows as a nested list per user.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;What about the internals? Sure, we got a result but did it do it efficiently? Well, Rad &lt;em&gt;is&lt;/em&gt; a brand new prototype, it doesn&amp;#x27;t have a world class cutting edge optimiser (yet) but it produces fairly decent plans already:&lt;/p&gt;
&lt;pre class=&quot;shiki shiki-themes github-dark github-dark&quot; style=&quot;--shiki-light:#e1e4e8;--shiki-dark:#e1e4e8;--shiki-light-bg:#24292e;--shiki-dark-bg:#24292e&quot; tabindex=&quot;0&quot; icon=&quot;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992,3 3,3 h 3 v 11 c 0,0.564129 -0.435871,1 -1,1 H 6 C 5.4358712,21 5,20.564129 5,20 V 4 C 5,3.4358712 5.4358712,3 6,3 Z M 15,3.4140625 18.585937,7 H 16 C 15.435871,7 15,6.5641288 15,6 Z&amp;quot; fill=&amp;quot;currentColor&amp;quot; /&amp;gt;&amp;lt;/svg&amp;gt;&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Plan card=many&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  Sort r.id#0 asc&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    Project&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      id#0 = u.id#0&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      name#1 = u.name#1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      posts#6 = posts#6&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      Attach&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        #6 = array key-correlated [user_id#3 = @0]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;          Sort po.created_at#5 asc&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;            Project&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;              title#4 = p.title#4&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;              created_at#5 = p.created_at#5&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;              Filter and(eq(p.user_id#3, u.id#0), gt(p.created_at#5, 126230400))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                IndexRangeScan posts posts_user_id_idx [user_id = @0]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        TableScan users&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Some key points on this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;array&lt;/code&gt; crossing compiled to a key-correlated &lt;code&gt;Attach&lt;/code&gt;: the nested posts are fetched, batched by the correlation key (&lt;code&gt;user_id = @0&lt;/code&gt;), not a per-user N+1. &lt;code&gt;@0&lt;/code&gt; is the outer user&amp;#x27;s &lt;code&gt;id&lt;/code&gt; threaded in.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The planner chose the &lt;code&gt;posts_user_id_idx&lt;/code&gt; (&lt;code&gt;IndexRangeScan … [user_id = @0]&lt;/code&gt;) on its own: nothing in the LIR asked for it because LIR is a logical plan which is lowered to a physical plan and undergoes some basic optimisation.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;created_at &amp;gt; 1974&lt;/code&gt; predicate rides as a residual &lt;code&gt;Filter&lt;/code&gt; above the access: the index narrows by &lt;code&gt;user_id&lt;/code&gt;, the filter finishes the job.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;#0&lt;/code&gt;,&lt;code&gt;#3&lt;/code&gt;,&lt;code&gt;#5&lt;/code&gt;,&lt;code&gt;#6&lt;/code&gt; are slots (post-binding column addresses); the top &lt;code&gt;Sort&lt;/code&gt; is the mandatory order for a many root.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let&amp;#x27;s go even lower, what actually hit the KV store?&lt;/p&gt;
&lt;pre class=&quot;shiki shiki-themes github-dark github-dark&quot; style=&quot;--shiki-light:#e1e4e8;--shiki-dark:#e1e4e8;--shiki-light-bg:#24292e;--shiki-dark-bg:#24292e&quot; tabindex=&quot;0&quot; icon=&quot;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992,3 3,3 h 3 v 11 c 0,0.564129 -0.435871,1 -1,1 H 6 C 5.4358712,21 5,20.564129 5,20 V 4 C 5,3.4358712 5.4358712,3 6,3 Z M 15,3.4140625 18.585937,7 H 16 C 15.435871,7 15,6.5641288 15,6 Z&amp;quot; fill=&amp;quot;currentColor&amp;quot; /&amp;gt;&amp;lt;/svg&amp;gt;&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;SCAN [/rad/data/t1/primary/ .. /rad/data/t1/primary0)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;SCAN [/rad/index/t4/i9/\x03\x80\x00\x00\x00\x00\x00\x00\x01 .. /rad/index/t4/i9/\x03\x80\x00\x00\x00\x00\x00\x00\x02)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;GET  /rad/data/t4/primary/\x03\x80\x00\x00\x00\x00\x00\x00\x01&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;GET  /rad/data/t4/primary/\x03\x80\x00\x00\x00\x00\x00\x00\x02&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Reading this:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;SCAN&lt;/code&gt; users: one scan over the users primary keyspace (the outer &lt;code&gt;TableScan&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SCAN&lt;/code&gt; the &lt;code&gt;user_id&lt;/code&gt; index for &lt;code&gt;user_id = 1&lt;/code&gt;: the batched correlated lookup. &lt;code&gt;\x03\x80\x00…\x01&lt;/code&gt; is the key encoding of &lt;code&gt;int64 1&lt;/code&gt; (&lt;code&gt;\x03&lt;/code&gt; type tag; &lt;code&gt;\x80…&lt;/code&gt; is the sign-flipped big-endian &lt;code&gt;int&lt;/code&gt;). The range is &lt;code&gt;[1 .. 2)&lt;/code&gt; which means &amp;quot;exactly user_id 1&amp;quot;.&lt;/li&gt;
&lt;li&gt;Two &lt;code&gt;GET&lt;/code&gt;s on posts rows pk &lt;code&gt;1&lt;/code&gt; and &lt;code&gt;2&lt;/code&gt;: both of Chamberlin&amp;#x27;s posts (both have &lt;code&gt;user_id&lt;/code&gt;=&lt;code&gt;1&lt;/code&gt;), fetched by primary key.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Key components like &lt;code&gt;t1&lt;/code&gt;, &lt;code&gt;i9&lt;/code&gt;, etc. are internal references to catalog tables and indexes, these are generated with a globally monotonic integer ID, every time a schema change adds something, this increments within the transaction.&lt;/p&gt;
&lt;h3 id=&quot;zooming-back-out&quot;&gt;Zooming back out&lt;/h3&gt;
&lt;p&gt;That&amp;#x27;s quite a long journey for a query nobody is expected to write by hand.&lt;/p&gt;
&lt;p&gt;The LIR described the data the application wanted, including its nested shape and ordering requirements. The planner decided how to retrieve it, turned the crossing into a batched correlated lookup and chose an index. Finally, the executor reduced the whole thing to a handful of operations against the key-value store.&lt;/p&gt;
&lt;p&gt;The caller describes relationships, predicates and result shape. It doesn&amp;#x27;t choose an index, construct a join strategy or decide whether a correlated query should execute once or twenty thousand times. Those decisions stay inside the database, where the catalog, statistics and planner already live. It&amp;#x27;s declarative,just like SQL!&lt;/p&gt;
&lt;p&gt;That gives Rad an hourglass-shaped architecture much like the compiler systems from the start of this post. Above LIR, there can be different ways to author a query. Below it, the engine is free to bind, optimise and execute that query however it sees fit.&lt;/p&gt;
&lt;p&gt;Rad&amp;#x27;s generated clients are the first frontend. They know the schema, expose it through the host language&amp;#x27;s type system and lower operations directly into LIR. But they don&amp;#x27;t need to be the only frontend. A pipe syntax, a visual query builder, SQL, GraphQL or something nobody has invented yet could target the same representation without each one becoming its own database engine.&lt;/p&gt;
&lt;p&gt;Likewise, adding a frontend doesn&amp;#x27;t require teaching it about SlateDB keys, indexes or physical plans. It only needs to describe a valid relational operation.&lt;/p&gt;
&lt;h3 id=&quot;is-lir-a-standard&quot;&gt;Is LIR a standard?&lt;/h3&gt;
&lt;p&gt;No, at least not currently. But it could be, with feedback and governance!&lt;/p&gt;
&lt;p&gt;Rad&amp;#x27;s LIR is a contract for a young database and it will change as I learn where the abstraction is wrong. Designing a portable database IR also involves much more than serialising relational algebra: type systems, transactions, capabilities, schema evolution, errors and versioning all need answers. Projects such as Substrait demonstrate both how useful this separation can be and how much detail it contains.&lt;/p&gt;
&lt;p&gt;I&amp;#x27;m also deliberately starting with a much narrower problem: application-shaped OLTP queries against one engine. The goal isn&amp;#x27;t to declare this JSON format the LLVM IR of databases. The goal is to find out what becomes possible when the primary application interface is a structured relational representation rather than an SQL string.&lt;/p&gt;
&lt;h2 id=&quot;final-words&quot;&gt;Final words&lt;/h2&gt;
&lt;p&gt;SQL remains a great frontend. It might even remain the best frontend for humans exploring unfamiliar data. But it doesn&amp;#x27;t have to be the interface every tool, library and programming language is forced to generate.&lt;/p&gt;
&lt;p&gt;Once the boundary moves down a layer, an ORM no longer has to pretend to be a query planner. A new query syntax shouldn&amp;#x27;t have to be implemented independently by every database vendor. Generated clients can preserve types and result shapes without reverse-engineering them from strings. The database still gets to make the decisions databases are good at making.&lt;/p&gt;
&lt;p&gt;Rad&amp;#x27;s LIR will certainly evolve, and some of these ideas may turn out to be wrong. but that&amp;#x27;s what this project is for.&lt;/p&gt;
&lt;p&gt;But I think the question is worth exploring: what could we build if SQL were one frontend to a relational database, rather than the narrow waist of the entire ecosystem?&lt;/p&gt;</description>
</item>
<item>
<title>Why build a new relational database</title>
<link>https://www.radengine.dev/blog/hello-rad</link>
<guid isPermaLink="true">https://www.radengine.dev/blog/hello-rad</guid>
<pubDate>Thu, 09 Jul 2026 00:00:00 GMT</pubDate>
<dc:creator>Barnaby Keene</dc:creator>
<description>&lt;p&gt;When Go was released in 2009, writing software looked very different back then. You&amp;#x27;d pick a compiler, maybe a linter and an IDE. Wire together some libraries with build scripts, CMakeLists.txt, a test compilation pipeline with an assertion library. HTTP was either roll your own or wire up a DLL from elsewhere. There was a lot of roll-your-own or just purchase a solution.&lt;/p&gt;
&lt;p&gt;Go evolved out of Google&amp;#x27;s world of internal tooling culture. And while things like a &amp;quot;proper&amp;quot; package manager came later, compared to what was around in the 2010s, Go really did boast a lot by its 1.0 release in 2012. It had:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A fantastic standard library, with HTTP servers, clients, TLS&lt;/li&gt;
&lt;li&gt;HTML and JSON encoding and decoding&lt;/li&gt;
&lt;li&gt;Built-in testing tools, linting and a single compiler&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The team didn&amp;#x27;t write a specification, release (or sell) it and say to the industry &amp;quot;here&amp;#x27;s our idea, go implement your interpretation of it&amp;quot; no, they just built everything in their vision. It was coherent and coupled for better or worse.&lt;/p&gt;
&lt;div&gt;&lt;figure class=&quot;fig&quot;&gt;&lt;img src=&quot;https://www.radengine.dev/blog/diagrams/ToolchainDiagram.png&quot; alt=&quot;On the left, four scattered tools: compiler, formatter, tests, deps. An arrow points to the right, where the same four sit inside a single box labelled &amp;#x27;one toolchain&amp;#x27;.&quot; style=&quot;max-width:100%;height:auto&quot; /&gt;&lt;figcaption&gt;One vision driving the whole stack: the thing Go got right.&lt;/figcaption&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Now it&amp;#x27;s 2026, Bun has a built in test runner, Rust has a built in package manager, TypeScript has, arguably an entire IDE and intellisense ecosystem. The industry realised that the text part of a language is only about 20% of what makes it &lt;em&gt;feel&lt;/em&gt; good to use.&lt;/p&gt;
&lt;h2 id=&quot;databases&quot;&gt;Databases&lt;/h2&gt;
&lt;p&gt;Databases feel different, in some ways. And by databases I am going to focus on OLTP relational databases. Which, at the time of writing, almost exclusively means SQL databases. Because those two worlds are so tightly intertwined it&amp;#x27;s almost impossible, outside of research and pet projects to find any meaningful separation between them.&lt;/p&gt;
&lt;p&gt;They feel different because, for one, they&amp;#x27;re quite important. You may argue more important than the language your application code runs in. If your Python application malfunctions, the fallout depends on your/team&amp;#x27;s implementation of error handling (or lack...) If your database malfunctions, you may in really big trouble. So databases have to work really really well and thus, are built by very smart people. Persisting state is hard.&lt;/p&gt;
&lt;p&gt;But in another way, they feel different because the companies and people researching and building databases don&amp;#x27;t necessarily represent all categories of the developers building software upon said databases.&lt;/p&gt;
&lt;p&gt;To draw an analogy, it evokes the same feeling as what the post &lt;a href=&quot;https://birtles.blog/2024/01/06/weird-things-engineers-believe-about-development/&quot;&gt;Weird things engineers believe about Web development&lt;/a&gt; particularly, the section titled &lt;a href=&quot;https://birtles.blog/2024/01/06/weird-things-engineers-believe-about-development/#the-people-who-make-web-specifications-know-web-development-really-well&quot;&gt;”The people who make Web specifications know Web development really well”&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Perhaps one of my favourite examples of this however is an academic paper titled &lt;a href=&quot;https://link.springer.com/article/10.1007/s10664-025-10695-1&quot;&gt;“Enhanced SQL error messages facilitate faster error fixing”&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Rust didn&amp;#x27;t write a paper about error messages, they just made their compiler do it.&lt;/p&gt;
&lt;p&gt;I suppose my socratic irony here is really saying: why is that paper not &lt;em&gt;just&lt;/em&gt; a PR to Postgres?&lt;/p&gt;
&lt;p&gt;alright, enough reductio ad absurdum, let&amp;#x27;s move on...&lt;/p&gt;
&lt;p&gt;I&amp;#x27;m not going to dive into the SQL side in this post, it&amp;#x27;s very well trodden ground:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://borretti.me/article/composable-sql&quot;&gt;https://borretti.me/article/composable-sql&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://lobste.rs/s/gd1pre/sql_has_problems_we_can_fix_them_pipe&quot;&gt;https://lobste.rs/s/gd1pre/sql_has_problems_we_can_fix_them_pipe&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nelhage.com/post/some-opinionated-sql-takes/&quot;&gt;https://blog.nelhage.com/post/some-opinionated-sql-takes/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.geldata.com/blog/we-can-do-better-than-sql&quot;&gt;https://www.geldata.com/blog/we-can-do-better-than-sql&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://stack.convex.dev/not-sql&quot;&gt;https://stack.convex.dev/not-sql&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://southcla.ws/sql&quot;&gt;https://southcla.ws/sql&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I&amp;#x27;ll dive a bit deeper on why Rad doesn&amp;#x27;t use SQL, and what it uses instead, in a future post.&lt;/p&gt;
&lt;h2 id=&quot;building-databases&quot;&gt;Building Databases&lt;/h2&gt;
&lt;p&gt;If your database malfunctions, you may in really big trouble. So really smart people build databases, because they are really difficult to get right and prove so. &lt;a href=&quot;https://jepsen.io/&quot;&gt;Jepsen&lt;/a&gt; is really good at proving otherwise.&lt;/p&gt;
&lt;p&gt;And my thesis has been that, because databases are really hard to build, the people who use them day to day, aren&amp;#x27;t the same peope who build them.&lt;/p&gt;
&lt;p&gt;Databases are also very monolithic. You can&amp;#x27;t use MySQL&amp;#x27;s dialect over PostgreSQL&amp;#x27;s file format. There&amp;#x27;s no intermediary format like how LLVM lets you write a fun little programming language and get it to compile for almost every modern chip.&lt;/p&gt;
&lt;p&gt;Databases don&amp;#x27;t have anything like that. Everything moves in lockstep. The SQL standard (which is not an open standard like almost everything else we use on the web btw, you buy it) releases, a few years later some databases MIGHT add SOME features from it.&lt;/p&gt;
&lt;p&gt;Then of course, as you know, every database is different, nobody &lt;em&gt;actually&lt;/em&gt; implements the standard, so there effectively &lt;em&gt;is&lt;/em&gt; no standard.&lt;/p&gt;
&lt;h2 id=&quot;the-olap-world&quot;&gt;The OLAP World&lt;/h2&gt;
&lt;p&gt;The OLAP world, as I learned recently, is &lt;em&gt;really&lt;/em&gt; different. Partly due to the risk profile, the workloads and the ecosystem.&lt;/p&gt;
&lt;p&gt;I recently tested three different &lt;em&gt;query engines&lt;/em&gt; against the exact same data. The data was in a file format called &lt;a href=&quot;https://parquet.apache.org/&quot;&gt;Parquet&lt;/a&gt; and was described by a metadata format called &lt;a href=&quot;https://iceberg.apache.org/&quot;&gt;Apache Iceberg&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This was really cool because I could directly compare these engines without changing the underlying data. It lived in a standardised format on object storage.&lt;/p&gt;
&lt;p&gt;And that ecosystem is really rich, that evaluation process was to build a Flink + Paimon streaming system and then allow querying the outputs via StarrocksDB. Everything &lt;em&gt;just worked&lt;/em&gt; together, hats off to Apache!&lt;/p&gt;
&lt;h2 id=&quot;olap-vs-oltp&quot;&gt;OLAP vs OLTP&lt;/h2&gt;
&lt;p&gt;In all the major OLTP databases I&amp;#x27;ve used, every layer is welded together. Storage, query language, planner, protocol. But then the bits on the outside can&amp;#x27;t easily inteoperate with any of these layers, all they have is SQL.&lt;/p&gt;
&lt;p&gt;In the OLAP world, those layers have been somewhat decomposed. The storage format is standardised. Multiple engines compete on execution. Metadata is shared. Suddenly innovation can happen independently at each layer.&lt;/p&gt;
&lt;div&gt;&lt;figure class=&quot;fig&quot;&gt;&lt;img src=&quot;https://www.radengine.dev/blog/diagrams/StackDiagram.png&quot; alt=&quot;Left, an OLTP database: protocol, query language, planner and storage welded into one block, reachable only through a SQL door. Right, an OLAP stack: several engines over a shared metadata layer and shared object storage.&quot; style=&quot;max-width:100%;height:auto&quot; /&gt;&lt;figcaption&gt;OLTP couples every layer behind one door. OLAP decomposes them: shared storage, competing engines.&lt;/figcaption&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;While it feels hard to contribute innovations on the layers I have the technical capability to do so with a project like PostgreSQL. And I equally haven&amp;#x27;t found it particularly fulfilling to innovate outside of the codebase because the only real tools I have are gluing SQL strings together.&lt;/p&gt;
&lt;h2 id=&quot;rad&quot;&gt;Rad&lt;/h2&gt;
&lt;p&gt;All of that has lead to Rad. A research project, but also a usable prototype, designed to start conversations about all the different shapes relational databases &lt;em&gt;could&lt;/em&gt; be.&lt;/p&gt;
&lt;p&gt;I want to explore three distinct areas with this project, that for various reasons are complex or awkward to do when being forced to live at the tip of the abstraction tree atop SQL.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Small and simple databases for the really common use-cases that still need the relational model&lt;/li&gt;
&lt;li&gt;Fully integrated toolchain, much like Go: one vision driving the whole stack&lt;/li&gt;
&lt;li&gt;SQL is just one of many ways to access relational data, what if we had an IR to target?&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;&lt;figure class=&quot;fig&quot;&gt;&lt;img src=&quot;https://www.radengine.dev/blog/diagrams/IRDiagram.png&quot; alt=&quot;Three front-ends: SQL, a typed client, and others: converge on a central query IR box, which fans out to a planner/execution box and a storage box.&quot; style=&quot;max-width:100%;height:auto&quot; /&gt;&lt;figcaption&gt;SQL could be one of many ways in. An IR lets many front-ends target one relational core: the LLVM move, for databases.&lt;/figcaption&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;h3 id=&quot;what-its-not&quot;&gt;What it&amp;#x27;s not&lt;/h3&gt;
&lt;p&gt;I&amp;#x27;m not setting out to build a competing platform to PostgreSQL. That first item, “small”, matters because in all the side projects I&amp;#x27;ve built over the last decade, I&amp;#x27;ve not once reached for foreign data wrappers, PL-pgSQL, table partitioning, etc.&lt;/p&gt;
&lt;p&gt;In the same way that C++ has a thousand features that solve every problem under the sun, and Go launched with 25 keywords and no generics.&lt;/p&gt;
&lt;p&gt;I&amp;#x27;m interested in what relational databases would look like if we started &lt;em&gt;designing&lt;/em&gt; them today, after watching what has happened to programming languages, developer tooling and the things developers have come to expect from software over the last decade.&lt;/p&gt;
&lt;h2 id=&quot;final-words&quot;&gt;Final words&lt;/h2&gt;
&lt;p&gt;The prototype on this site is real. It was the result of finally giving in and just building it. AI helped a lot, but that&amp;#x27;s fine, it&amp;#x27;s a proof of concept to test the waters.&lt;/p&gt;
&lt;p&gt;Another thing this project would not exist without is &lt;a href=&quot;https://slatedb.io/&quot;&gt;SlateDB&lt;/a&gt; a really high quality abstraction over object storage that powers Rad&amp;#x27;s key-value store, upon which the relational model is assembled.&lt;/p&gt;
&lt;p&gt;Please share your thoughts and try Rad out on a toy project. It&amp;#x27;s an exploration of developer experience as much as it is of implementing a relational algebra engine. It&amp;#x27;s nowhere near production ready, but if the project resonates, I&amp;#x27;d love to commit more time to fuzz testing, consistency and more critical requirements for real world usage.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;This project was the result of many productive discussions over at &lt;a href=&quot;https://makeroom.club/&quot;&gt;Makeroom&lt;/a&gt; readers of this are invited to join us not only to provide feedback, but become a part of our community!&lt;/em&gt;&lt;/p&gt;</description>
</item>
</channel>
</rss>