Skip to content

fix(sql): compile tick expressions with date variables into IR for zero-parse evaluation when executing caches SQL statements#6780

Merged
bluestreak01 merged 22 commits intomasterfrom
vi_dyn_now
Feb 13, 2026
Merged

fix(sql): compile tick expressions with date variables into IR for zero-parse evaluation when executing caches SQL statements#6780
bluestreak01 merged 22 commits intomasterfrom
vi_dyn_now

Conversation

@bluestreak01
Copy link
Copy Markdown
Member

@bluestreak01 bluestreak01 commented Feb 12, 2026

Summary

  • Add CompiledTickExpression that pre-parses tick expressions containing date variables ($now, $today, $yesterday, $tomorrow) into a single long[] IR at compile time. Runtime evaluate() performs only long arithmetic — no string parsing, no allocations.
  • Add DateVariableExpr to encode/evaluate $variable ± offset expressions (supports all time units plus business days).
  • Add IntervalUtils.compileTickExpr() that builds the IR: duration parts, time override triples, and element entries (SINGLE_VAR, STATIC, RANGE) packed into one array with a header.
  • Wire through RuntimeIntervalModelBuilder: expressions containing $ variables now produce a dynamic CompiledTickExpression instead of re-parsing the string on every query execution.
  • Replace Character.isWhitespace / Character.isDigit with Chars.isAsciiWhitespace / Chars.isAsciiDigit throughout IntervalUtils to avoid locale-dependent behavior.

IR design

ir[0]           header (elem/timeOverride/duration counts, dayFilterMask, flags)
ir[1]           numericTzOffset (Long.MIN_VALUE if named tz)
ir[2..2+D)      duration parts (unit + value per long)
ir[2+D..2+D+3T) time override triples (offset, width, zoneMatch)
ir[2+D+3T..end) elements: TAG_SINGLE_VAR(1 long), TAG_STATIC(3 longs), TAG_RANGE(2 longs)

Non-encodable fields (TimeZoneRules, DateLocale, LongList exchangeSchedule) remain as object references on the CompiledTickExpression instance.

Evaluate algorithm

  1. Walk elements → emit intervals (single var, static pass-through, or day-by-day range iteration)
  2. Apply day filter bitmask (local time)
  3. Apply timezone (numeric subtraction or DST-aware toUTC)
  4. Apply exchange schedule filter + optional duration
  5. Sort and merge overlapping intervals

Test plan

  • Oracle tests (assertCompiledTickExpr) compare compiled evaluate() vs reference parseTickExpr with 10 random "now" values per expression
  • Fixed-now tests (assertCompiledTickExprWithNow) for DST edge cases (spring forward, fall back, per-element + global named timezone)
  • Negative tests (assertCompileTickExprError) for invalid expressions
  • Coverage for IR growth (bracket expansion filling initial 64-long array)
  • Edge case tests for mixed-precision ranges, month-precision static with day filter, sub-day ranges spanning midnight, $now with timezone, mixed $now/$today lists with time override
  • DateVariableExpr unit tests for all variable types, offsets, business days, case insensitivity

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Feb 12, 2026

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch vi_dyn_now

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@bluestreak01 bluestreak01 changed the title fix(sql): fix dynamic behaviour of $now in the tick syntax feat(sql): compile tick expressions with date variables into IR for zero-parse evaluation Feb 12, 2026
@bluestreak01 bluestreak01 changed the title feat(sql): compile tick expressions with date variables into IR for zero-parse evaluation fix(sql): compile tick expressions with date variables into IR for zero-parse evaluation when executing caches SQL statements Feb 12, 2026
@glasstiger
Copy link
Copy Markdown
Contributor

[PR Coverage check]

😍 pass : 883 / 949 (93.05%)

file detail

path covered line new line coverage
🔵 io/questdb/griffin/model/RuntimeIntervalModel.java 1 5 20.00%
🔵 io/questdb/griffin/model/RuntimeIntervalModelBuilder.java 16 35 45.71%
🔵 io/questdb/griffin/SqlOptimiser.java 100 113 88.50%
🔵 io/questdb/griffin/model/DateVariableExpr.java 100 112 89.29%
🔵 io/questdb/griffin/model/CompiledTickExpression.java 173 188 92.02%
🔵 io/questdb/griffin/model/DateExpressionEvaluator.java 60 62 96.77%
🔵 io/questdb/griffin/model/IntervalUtils.java 422 423 99.76%
🔵 io/questdb/std/Chars.java 8 8 100.00%
🔵 io/questdb/griffin/SqlParser.java 3 3 100.00%

@bluestreak01 bluestreak01 merged commit de24b14 into master Feb 13, 2026
44 checks passed
@bluestreak01 bluestreak01 deleted the vi_dyn_now branch February 13, 2026 19:56
maciulis pushed a commit to maciulis/questdb that referenced this pull request Feb 19, 2026
…ro-parse evaluation when executing caches SQL statements (questdb#6780)
@bluestreak01 bluestreak01 restored the vi_dyn_now branch March 2, 2026 17:36
@bluestreak01 bluestreak01 deleted the vi_dyn_now branch March 2, 2026 20:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants