<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>foxido</title>
    <link>https://foxido.dev/</link>
    <description>Recent content on foxido</description>
    <generator>Hugo</generator>
    <language>en</language>
    <lastBuildDate>Mon, 11 May 2026 00:00:00 +0300</lastBuildDate>
    <atom:link href="https://foxido.dev/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>eBPF compilation, part 2: We have compiler at home</title>
      <link>https://foxido.dev/posts/ebpf-comp-2/</link>
      <pubDate>Mon, 11 May 2026 00:00:00 +0300</pubDate>
      <guid>https://foxido.dev/posts/ebpf-comp-2/</guid>
      <description>&lt;p&gt;&lt;em&gt;In the previous part we walked through the userspace part of loading an eBPF program and stopped right before the kernel.&lt;/em&gt;&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;what-does-kernel-do-with-ebpf&#34;&gt;What does kernel do with eBPF?&lt;/h2&gt;&#xA;&lt;p&gt;The kernel&amp;rsquo;s task is to compile eBPF into native instructions. As with any compiler, there are 3 stages:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;strong&gt;Front-end&lt;/strong&gt;: eBPF verifier. It parses the received eBPF code and checks its validity. You can think of it as a borrow checker in Rust or static checks in Clang.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;eBPF provides the following guarantees:&lt;/p&gt;</description>
    </item>
    <item>
      <title>eBPF compilation, part 1: Userspace point of view</title>
      <link>https://foxido.dev/posts/ebpf-comp-1/</link>
      <pubDate>Wed, 29 Apr 2026 00:00:00 +0300</pubDate>
      <guid>https://foxido.dev/posts/ebpf-comp-1/</guid>
      <description>&lt;p&gt;&lt;em&gt;This is an enhanced transcription of my &lt;a href=&#34;https://cppconf.ru/talks/c443ce6c2e974d3fb78aa48b0f87281e/&#34;&gt;C++Russia talk&lt;/a&gt;. This research was done during my work on a Userspace JIT for eBPF (not opensource yet).&lt;/em&gt;&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;recap-what-is-ebpf&#34;&gt;Recap: What is eBPF?&lt;/h2&gt;&#xA;&lt;p&gt;From a user&amp;rsquo;s perspective, eBPF is a restricted virtual machine inside the Linux kernel. Originally, the idea for eBPF came from the network subsystem, where it was designed for fast and safe packet filtering. Safety is the key part here &amp;ndash; it is the main difference between eBPF&amp;rsquo;s VM approach and the raw binary approach of kernel modules. It is also much simpler to communicate with eBPF than with the kernel or kernel modules, because the &amp;ldquo;loader&amp;rdquo; process and the eBPF program can communicate via various types of maps (ring buffers, arrays, hash maps, etc.) instead of using sysfs, procfs, ioctls, and other filesystem-based mechanisms.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Fuzzing</title>
      <link>https://foxido.dev/posts/fuzzzing/</link>
      <pubDate>Tue, 15 Jul 2025 20:00:00 +0300</pubDate>
      <guid>https://foxido.dev/posts/fuzzzing/</guid>
      <description>&lt;h2 id=&#34;overview&#34;&gt;Overview&lt;/h2&gt;&#xA;&lt;p&gt;Fuzzing is a software testing technique that involves feeding a program with random generated data to identify corner-case errors. There are different types of fuzzers:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&amp;ldquo;Black-box&amp;rdquo; fuzzers, that runs your program as-is, without any instrumentation and knowledge.&lt;/li&gt;&#xA;&lt;li&gt;&amp;ldquo;Grey-box&amp;rdquo; fuzzers, that instruments your program at compile time or runs it inside QEMU (efficiently), gaining insight about control flow.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;Grey-box fuzzers, also known as &lt;em&gt;feedback-driven&lt;/em&gt; fuzzers, are superior to black-box ones but require full access to the binary or source code. By leveraging control-flow knowledge, they can employ genetic algorithms for input mutation, save new discovered path and explore your program step-by-step.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Understanding PostgreSQL internals, part 2: Executor (with JIT)</title>
      <link>https://foxido.dev/posts/postgresql-internal-2/</link>
      <pubDate>Mon, 09 Jun 2025 20:00:00 +0300</pubDate>
      <guid>https://foxido.dev/posts/postgresql-internal-2/</guid>
      <description>&lt;p&gt;In the &lt;a href=&#34;https://foxido.dev/posts/postgresql-internal-1/&#34;&gt;previous part&lt;/a&gt;, we discussed how PostgreSQL transforms declarative queries into imperative steps. Therefore, it seems logical to discuss the execution part next.&lt;/p&gt;&#xA;&lt;h2 id=&#34;overview&#34;&gt;Overview&lt;/h2&gt;&#xA;&lt;p&gt;A basic understanding of how PostgreSQL executes trees can be obtained from the following &lt;a href=&#34;https://git.foxido.dev/archive/postgres/-/blob/REL_17_5/src/backend/executor/execProcnode.c#L20&#34;&gt;source code&lt;/a&gt; comment:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;/*&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; *&#x9; NOTES&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; *&#x9;&#x9;This used to be three files.  It is now all combined into&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; *&#x9;&#x9;one file so that it is easier to keep the dispatch routines&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; *&#x9;&#x9;in sync when new nodes are added.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; *&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; *&#x9; EXAMPLE&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; *&#x9;&#x9;Suppose we want the age of the manager of the shoe department and&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; *&#x9;&#x9;the number of employees in that department.  So we have the query:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; *&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; *&#x9;&#x9;&#x9;&#x9;select DEPT.no_emps, EMP.age&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; *&#x9;&#x9;&#x9;&#x9;from DEPT, EMP&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; *&#x9;&#x9;&#x9;&#x9;where EMP.name = DEPT.mgr and&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; *&#x9;&#x9;&#x9;&#x9;&#x9;  DEPT.name = &amp;#34;shoe&amp;#34;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; *&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; *&#x9;&#x9;Suppose the planner gives us the following plan:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; *&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; *&#x9;&#x9;&#x9;&#x9;&#x9;&#x9;Nest Loop (DEPT.mgr = EMP.name)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; *&#x9;&#x9;&#x9;&#x9;&#x9;&#x9;/&#x9;&#x9;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; *&#x9;&#x9;&#x9;&#x9;&#x9;   /&#x9;&#x9; \&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; *&#x9;&#x9;&#x9;&#x9;   Seq Scan&#x9;&#x9;Seq Scan&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; *&#x9;&#x9;&#x9;&#x9;&#x9;DEPT&#x9;&#x9;  EMP&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; *&#x9;&#x9;&#x9;&#x9;(name = &amp;#34;shoe&amp;#34;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; *&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; *&#x9;&#x9;ExecutorStart() is called first.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; *&#x9;&#x9;It calls InitPlan() which calls ExecInitNode() on&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; *&#x9;&#x9;the root of the plan -- the nest loop node.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; *&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; *&#x9;  * ExecInitNode() notices that it is looking at a nest loop and&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; *&#x9;&#x9;as the code below demonstrates, it calls ExecInitNestLoop().&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; *&#x9;&#x9;Eventually this calls ExecInitNode() on the right and left subplans&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; *&#x9;&#x9;and so forth until the entire plan is initialized.  The result&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; *&#x9;&#x9;of ExecInitNode() is a plan state tree built with the same structure&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; *&#x9;&#x9;as the underlying plan tree.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; *&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; *&#x9;  * Then when ExecutorRun() is called, it calls ExecutePlan() which calls&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; *&#x9;&#x9;ExecProcNode() repeatedly on the top node of the plan state tree.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; *&#x9;&#x9;Each time this happens, ExecProcNode() will end up calling&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; *&#x9;&#x9;ExecNestLoop(), which calls ExecProcNode() on its subplans.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; *&#x9;&#x9;Each of these subplans is a sequential scan so ExecSeqScan() is&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; *&#x9;&#x9;called.  The slots returned by ExecSeqScan() may contain&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; *&#x9;&#x9;tuples which contain the attributes ExecNestLoop() uses to&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; *&#x9;&#x9;form the tuples it returns.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; *&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; *&#x9;  * Eventually ExecSeqScan() stops returning tuples and the nest&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; *&#x9;&#x9;loop join ends.  Lastly, ExecutorEnd() calls ExecEndNode() which&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; *&#x9;&#x9;calls ExecEndNestLoop() which in turn calls ExecEndNode() on&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; *&#x9;&#x9;its subplans which result in ExecEndSeqScan().&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; *&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; *&#x9;&#x9;This should show how the executor works by having&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; *&#x9;&#x9;ExecInitNode(), ExecProcNode() and ExecEndNode() dispatch&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; *&#x9;&#x9;their work to the appropriate node support routines which may&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; *&#x9;&#x9;in turn call these routines themselves on their subplans.&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt; */&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In PostgreSQL, trees execute with a &amp;lsquo;pull strategy&amp;rsquo;: the plan is executed from top to bottom, and each node &lt;em&gt;pulls&lt;/em&gt; content row by row from child nodes. As an alternative approach, we could try to execute queries from bottom to top, but among other cons, this approach lacks laziness (in simple implementation). For example, &lt;code&gt;select * from very_big_table limit 1&lt;/code&gt; would scan the whole table and then filter everything out instead of pulling just one row. This problem can&amp;rsquo;t be easily fixed, because you can&amp;rsquo;t really push &lt;code&gt;limit&lt;/code&gt; operator below any join or filter, so the pull strategy is the simpliest way to implement laziness. Its operator calls overhead can be optimized via batching (pulling multiple rows at once, though this is currently not implemented in PostgreSQL).&lt;/p&gt;</description>
    </item>
    <item>
      <title>Understanding PostgreSQL internals, part 1: Planner</title>
      <link>https://foxido.dev/posts/postgresql-internal-1/</link>
      <pubDate>Wed, 04 Jun 2025 20:00:00 +0300</pubDate>
      <guid>https://foxido.dev/posts/postgresql-internal-1/</guid>
      <description>&lt;h2 id=&#34;introduction&#34;&gt;Introduction&lt;/h2&gt;&#xA;&lt;p&gt;This is a small translation of &lt;a href=&#34;https://git.foxido.dev/foxido/db-course&#34;&gt;my homework&lt;/a&gt; for an MIPT course, where I describe how PostgreSQL internals work with references to the source code.&lt;/p&gt;&#xA;&lt;p&gt;All source code references are based on the &lt;code&gt;REL_17_5&lt;/code&gt; PostgreSQL git tag. For building PostgreSQL, you can refer to the &lt;a href=&#34;https://git.foxido.dev/foxido/db-course/-/blob/master/dockerbuild&#34;&gt;dockerbuild directory&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;During this series, I assume that you have following tables:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;CREATE&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;TABLE&lt;/span&gt; t1(a int, b1 int);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;CREATE&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;TABLE&lt;/span&gt; t2(a int, b2 int);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;CREATE&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;TABLE&lt;/span&gt; t3(a int, b3 int);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;INSERT&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;INTO&lt;/span&gt; t1 &lt;span style=&#34;color:#66d9ef&#34;&gt;SELECT&lt;/span&gt; i, (i &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt;) &lt;span style=&#34;color:#f92672&#34;&gt;%&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;7&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; generate_series(&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;10&lt;/span&gt;) i;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;INSERT&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;INTO&lt;/span&gt; t2 &lt;span style=&#34;color:#66d9ef&#34;&gt;SELECT&lt;/span&gt; i &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;, (i &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt;) &lt;span style=&#34;color:#f92672&#34;&gt;%&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;7&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; generate_series(&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;10&lt;/span&gt;) i;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;INSERT&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;INTO&lt;/span&gt; t3 &lt;span style=&#34;color:#66d9ef&#34;&gt;SELECT&lt;/span&gt; i &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt;, (i &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt;) &lt;span style=&#34;color:#f92672&#34;&gt;%&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;7&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;from&lt;/span&gt; generate_series(&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;10&lt;/span&gt;) i;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;VACUUM&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;ANALYZE&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;FULL&lt;/span&gt;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;why-we-need-planner-at-all&#34;&gt;Why we need planner at all?&lt;/h2&gt;&#xA;&lt;p&gt;Well, SQL is a declarative (not imperative) language: it specifies what we want from the database but not how to get it. So because we can execute only imperative statements, we need to transform these wishful queries into executable plans — and like any good developer, we want this transformation to be optimal.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Raspberry Pi &#43; Archlinux ARM &#43; btrfs</title>
      <link>https://foxido.dev/posts/rpi-archlinux-btrfs/</link>
      <pubDate>Sat, 28 May 2022 14:09:13 +0300</pubDate>
      <guid>https://foxido.dev/posts/rpi-archlinux-btrfs/</guid>
      <description>Simple instructions for installing arch linux with btrfs root partition instead of default ext4.</description>
    </item>
    <item>
      <title>$ whoami</title>
      <link>https://foxido.dev/whoami/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://foxido.dev/whoami/</guid>
      <description>&lt;p&gt;I love system programming and have some knowledge of OS, DBMS and compilers, as well as concurrency (low-level [CPU] and high-level [runtimes and distributed systems]).&lt;/p&gt;&#xA;&lt;p&gt;During my work hours I&amp;rsquo;ve played with:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Bridging LLVM&amp;rsquo;s optimizer for eBPF with kernel via custom frontend&lt;/li&gt;&#xA;&lt;li&gt;Lock-free/RCU B+ trees and algorithms in general&lt;/li&gt;&#xA;&lt;li&gt;Hazard pointers, folio refcount contention reduction, etc, etc&amp;hellip;&lt;/li&gt;&#xA;&lt;li&gt;PostgreSQL query planner (AQO and in general)&lt;/li&gt;&#xA;&lt;li&gt;GaussDB distributed planner&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;During my study and hobby time I&amp;rsquo;ve:&lt;/p&gt;</description>
    </item>
    <item>
      <title>C&#43;&#43;Russia Landing Pad</title>
      <link>https://foxido.dev/cpprussia_landing_pad/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://foxido.dev/cpprussia_landing_pad/</guid>
      <description>&lt;hr&gt;&#xA;&lt;p&gt;Obligatory self-promotion: &lt;a href=&#34;https://www.linkedin.com/in/ilya-gladyshev-92a8603b8&#34;&gt;Linkedin&lt;/a&gt; / &lt;a href=&#34;https://raw.githubusercontent.com/foxidokun/cv/refs/heads/master/cv.pdf&#34;&gt;CV&lt;/a&gt;&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;h3 id=&#34;дополнительные-материалы&#34;&gt;Дополнительные материалы&lt;/h3&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Попытка в текстовую версию доклада: &lt;a href=&#34;https://foxido.dev/posts/ebpf-comp-1/&#34;&gt;link&lt;/a&gt;. Будет обновлена третьей частью про написанное решение.&lt;/li&gt;&#xA;&lt;li&gt;Статья про &lt;a href=&#34;https://www.usenix.org/system/files/atc25-jia.pdf&#34;&gt;Rex&lt;/a&gt; &amp;ndash; out-of-tree замену eBPF на Rust (слегка пропатченный userspace компилятор вместо верификатора в ядре). Статья примечательна примерами почему текущий подход с верификатором не работает.&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://dl.acm.org/doi/10.1145/3620666.3651387&#34;&gt;Статья&lt;/a&gt; про альтернативный eBPF оптимизатор вне ядра.&lt;/li&gt;&#xA;&lt;li&gt;Доклад про планируемую модель памяти:&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;2024: &lt;a href=&#34;https://youtube.com/watch?v=QG-cLG9PekI&#34;&gt;video&lt;/a&gt; / &lt;a href=&#34;https://lwn.net/Articles/976071/&#34;&gt;summary&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;2021: &lt;a href=&#34;https://lpc.events/event/11/contributions/941/&#34;&gt;talk at LPC&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;исходный-код&#34;&gt;Исходный код&lt;/h3&gt;&#xA;&lt;p&gt;Заранее стоит отметить, что код не соответствует стандартам автора для open-source, и его стоит воспринимать как попавшую на белый свет корпоративную v1. После косметической обработки будет оформлено RFC в ядро, и данная страница будет обновлена ссылкой.&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
