<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="369175" data-post-id="369175">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="Schultzer" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/Schultzer/120/4339_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  Schultzer
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<blockquote>
<p>It’s actually the same API! The only difference is that Ecto does not support executing multiple queries in one round-trip. AFAIK it actually is valid to send multiple SQL statements in one request, but it seems like nobody ever does that. I wonder why that is.</p>
</blockquote>
<p>It’s common to execute multiple statements in a query. Ecto and Ecto.Query only supports that within a transaction. Doing this outside of a transaction with is also common would require you to write raw SQL and only myxql supports returning multiple values.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="369175" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/ecto-foundationdb-an-ecto-adapter-for-foundationdb/61642/52">Post #51</a>
	                </div>
	            </div>
              <div id="likers-container-369175" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="369175"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #51"></div>
  </section>
</div>
    <div class="postbit" id="369177" data-post-id="369177">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="garrison" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  garrison
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="jstimps" data-post="51" data-topic="61642">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/jstimps/48/41062_2.png" class="avatar"> jstimps:</div>
<blockquote>
<p>Non-batching behavior is to send the <code>get()</code> on the wire immediately.</p>
</blockquote>
</aside>
<p>Do you know if this is actually what happens? It seems like the C API allows you to create <code>get()</code> futures and then block on any (one) of them (or register a callback). The point at which you block seems like a great time to send out a batch, though of course it could also batch early if a lot of futures are created. There is a classic batching throughput/latency tradeoff here.</p>
<p>If all you do is register callbacks I don’t see how the client would know you want to block, though. So I guess it must just be a timeout after all? I feel like providing explicit control to the developer here is preferable, so I’m curious why they did it that way.</p>
<p>I should say for the record that I have spent almost zero time reverse-engineering the client because unlike the server side the client implementation is pretty obvious (sans the specifics, clearly).</p>
<aside class="quote no-group" data-username="Schultzer" data-post="52" data-topic="61642">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/schultzer/48/4339_2.png" class="avatar"> Schultzer:</div>
<blockquote>
<p>Ecto and Ecto.Query only supports that within a transaction.</p>
</blockquote>
</aside>
<p>Wait, it does? What is the syntax for that?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="369177" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/ecto-foundationdb-an-ecto-adapter-for-foundationdb/61642/53">Post #52</a>
	                </div>
	            </div>
              <div id="likers-container-369177" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="369177"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #52"></div>
  </section>
</div>
    <div class="postbit" id="369178" data-post-id="369178">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="Schultzer" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/Schultzer/120/4339_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  Schultzer
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>When I execute multiple queries in a transaction, then I use Ecto multi, however that has become frown upon, for reasons I don’t find compelling. So today you would probably have to wrap all of them in anonymized function if you were to use Ecto. But for me, in the future I will be using SQL, which removes any limitations and abstraction.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="369178" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/ecto-foundationdb-an-ecto-adapter-for-foundationdb/61642/54">Post #53</a>
	                </div>
	            </div>
              <div id="likers-container-369178" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="369178"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #53"></div>
  </section>
</div>
    <div class="postbit" id="369216" data-post-id="369216">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="garrison" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  garrison
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>But Ecto.Multi still doesn’t execute multiple statements in one request, right? I meant something like this:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">select * from users where name = 'bob';
select * from users where name = 'alice';
# ... and so on
</code></pre>
<p>That is, sending multiple (semicolon-separated) SQL statements in one round-trip to the server. Obviously there are ways you could constrain this particular example into one statement, but there are cases where that gets messy (if the queries were more complicated).</p>
<p>I am not aware of any way to do this with Ecto short of dropping down to raw SQL, and even then I’m not sure if multiple result sets are supported. TBH I had some trouble determining if <em>Postgres</em> even supports them, though I did not look that hard.</p>
<p>FDB is a little different than an SQL database because the idea is you’re supposed to write the high-level query planner stuff as a stateless client to the underlying datastore, so unlike with SQL we need to think a bit harder about round-trips. The batching is also difficult because there are actually many servers and choosing which ones to send the requests to is a little more complicated than you might think, plus you might want to make requests to multiple servers concurrently to save latency.</p>
<p>But in a parallel universe where things went differently, you might expect a syntax like this:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">query1 = one(from u in Users, where: u.name == 'alice')
query2 = one(from u in Users, where: u.name == 'bob')
{alice, bob} = Repo.execute({query1, query2})
</code></pre>
<p>And as you can see this is essentially what <a class="mention" href="/u/jstimps" rel="nofollow">@jstimps</a> has ended up with, except he has to fight Ecto a bit to do it because it was not designed for this.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="369216" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/ecto-foundationdb-an-ecto-adapter-for-foundationdb/61642/55">Post #54</a>
	                </div>
	            </div>
              <div id="likers-container-369216" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="369216"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #54"></div>
  </section>
