OriginChain docs
examples · sql · 3 / 13

3. WHERE col IN (...)

← SQL examples
what this does

Return rows whose status matches any value in a small set of literals. IN (...) is the OriginChain-supported way to express what x = 'pending' OR x = 'paid' would mean in traditional SQL - OR in WHERE isn't supported yet, so use IN for value alternatives.

when to use it
  • "Match one of these values" - small enumerations, status fields, category lists.
  • As a replacement for OR-of-equalities.
  • The IN list is short (under ~100 values). For larger sets, consider a JOIN against a temp table.
the schema
namespace   = "shop"
table       = "orders"
primary_key = ["id"]

[[columns]]
name = "id"
ty   = "str"
required = true

[[columns]]
name = "customer_id"
ty   = "str"

[[columns]]
name = "amount_cents"
ty   = "i64"

[[columns]]
name = "status"
ty   = "str"

[[indexes]]
name    = "by_status"
columns = ["status"]
seed data
curl -X POST "https://$OC_HOST/v1/tenants/$OC_TENANT/rows/shop.orders/_batch" \
  -H "Authorization: Bearer $OC_TOKEN" \
  -H "Content-Type: application/json" \
  -d '[
    { "id": "o_001", "customer_id": "c_1", "amount_cents":  4990, "status": "paid" },
    { "id": "o_002", "customer_id": "c_2", "amount_cents": 12900, "status": "pending" },
    { "id": "o_003", "customer_id": "c_1", "amount_cents":  1250, "status": "paid" }
  ]'
the request
POST /v1/tenants/:t/sql
curl -X POST "https://$OC_HOST/v1/tenants/$OC_TENANT/sql" \
  -H "Authorization: Bearer $OC_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "sql": "SELECT id, status FROM shop.orders WHERE status IN ('\''pending'\'', '\''paid'\'') LIMIT 50"
  }'
what you get back
{
  "kind": "select",
  "rows": [
    { "id": "o_001", "status": "paid" },
    { "id": "o_002", "status": "pending" },
    { "id": "o_003", "status": "paid" }
  ]
}
how it works

The translator folds status IN ('pending', 'paid') into a disjunction over equalities internally and dispatches the index lookups in parallel. From the engine's perspective each candidate value is treated like a separate IndexScan and the results are merged.

common mistakes
  • Very long IN lists. A few hundred values is fine. Thousands? Bulk-insert the list into a temp table and JOIN. The engine accepts long IN lists but the parser overhead grows with size.
  • NOT IN with NULL. If any value in the list is NULL, NOT IN returns no rows (standard SQL three-valued logic). Filter NULL explicitly before negating.