Hacker DirectoryHacker Directory
Öğrenmeye devam et
ENHTML kaydet ↓

WEB / WEB-18.S01

SQL ve NoSQL’de query/data ayrımı

Public catalog’da typed intent’in, uygulamanın seçtiği query’nin ve projection sonucu verinin sahiplerini izle.

CORE · RED · BLUE · ARTIFACT · PRACTICE

1. Core · Mekanizma

Hareket olmadan bütün senaryoları oku

Bağlanan SQL title

  1. Catalog isteği hazır

    Caller’ın catalog intent’i backend=sql; title=O'Reilly; sort=id değerlerini taşır. Query builder bu alanları doğrulayacaktır; statement/filter veya tamamlanmış row sonucu henüz yoktur.

    Girdi bilgileri
    backend=sql; title=O'Reilly; sort=id
    Query builder
    Query contract yok
    Data owner
    Arama yok; count=0
    Sonuç görünümü
    Sonuç yok
  2. Field type kararı

    Closed backend/title/sort field set’i, izinli backend enum’u ve scalar title koşulu geçer. Title 1–40 code point sınırındadır; sort’un türü string olsa da izinli değeri sonraki aşamada kontrol edilir.

    Girdi bilgileri
    backend=sql; title=O'Reilly; sort=id
    Query builder
    Alan türleri doğrulandı
    Data owner
    Arama yok; count=0
    Sonuç görünümü
    Sonuç yok
  3. Query contract seçimi

    sort=id, uygulamanın sabit by-id SELECT’ini seçer. title ve visibility için bound tuple O'Reilly/public’tir; bu değerler statement syntax’ına birleştirilmez.

    Girdi bilgileri
    backend=sql; title=O'Reilly; sort=id
    Query builder
    by-id + bağlanan değerler
    Data owner
    Arama yok; count=0
    Sonuç görünümü
    Sonuç yok
  4. Local lookup kararı

    Local SQLite SELECT tamamlanır: title=O'Reilly ve visibility=public koşulları id=2 kaydını bulur; queries=1 olur. Seed data değişmez, result view henüz projection’ı tüketmemiştir.

    Girdi bilgileri
    backend=sql; title=O'Reilly; sort=id
    Query builder
    by-id + bağlanan değerler
    Data owner
    Arama tamam; count=1; rows=1
    Sonuç görünümü
    Sonuç yok
  5. Projection hazır

    Tamamlanan aramanın row’ları yalnız id/title projection’ına alınır. Reddedilen dalda rows null kalır; consumer henüz sonuç göstermez.

    Girdi bilgileri
    backend=sql; title=O'Reilly; sort=id
    Query builder
    by-id + bağlanan değerler
    Data owner
    Projection tamam; rows=1; count=1
    Sonuç görünümü
    Sonuç yok
  6. Sonuç görünümü kararı

    Görünüm yalnız projection’ı tamamlanmış sonucu kullanır. Reddedilen işlem, başarı veya eşleşmeyen arama gibi gösterilmez; başlangıç verisi değişmez.

    Girdi bilgileri
    backend=sql; title=O'Reilly; sort=id
    Query builder
    by-id + bağlanan değerler
    Data owner
    Projection tamam; rows=1; count=1
    Sonuç görünümü
    Public sonuç: id=2, title=O'Reilly