</div>
    <div class="postbit" id="369220" data-post-id="369220">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="Schultzer" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/Schultzer/120/4339_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  Schultzer
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Myxql supports multiple results <a href="https://hexdocs.pm/ecto_sql/Ecto.Adapters.SQL.html#query_many/4" class="inline-onebox" rel="noopener nofollow ugc">Ecto.Adapters.SQL — Ecto SQL v3.14.0</a>, but yeah you would have to write SQL, my memory might be off, but I could swear that the transaction would happen in one go. If not then theres another limitation to Ecto I wasn’t aware of.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="369220" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/ecto-foundationdb-an-ecto-adapter-for-foundationdb/61642/56">Post #55</a>
	                </div>
	            </div>
              <div id="likers-container-369220" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="369220"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #55"></div>
  </section>
</div>
    <div class="postbit" id="369221" data-post-id="369221">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="josevalim" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/120/1787_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  josevalim
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Creator of Elixir</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Exactly. Ecto doesn’t support it through its API but it does have Repo.query where the adapter can do what it wants (including multiple queries). This is a feature we could add at the high level API if required though and contributions are welcome.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="369221" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/ecto-foundationdb-an-ecto-adapter-for-foundationdb/61642/57">Post #56</a>
	                </div>
	            </div>
              <div id="likers-container-369221" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="369221"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #56"></div>
  </section>
</div>
    <div class="postbit" id="372098" data-post-id="372098">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="jstimps" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/jstimps/120/41062_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  jstimps
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Hi folks,</p>
<p>An update that’s not strictly EctoFDB related – I converted (/copied) the official FoundationDB <a href="https://apple.github.io/foundationdb/class-scheduling.html" rel="noopener nofollow ugc">Class Scheduling Tutorial</a> to an Elixir-focused Livebook:</p>
<aside class="onebox allowlistedgeneric" data-onebox-src="https://erlfdb.hexdocs.pm/tutorial-elixir.html">
  <header class="source">

      <a href="https://erlfdb.hexdocs.pm/tutorial-elixir.html" target="_blank" rel="noopener nofollow ugc">erlfdb.hexdocs.pm</a>
  </header>

  <article class="onebox-body">
    

<h3><a href="https://erlfdb.hexdocs.pm/tutorial-elixir.html" target="_blank" rel="noopener nofollow ugc">Tutorial - Elixir — erlfdb v1.2.1</a></h3>



  </article>

  <div class="onebox-metadata">
    
    
  </div>

  <div style="clear: both"></div>
</aside>

<p>In the tutorial, we develop a simple data layer (using key-values in subspaces) that an application could use to sign up students for classes and drop those classes, adding some interesting business logic along the way.</p>
<p>The tutorial could be useful for anyone who wants to</p>
<ul>
<li>Get started with <code>:erlfdb</code> itself</li>
<li>Understand the essentials of the EctoFDB implementation, which takes these same ideas and fits them to a subset of the Ecto abstractions</li>
</ul> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="372098" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/ecto-foundationdb-an-ecto-adapter-for-foundationdb/61642/58">Post #57</a>
	                </div>
	            </div>
              <div id="likers-container-372098" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="372098"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #57"></div>
  </section>
</div>
    <div class="postbit" id="372118" data-post-id="372118">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="garrison" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  garrison
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Nice guide! Reading through it reminded me of something.</p>
<p>I had been considering for some time whether it would be a good idea to make the tuple encodings “follow” Erlang term order. Not <em>exactly</em>, but closer than the FDB tuples. The first step would be to rearrange the typecodes to match term order, which is easy enough.</p>
<p>But the problem is that Erlang tuples are sorted length-first rather than lexicographically, which is very bad behavior for something like FDB. However, during a conversation with <a class="mention" href="/u/asd" rel="nofollow">@Asd</a> in the Bedrock thread I realized that if you just avoid tuples and use lists instead you don’t have this problem because lists are ordered correctly (by their elements). Which makes perfect sense, because computing the length of a list would be very expensive. (It remains a mystery why tuples are compared in such an unhelpful manner, though.)</p>
<p>The irony is that I was implementing tuple encodings a couple of weeks ago following the <code>:erlfdb_tuple</code> implementation (out of laziness) and I noticed that the encoder/decoder uses lists internally and converts from/to tuples at the start/end, which makes perfect sense because you want to build up the list incrementally as you parse. And I thought “why bother, the lists will generally be short anyway”, so I just used lists in the API instead of tuples.</p>
<p>So as it turns out, I have actually already done this. By accident!</p>
<p>With <code>erlfdb</code> this is probably not something you want to change at this point (and you wouldn’t want to break compatibility with FDB tuples either), but I’m curious what you think about trying to follow term order with the encodings. It’s not something that <em>actually</em> matters in reality, but I find it oddly satisfying.</p>
<p>The performance of lists vs. tuples is an interesting question. In practice, I assume tuples are slightly faster:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">[a, b, [c, d]] = Tuple.unpack(bin)
# vs.
{a, b, {c, d}} = Tuple.unpack(bin)
</code></pre>
<p>But for short lists I’m doubtful there is a meaningful difference. And using tuples costs some performance too because there is an extra conversion (<code>:erlfdb_tuple</code> builds up a list first). Is there any record of why <code>erlfdb</code> uses tuples over lists?</p>
<p>The integer/float comparison behavior seems like a bad path to go down, though, so I would still deviate from term order there I think.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="372118" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/ecto-foundationdb-an-ecto-adapter-for-foundationdb/61642/59">Post #58</a>
	                </div>
	            </div>
              <div id="likers-container-372118" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="372118"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #58"></div>
  </section>
