Skip to main content

Phase 7.3. Query string ops

FieldValue
MEPMEP-54
StatusLANDED
Started2026-05-28 (GMT+7)
Landed2026-05-28 (GMT+7)
Tracking PR#22561
Commit3510d3295d

Gate

4 fixtures cover the cases needed to unlock string predicates and len(s) in query clauses: contains as a where predicate, len(s) as the select expression, contains across multiple matches, len(s) in a numeric comparison. All pass under go test ./transpiler3/go/build/....

Lowering decisions

StrLenExpr lowers to int64(len([]rune(s))) so the count follows Mochi semantics (Unicode codepoints, matching the C runtime's mochi_str_len which counts rune index positions). The naive int64(len(s)) would return UTF-8 byte count, which diverges from C for any non-ASCII input. Wrapping with int64(...) preserves the int pin established in Phase 2.

StrContainsExpr lowers to strings.Contains(s, sub), matching the C runtime's substring search (empty sub returns true). The strings import is registered on demand. Phase 7.3 covers only the two ops needed by the query DSL; the broader string surface (substring, index, reverse, split, join, str) lands in Phase 7.6.

Files changed

FilePurpose
transpiler3/go/lower/expr.goStrLenExpr -> int64(len([]rune(s))); StrContainsExpr -> strings.Contains(s, sub)
tests/transpiler3/go/fixtures/query_str_*/4 fixtures

Test set

  • 4 TestPhase1Hello/query_str_* subtests covering contains predicate, len select, contains multi-match, len comparison.

Closeout notes

The rune-count decision was load-bearing for the Phase 7.6 fixtures (which exercise len on multibyte strings). Catching it in Phase 7.3 cost one wrap; catching it later would have required a Phase 7.6-time audit of every existing query golden.