Scalar filter

  1. Catalog isteği hazır

    Caller’ın catalog intent’i backend=document; title=Tea; sort=id değerlerini taşır. Query builder bu alanları doğrulayacaktır; statement/filter veya tamamlanmış row sonucu henüz yoktur.

    Girdi bilgileri
    backend=document; title=Tea; sort=id
    Query builder
    Query contract yok
    Data owner
    Arama yok; count=0
    Sonuç görünümü
    Sonuç yok
  2. Field type kararı

    Closed backend/title/sort field set’i, izinli backend enum’u ve scalar title koşulu geçer. Title 1–40 code point sınırındadır; sort’un türü string olsa da izinli değeri sonraki aşamada kontrol edilir.

    Girdi bilgileri
    backend=document; title=Tea; sort=id
    Query builder
    Alan türleri doğrulandı
    Data owner
    Arama yok; count=0
    Sonuç görünümü
    Sonuç yok
  3. Query contract seçimi

    Uygulama kabul edilen Tea string’inden {title:Tea,visibility:public} equality filter’ını oluşturur ve sort=id seçer. Caller object’i filter olarak kopyalanmaz; bu dar matcher MongoDB değildir.

    Girdi bilgileri
    backend=document; title=Tea; sort=id
    Query builder
    Scalar public filter
    Data owner
    Arama yok; count=0
    Sonuç görünümü
    Sonuç yok
  4. Local lookup kararı

    Yerel literal matcher, title=Tea ve visibility=public için id=1 ile id=3 kayıtlarını bulur ve id sırasına koyar. queries=1 ve iki eşleşme vardır; view henüz bu sonucu kullanmaz.

    Girdi bilgileri
    backend=document; title=Tea; sort=id
    Query builder
    Scalar public filter
    Data owner
    Arama tamam; count=1; rows=2
    Sonuç görünümü
    Sonuç yok
  5. Projection hazır

    Tamamlanan aramanın row’ları yalnız id/title projection’ına alınır. Reddedilen dalda rows null kalır; consumer henüz sonuç göstermez.

    Girdi bilgileri
    backend=document; title=Tea; sort=id
    Query builder
    Scalar public filter
    Data owner
    Projection tamam; rows=2; count=1
    Sonuç görünümü
    Sonuç yok
  6. Sonuç görünümü kararı

    Görünüm yalnız projection’ı tamamlanmış sonucu kullanır. Reddedilen işlem, başarı veya eşleşmeyen arama gibi gösterilmez; başlangıç verisi değişmez.

    Girdi bilgileri
    backend=document; title=Tea; sort=id
    Query builder
    Scalar public filter
    Data owner
    Projection tamam; rows=2; count=1
    Sonuç görünümü
    Public sonuç: Tea, id=1 ve id=3

Object title

  1. Catalog isteği hazır

    Caller’ın catalog intent’i backend=document; title={display:Tea}; sort=id değerlerini taşır. Query builder bu alanları doğrulayacaktır; statement/filter veya tamamlanmış row sonucu henüz yoktur.

    Girdi bilgileri
    backend=document; title={display:Tea}; sort=id
    Query builder
    Query contract yok
    Data owner
    Arama yok; count=0
    Sonuç görünümü
    Sonuç yok
  2. Field type kararı

    title={display:Tea} geçerli plain object olabilir, fakat title:string koşulunu sağlamaz. Reason field-type olur; sort kontrolü, query factory ve data-owner lookup başlatılmaz.

    Girdi bilgileri
    backend=document; title={display:Tea}; sort=id
    Query builder
    Reddedildi: field-type
    Data owner
    Arama yok; count=0
    Sonuç görünümü
    Sonuç yok
  3. Query contract seçimi

    Tür kabul edildikten sonra sort enum seçilir. Bilinmeyen sort için statement üretilmez; tür kontrolü başarısızsa sort değerlendirilmez.

    Girdi bilgileri
    backend=document; title={display:Tea}; sort=id
    Query builder
    Sort değerlendirilmedi
    Data owner
    Arama yok; count=0
    Sonuç görünümü
    Sonuç yok
  4. Local lookup kararı

    Bu ret dalında SQLite driver veya literal document matcher çağrılmaz. queries=0, gerçekten çalışmış bir query’nin boş sonucu değildir; daha önceki sonuç bu intent’e aktarılmaz.

    Girdi bilgileri
    backend=document; title={display:Tea}; sort=id
    Query builder
    Sort değerlendirilmedi
    Data owner
    Arama yok; count=0
    Sonuç görünümü
    Sonuç yok
  5. Projection yapılmadı

    Lookup yapılmadığından projection üretilemez; rows=null kalır. Kabul edilip Bread için eşleşmeyen query’nin rows=[] sonucuyla farklıdır; seed data değişmez.

    Girdi bilgileri
    backend=document; title={display:Tea}; sort=id
    Query builder
    Sort değerlendirilmedi
    Data owner
    Rows null; count=0
    Sonuç görünümü
    Sonuç yok
  6. Sonuç görünümü kararı

    Görünüm yalnız projection’ı tamamlanmış sonucu kullanır. Reddedilen işlem, başarı veya eşleşmeyen arama gibi gösterilmez; başlangıç verisi değişmez.

    Girdi bilgileri
    backend=document; title={display:Tea}; sort=id
    Query builder
    Sort değerlendirilmedi
    Data owner
    Rows null; count=0
    Sonuç görünümü
    Sonuç yok; field-type

