<!-- CANARY: REQ=REQ-DOCS-001; FEATURE="Docs"; ASPECT=Documentation; STATUS=TESTED; OWNER=docs; UPDATED=2026-01-15 --> <h2 id="nullable-fields--null-handling" class="position-relative d-flex align-items-center group"> <span>Nullable Fields &amp;amp; NULL Handling</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="nullable-fields--null-handling" aria-haspopup="dialog" aria-label="Share link: Nullable Fields &amp;amp; NULL Handling"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h2><div id="headingShareModal" class="heading-share-modal" role="dialog" aria-modal="true" aria-labelledby="headingShareTitle" hidden> <div class="hsm-dialog" role="document"> <div class="hsm-header"> <h2 id="headingShareTitle" class="h6 mb-0 fw-bold">Share this section</h2> <button type="button" class="hsm-close" aria-label="Close"> <i class="fa-solid fa-xmark"></i> </button> </div> <div class="hsm-body"> <label for="headingShareInput" class="form-label small text-muted mb-1 text-uppercase fw-bold" style="font-size: 0.7rem; letter-spacing: 0.5px;">Permalink</label> <div class="input-group mb-4 hsm-url-group"> <input id="headingShareInput" type="text" class="form-control font-monospace" readonly aria-readonly="true" style="font-size: 0.85rem;" /> <button class="btn btn-primary hsm-copy" type="button" aria-label="Copy" title="Copy"> <i class="fa-duotone fa-clipboard" aria-hidden="true"></i> </button> </div> <div class="small fw-bold mb-2 text-muted text-uppercase" style="font-size: 0.7rem; letter-spacing: 0.5px;">Share via</div> <div class="hsm-share-grid"> <a id="share-twitter" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer"> <i class="fa-brands fa-twitter me-2"></i>Twitter </a> <a id="share-linkedin" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer"> <i class="fa-brands fa-linkedin me-2"></i>LinkedIn </a> <a id="share-facebook" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer"> <i class="fa-brands fa-facebook me-2"></i>Facebook </a> </div> </div> </div> </div> <style> .heading-share-modal { position: fixed; inset: 0; display: flex; justify-content: center; align-items: center; background: rgba(0, 0, 0, 0.6); z-index: 1050; padding: 1rem; backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px); } .heading-share-modal[hidden] { display: none !important; } .hsm-dialog { max-width: 420px; width: 100%; background: var(--bs-body-bg, #fff); color: var(--bs-body-color, #212529); border: 1px solid var(--bs-border-color, rgba(0,0,0,0.1)); border-radius: 1rem; box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25); overflow: hidden; animation: hsm-fade-in 0.2s ease-out; } @keyframes hsm-fade-in { from { opacity: 0; transform: scale(0.95); } to { opacity: 1; transform: scale(1); } } [data-bs-theme="dark"] .hsm-dialog { background: #1e293b; border-color: rgba(255,255,255,0.1); color: #f8f9fa; } .hsm-header { display: flex; justify-content: space-between; align-items: center; padding: 1rem 1.5rem; border-bottom: 1px solid var(--bs-border-color, rgba(0,0,0,0.1)); background: rgba(0,0,0,0.02); } [data-bs-theme="dark"] .hsm-header { background: rgba(255,255,255,0.02); border-color: rgba(255,255,255,0.1); } .hsm-close { background: transparent; border: none; color: inherit; opacity: 0.5; padding: 0.25rem 0.5rem; border-radius: 0.25rem; font-size: 1.2rem; line-height: 1; transition: opacity 0.2s; } .hsm-close:hover { opacity: 1; } .hsm-body { padding: 1.5rem; } .hsm-url-group { display: flex !important; align-items: stretch; } .hsm-url-group .form-control { flex: 1; min-width: 0; margin: 0; background: var(--bs-secondary-bg, #f8f9fa); border-color: var(--bs-border-color, #dee2e6); border-top-right-radius: 0; border-bottom-right-radius: 0; height: 42px; } .hsm-url-group .btn { flex: 0 0 auto; margin: 0; margin-left: -1px; border-top-left-radius: 0; border-bottom-left-radius: 0; height: 42px; display: flex; align-items: center; justify-content: center; padding: 0 1.25rem; z-index: 2; } [data-bs-theme="dark"] .hsm-url-group .form-control { background: #0f172a; border-color: #334155; color: #e2e8f0; } .hsm-share-grid { display: flex; flex-direction: column; gap: 0.5rem; } .hsm-share-grid .btn { display: flex; align-items: center; justify-content: center; font-size: 0.9rem; padding: 0.6rem; border-color: var(--bs-border-color); width: 100%; } [data-bs-theme="dark"] .hsm-share-grid .btn { color: #e2e8f0; border-color: #475569; } [data-bs-theme="dark"] .hsm-share-grid .btn:hover { background: #334155; border-color: #cbd5e1; } </style> <script> (function(){ const modal = document.getElementById('headingShareModal'); if(!modal) return; const input = modal.querySelector('#headingShareInput'); const copyBtn = modal.querySelector('.hsm-copy'); const twitter = modal.querySelector('#share-twitter'); const linkedin = modal.querySelector('#share-linkedin'); const facebook = modal.querySelector('#share-facebook'); const closeBtn = modal.querySelector('.hsm-close'); let lastFocus=null; let trapBound=false; function buildUrl(id){ return window.location.origin + window.location.pathname + '#' + id; } function isOpen(){ return !modal.hasAttribute('hidden'); } function hydrate(id){ const url=buildUrl(id); input.value=url; const enc=encodeURIComponent(url); const text=encodeURIComponent(document.title); if(twitter) twitter.href=`https://twitter.com/intent/tweet?url=${enc}&text=${text}`; if(linkedin) linkedin.href=`https://www.linkedin.com/sharing/share-offsite/?url=${enc}`; if(facebook) facebook.href=`https://www.facebook.com/sharer/sharer.php?u=${enc}`; } function openModal(id){ lastFocus=document.activeElement; hydrate(id); if(!isOpen()){ modal.removeAttribute('hidden'); } requestAnimationFrame(()=>{ input.focus(); }); trapFocus(); } function closeModal(){ if(!isOpen()) return; modal.setAttribute('hidden',''); if(lastFocus && typeof lastFocus.focus==='function') lastFocus.focus(); } function copyCurrent(){ try{ navigator.clipboard.writeText(input.value).then(()=>feedback(true),()=>fallback()); } catch(e){ fallback(); } } function fallback(){ input.select(); try{ document.execCommand('copy'); feedback(true);}catch(e){ feedback(false);} } function feedback(ok){ if(!copyBtn) return; const icon=copyBtn.querySelector('i'); if(!icon) return; const prev=copyBtn.getAttribute('data-prev')||icon.className; if(!copyBtn.getAttribute('data-prev')) copyBtn.setAttribute('data-prev',prev); icon.className= ok ? 'fa-duotone fa-clipboard-check':'fa-duotone fa-circle-exclamation'; setTimeout(()=>{ icon.className=prev; },1800); } function handleShareClick(e){ e.preventDefault(); const btn=e.currentTarget; const id=btn.getAttribute('data-share-target'); if(id) openModal(id); } function bindShareButtons(){ document.querySelectorAll('.h-share').forEach(btn=>{ if(!btn.dataset.hShareBound){ btn.addEventListener('click', handleShareClick); btn.dataset.hShareBound='1'; } }); } bindShareButtons(); if(document.readyState==='loading'){ document.addEventListener('DOMContentLoaded', bindShareButtons); } else { requestAnimationFrame(bindShareButtons); } document.addEventListener('click', function(e){ const shareBtn=e.target.closest && e.target.closest('.h-share'); if(shareBtn && !shareBtn.dataset.hShareBound){ handleShareClick.call(shareBtn, e); } }, true); document.addEventListener('click', e=>{ if(e.target===modal) closeModal(); if(e.target.closest && e.target.closest('.hsm-close')){ e.preventDefault(); closeModal(); } if(copyBtn && (e.target===copyBtn || (e.target.closest && e.target.closest('.hsm-copy')))) { e.preventDefault(); copyCurrent(); } }); document.addEventListener('keydown', e=>{ if(e.key==='Escape' && isOpen()) closeModal(); }); function trapFocus(){ if(trapBound) return; trapBound=true; modal.addEventListener('keydown', f=>{ if(f.key==='Tab' && isOpen()){ const focusable=[...modal.querySelectorAll('a[href],button,input,textarea,select,[tabindex]:not([tabindex="-1"])')].filter(el=>!el.hasAttribute('disabled')); if(!focusable.length) return; const first=focusable[0]; const last=focusable[focusable.length-1]; if(f.shiftKey && document.activeElement===first){ f.preventDefault(); last.focus(); } else if(!f.shiftKey && document.activeElement===last){ f.preventDefault(); first.focus(); } } }); } if(closeBtn) closeBtn.addEventListener('click', e=>{ e.preventDefault(); closeModal(); }); })(); </script><p>Nullable fields in Geode allow properties to contain NULL values, representing missing, unknown, or inapplicable data. Understanding NULL semantics is critical for correct graph queries, data modeling, and application logic. Geode implements three-valued logic according to the GQL standard, where expressions can evaluate to TRUE, FALSE, or NULL.</p> <h3 id="understanding-null-in-graph-databases" class="position-relative d-flex align-items-center group"> <span>Understanding NULL in Graph Databases</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="understanding-null-in-graph-databases" aria-haspopup="dialog" aria-label="Share link: Understanding NULL in Graph Databases"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3><p>NULL is not a value—it represents the absence of a value. In graph databases, NULL has specific semantic meanings:</p> <ul> <li><strong>Missing Information</strong>: Data not yet collected (e.g., middle name)</li> <li><strong>Inapplicable Data</strong>: Property doesn&rsquo;t apply (e.g., retirement date for active employees)</li> <li><strong>Unknown Values</strong>: Information exists but is unknown (e.g., exact birth date)</li> <li><strong>Optional Relationships</strong>: Edge properties that may not exist</li> </ul> <p>Unlike relational databases where NULL handling is often an afterthought, graph databases require explicit modeling of optionality because NULL values affect traversals, aggregations, and pattern matching.</p> <h3 id="defining-nullable-vs-not-null-properties" class="position-relative d-flex align-items-center group"> <span>Defining Nullable vs NOT NULL Properties</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="defining-nullable-vs-not-null-properties" aria-haspopup="dialog" aria-label="Share link: Defining Nullable vs NOT NULL Properties"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3><p>By default in Geode, all properties are nullable unless explicitly declared as NOT NULL. This default-nullable behavior requires careful consideration during schema design.</p> <h4 id="explicit-nullability" class="position-relative d-flex align-items-center group"> <span>Explicit Nullability</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="explicit-nullability" aria-haspopup="dialog" aria-label="Share link: Explicit Nullability"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Best</span><span class="w"> </span><span class="py">practice</span><span class="p">:</span><span class="w"> </span><span class="nc">explicitly</span><span class="w"> </span><span class="py">declare</span><span class="w"> </span><span class="py">nullability</span><span class="w"> </span><span class="py">intent</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CREATE</span><span class="w"> </span><span class="py">NODE</span><span class="w"> </span><span class="py">TYPE</span><span class="w"> </span><span class="py">Person</span><span class="w"> </span><span class="p">(</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">id</span><span class="w"> </span><span class="py">STRING</span><span class="w"> </span><span class="py">NOT</span><span class="w"> </span><span class="py">NULL</span><span class="p">,</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Required</span><span class="p">:</span><span class="w"> </span><span class="nc">primary</span><span class="w"> </span><span class="py">identifier</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">name</span><span class="w"> </span><span class="py">STRING</span><span class="w"> </span><span class="py">NOT</span><span class="w"> </span><span class="py">NULL</span><span class="p">,</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Required</span><span class="p">:</span><span class="w"> </span><span class="nc">every</span><span class="w"> </span><span class="py">person</span><span class="w"> </span><span class="py">has</span><span class="w"> </span><span class="py">a</span><span class="w"> </span><span class="py">name</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">middle_name</span><span class="w"> </span><span class="py">STRING</span><span class="w"> </span><span class="py">NULL</span><span class="p">,</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Explicitly</span><span class="w"> </span><span class="py">nullable</span><span class="w"> </span><span class="p">(</span><span class="py">optional</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">nickname</span><span class="w"> </span><span class="py">STRING</span><span class="p">,</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Implicitly</span><span class="w"> </span><span class="py">nullable</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">email</span><span class="w"> </span><span class="py">STRING</span><span class="w"> </span><span class="py">NOT</span><span class="w"> </span><span class="py">NULL</span><span class="p">,</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Required</span><span class="w"> </span><span class="py">for</span><span class="w"> </span><span class="py">communication</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">phone</span><span class="w"> </span><span class="py">STRING</span><span class="w"> </span><span class="py">NULL</span><span class="p">,</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Optional</span><span class="w"> </span><span class="py">contact</span><span class="w"> </span><span class="py">method</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">date_of_birth</span><span class="w"> </span><span class="py">DATE</span><span class="p">,</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">May</span><span class="w"> </span><span class="py">be</span><span class="w"> </span><span class="py">unknown</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">date_of_death</span><span class="w"> </span><span class="py">DATE</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">NULL</span><span class="w"> </span><span class="py">for</span><span class="w"> </span><span class="py">living</span><span class="w"> </span><span class="py">persons</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Edge</span><span class="w"> </span><span class="py">with</span><span class="w"> </span><span class="py">required</span><span class="w"> </span><span class="py">and</span><span class="w"> </span><span class="py">optional</span><span class="w"> </span><span class="py">properties</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CREATE</span><span class="w"> </span><span class="py">EDGE</span><span class="w"> </span><span class="py">TYPE</span><span class="w"> </span><span class="py">WORKS_FOR</span><span class="w"> </span><span class="p">(</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">start_date</span><span class="w"> </span><span class="py">DATE</span><span class="w"> </span><span class="py">NOT</span><span class="w"> </span><span class="py">NULL</span><span class="p">,</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Employment</span><span class="w"> </span><span class="py">must</span><span class="w"> </span><span class="py">have</span><span class="w"> </span><span class="py">start</span><span class="w"> </span><span class="py">date</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">end_date</span><span class="w"> </span><span class="py">DATE</span><span class="p">,</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">NULL</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">currently</span><span class="w"> </span><span class="py">employed</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">position</span><span class="w"> </span><span class="py">STRING</span><span class="w"> </span><span class="py">NOT</span><span class="w"> </span><span class="py">NULL</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">salary</span><span class="w"> </span><span class="py">DECIMAL</span><span class="p">,</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">May</span><span class="w"> </span><span class="py">be</span><span class="w"> </span><span class="py">confidential</span><span class="err">/</span><span class="py">unknown</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">department</span><span class="w"> </span><span class="py">STRING</span><span class="w"> </span><span class="py">NOT</span><span class="w"> </span><span class="py">NULL</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="err">;</span><span class="w"> </span></span></span></code></pre></div> <h4 id="not-null-constraints" class="position-relative d-flex align-items-center group"> <span>NOT NULL Constraints</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="not-null-constraints" aria-haspopup="dialog" aria-label="Share link: NOT NULL Constraints"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>NOT NULL constraints ensure data completeness for critical properties:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">CREATE</span><span class="w"> </span><span class="py">NODE</span><span class="w"> </span><span class="py">TYPE</span><span class="w"> </span><span class="py">Product</span><span class="w"> </span><span class="p">(</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">sku</span><span class="w"> </span><span class="py">STRING</span><span class="w"> </span><span class="py">NOT</span><span class="w"> </span><span class="py">NULL</span><span class="p">,</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Must</span><span class="w"> </span><span class="py">have</span><span class="w"> </span><span class="py">identifier</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">name</span><span class="w"> </span><span class="py">STRING</span><span class="w"> </span><span class="py">NOT</span><span class="w"> </span><span class="py">NULL</span><span class="p">,</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Must</span><span class="w"> </span><span class="py">be</span><span class="w"> </span><span class="py">named</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">price</span><span class="w"> </span><span class="py">DECIMAL</span><span class="w"> </span><span class="py">NOT</span><span class="w"> </span><span class="py">NULL</span><span class="p">,</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Must</span><span class="w"> </span><span class="py">have</span><span class="w"> </span><span class="py">price</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">description</span><span class="w"> </span><span class="py">TEXT</span><span class="p">,</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Optional</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">manufacturer</span><span class="w"> </span><span class="py">STRING</span><span class="p">,</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">May</span><span class="w"> </span><span class="py">be</span><span class="w"> </span><span class="py">unknown</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">discontinued_date</span><span class="w"> </span><span class="py">DATE</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">NULL</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">still</span><span class="w"> </span><span class="py">active</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="err">;</span><span class="w"> </span></span></span></code></pre></div><p>Using NOT NULL with defaults provides sensible fallbacks:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">CREATE</span><span class="w"> </span><span class="py">NODE</span><span class="w"> </span><span class="py">TYPE</span><span class="w"> </span><span class="py">User</span><span class="w"> </span><span class="p">(</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">id</span><span class="w"> </span><span class="py">STRING</span><span class="w"> </span><span class="py">NOT</span><span class="w"> </span><span class="py">NULL</span><span class="w"> </span><span class="py">DEFAULT</span><span class="w"> </span><span class="py">gen_random_uuid</span><span class="p">(),</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">email</span><span class="w"> </span><span class="py">STRING</span><span class="w"> </span><span class="py">NOT</span><span class="w"> </span><span class="py">NULL</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">created_at</span><span class="w"> </span><span class="py">TIMESTAMP</span><span class="w"> </span><span class="py">NOT</span><span class="w"> </span><span class="py">NULL</span><span class="w"> </span><span class="py">DEFAULT</span><span class="w"> </span><span class="py">NOW</span><span class="p">(),</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">status</span><span class="w"> </span><span class="py">STRING</span><span class="w"> </span><span class="py">NOT</span><span class="w"> </span><span class="py">NULL</span><span class="w"> </span><span class="py">DEFAULT</span><span class="w"> </span><span class="err">&#39;</span><span class="py">active</span><span class="err">&#39;</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">last_login</span><span class="w"> </span><span class="py">TIMESTAMP</span><span class="p">,</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">NULL</span><span class="w"> </span><span class="py">until</span><span class="w"> </span><span class="py">first</span><span class="w"> </span><span class="py">login</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">preferences</span><span class="w"> </span><span class="py">JSONB</span><span class="w"> </span><span class="py">NOT</span><span class="w"> </span><span class="py">NULL</span><span class="w"> </span><span class="py">DEFAULT</span><span class="w"> </span><span class="err">&#39;</span><span class="p">{}</span><span class="err">&#39;</span><span class="p">::</span><span class="nc">JSONB</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="nc">Empty</span><span class="w"> </span><span class="py">but</span><span class="w"> </span><span class="py">not</span><span class="w"> </span><span class="py">NULL</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="err">;</span><span class="w"> </span></span></span></code></pre></div> <h3 id="null-in-gql-queries" class="position-relative d-flex align-items-center group"> <span>NULL in GQL Queries</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="null-in-gql-queries" aria-haspopup="dialog" aria-label="Share link: NULL in GQL Queries"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="testing-for-null-values" class="position-relative d-flex align-items-center group"> <span>Testing for NULL Values</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="testing-for-null-values" aria-haspopup="dialog" aria-label="Share link: Testing for NULL Values"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>The only correct way to test for NULL is using <code>IS NULL</code> or <code>IS NOT NULL</code>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Find</span><span class="w"> </span><span class="py">people</span><span class="w"> </span><span class="py">without</span><span class="w"> </span><span class="py">middle</span><span class="w"> </span><span class="py">names</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">middle_name</span><span class="w"> </span><span class="py">IS</span><span class="w"> </span><span class="py">NULL</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">name</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Find</span><span class="w"> </span><span class="py">people</span><span class="w"> </span><span class="py">with</span><span class="w"> </span><span class="py">known</span><span class="w"> </span><span class="py">phone</span><span class="w"> </span><span class="py">numbers</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">phone</span><span class="w"> </span><span class="py">IS</span><span class="w"> </span><span class="py">NOT</span><span class="w"> </span><span class="py">NULL</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">name</span><span class="p">,</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">phone</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Find</span><span class="w"> </span><span class="py">current</span><span class="w"> </span><span class="py">employees</span><span class="w"> </span><span class="p">(</span><span class="py">no</span><span class="w"> </span><span class="py">end_date</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="err">-</span><span class="p">[</span><span class="py">e</span><span class="p">:</span><span class="nc">WORKS_FOR</span><span class="p">]</span><span class="err">-&gt;</span><span class="p">(</span><span class="py">c</span><span class="p">:</span><span class="nc">Company</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">e</span><span class="err">.</span><span class="py">end_date</span><span class="w"> </span><span class="py">IS</span><span class="w"> </span><span class="py">NULL</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">name</span><span class="p">,</span><span class="w"> </span><span class="py">c</span><span class="err">.</span><span class="py">name</span><span class="p">,</span><span class="w"> </span><span class="py">e</span><span class="err">.</span><span class="py">start_date</span><span class="err">;</span><span class="w"> </span></span></span></code></pre></div><p><strong>Common mistake</strong>: Using equality operators with NULL:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">WRONG</span><span class="p">:</span><span class="w"> </span><span class="nc">This</span><span class="w"> </span><span class="py">will</span><span class="w"> </span><span class="py">NEVER</span><span class="w"> </span><span class="py">match</span><span class="w"> </span><span class="py">anything</span><span class="p">,</span><span class="w"> </span><span class="py">even</span><span class="w"> </span><span class="py">NULL</span><span class="w"> </span><span class="py">values</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">middle_name</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">NULL</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Always</span><span class="w"> </span><span class="py">evaluates</span><span class="w"> </span><span class="py">to</span><span class="w"> </span><span class="py">NULL</span><span class="w"> </span><span class="p">(</span><span class="py">unknown</span><span class="p">),</span><span class="w"> </span><span class="py">never</span><span class="w"> </span><span class="py">TRUE</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">WRONG</span><span class="p">:</span><span class="w"> </span><span class="nc">This</span><span class="w"> </span><span class="py">also</span><span class="w"> </span><span class="py">doesn</span><span class="err">&#39;</span><span class="py">t</span><span class="w"> </span><span class="py">work</span><span class="w"> </span><span class="py">as</span><span class="w"> </span><span class="py">expected</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">middle_name</span><span class="w"> </span><span class="p">!=</span><span class="w"> </span><span class="py">NULL</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Also</span><span class="w"> </span><span class="py">always</span><span class="w"> </span><span class="py">NULL</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">;</span><span class="w"> </span></span></span></code></pre></div><p>Why? In three-valued logic, <code>NULL = NULL</code> is NULL (unknown), not TRUE. You can&rsquo;t compare unknown to unknown.</p> <h4 id="coalesce-providing-fallback-values" class="position-relative d-flex align-items-center group"> <span>COALESCE: Providing Fallback Values</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="coalesce-providing-fallback-values" aria-haspopup="dialog" aria-label="Share link: COALESCE: Providing Fallback Values"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>COALESCE returns the first non-NULL value from a list of expressions:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Use</span><span class="w"> </span><span class="py">nickname</span><span class="w"> </span><span class="py">if</span><span class="w"> </span><span class="py">available</span><span class="p">,</span><span class="w"> </span><span class="py">otherwise</span><span class="w"> </span><span class="py">use</span><span class="w"> </span><span class="py">formal</span><span class="w"> </span><span class="py">name</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">name</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">COALESCE</span><span class="p">(</span><span class="py">p</span><span class="err">.</span><span class="py">nickname</span><span class="p">,</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">name</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">display_name</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Multi</span><span class="err">-</span><span class="py">level</span><span class="w"> </span><span class="py">fallback</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">COALESCE</span><span class="p">(</span><span class="py">p</span><span class="err">.</span><span class="py">mobile_phone</span><span class="p">,</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">home_phone</span><span class="p">,</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">work_phone</span><span class="p">,</span><span class="w"> </span><span class="err">&#39;</span><span class="py">No</span><span class="w"> </span><span class="py">phone</span><span class="err">&#39;</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">contact_number</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Default</span><span class="w"> </span><span class="py">to</span><span class="w"> </span><span class="py">zero</span><span class="w"> </span><span class="py">for</span><span class="w"> </span><span class="py">calculations</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Product</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">name</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">base_price</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">COALESCE</span><span class="p">(</span><span class="py">p</span><span class="err">.</span><span class="py">discount_amount</span><span class="p">,</span><span class="w"> </span><span class="py">0</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">discount</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">base_price</span><span class="w"> </span><span class="err">-</span><span class="w"> </span><span class="py">COALESCE</span><span class="p">(</span><span class="py">p</span><span class="err">.</span><span class="py">discount_amount</span><span class="p">,</span><span class="w"> </span><span class="py">0</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">final_price</span><span class="err">;</span><span class="w"> </span></span></span></code></pre></div><p>Python client example:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># Python - COALESCE in queries</span> </span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">geode_client</span> <span class="kn">import</span> <span class="n">Client</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="n">client</span> <span class="o">=</span> <span class="n">Client</span><span class="p">(</span><span class="n">host</span><span class="o">=</span><span class="s2">&#34;localhost&#34;</span><span class="p">,</span> <span class="n">port</span><span class="o">=</span><span class="mi">3141</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="k">async</span> <span class="k">with</span> <span class="n">client</span><span class="o">.</span><span class="n">connection</span><span class="p">()</span> <span class="k">as</span> <span class="n">conn</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="c1"># Get user display names with fallback logic</span> </span></span><span class="line"><span class="cl"> <span class="n">result</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (u:User) </span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN </span></span></span><span class="line"><span class="cl"><span class="s2"> u.id, </span></span></span><span class="line"><span class="cl"><span class="s2"> COALESCE(u.display_name, u.username, u.email) AS name, </span></span></span><span class="line"><span class="cl"><span class="s2"> COALESCE(u.avatar_url, &#39;/default-avatar.png&#39;) AS avatar </span></span></span><span class="line"><span class="cl"><span class="s2"> ORDER BY name </span></span></span><span class="line"><span class="cl"><span class="s2"> &#34;&#34;&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">result</span><span class="o">.</span><span class="n">bindings</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;</span><span class="si">{</span><span class="n">row</span><span class="p">[</span><span class="s1">&#39;name&#39;</span><span class="p">]</span><span class="si">}</span><span class="s2"> - Avatar: </span><span class="si">{</span><span class="n">row</span><span class="p">[</span><span class="s1">&#39;avatar&#39;</span><span class="p">]</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span> </span></span></code></pre></div> <h4 id="nullif-converting-values-to-null" class="position-relative d-flex align-items-center group"> <span>NULLIF: Converting Values to NULL</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="nullif-converting-values-to-null" aria-haspopup="dialog" aria-label="Share link: NULLIF: Converting Values to NULL"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>NULLIF returns NULL if two expressions are equal, otherwise returns the first expression. Useful for treating specific values as NULL:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Treat</span><span class="w"> </span><span class="py">empty</span><span class="w"> </span><span class="py">strings</span><span class="w"> </span><span class="py">as</span><span class="w"> </span><span class="py">NULL</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">name</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">NULLIF</span><span class="p">(</span><span class="py">p</span><span class="err">.</span><span class="py">middle_name</span><span class="p">,</span><span class="w"> </span><span class="err">&#39;&#39;</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">middle_name</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">NULLIF</span><span class="p">(</span><span class="py">p</span><span class="err">.</span><span class="py">phone</span><span class="p">,</span><span class="w"> </span><span class="err">&#39;</span><span class="py">N</span><span class="err">/</span><span class="py">A</span><span class="err">&#39;</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">phone</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Treat</span><span class="w"> </span><span class="py">zero</span><span class="w"> </span><span class="py">as</span><span class="w"> </span><span class="py">NULL</span><span class="w"> </span><span class="py">for</span><span class="w"> </span><span class="py">optional</span><span class="w"> </span><span class="py">numeric</span><span class="w"> </span><span class="py">fields</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Product</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">name</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">NULLIF</span><span class="p">(</span><span class="py">p</span><span class="err">.</span><span class="py">discount_pct</span><span class="p">,</span><span class="w"> </span><span class="py">0</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">discount</span><span class="err">;</span><span class="w"> </span></span></span></code></pre></div><p>Combined with COALESCE:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Normalize</span><span class="w"> </span><span class="py">empty</span><span class="w"> </span><span class="py">strings</span><span class="w"> </span><span class="py">to</span><span class="w"> </span><span class="py">NULL</span><span class="p">,</span><span class="w"> </span><span class="py">then</span><span class="w"> </span><span class="py">provide</span><span class="w"> </span><span class="py">default</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">COALESCE</span><span class="p">(</span><span class="py">NULLIF</span><span class="p">(</span><span class="py">p</span><span class="err">.</span><span class="py">bio</span><span class="p">,</span><span class="w"> </span><span class="err">&#39;&#39;</span><span class="p">),</span><span class="w"> </span><span class="err">&#39;</span><span class="py">No</span><span class="w"> </span><span class="py">bio</span><span class="w"> </span><span class="py">provided</span><span class="err">&#39;</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">bio</span><span class="err">;</span><span class="w"> </span></span></span></code></pre></div> <h3 id="null-in-comparisons-and-three-valued-logic" class="position-relative d-flex align-items-center group"> <span>NULL in Comparisons and Three-Valued Logic</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="null-in-comparisons-and-three-valued-logic" aria-haspopup="dialog" aria-label="Share link: NULL in Comparisons and Three-Valued Logic"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3><p>Geode implements three-valued logic (TRUE, FALSE, NULL) for all boolean expressions. Understanding this is crucial for correct query behavior.</p> <h4 id="comparison-truth-table" class="position-relative d-flex align-items-center group"> <span>Comparison Truth Table</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="comparison-truth-table" aria-haspopup="dialog" aria-label="Share link: Comparison Truth Table"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><table> <thead> <tr> <th>Expression</th> <th>p.age IS NULL</th> <th>p.age IS NOT NULL</th> </tr> </thead> <tbody> <tr> <td><code>p.age = 25</code></td> <td>NULL</td> <td>TRUE or FALSE</td> </tr> <tr> <td><code>p.age &gt; 18</code></td> <td>NULL</td> <td>TRUE or FALSE</td> </tr> <tr> <td><code>p.age IS NULL</code></td> <td>TRUE</td> <td>FALSE</td> </tr> </tbody> </table> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Three</span><span class="err">-</span><span class="py">valued</span><span class="w"> </span><span class="py">logic</span><span class="w"> </span><span class="py">in</span><span class="w"> </span><span class="py">action</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">age</span><span class="w"> </span><span class="err">&gt;</span><span class="w"> </span><span class="py">18</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Excludes</span><span class="w"> </span><span class="py">NULL</span><span class="w"> </span><span class="py">ages</span><span class="w"> </span><span class="p">(</span><span class="py">NULL</span><span class="w"> </span><span class="err">&gt;</span><span class="w"> </span><span class="py">18</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">NULL</span><span class="p">,</span><span class="w"> </span><span class="py">not</span><span class="w"> </span><span class="py">TRUE</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">name</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Include</span><span class="w"> </span><span class="py">people</span><span class="w"> </span><span class="py">with</span><span class="w"> </span><span class="py">unknown</span><span class="w"> </span><span class="py">age</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">age</span><span class="w"> </span><span class="err">&gt;</span><span class="w"> </span><span class="py">18</span><span class="w"> </span><span class="py">OR</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">age</span><span class="w"> </span><span class="py">IS</span><span class="w"> </span><span class="py">NULL</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">name</span><span class="p">,</span><span class="w"> </span><span class="py">COALESCE</span><span class="p">(</span><span class="py">p</span><span class="err">.</span><span class="py">age</span><span class="p">,</span><span class="w"> </span><span class="err">&#39;</span><span class="py">Unknown</span><span class="err">&#39;</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">age</span><span class="err">;</span><span class="w"> </span></span></span></code></pre></div> <h4 id="null-propagation-in-expressions" class="position-relative d-flex align-items-center group"> <span>NULL Propagation in Expressions</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="null-propagation-in-expressions" aria-haspopup="dialog" aria-label="Share link: NULL Propagation in Expressions"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>NULL propagates through most expressions:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">name</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">age</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">age</span><span class="w"> </span><span class="err">+</span><span class="w"> </span><span class="py">5</span><span class="p">,</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">NULL</span><span class="w"> </span><span class="py">if</span><span class="w"> </span><span class="py">age</span><span class="w"> </span><span class="py">is</span><span class="w"> </span><span class="py">NULL</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">age</span><span class="w"> </span><span class="err">*</span><span class="w"> </span><span class="py">1</span><span class="mf">.1</span><span class="p">,</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">NULL</span><span class="w"> </span><span class="py">if</span><span class="w"> </span><span class="py">age</span><span class="w"> </span><span class="py">is</span><span class="w"> </span><span class="py">NULL</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">age</span><span class="w"> </span><span class="err">&gt;</span><span class="w"> </span><span class="py">18</span><span class="p">,</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">NULL</span><span class="w"> </span><span class="py">if</span><span class="w"> </span><span class="py">age</span><span class="w"> </span><span class="py">is</span><span class="w"> </span><span class="py">NULL</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">first_name</span><span class="w"> </span><span class="p">||</span><span class="w"> </span><span class="err">&#39;</span><span class="w"> </span><span class="err">&#39;</span><span class="w"> </span><span class="p">||</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">middle_name</span><span class="w"> </span><span class="p">||</span><span class="w"> </span><span class="err">&#39;</span><span class="w"> </span><span class="err">&#39;</span><span class="w"> </span><span class="p">||</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">last_name</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">NULL</span><span class="w"> </span><span class="py">if</span><span class="w"> </span><span class="py">any</span><span class="w"> </span><span class="py">part</span><span class="w"> </span><span class="py">is</span><span class="w"> </span><span class="py">NULL</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">;</span><span class="w"> </span></span></span></code></pre></div><p>Safe string concatenation:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Handles</span><span class="w"> </span><span class="py">NULL</span><span class="w"> </span><span class="py">middle</span><span class="w"> </span><span class="py">names</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">first_name</span><span class="w"> </span><span class="p">||</span><span class="w"> </span><span class="err">&#39;</span><span class="w"> </span><span class="err">&#39;</span><span class="w"> </span><span class="p">||</span><span class="w"> </span><span class="py">COALESCE</span><span class="p">(</span><span class="py">p</span><span class="err">.</span><span class="py">middle_name</span><span class="w"> </span><span class="p">||</span><span class="w"> </span><span class="err">&#39;</span><span class="w"> </span><span class="err">&#39;</span><span class="p">,</span><span class="w"> </span><span class="err">&#39;&#39;</span><span class="p">)</span><span class="w"> </span><span class="p">||</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">last_name</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">full_name</span><span class="err">;</span><span class="w"> </span></span></span></code></pre></div> <h3 id="null-in-aggregations" class="position-relative d-flex align-items-center group"> <span>NULL in Aggregations</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="null-in-aggregations" aria-haspopup="dialog" aria-label="Share link: NULL in Aggregations"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3><p>Aggregate functions (except COUNT(*)) ignore NULL values:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">These</span><span class="w"> </span><span class="py">ignore</span><span class="w"> </span><span class="py">NULL</span><span class="w"> </span><span class="py">values</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">COUNT</span><span class="p">(</span><span class="err">*</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">total_people</span><span class="p">,</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Counts</span><span class="w"> </span><span class="py">all</span><span class="w"> </span><span class="py">nodes</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">COUNT</span><span class="p">(</span><span class="py">p</span><span class="err">.</span><span class="py">age</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">people_with_age</span><span class="p">,</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Counts</span><span class="w"> </span><span class="py">non</span><span class="err">-</span><span class="py">NULL</span><span class="w"> </span><span class="py">ages</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">AVG</span><span class="p">(</span><span class="py">p</span><span class="err">.</span><span class="py">age</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">average_age</span><span class="p">,</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Average</span><span class="w"> </span><span class="py">of</span><span class="w"> </span><span class="py">non</span><span class="err">-</span><span class="py">NULL</span><span class="w"> </span><span class="py">ages</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">MIN</span><span class="p">(</span><span class="py">p</span><span class="err">.</span><span class="py">age</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">youngest</span><span class="p">,</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Minimum</span><span class="w"> </span><span class="py">non</span><span class="err">-</span><span class="py">NULL</span><span class="w"> </span><span class="py">age</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">MAX</span><span class="p">(</span><span class="py">p</span><span class="err">.</span><span class="py">age</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">oldest</span><span class="err">;</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Maximum</span><span class="w"> </span><span class="py">non</span><span class="err">-</span><span class="py">NULL</span><span class="w"> </span><span class="py">age</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Count</span><span class="w"> </span><span class="py">NULL</span><span class="w"> </span><span class="py">values</span><span class="w"> </span><span class="py">explicitly</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">COUNT</span><span class="p">(</span><span class="err">*</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">total</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">COUNT</span><span class="p">(</span><span class="py">p</span><span class="err">.</span><span class="py">phone</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">with_phone</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">COUNT</span><span class="p">(</span><span class="err">*</span><span class="p">)</span><span class="w"> </span><span class="err">-</span><span class="w"> </span><span class="py">COUNT</span><span class="p">(</span><span class="py">p</span><span class="err">.</span><span class="py">phone</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">without_phone</span><span class="err">;</span><span class="w"> </span></span></span></code></pre></div><p>Go client example:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// Go client - handling NULL in aggregations </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kn">package</span> <span class="nx">main</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="s">&#34;context&#34;</span> </span></span><span class="line"><span class="cl"> <span class="s">&#34;database/sql&#34;</span> </span></span><span class="line"><span class="cl"> <span class="s">&#34;fmt&#34;</span> </span></span><span class="line"><span class="cl"> <span class="s">&#34;geodedb.com/geode&#34;</span> </span></span><span class="line"><span class="cl"><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="kd">func</span> <span class="nf">analyzeUserData</span><span class="p">(</span><span class="nx">ctx</span> <span class="nx">context</span><span class="p">.</span><span class="nx">Context</span><span class="p">,</span> <span class="nx">db</span> <span class="o">*</span><span class="nx">geode</span><span class="p">.</span><span class="nx">DB</span><span class="p">)</span> <span class="kt">error</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kd">var</span> <span class="nx">total</span><span class="p">,</span> <span class="nx">withAge</span><span class="p">,</span> <span class="nx">avgAge</span> <span class="nx">sql</span><span class="p">.</span><span class="nx">NullFloat64</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">db</span><span class="p">.</span><span class="nf">QueryRowContext</span><span class="p">(</span><span class="nx">ctx</span><span class="p">,</span> <span class="s">` </span></span></span><span class="line"><span class="cl"><span class="s"> MATCH (u:User) </span></span></span><span class="line"><span class="cl"><span class="s"> RETURN </span></span></span><span class="line"><span class="cl"><span class="s"> COUNT(*) AS total, </span></span></span><span class="line"><span class="cl"><span class="s"> COUNT(u.age) AS with_age, </span></span></span><span class="line"><span class="cl"><span class="s"> AVG(u.age) AS avg_age </span></span></span><span class="line"><span class="cl"><span class="s"> `</span><span class="p">).</span><span class="nf">Scan</span><span class="p">(</span><span class="o">&amp;</span><span class="nx">total</span><span class="p">,</span> <span class="o">&amp;</span><span class="nx">withAge</span><span class="p">,</span> <span class="o">&amp;</span><span class="nx">avgAge</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">err</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;Total users: %.0f\n&#34;</span><span class="p">,</span> <span class="nx">total</span><span class="p">.</span><span class="nx">Float64</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;Users with age: %.0f\n&#34;</span><span class="p">,</span> <span class="nx">withAge</span><span class="p">.</span><span class="nx">Float64</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">avgAge</span><span class="p">.</span><span class="nx">Valid</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;Average age: %.1f\n&#34;</span><span class="p">,</span> <span class="nx">avgAge</span><span class="p">.</span><span class="nx">Float64</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;Average age: No data&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="kc">nil</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></div> <h3 id="null-in-sorting" class="position-relative d-flex align-items-center group"> <span>NULL in Sorting</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="null-in-sorting" aria-haspopup="dialog" aria-label="Share link: NULL in Sorting"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3><p>NULL values require explicit handling in ORDER BY clauses:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">NULL</span><span class="w"> </span><span class="py">values</span><span class="w"> </span><span class="py">sort</span><span class="w"> </span><span class="py">last</span><span class="w"> </span><span class="py">by</span><span class="w"> </span><span class="py">default</span><span class="w"> </span><span class="p">(</span><span class="py">in</span><span class="w"> </span><span class="py">ascending</span><span class="w"> </span><span class="py">order</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">name</span><span class="p">,</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">age</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">age</span><span class="w"> </span><span class="py">ASC</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">NULL</span><span class="w"> </span><span class="py">values</span><span class="w"> </span><span class="py">first</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">name</span><span class="p">,</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">age</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">age</span><span class="w"> </span><span class="py">ASC</span><span class="w"> </span><span class="py">NULLS</span><span class="w"> </span><span class="py">FIRST</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">NULL</span><span class="w"> </span><span class="py">values</span><span class="w"> </span><span class="py">last</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">name</span><span class="p">,</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">age</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">age</span><span class="w"> </span><span class="py">DESC</span><span class="w"> </span><span class="py">NULLS</span><span class="w"> </span><span class="py">LAST</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Use</span><span class="w"> </span><span class="py">COALESCE</span><span class="w"> </span><span class="py">to</span><span class="w"> </span><span class="py">control</span><span class="w"> </span><span class="py">NULL</span><span class="w"> </span><span class="py">sorting</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">name</span><span class="p">,</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">age</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">COALESCE</span><span class="p">(</span><span class="py">p</span><span class="err">.</span><span class="py">age</span><span class="p">,</span><span class="w"> </span><span class="py">999</span><span class="p">)</span><span class="w"> </span><span class="py">ASC</span><span class="err">;</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Treat</span><span class="w"> </span><span class="py">NULL</span><span class="w"> </span><span class="py">as</span><span class="w"> </span><span class="py">999</span><span class="w"> </span></span></span></code></pre></div> <h3 id="application-level-null-handling" class="position-relative d-flex align-items-center group"> <span>Application-Level NULL Handling</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="application-level-null-handling" aria-haspopup="dialog" aria-label="Share link: Application-Level NULL Handling"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="rust-client-with-option-types" class="position-relative d-flex align-items-center group"> <span>Rust Client with Option Types</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="rust-client-with-option-types" aria-haspopup="dialog" aria-label="Share link: Rust Client with Option Types"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="c1">// Rust client - type-safe NULL handling with Option&lt;T&gt; </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">use</span><span class="w"> </span><span class="n">geode_client</span>::<span class="p">{</span><span class="n">Client</span><span class="p">,</span><span class="w"> </span><span class="n">Value</span><span class="p">};</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">use</span><span class="w"> </span><span class="n">std</span>::<span class="n">collections</span>::<span class="n">HashMap</span><span class="p">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="cp">#[derive(Debug)]</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">struct</span> <span class="nc">Person</span><span class="w"> </span><span class="p">{</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">id</span>: <span class="nb">String</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">name</span>: <span class="nb">String</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">middle_name</span>: <span class="nb">Option</span><span class="o">&lt;</span><span class="nb">String</span><span class="o">&gt;</span><span class="p">,</span><span class="w"> </span><span class="c1">// NULL maps to None </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="n">age</span>: <span class="nb">Option</span><span class="o">&lt;</span><span class="kt">i32</span><span class="o">&gt;</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">phone</span>: <span class="nb">Option</span><span class="o">&lt;</span><span class="nb">String</span><span class="o">&gt;</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">async</span><span class="w"> </span><span class="k">fn</span> <span class="nf">get_person</span><span class="p">(</span><span class="n">client</span>: <span class="kp">&amp;</span><span class="nc">Client</span><span class="p">,</span><span class="w"> </span><span class="n">id</span>: <span class="kp">&amp;</span><span class="kt">str</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nb">Result</span><span class="o">&lt;</span><span class="n">Person</span><span class="p">,</span><span class="w"> </span><span class="n">geode_client</span>::<span class="n">Error</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">params</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">HashMap</span>::<span class="n">new</span><span class="p">();</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">params</span><span class="p">.</span><span class="n">insert</span><span class="p">(</span><span class="s">&#34;id&#34;</span><span class="p">,</span><span class="w"> </span><span class="n">Value</span>::<span class="nb">String</span><span class="p">(</span><span class="n">id</span><span class="p">.</span><span class="n">to_string</span><span class="p">()));</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">result</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">client</span><span class="p">.</span><span class="n">execute</span><span class="p">(</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="s">&#34;MATCH (p:Person {id: $id}) RETURN p.id, p.name, p.middle_name, p.age, p.phone&#34;</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="o">&amp;</span><span class="n">params</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">).</span><span class="k">await</span><span class="o">?</span><span class="p">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">row</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">result</span><span class="p">.</span><span class="n">bindings</span><span class="p">.</span><span class="n">first</span><span class="p">().</span><span class="n">ok_or</span><span class="p">(</span><span class="n">geode_client</span>::<span class="n">Error</span>::<span class="n">NotFound</span><span class="p">)</span><span class="o">?</span><span class="p">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Ok</span><span class="p">(</span><span class="n">Person</span><span class="w"> </span><span class="p">{</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">id</span>: <span class="nc">row</span><span class="p">[</span><span class="s">&#34;p.id&#34;</span><span class="p">].</span><span class="n">as_str</span><span class="p">().</span><span class="n">unwrap</span><span class="p">().</span><span class="n">to_string</span><span class="p">(),</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">name</span>: <span class="nc">row</span><span class="p">[</span><span class="s">&#34;p.name&#34;</span><span class="p">].</span><span class="n">as_str</span><span class="p">().</span><span class="n">unwrap</span><span class="p">().</span><span class="n">to_string</span><span class="p">(),</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">middle_name</span>: <span class="nc">row</span><span class="p">[</span><span class="s">&#34;p.middle_name&#34;</span><span class="p">].</span><span class="n">as_str</span><span class="p">().</span><span class="n">map</span><span class="p">(</span><span class="nb">String</span>::<span class="n">from</span><span class="p">),</span><span class="w"> </span><span class="c1">// NULL → None </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="n">age</span>: <span class="nc">row</span><span class="p">[</span><span class="s">&#34;p.age&#34;</span><span class="p">].</span><span class="n">as_i64</span><span class="p">().</span><span class="n">map</span><span class="p">(</span><span class="o">|</span><span class="n">i</span><span class="o">|</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="kt">i32</span><span class="p">),</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">phone</span>: <span class="nc">row</span><span class="p">[</span><span class="s">&#34;p.phone&#34;</span><span class="p">].</span><span class="n">as_str</span><span class="p">().</span><span class="n">map</span><span class="p">(</span><span class="nb">String</span>::<span class="n">from</span><span class="p">),</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">})</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">fn</span> <span class="nf">format_full_name</span><span class="p">(</span><span class="n">person</span>: <span class="kp">&amp;</span><span class="nc">Person</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nb">String</span> <span class="p">{</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">match</span><span class="w"> </span><span class="o">&amp;</span><span class="n">person</span><span class="p">.</span><span class="n">middle_name</span><span class="w"> </span><span class="p">{</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Some</span><span class="p">(</span><span class="n">middle</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="fm">format!</span><span class="p">(</span><span class="s">&#34;</span><span class="si">{}</span><span class="s"> </span><span class="si">{}</span><span class="s"> </span><span class="si">{}</span><span class="s">&#34;</span><span class="p">,</span><span class="w"> </span><span class="n">person</span><span class="p">.</span><span class="n">name</span><span class="p">,</span><span class="w"> </span><span class="n">middle</span><span class="p">,</span><span class="w"> </span><span class="n">person</span><span class="p">.</span><span class="n">name</span><span class="p">),</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">None</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="n">person</span><span class="p">.</span><span class="n">name</span><span class="p">.</span><span class="n">clone</span><span class="p">(),</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w"> </span></span></span></code></pre></div> <h4 id="python-client-with-none" class="position-relative d-flex align-items-center group"> <span>Python Client with None</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="python-client-with-none" aria-haspopup="dialog" aria-label="Share link: Python Client with None"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># Python - NULL handling with None</span> </span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">typing</span> <span class="kn">import</span> <span class="n">Optional</span> </span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">dataclasses</span> <span class="kn">import</span> <span class="n">dataclass</span> </span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">geode_client</span> <span class="kn">import</span> <span class="n">Client</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="nd">@dataclass</span> </span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">User</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="nb">id</span><span class="p">:</span> <span class="nb">str</span> </span></span><span class="line"><span class="cl"> <span class="n">email</span><span class="p">:</span> <span class="nb">str</span> </span></span><span class="line"><span class="cl"> <span class="n">phone</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span> </span></span><span class="line"><span class="cl"> <span class="n">bio</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span> </span></span><span class="line"><span class="cl"> <span class="n">last_login</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">create_user</span><span class="p">(</span><span class="n">client</span><span class="p">:</span> <span class="n">Client</span><span class="p">,</span> <span class="n">email</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">phone</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;&#34;&#34;Create user with optional phone number.&#34;&#34;&#34;</span> </span></span><span class="line"><span class="cl"> <span class="n">params</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&#34;email&#34;</span><span class="p">:</span> <span class="n">email</span><span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="n">phone</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="n">params</span><span class="p">[</span><span class="s2">&#34;phone&#34;</span><span class="p">]</span> <span class="o">=</span> <span class="n">phone</span> </span></span><span class="line"><span class="cl"> <span class="n">query</span> <span class="o">=</span> <span class="s2">&#34;INSERT (u:User {email: $email, phone: $phone}) RETURN u&#34;</span> </span></span><span class="line"><span class="cl"> <span class="k">else</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="n">query</span> <span class="o">=</span> <span class="s2">&#34;INSERT (u:User {email: $email}) RETURN u&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="n">result</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="n">client</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="n">query</span><span class="p">,</span> <span class="n">params</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">result</span><span class="o">.</span><span class="n">bindings</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="s2">&#34;u&#34;</span><span class="p">]</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">get_contact_info</span><span class="p">(</span><span class="n">client</span><span class="p">:</span> <span class="n">Client</span><span class="p">,</span> <span class="n">user_id</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;&#34;&#34;Get contact info with NULL-safe formatting.&#34;&#34;&#34;</span> </span></span><span class="line"><span class="cl"> <span class="n">result</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="n">client</span><span class="o">.</span><span class="n">query</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;MATCH (u:User {id: $id}) RETURN u.email, u.phone&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span><span class="s2">&#34;id&#34;</span><span class="p">:</span> <span class="n">user_id</span><span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="n">row</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">bindings</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> </span></span><span class="line"><span class="cl"> <span class="n">email</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="s2">&#34;u.email&#34;</span><span class="p">]</span> </span></span><span class="line"><span class="cl"> <span class="n">phone</span> <span class="o">=</span> <span class="n">row</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&#34;u.phone&#34;</span><span class="p">)</span> <span class="c1"># May be None</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="n">phone</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="sa">f</span><span class="s2">&#34;</span><span class="si">{</span><span class="n">email</span><span class="si">}</span><span class="s2"> (Phone: </span><span class="si">{</span><span class="n">phone</span><span class="si">}</span><span class="s2">)&#34;</span> </span></span><span class="line"><span class="cl"> <span class="k">else</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="sa">f</span><span class="s2">&#34;</span><span class="si">{</span><span class="n">email</span><span class="si">}</span><span class="s2"> (No phone)&#34;</span> </span></span></code></pre></div> <h3 id="best-practices-for-null-handling" class="position-relative d-flex align-items-center group"> <span>Best Practices for NULL Handling</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="best-practices-for-null-handling" aria-haspopup="dialog" aria-label="Share link: Best Practices for NULL Handling"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3><ol> <li><strong>Explicit Nullability</strong>: Always declare whether properties can be NULL in schema</li> <li><strong>NOT NULL by Default for Key Properties</strong>: IDs, timestamps, required business fields</li> <li><strong>Use COALESCE for Display</strong>: Provide fallback values in user-facing queries</li> <li><strong>Document NULL Semantics</strong>: Explain what NULL means for each nullable property</li> <li><strong>Test NULL Cases</strong>: Write tests for NULL value handling in queries</li> <li><strong>Avoid NULL in Calculations</strong>: Use COALESCE to provide numeric defaults</li> <li><strong>Prefer DEFAULT over NULL</strong>: When sensible defaults exist, use them</li> <li><strong>Type-Safe Clients</strong>: Use Option<T> (Rust), Optional (Python), sql.NullString (Go)</li> </ol> <h3 id="common-anti-patterns" class="position-relative d-flex align-items-center group"> <span>Common Anti-Patterns</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="common-anti-patterns" aria-haspopup="dialog" aria-label="Share link: Common Anti-Patterns"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3><p><strong>Anti-pattern</strong>: Using empty strings instead of NULL</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">BAD</span><span class="p">:</span><span class="w"> </span><span class="nc">Empty</span><span class="w"> </span><span class="py">string</span><span class="w"> </span><span class="py">is</span><span class="w"> </span><span class="py">not</span><span class="w"> </span><span class="py">NULL</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">UPDATE</span><span class="w"> </span><span class="py">Person</span><span class="w"> </span><span class="py">SET</span><span class="w"> </span><span class="py">middle_name</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="err">&#39;&#39;</span><span class="w"> </span><span class="py">WHERE</span><span class="w"> </span><span class="py">id</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="err">&#39;</span><span class="py">123</span><span class="err">&#39;;</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Use</span><span class="w"> </span><span class="py">NULL</span><span class="w"> </span><span class="py">instead</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">GOOD</span><span class="p">:</span><span class="w"> </span><span class="nc">NULL</span><span class="w"> </span><span class="py">represents</span><span class="w"> </span><span class="py">absence</span><span class="w"> </span><span class="py">of</span><span class="w"> </span><span class="py">middle</span><span class="w"> </span><span class="py">name</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">UPDATE</span><span class="w"> </span><span class="py">Person</span><span class="w"> </span><span class="py">SET</span><span class="w"> </span><span class="py">middle_name</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">NULL</span><span class="w"> </span><span class="py">WHERE</span><span class="w"> </span><span class="py">id</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="err">&#39;</span><span class="py">123</span><span class="err">&#39;;</span><span class="w"> </span></span></span></code></pre></div><p><strong>Anti-pattern</strong>: Comparing with NULL using <code>=</code></p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">BAD</span><span class="p">:</span><span class="w"> </span><span class="nc">Never</span><span class="w"> </span><span class="py">TRUE</span><span class="p">,</span><span class="w"> </span><span class="py">always</span><span class="w"> </span><span class="py">NULL</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">middle_name</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">NULL</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">GOOD</span><span class="p">:</span><span class="w"> </span><span class="nc">Use</span><span class="w"> </span><span class="py">IS</span><span class="w"> </span><span class="py">NULL</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">middle_name</span><span class="w"> </span><span class="py">IS</span><span class="w"> </span><span class="py">NULL</span><span class="w"> </span></span></span></code></pre></div><p><strong>Anti-pattern</strong>: Ignoring NULL in business logic</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># BAD: age might be None, causing TypeError</span> </span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">is_adult</span><span class="p">(</span><span class="n">person</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">person</span><span class="o">.</span><span class="n">age</span> <span class="o">&gt;=</span> <span class="mi">18</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># GOOD: Handle NULL explicitly</span> </span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">is_adult</span><span class="p">(</span><span class="n">person</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">person</span><span class="o">.</span><span class="n">age</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">person</span><span class="o">.</span><span class="n">age</span> <span class="o">&gt;=</span> <span class="mi">18</span> </span></span></code></pre></div> <h3 id="troubleshooting" class="position-relative d-flex align-items-center group"> <span>Troubleshooting</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="troubleshooting" aria-haspopup="dialog" aria-label="Share link: Troubleshooting"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3><p><strong>Query returns no results despite data existing</strong>: Check for NULL comparisons using <code>=</code> instead of <code>IS NULL</code></p> <p><strong>Aggregations showing unexpected results</strong>: Remember that COUNT, SUM, AVG ignore NULL values</p> <p><strong>String concatenation producing NULL</strong>: Use COALESCE to handle NULL components</p> <p><strong>Type errors in application</strong>: Ensure client code handles NULL with appropriate types (Option, Optional, Nullable)</p> <h3 id="related-topics" class="position-relative d-flex align-items-center group"> <span>Related Topics</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="related-topics" aria-haspopup="dialog" aria-label="Share link: Related Topics"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3><ul> <li><a href="/tags/defaults" >Defaults</a> - Default values as alternative to NULL</li> <li><a href="/tags/constraints" >Constraints</a> - NOT NULL constraints and schema rules</li> <li><a href="/tags/validation" >Validation</a> - Validating optional vs required data</li> <li><a href="/tags/data-quality" >Data Quality</a> - Managing data completeness</li> <li><a href="/tags/schema/" >Schemas</a> - Schema design with nullability</li> <li><a href="/tags/gql" >GQL</a> - GQL standard three-valued logic semantics</li> </ul>

Related Articles

No articles found with this tag yet.

Back to Home