</div>
    <div class="postbit" id="372126" data-post-id="372126">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="jstimps" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/jstimps/120/41062_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  jstimps
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="garrison" data-post="59" data-topic="61642">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/g/3bc359/48.png" class="avatar"> garrison:</div>
<blockquote>
<p>Is there any record of why <code>erlfdb</code> uses tuples over lists?</p>
</blockquote>
</aside>
<p>I haven’t seen one. Now that you mention it, I do agree that using lists in Erlang/Elixir (I’ll use “erts” for shorthand) would be more ergonomic. As you say, the FDB Tuple layer encourages the practice of “building up” a fdb-tuple, which is awkward with an erts-tuple, since they’re fixed length data structures.</p>
<p>Also, pattern matching on erts-lists is even more powerful than erts-tuples, so it sounds like very good idea indeed!</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">{"user", user_id, _, _, _, _, _, _}
  = :erlfdb_tuple.unpack(key) # ugh!

["user", user_id | _]
  = :erlfdb_tuple_v2.unpack(key) # yay!
</code></pre>
<aside class="quote no-group" data-username="garrison" data-post="59" data-topic="61642">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/g/3bc359/48.png" class="avatar"> garrison:</div>
<blockquote>
<p>The performance of lists vs. tuples is an interesting question.</p>
</blockquote>
</aside>
<p>I have a bad track record of predicting reality in micro-benchmarks like this, but I wonder if using erts-lists would actually be faster in the best case than erts-tuples due to the conversion you mention. Either way, it’s likely to be negligible compared to I/O <img src="https://forum.elixirforum.com/images/emoji/apple/person_shrugging.png?v=15" title=":person_shrugging:" class="emoji" alt=":person_shrugging:" loading="lazy" width="20" height="20"> .</p>
<aside class="quote no-group" data-username="garrison" data-post="59" data-topic="61642">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/g/3bc359/48.png" class="avatar"> garrison:</div>
<blockquote>
<p>I had been considering for some time whether it would be a good idea to make the tuple encodings “follow” Erlang term order.</p>
</blockquote>
</aside>
<p>I can see why this would be useful for your database server, likewise for Bedrock, since you’re more likely to want to do key comparisons with both the binary representation and the data structure. On the client, this has never been a pain point for me, though, since the server always returns keys in the correct sort order, and I can’t remember ever needing to compare them myself. That being said, I’m a big fan of design simplicity, so <img src="https://forum.elixirforum.com/images/emoji/apple/+1.png?v=15" title=":+1:" class="emoji" alt=":+1:" loading="lazy" width="20" height="20"> from me!</p>
<p>On the question of whether or not an ERTS-friendly Tuple V2 would be a good idea to store in actual FDB – I’m a maybe on this. On the one hand, FDB is supposed to allow the client to be entirely in control of the Layer.</p>
<p>On the other hand, GetMappedRange exists. As you’re aware, FDB implements this feature with assumptions about the key and value encoding, specifically that they are Tuple encoded. If you were to <em>only</em> change the type codes, it would probably still work because FDB would have no reason to decode the types. AFAIK their only assumption is regarding the boundaries between fields. But GetMappedRange is so finicky that I worry there is some dragon lurking there.</p>
<aside class="quote no-group" data-username="garrison" data-post="59" data-topic="61642">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/g/3bc359/48.png" class="avatar"> garrison:</div>
<blockquote>
<p>It remains a mystery why tuples are compared in such an unhelpful manner, though</p>
</blockquote>
</aside>
<p>Keeping in mind how important records were (and still are) in Erlang, the tuple ordering makes sense. Having fixed-length tuples together means that different versions of your ets and mnesia records would be nicely grouped. I don’t know if this is <em>the</em> reason, but it seems like a real benefit.</p>
<p>(This also illustrates why records can be tricky <img src="https://forum.elixirforum.com/images/emoji/apple/smiley.png?v=15" title=":smiley:" class="emoji" alt=":smiley:" loading="lazy" width="20" height="20"> )</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">iex(1)&gt; :ets.new(:tab, [:named_table, {:keypos, 2}, :bag])
:tab
iex(2)&gt; :ets.insert(:tab, {:user, "1"})
true
iex(3)&gt; :ets.insert(:tab, {:user, "2"})
true
iex(4)&gt; :ets.insert(:tab, {:user, "1", "Alice"})
true
iex(5)&gt; :ets.insert(:tab, {:user, "2", "Bob"})
true
iex(6)&gt; :ets.tab2list(:tab) |&gt; Enum.sort()
[{:user, "1"}, {:user, "2"}, {:user, "1", "Alice"}, {:user, "2", "Bob"}]
</code></pre>
<aside class="quote no-group" data-username="garrison" data-post="59" data-topic="61642">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/g/3bc359/48.png" class="avatar"> garrison:</div>
<blockquote>
<p>The integer/float comparison behavior seems like a bad path to go down, though, so I would still deviate from term order there I think.</p>
</blockquote>
</aside>
<p>Wdym? If you’re going for a stable sort order in both binary and erts, you must, no?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="372126" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/ecto-foundationdb-an-ecto-adapter-for-foundationdb/61642/60">Post #59</a>
	                </div>
	            </div>
              <div id="likers-container-372126" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="372126"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #59"></div>
  </section>