Bilinmeyen sort

  1. Catalog isteği hazır

    Caller’ın catalog intent’i backend=sql; title=Tea; sort=rating değerlerini taşır. Query builder bu alanları doğrulayacaktır; statement/filter veya tamamlanmış row sonucu henüz yoktur.

    Girdi bilgileri
    backend=sql; title=Tea; sort=rating
    Query builder
    Query contract yok
    Data owner
    Arama yok; count=0
    Sonuç görünümü
    Sonuç yok
  2. Field type kararı

    İzin verilen alanlar ve scalar title/string türü değerlendirilir. Sıradan display object bu dalda title değeri olarak kabul edilmez.

    Girdi bilgileri
    backend=sql; title=Tea; sort=rating
    Query builder
    Alan türleri doğrulandı
    Data owner
    Arama yok; count=0
    Sonuç görünümü
    Sonuç yok
  3. Query contract seçimi

    Backend ve scalar title türleri uygundur; sort=rating ise izinli id/title enum’unda değildir. Reason unknown-sort olur; statementId=null, filter=null ve queries=0 korunur.

    Girdi bilgileri
    backend=sql; title=Tea; sort=rating
    Query builder
    Reddedildi: unknown-sort
    Data owner
    Arama yok; count=0
    Sonuç görünümü
    Sonuç yok
  4. Local lookup kararı

    Bu ret dalında SQLite driver veya literal document matcher çağrılmaz. queries=0, gerçekten çalışmış bir query’nin boş sonucu değildir; daha önceki sonuç bu intent’e aktarılmaz.

    Girdi bilgileri
    backend=sql; title=Tea; sort=rating
    Query builder
    Reddedildi: unknown-sort
    Data owner
    Arama yok; count=0
    Sonuç görünümü
    Sonuç yok
  5. Projection yapılmadı

    Lookup yapılmadığından projection üretilemez; rows=null kalır. Kabul edilip Bread için eşleşmeyen query’nin rows=[] sonucuyla farklıdır; seed data değişmez.

    Girdi bilgileri
    backend=sql; title=Tea; sort=rating
    Query builder
    Reddedildi: unknown-sort
    Data owner
    Rows null; count=0
    Sonuç görünümü
    Sonuç yok
  6. Sonuç görünümü kararı

    Görünüm yalnız projection’ı tamamlanmış sonucu kullanır. Reddedilen işlem, başarı veya eşleşmeyen arama gibi gösterilmez; başlangıç verisi değişmez.

    Girdi bilgileri
    backend=sql; title=Tea; sort=rating
    Query builder
    Reddedildi: unknown-sort
    Data owner
    Rows null; count=0
    Sonuç görünümü
    Sonuç yok; unknown-sort

ROLLER · STATE · VERİ AKIŞI

Query yapısı ve aranan değer farklı sahiplerde

Atlas public catalog, title için exact match ve iki onaylı sort seçeneği sunar. Kullanıcı bir kitabın adını verir; uygulama hangi table, field, comparison ve projection kullanılacağını seçer. O'Reilly sıradan bir title’dır. Apostrophe olması onu hatalı business input yapmaz. Bu örnekte SQL statement sabittir, title ve public visibility ayrı bound values olarak driver’a gider. Statement içinde kitabın adı bir syntax parçası olarak birleştirilmez.

Query/data ayrımı parser’dan önce başlar. Handler yalnız backend, title ve sort alanları olan typed bir intent üretir. Backend bu eğitim modelinde sql veya document enum’udur; gerçek üründe client’ın database backend seçmesi gerekmez. Title 1–40 code point aralığında bir string, sort ise id veya title olur. Bu domain contract, parameterization’ın yerine geçmez. Contract hangi operation’ı kabul ettiğini; binding kabul edilen değerin query içindeki rolünü belirler.

SQL driver’a iki ayrı argüman gider

Artifact’te by-id ve by-title için iki önceden yazılmış SELECT bulunur. Her biri id ve title projection’ı, title equality ve visibility equality condition’ını içerir. Python sqlite3 execute çağrısına statement ve (title, public) tuple’ı ayrı verilir. Native check kendi :memory: database’ini açar, sıradan üç catalog row ekler ve O'Reilly için yalnız id=2 row’unu okur. İlk input kabulü query değildir; execute bitmeden result row hazır gösterilmez.

Python qmark binding’de sequence uzunluğu placeholder sayısına uymalıdır. Named placeholder için mapping beklenir. Bunlar driver contract’ıdır; field validation veya resource authorization değildir. Buradaki iki sabit statement’ın value slot’ları aynı kalır. Driver’ın her internal prepare/cache adımı veya başka SQL engine’in dialect’i animasyonda tahmin edilmez. Kanıt, seçilmiş SQLite çağrısına ve gözlenen row listesine aittir.

Sort bir value slot değildir

