| Ocalt Query Language
Pricing Dashboard ocalt.com v1.0

Control Flow

IF / ELSE IF / ELSE, IF SOME, SWITCH, WHILE, WHILE SOME, FOREACH. All blocks use OPEN NEST / CLOSE NEST.

IF / ELSE IF / ELSE

CALCULATE "85" SET ?score IF ?score IS GREATER THAN 90 OPEN NEST EMIT "A" CLOSE NEST ELSE IF ?score IS GREATER THAN 70 OPEN NEST EMIT "B" CLOSE NEST ELSE IF ?score IS GREATER THAN 50 OPEN NEST EMIT "C" CLOSE NEST ELSE OPEN NEST EMIT "F" CLOSE NEST
Try it ›
(* IF with null check *) FETCH "https://httpbin.org/uuid" SET ?resp AFTER IF ?resp(uuid) IS NOT NULL OPEN NEST EMIT "got UUID: " & ?resp(uuid) CLOSE NEST ELSE OPEN NEST EMIT "no UUID returned" CLOSE NEST
Try it ›
(* IF with string contains *) STRING "Engineering Magic" SET ?s AFTER IF ?s CONTAINS "Magic" OPEN NEST EMIT "found it" CLOSE NEST ELSE OPEN NEST EMIT "not found" CLOSE NEST
Try it ›
(* IF with regex MATCHES *) STRING "user@example.com" SET ?email AFTER IF ?email MATCHES "^[^@]+@[^@]+\.[^@]+$" OPEN NEST EMIT "valid email" CLOSE NEST ELSE OPEN NEST EMIT "invalid email" CLOSE NEST
Try it ›

Comparison operators

OperatorMeaningContext
IS EQUAL TOEquality with type coercionIF
IS IDENTICAL TOStrict equality — type and valueIF
IS NOT EQUAL TOInequality with type coercionIF
IS GREATER THANNumeric greater thanIF
IS LESS THANNumeric less thanIF
IS GREATER THAN OR EQUAL TONumeric ≥IF
IS LESS THAN OR EQUAL TONumeric ≤IF
IS NULLValue is nullIF
IS NOT NULLValue is not nullIF
CONTAINS / CONTAINString or array contains substring/elementIF
MATCHES / MATCHRegex match — returns booleanIF
ARE EQUAL TOAny element equals valueIF SOME / WHILE SOME
ARE IDENTICAL TOAny element strictly equals valueIF SOME / WHILE SOME
ARE NOT EQUAL TOAny element does not equal valueIF SOME / WHILE SOME
ARE GREATER THANAny element is greater than valueIF SOME / WHILE SOME
ARE LESS THANAny element is less than valueIF SOME / WHILE SOME
ARE GREATER THAN OR EQUAL TOAny element ≥ valueIF SOME / WHILE SOME
ARE LESS THAN OR EQUAL TOAny element ≤ valueIF SOME / WHILE SOME
ARE NULLAny element is nullIF SOME / WHILE SOME
ARE NOT NULLAny element is not nullIF SOME / WHILE SOME

IF SOME — any-match on arrays

Branches if any element of the array matches. OR is the fallback when no element matches.

SPLIT "active,inactive,active" WITH "," SET ?s AFTER IF SOME ?s ARE EQUAL TO "active" OPEN NEST EMIT "at least one active" CLOSE NEST ELSE OPEN NEST EMIT "none active" CLOSE NEST
Try it ›
(* Check if any score is above threshold *) SPLIT "45,82,91,33,67" WITH "," SET ?scores AFTER IF SOME ?scores ARE GREATER THAN "80" OPEN NEST EMIT "at least one high scorer" CLOSE NEST ELSE OPEN NEST EMIT "no high scorers" CLOSE NEST
Try it ›
(* Check if any value is null *) NEW ARRAY OPEN NEST ENLIST "ok" ENLIST null ENLIST "fine" CLOSE NEST SET ?vals AFTER IF SOME ?vals ARE NULL OPEN NEST EMIT "nulls present" CLOSE NEST ELSE OPEN NEST EMIT "all values set" CLOSE NEST

SWITCH / CASE / DEFAULT

Match a value against multiple literal cases. DEFAULT is the fallback.

STRING "pro" SET ?tier SWITCH ?tier CASE "free" OPEN NEST EMIT "100 queries/day" CLOSE NEST CASE "starter" OPEN NEST EMIT "10,000 queries/day" CLOSE NEST CASE "pro" OPEN NEST EMIT "100,000 queries/day" CLOSE NEST CASE "enterprise" OPEN NEST EMIT "1,000,000 queries/day" CLOSE NEST DEFAULT OPEN NEST EMIT "unknown tier" CLOSE NEST
Try it ›

WHILE

CALCULATE "1" SET ?i WHILE ?i IS LESS THAN OR EQUAL TO 5 OPEN NEST EMIT ?i AFTER CALCULATE "?i + 1" SET ?i CLOSE NEST
Try it ›

WHILE SOME

Loops while any element of the array matches the condition. Re-evaluate the array each iteration by reassigning it.

SPLIT "pending,pending,done" WITH "," SET ?states WHILE SOME ?states ARE EQUAL TO "pending" OPEN NEST EMIT "still pending..." AFTER SLEEP "1s" AFTER FETCH "https://api.example.com/status" SET ?resp AFTER SPLIT ?resp(states) WITH "," SET ?states CLOSE NEST AFTER EMIT "all done"

FOREACH

Iterates an array. Inside the block: !INDEX is the 0-based position, !VALUE is the current item (same as the alias variable). Each iteration's result is collected — add SET ?results after CLOSE NEST to capture all results as an array.

SPLIT "red,green,blue" WITH "," SET ?colors AFTER FOREACH ?colors AS ?color OPEN NEST EMIT ?color & " (#" & !INDEX & ")" CLOSE NEST
Try it ›
(* Capture all results — SET after CLOSE NEST collects every iteration value *) SPLIT "hello,world,oql" WITH "," SET ?words AFTER FOREACH ?words AS ?w OPEN NEST UPPER ?w SET ?up AFTER EMIT ?up CLOSE NEST SET ?uppers AFTER EMIT ?uppers (* → ["HELLO","WORLD","OQL"] *)
Try it ›
(* FOREACH over query results *) QUERY "products" FROM "shop" SET ?rows AFTER FOREACH ?rows AS ?p OPEN NEST EMIT ?p(name) & " — R" & ?p(price) CLOSE NEST
(* Nested FOREACH *) SPLIT "a,b" WITH "," SET ?outer AFTER FOREACH ?outer AS ?x OPEN NEST SPLIT "1,2,3" WITH "," SET ?inner AFTER FOREACH ?inner AS ?n OPEN NEST EMIT ?x & ?n CLOSE NEST CLOSE NEST
Try it ›
Inside FOREACH: ?alias and !VALUE both hold the current item. !INDEX is the 0-based position. FOREACH on a non-array value wraps it in a single-element array and iterates once.