</div>
    <div class="postbit" id="372129" data-post-id="372129">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="garrison" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  garrison
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="jstimps" data-post="60" data-topic="61642">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/jstimps/48/41062_2.png" class="avatar"> jstimps:</div>
<blockquote>
<p>I can see why this would be useful for your database server, likewise for Bedrock, since you’re more likely to want to do key comparisons with both the binary representation and the data structure.</p>
</blockquote>
</aside>
<p>This was not my original motivation, but I could see it being handy. I haven’t written a higher-level layer yet so I don’t know exactly how often it comes up. Probably the reason you haven’t run into it is that you are specifically pushing responsibility for further filtering/sorting on to the user (as opposed to having a query planner), so you can always take advantage of FDB’s sorting. But I do wonder how often I will need to compare a keyset <em>without</em> having already encoded the underlying binary.</p>
<p>I know <code>erlfdb</code> has an FDB term comparator somewhere.</p>
<aside class="quote no-group" data-username="jstimps" data-post="60" data-topic="61642">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/jstimps/48/41062_2.png" class="avatar"> jstimps:</div>
<blockquote>
<p>If you’re going for a stable sort order in both binary and erts, you must, no?</p>
</blockquote>
</aside>
<p>Well my original thinking was that if you always have a schema with fixed types this doesn’t matter. FDB presumably had the same thinking as they don’t mix floats and ints.</p>
<p>But, actually, I am very interested in providing a type system with union types, and it would be quite elegant if an index on an <code>integer | float</code> field could be built. I suppose you could still get away with coercing the integers into floats in the index.</p>
<p>I’m torn on this, I’ll have to look into it. The varint encoding from FDB is very elegant and useful so I wouldn’t want to lose that.</p>
<p><a href="https://github.com/uwiger/sext" rel="noopener nofollow ugc">The sext library</a> (yeah) seems to handle this by encoding a fraction after the integer part somehow. I’ll stare at it some more until I understand it.</p>
<aside class="quote no-group" data-username="jstimps" data-post="60" data-topic="61642">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/jstimps/48/41062_2.png" class="avatar"> jstimps:</div>
<blockquote>
<p>But GetMappedRange is so finicky that I worry there is some dragon lurking there.</p>
</blockquote>
</aside>
<p>Yeah, this is exactly the reason I think K/V is a bad abstraction (as discussed previously). I think at this point I’m just going to go for “record store” branding and skip the term “key/value store” entirely (even though the underlying internals are still ordered binary/binary). My only worry is people might then expect a schema, but I’ll work around that. “Schemaless record store?” “Semi-structured”? Idk.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="372129" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/ecto-foundationdb-an-ecto-adapter-for-foundationdb/61642/61">Post #60</a>
	                </div>
	            </div>
              <div id="likers-container-372129" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="372129"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #60"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <a class="load-more-button" data-turbo-stream="true" href="/topics/61642/load_more?page=7">Load more posts (16 remaining)</a>
</div></template></turbo-stream>