Title değeri ile ORDER BY column seçimi aynı görev değildir. Bir bind slot’una title yazmak onu column identifier haline getirmez. Uygulama id ve title seçeneklerini kendi iki sabit statement’ına map eder; rating gibi tanınmayan bir sort query çalışmadan reddedilir. Bu örnekte arbitrary identifier, raw SQL fragment veya yön string’i kabul edilmez. Kullanıcının sort seçmesi, query dilini yazma yetkisi vermez.

Bu farkı bir formun görünüşünden çıkaramazsın. Text box’tan gelen title data olarak bağlanabilir; dropdown’dan gelen sort da server’da enum olarak doğrulanmalıdır. UI’da iki option olması server contract’ının kanıtı değildir. Sort tanınmıyorsa builder’ın seçeceği statement null, data owner için query count=0 olur; result view sonuç göstermez. Eksik intent ayrı bir NOT-COMPUTED durumudur; tanınmayan değer ile eksik bilgi aynı karar değildir.

Document filter da bir query dilinin parçasıdır

NoSQL etiketi interpretation boundary’yi ortadan kaldırmaz. Uygulama scalar title’ın type’ını doğruladıktan sonra kendi equality filter’ını kurar. Client’tan gelen object’i olduğu gibi filter diye kullanmak, uygulamanın query yapısını client’ın veri yapısıyla karıştırır. Bu derste sıradan {display: Tea} object’i title:string contract’ına uymaz ve herhangi bir document lookup yapılmadan reddedilir. Object’in grammar olarak parse olması title değeri olmasını sağlamaz.

Document branch’i Python’da dar bir literal matcher’dır: uygulamanın kurduğu title ve visibility alanları exact equality ile kendi seed documents’ını seçer, id veya title sırasına koyar, id/title alanlarını projekte eder. Bu matcher MongoDB server, BSON codec, cursor veya ODM değildir. MongoDB’nin find sonucu cursor’dır; örneğin hazır listesi onun bütün davranışlarını taklit etmez. Animasyonun local Data owner kutusu bu sınırı açık bırakır.

Doğru query, doğru erişim kararıyla birleşmeli

Binding query yapısını korur; hangi row’un hangi caller’a sunulabileceğini tek başına belirlemez. Bu catalog yalnız public visibility için oluşturulmuş sabit eğitim verisidir. Özel kayıtlar, tenant membership, servis account izinleri ve field-level disclosure gerçek uygulamada ayrı policy ister. Public scope condition uygulama tarafından seçilir; title alanının içinden yeni bir scope kararı türetilmez.

Kabul edilen query’nin boş row listesi döndürmesi de rejection değildir. Type/schema failure, unknown sort, driver failure ve accepted-but-no-match farklı sonuçlardır. Result view ancak tamamlanmış lookup ve projection’dan sonra değişir. Bu ayrım retry ve error handler tasarımına taşınır: query hiç yapılmadıysa bunu empty result gibi kaydetmek, uygulamanın gerçekte neyi doğruladığını gizler. Bu artifact yalnız SELECT/literal lookup yapar; mutation, network veya production authorization çalıştırmaz.

2. Red · Güven ve etki

Hareket olmadan bütün senaryoları oku

Field type

  1. Query intent profili okundu

    Document backend title için scalar string bekler. wrong-type input title={display:Tea} içerir; bu ordinary object valid JSON olabilir ama kabul edilen title türü değildir.

    Caller intent
    Backend: document
    Typed query factory
    Intent validation pending
    Data-owner boundary
    Query not executed
  2. Value ve structure sorumluluğu ayrıldı

    JSON’dan çıkan object doğrudan query filter’a kopyalanmaz. Application typed title’dan yeni equality filter oluşturur; accepted olmayan type bu factory’ye ulaşmaz.

    Caller intent
    Application selects structure
    Typed query factory
    Field-type mismatch
    Data-owner boundary
    Factory gate pending
  3. Intent gate reddi belirlendi

    expected decision=REJECT ve reason=field-type’tır. Accepted filter veya statement hazırlanmaz; queries=0 tutulur.

    Caller intent
    Decision: REJECT
    Typed query factory
    Queries=0
    Data-owner boundary
    Rows=null
  4. Data owner’a dispatch yapılmadı

    statementId=null ve filter=null’dır. Driver veya document matcher’ın input’u çalıştırıp sonra gizli result döndürdüğü şeklinde anlatılmaz.

    Caller intent
    No accepted query structure
    Typed query factory
    No data-owner call
    Data-owner boundary
    No result delivery
  5. Failure ile no-match ayrıldı

    rows=null intent failure’dır. acceptedNoMatch için Bread araması ACCEPT, queries=1 ve rows=[] verir; boş sonuç gerçekten yapılmış read gerektirir.

    Caller intent
    Rejection: rows=null
    Typed query factory
    Accepted no-match: rows=[]
    Data-owner boundary
    Outcomes distinct
  6. Ret sınıfı yanlış genişletilmedi

    Bu ordinary type/sort retleri boundary contract’ını gösterir. Executable injection, endpoint vulnerability veya actor permission failure sonucu değildir.

    Caller intent
    Contract rejection known
    Typed query factory
    No query execution
    Data-owner boundary
    Permission separate

Sort unknown

  1. Query intent profili okundu

    SQL backend sort için yalnız id veya title seçer. unknown-sort input sort=rating içerir; client tercihi approved statement setine karşılaştırılır.

    Caller intent
    Backend: sql
    Typed query factory
    Intent validation pending
    Data-owner boundary
    Query not executed
  2. Value ve structure sorumluluğu ayrıldı

    Sort tercihi identifier’ı value parameter’ına bağlamakla çözülmez. Application id/title enum’unu iki fixed statement’a eşler; rating için yeni SQL oluşturmaz.

    Caller intent
    Application selects structure
    Typed query factory
    Sort outside enum
    Data-owner boundary
    Factory gate pending
  3. Intent gate reddi belirlendi

    expected decision=REJECT ve reason=unknown-sort’tur. Approved statement seçilmediği için queries=0 kalır; result empty list gibi sunulmaz.

    Caller intent
    Decision: REJECT
    Typed query factory
    Queries=0
    Data-owner boundary
    Rows=null
  4. Data owner’a dispatch yapılmadı

    statementId=null ve filter=null’dır. Driver veya document matcher’ın input’u çalıştırıp sonra gizli result döndürdüğü şeklinde anlatılmaz.

    Caller intent
    No accepted query structure
    Typed query factory
    No data-owner call
    Data-owner boundary
    No result delivery
  5. Failure ile no-match ayrıldı

    rows=null intent failure’dır. acceptedNoMatch için Bread araması ACCEPT, queries=1 ve rows=[] verir; boş sonuç gerçekten yapılmış read gerektirir.

    Caller intent
    Rejection: rows=null
    Typed query factory
    Accepted no-match: rows=[]
    Data-owner boundary
    Outcomes distinct
  6. Ret sınıfı yanlış genişletilmedi

    Bu ordinary type/sort retleri boundary contract’ını gösterir. Executable injection, endpoint vulnerability veya actor permission failure sonucu değildir.

    Caller intent
    Contract rejection known
    Typed query factory
    No query execution
    Data-owner boundary
    Permission separate

VARSAYIM · SINIR · KONTROL

Review sorusu: değer ne zaman yapıya dönüştü?

Bir incelemede ilk soruyu input’un görünüşü yerine sorumluluklar üzerine kur: uygulama statement/filter’ı nerede seçiyor, caller hangi alanları etkileyebiliyor, driver’a tam olarak hangi typed values gidiyor? Sıradan O'Reilly title’ı, noktalama işaretinin business data olarak korunabildiğini gösterir. Bu bir saldırı string’i denemesi değildir. Örneğin sabit SELECT’i ve ayrı tuple’ı, query yapısının hangi dosyada uygulama tarafından belirlendiğini görünür kılar.

ORM kullanıldığı bilgisinden bütün call path’in güvenli olduğu sonucunu çıkarma. Model method’u, raw expression escape hatch’i ve sort/projection factory’si farklı kontratlar olabilir. Bu derste raw expression çalıştırılmaz; review hedefi uygulamanın onaylı factory’yi kullanıp kullanmadığıdır. İnceleme çıktısı için statement identifier, doğrulanan field türleri ve seçilen scope yeterlidir. Bütün input değerlerini log’a dökmek gereksiz disclosure oluşturabilir.

Parse edilmiş object ile kabul edilmiş filter ayrılır

Document branch’inde title yerine sıradan display object verilince geçerli JSON’dan uygulamanın beklediği türe geçiş durur. Data owner’a query iletilmez ve önceki row listesi yeni bir başarı gibi gösterilmez. Bu inert failure, parser acceptance ile operation acceptance arasındaki farkı öğretir. Query count=0 ve result null birlikte kanıttır; yalnız ekranda bir error mesajı olması yeterli değildir.

Boş sonuç için kabul edilmiş Tea match’inin gerçekten çalışıp çalışmadığına bakmak gerekir. Unknown sort rating aynı empty list sonucu ile temsil edilseydi contract failure kaybolurdu. Eksik kanıt da otomatik bir red veya izin kararına dönüştürülmez. Bu örneğin sınırlı check’leri gerçek endpoint keşfi, injection payload, auth bypass veya başka sistemde vulnerability reproduction içermez; bir boundary review’ün hangi olgulara dayanabileceğini gösterir.

3. Blue · Güvenli geliştirme ve savunma

Hareket olmadan bütün senaryoları oku

Value binding

  1. Normal public intent seçildi

    Normal SQL input title=O'Reilly ve sort=id içerir. Noktalama title’ın business data’sıdır; query syntax seçmek için kullanılmaz.

    Intent/query observation
    Title: O'Reilly
    Factory/result comparison
    Sort: id
    Evidence conclusion
    Factory review pending
  2. Fixed statement kimliği eşleştirildi

    sort=id, by-id statement’ını seçer. Statement title=? ve visibility=? kullanır; title ile public scope ayrı bound values olarak kalır.

    Intent/query observation
    Statement: by-id
    Factory/result comparison
    Values: O'Reilly / public
    Evidence conclusion
    Execution pending
  3. Beklenen query sonucu okundu

    normal expected queries=1 ve rows=[{id:2,title:O'Reilly}] içerir. Bu positive outcome noktalamanın value olarak korunduğunu gösterir; bütün query path’lerini doğrulamaz.

    Intent/query observation
    Queries=1
    Factory/result comparison
    Row id=2
    Evidence conclusion
    Title preserved
  4. Response projection alanları ayrıldı

    Profile projection yalnız id ve title’dır. Visibility public scope koşulu olarak kullanılır; response’a bütün stored field’ları kopyalamak zorunlu değildir.

    Intent/query observation
    Scope: public
    Factory/result comparison
    Projection: id/title
    Evidence conclusion
    No extra stored fields
  5. Document branch factory’si karşılaştırıldı

    Document input title=Tea için uygulama {title:Tea,visibility:public} equality filter’ı kurar. Accepted string’den yeni filter oluşturmak, caller object’ini kopyalamaktan farklıdır.

    Intent/query observation
    SQL fixed statement
    Factory/result comparison
    Document fixed equality filter
    Evidence conclusion
    Factories explicit
  6. Binding permission’a çevrilmedi

    Parameter binding value/structure sınırına yardım eder. Public fixture scope’u dışında tenant authorization, database account yetkisi veya production query timeout için ayrıca control gerekir.

    Intent/query observation
    Value boundary known
    Factory/result comparison
    Public scope fixed
    Evidence conclusion
    Authorization separate

No-match ve eksik

  1. Accepted no-match kaydı açıldı

    acceptedNoMatch title=Bread için decision=ACCEPT ve queries=1 bildirir. rows=[] aramanın kabul edilip çalıştığı fakat eşleşme bulunmadığı sonuçtur.

    Intent/query observation
    Intent accepted
    Factory/result comparison
    Queries=1
    Evidence conclusion
    Rows=[]
  2. Missing input farklı tuple sayıldı

    missing.input=null, decision=NOT-COMPUTED, queries=0 ve rows=null’dır. Arama yapılmadığı için bu kayıt Bread’in empty result’ı gibi yorumlanmaz.

    Intent/query observation
    Input=null
    Factory/result comparison
    Queries=0
    Evidence conclusion
    Rows=null
  3. Bilinen ret ile missing ayrıldı

    wrong-type ve unknown-sort için REJECT, missing için NOT-COMPUTED vardır. Hepsi no-query olabilir ama hangi contract koşulunun değerlendirildiği farklıdır.

    Intent/query observation
    Known rejection distinct
    Factory/result comparison
    Missing intent unresolved
    Evidence conclusion
    No-query cause explicit
  4. Query count result ile bağlandı

    Accepted match için queries=1 ve projected rows gerekir; no-match için aynı query count ile [] beklenir. Yalnız UI error veya empty view bu tuple’ı tamamlamaz.

    Intent/query observation
    Intent + query + rows
    Factory/result comparison
    UI alone insufficient
    Evidence conclusion
    Evidence tuple required
  5. Document sonucu sınırlı okundu

    Tea equality filter’ı id=1 ve id=3 için iki projected row döndürür. Bu literal matcher sonucu gerçek MongoDB/ODM davranışı veya bütün filter operatörlerini gözlemez.

    Intent/query observation
    Document rows: 1, 3
    Factory/result comparison
    Literal matcher scope
    Evidence conclusion
    ODM runtime unobserved
  6. Teşhis için değerler gereksiz loglanmadı

    Statement identifier, field türleri, scope ve outcome review için yeterli olabilir. Bütün input değerlerini loglamak permission veya query correctness kanıtını güçlendirmez ve gereksiz disclosure yaratabilir.

    Intent/query observation
    Bounded decision metadata
    Factory/result comparison
    No-match vs missing retained
    Evidence conclusion
    No excessive value log

UYGULAMA · GÜVENLİK KONTROLÜ · DOĞRULAMA

Query factory’yi küçük ve açık tut

Uygulamanın public catalog factory’si closed field set, scalar title ve sort enum’unu doğrular. Kabul edilen id/title seçimleri yalnız iki sabit SELECT’e bağlanır. Value’lar sqlite3’ye tuple olarak verilir; document branch’inde uygulamanın belirlediği yeni equality filter oluşturulur. Client object’i copy etmek tek başına validation değildir. Type ve allowed field kararı, query builder’ın output’undan önce tamamlanır.

Testler source shape’ı tekrar söylemekle kalmamalı: native SQLite’de sıradan noktalama işareti içeren title’ın gerçekten doğru row’u verdiğini, query sonrası seed row sayısının değişmediğini ve unknown sort’un execute sayısını artırmadığını ölç. Document matcher için yanlış type’ın lookup yapmadan dönmesini ve kabul edilen match’in yalnız projected fields vermesini karşılaştır. Bu ölçümler driver/framework değişirse tekrar değerlendirilir; bir SQLite sonucu bütün engine ve ODM’lere genellenmez.

Failure, scope ve evidence aynı kayıtta bulunmalı

Kabul edilebilir intent, seçilen statement/filter, query count ve projected result ayrı alanlar olarak tutulur. Rejection result null üretir; kabul edilmiş fakat eşleşmeyen arama [] üretir. Intent eksikse NOT-COMPUTED olur. Bu küçük ayrım incident review’de önemlidir: permission kararı, database connectivity failure ve gerçekten bulunamayan resource aynı kayıt altında görünmemelidir. Public visibility örneğin sabit scope’udur; tenant erişimi yaptığımız iddia edilmez.

Database account’ın yetkileri operation’ın gerektirdiği düzeyde tutulmalı; read-only catalog için admin privilege gerekçesi yoktur. Production’da authz, query timeout, row/page bound, error disclosure ve transaction policy ayrıca tasarlanır. Bu artifact bunları test etmiş gibi bir başarı işareti göstermez. Gözlenen native kanıt kendi memory database’i, sıradan başlangıç verisi, sabit statement binding ve dar literal matcher ile sınırlıdır; UI reduced motion’da da aynı kararları okunur sunar.

ŞİMDİ VAKAYA UYGULA

Accepted JSON ne zaman query olmadan durmalıdır?

Application closed intent ve sort enum’dan fixed SQL veya equality filter seçer. Harmless title values data kalır; ret, no-match ve missing input ayrı tuple’larla anlatılır.

Vakadaki cached representation’ı authoritative data owner’la karşılaştır. Stored value, revision, transaction ve cache copy için aynı completion sonucunu kullanma.

Bağlı vaka dosyasını aç ↗

ÖRNEĞİ BİRLİKTE OKUYALIM

Atlas query contract ve public sonuç kaydı

Bir alan seç; hangi sonucu desteklediğini ve nerede yetersiz kaldığını incele.

Ham kaydı ve alan açıklamalarını oku
{
  "profile": {
    "allowedKeys": [
      "backend",
      "title",
      "sort"
    ],
    "backends": [
      "sql",
      "document"
    ],
    "titleCodePoints": [
      1,
      40
    ],
    "sortChoices": [
      "id",
      "title"
    ],
    "scope": "public",
    "projection": [
      "id",
      "title"
    ]
  },
  "seed": [
    {
      "id": 1,
      "title": "Tea",
      "visibility": "public"
    },
    {
      "id": 2,
      "title": "O'Reilly",
      "visibility": "public"
    },
    {
      "id": 3,
      "title": "Tea",
      "visibility": "public"
    }
  ],
  "statements": {
    "by-id": "SELECT id, title FROM books WHERE title = ? AND visibility = ? ORDER BY id",
    "by-title": "SELECT id, title FROM books WHERE title = ? AND visibility = ? ORDER BY title, id"
  },
  "inputs": {
    "normal": {
      "backend": "sql",
      "title": "O'Reilly",
      "sort": "id"
    },
    "document": {
      "backend": "document",
      "title": "Tea",
      "sort": "id"
    },
    "wrong-type": {
      "backend": "document",
      "title": {
        "display": "Tea"
      },
      "sort": "id"
    },
    "unknown-sort": {
      "backend": "sql",
      "title": "Tea",
      "sort": "rating"
    }
  },
  "expected": {
    "normal": {
      "decision": "ACCEPT",
      "reason": "public-exact-match",
      "queries": 1,
      "statementId": "by-id",
      "filter": null,
      "rows": [
        {
          "id": 2,
          "title": "O'Reilly"
        }
      ]
    },
    "document": {
      "decision": "ACCEPT",
      "reason": "public-exact-match",
      "queries": 1,
      "statementId": null,
      "filter": {
        "title": "Tea",
        "visibility": "public"
      },
      "rows": [
        {
          "id": 1,
          "title": "Tea"
        },
        {
          "id": 3,
          "title": "Tea"
        }
      ]
    },
    "wrong-type": {
      "decision": "REJECT",
      "reason": "field-type",
      "queries": 0,
      "statementId": null,
      "filter": null,
      "rows": null
    },
    "unknown-sort": {
      "decision": "REJECT",
      "reason": "unknown-sort",
      "queries": 0,
      "statementId": null,
      "filter": null,
      "rows": null
    }
  },
  "missing": {
    "input": null,
    "decision": "NOT-COMPUTED",
    "queries": 0,
    "rows": null
  },
  "acceptedNoMatch": {
    "title": "Bread",
    "decision": "ACCEPT",
    "queries": 1,
    "rows": []
  }
}
inputs
Sıradan typed intent; client’ın yazdığı query syntax değildir.
statements / filter
Uygulamanın belirlediği yapı ve sabit public scope.
queries
Tamamlanan aramaların sayacı; reddedilen dalda0.
rows
Tamamlanan projection: sonuç yoksa null, kabul edilen aramada eşleşme yoksa [] olur.

Örneğin Python SQLite :memory: veritabanında değerleri bağlanan SELECT ve local Python literal-document matcher. MongoDB server/driver/cursor, network, ORM, rastgele query, exploit veya user authorization çalıştırılmaz.

İki yanlış kanı

Bind edilen her değer column veya sort seçebilir.

Value slot yapıyı seçmez; sort/identifier için uygulamanın onaylı mapping’i gerekir.

JSON object kullanan query kendiliğinden güvenlidir.

Field/type contract ve uygulamanın belirlediği filter gerekir; parsing authorization değildir.

SIRA SENDE

Bu hikâyeyi sen çöz.

Sonucu tahmin et, kanıtın sınırını bul ve nedenini kendi cümlenle anlat.

Document backend için title bir string değil, {display: Tea} object’i. Query çalışır mı?

  1. Hayır. field-type; queries=0 ve filter=null.
  2. Evet. Her JSON object otomatik database filter’ıdır.
Gerekçeli cevabı oku

Hayır. field-type; queries=0 ve filter=null. — Bu sözleşme title string’i ister. Input object’i query operator veya filter olarak doğrudan kullanılmaz.

O'Reilly başlığı neden SQL statement’ın source’u değil, eşleşecek data olarak kalıyor?

Dersten seçilen artifact alanları; öğretim örneği

inputs.normal
{"backend":"sql","title":"O'Reilly","sort":"id"}
statements.by-id
SELECT id, title FROM books WHERE title = ? AND visibility = ? ORDER BY id
expected.normal
{"decision":"ACCEPT","reason":"public-exact-match","queries":1,"statementId":"by-id","filter":null,"rows":[{"id":2,"title":"O'Reilly"}]}
  1. Başlıktaki apostrophe yeni statement structure oluşturur.
  2. Statement sabit; title placeholder’a data olarak bağlanır.
Gerekçeli cevabı oku

Statement sabit; title placeholder’a data olarak bağlanır. — by-id statement’ı title ve visibility değerlerini ? placeholder’larıyla alır. Sonuç public id=2 kaydıdır; başlık query grammar seçmez.

sort=rating için queries=0, acceptedNoMatch için queries=1 ve rows=[]. Neden bu iki boş sonuç aynı değildir? Query/data ayrımı authorization mı?

Gerekçeli cevabı oku

Unknown sort sözleşmenin id/title seçeneklerinde değildir; query gönderilmeden reddedilir ve rows=null kalır. Bread başlığı kabul edilir, query çalışır ve eşleşme bulunmadığı için rows=[] döner. Query structure server’ın sabit seçimi olmalıdır; parameterization object/tenant izni yerine geçmez. Bu profile yalnız public projection kullanır; document adapter sonucu gerçek MongoDB deployment testi değildir.

□ Ret ile başarılı no-match sonucunu ayırdım.

□ Parameterization’ı resource authorization saymadım.

Uygulama konsolunu aç · request / response / browser
Request, URL, cookie ve DOM örneklerini ayrıca aç

Kaynaklar ve kapsam