Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
137 commits
Select commit Hold shift + click to select a range
cda0b6f
feat(hogql): add native parser and AST compiler
bill-ph Aug 27, 2026
455a5a9
feat(hogql): add coordinator submission seam
bill-ph Aug 27, 2026
cca1e82
feat(hogql): pin canonical language contract
bill-ph Aug 27, 2026
c923e6a
feat(hogql): parse canonical expressions
bill-ph Aug 27, 2026
5301a22
feat(hogql): vendor compatibility artifact
bill-ph Aug 27, 2026
677fcd9
feat(hogql): add exhaustive compatibility manifest
bill-ph Aug 27, 2026
fb50782
feat(hogql): lower collection and predicate expressions
bill-ph Aug 27, 2026
dedcde8
feat(hogql): lower case and cast expressions
bill-ph Aug 27, 2026
446cbc7
feat(hogql): identify unlabeled grammar alternatives
bill-ph Aug 27, 2026
161ad0a
feat(hogql): preserve the complete query syntax tree
bill-ph Aug 27, 2026
7443077
feat(hogql): bound parser resource usage
bill-ph Aug 27, 2026
cb2564a
feat(hogql): classify non-query syntax
bill-ph Aug 27, 2026
76cfc11
feat(hogql): publish the syntax AST manifest
bill-ph Aug 27, 2026
4f75e8a
feat(hogql): expose the canonical expression parser
bill-ph Aug 27, 2026
ef5b6a1
chore(hogql): compare canonical parser diagnostics
bill-ph Aug 27, 2026
84d95db
chore(hogql): add deterministic parser robustness corpus
bill-ph Aug 27, 2026
2e86b89
feat(hogql): add compiler diagnostics
bill-ph Aug 27, 2026
13771ba
feat(hogql): define the typed request envelope
bill-ph Aug 27, 2026
436b4b6
feat(hogql): carry typed query submissions
bill-ph Aug 27, 2026
677be76
feat(hogql): define semantic catalog snapshots
bill-ph Aug 27, 2026
c3db92e
feat(hogql): classify catalog snapshot failures
bill-ph Aug 27, 2026
1e8179f
feat(hogql): lower named parameter placeholders
bill-ph Aug 27, 2026
e8977a4
feat(hogql): cache semantic catalog snapshots
bill-ph Aug 27, 2026
e2a7590
feat(hogql): accept versioned request envelopes
bill-ph Aug 27, 2026
803cdcd
feat(hogql): bound semantic request bindings
bill-ph Aug 27, 2026
facd754
test(hogql): cover queued query lifecycle
bill-ph Aug 27, 2026
2a5bf4c
feat(hogql): decode semantic catalog manifests
bill-ph Aug 27, 2026
1ed6a1d
feat(hogql): lower ordering and pagination
bill-ph Aug 27, 2026
822e824
feat(hogql): bind typed parameter values
bill-ph Aug 27, 2026
f4a8c49
feat(hogql): refresh semantic catalogs asynchronously
bill-ph Aug 27, 2026
2cd09f4
feat(hogql): lower grouping and aggregates
bill-ph Aug 27, 2026
160056b
feat(hogql): validate temporal parameter literals
bill-ph Aug 27, 2026
4a459a2
feat(hogql): observe compilation outcomes
bill-ph Aug 27, 2026
114b7fb
feat(hogql): resolve semantic catalog tables
bill-ph Aug 27, 2026
6bcfdc3
fix(hogql): bound request envelope resources
bill-ph Aug 27, 2026
52a3ffe
fix(hogql): use Java IP literal validation
bill-ph Aug 27, 2026
bb8bc39
fix(hogql): declare parser dependency
bill-ph Aug 27, 2026
6b2de41
feat(hogql): resolve session semantic catalogs
bill-ph Aug 27, 2026
da732ad
feat(hogql): lower aliases and stock joins
bill-ph Aug 27, 2026
c1ce38c
test(hogql): verify semantic catalog wiring
bill-ph Aug 27, 2026
af43901
docs(hogql): document native coordinator frontend
bill-ph Aug 27, 2026
c22aaed
feat(hogql): prewarm catalog snapshots
bill-ph Aug 27, 2026
c50099c
feat(hogql): consume semantic catalog schema v2
bill-ph Aug 27, 2026
bca52ce
feat(hogql): lower ctes and derived tables
bill-ph Aug 27, 2026
09bc348
test(hogql): harden semantic catalog refresh
bill-ph Aug 27, 2026
1cbd28e
feat(hogql): lower sets and semantic catalog recipes
bill-ph Aug 27, 2026
7f0120e
feat(hogql): enforce function capabilities
bill-ph Aug 27, 2026
84b9d76
feat(hogql): expose native explain plans
bill-ph Aug 27, 2026
13eb5e1
feat(hogql): lower window semantics
bill-ph Aug 27, 2026
4ea65e5
feat(hogql): bound compiler concurrency
bill-ph Aug 27, 2026
73ce634
feat(hogql): lower collection access
bill-ph Aug 27, 2026
f25513d
feat(hogql): consume semantic relation recipes
bill-ph Aug 27, 2026
801a9be
perf(hogql): benchmark native compilation
bill-ph Aug 27, 2026
6a55493
feat(hogql): expand generic properties
bill-ph Aug 27, 2026
2cf9e2b
feat(hogql): lower null predicate rewrites
bill-ph Aug 27, 2026
3bd5fe5
feat(hogql): expand relationship paths
bill-ph Aug 27, 2026
b5b02ba
feat(hogql): apply semantic modifiers
bill-ph Aug 27, 2026
ca97146
feat(hogql): expand actions and cohorts
bill-ph Aug 27, 2026
fa8d7e7
feat(hogql): expand qualified stars
bill-ph Aug 27, 2026
08446d5
feat(hogql): expose physical catalog metadata
bill-ph Aug 27, 2026
113370d
feat(hogql): expand advanced column selectors
bill-ph Aug 27, 2026
c3efdde
feat(hogql): translate cast type syntax
bill-ph Aug 27, 2026
965bdb1
test(hogql): execute endpoint differentials
bill-ph Aug 27, 2026
4471ff5
feat(hogql): prune derived lazy projections
bill-ph Aug 27, 2026
64a1dc9
feat(hogql): compile canonical interval expressions
bill-ph Aug 27, 2026
35ca155
feat(hogql): compile correlated in subqueries
bill-ph Aug 27, 2026
f962704
feat(hogql): compile scalar subqueries
bill-ph Aug 27, 2026
7d16279
feat(hogql): resolve semantic correlations
bill-ph Aug 27, 2026
6b5128e
feat(hogql): propagate cte projection demand
bill-ph Aug 27, 2026
17081aa
feat(hogql): infer derived query outputs
bill-ph Aug 27, 2026
c342bed
feat(hogql): remap aliased projection demand
bill-ph Aug 27, 2026
afb87dd
feat(hogql): propagate set operation demand
bill-ph Aug 27, 2026
2b4b76a
feat(hogql): compile pivot relations
bill-ph Aug 27, 2026
8ef8d1d
feat(hogql): freeze the v0 compiler profile
bill-ph Aug 28, 2026
130cf8b
feat(hogql): pin authenticated catalog generations
bill-ph Aug 28, 2026
5dc283d
chore(hogql): identify release artifacts
bill-ph Aug 28, 2026
099c57e
fix(hogql): verify release image provenance
bill-ph Aug 28, 2026
ad1477b
feat(hogql): lower additional query syntax
bill-ph Aug 28, 2026
3eba4f9
feat(hogql): add common function rewrites
bill-ph Aug 28, 2026
d234327
fix(hogql): pass through physical CTE schemas
bill-ph Aug 28, 2026
f939043
feat(hogql): lower conditional functions
bill-ph Aug 28, 2026
38aefcb
feat(hogql): lower json extraction functions
bill-ph Aug 28, 2026
19ac03c
feat(hogql): lower date time compatibility
bill-ph Aug 28, 2026
e52d7c0
feat(hogql): lower scalar syntax sugar
bill-ph Aug 28, 2026
c94d373
feat(hogql): lower scalar compatibility functions
bill-ph Aug 28, 2026
5f6a9f4
feat(hogql): lower regex compatibility functions
bill-ph Aug 28, 2026
2b71c9a
feat(hogql): lower aggregate combinators
bill-ph Aug 28, 2026
68cfc5d
feat(hogql): lower numeric conversions
bill-ph Aug 28, 2026
9224cf1
feat(hogql): lower array compatibility functions
bill-ph Aug 28, 2026
e547eae
fix(hogql): preserve array edge semantics
bill-ph Aug 28, 2026
c5e9383
feat(hogql): lower expression and date aliases
bill-ph Aug 28, 2026
5a7cf9d
feat(hogql): lower extended json and regex functions
bill-ph Aug 28, 2026
e52bab0
feat(hogql): lower remaining scalar aliases
bill-ph Aug 28, 2026
8c4b623
feat(hogql): map final stock function aliases
bill-ph Aug 28, 2026
a9a8b48
feat(hogql): preserve windows on aggregate rewrites
bill-ph Aug 28, 2026
e5f4d43
feat(hogql): lower array join expressions
bill-ph Aug 28, 2026
ed2bb84
feat(hogql): lower final stock compatibility aliases
bill-ph Aug 28, 2026
80ec328
feat(hogql): lower exposed scalar aliases
bill-ph Aug 28, 2026
ff567cd
feat(hogql): lower division alias
bill-ph Aug 28, 2026
32210f4
feat(hogql): lower static survey responses
bill-ph Aug 28, 2026
6044ffd
fix(hogql): delimit property identifiers
bill-ph Aug 28, 2026
7b8e76b
feat(hogql): preserve local set operand clauses
bill-ph Aug 28, 2026
2ca7c87
fix(hogql): resolve derived set output scope
bill-ph Aug 28, 2026
8878d05
feat(hogql): lower comparison aliases
bill-ph Aug 28, 2026
924c42e
feat(hogql): lower parametric aggregates
bill-ph Aug 28, 2026
ea77ff9
feat(hogql): lower exposed aggregate aliases
bill-ph Aug 28, 2026
d162483
feat(hogql): lower array key sorting
bill-ph Aug 28, 2026
e8b7441
feat(hogql): lower iso day of week
bill-ph Aug 28, 2026
f8812be
feat(hogql): lower numbers table function
bill-ph Aug 28, 2026
80f5133
feat(hogql): lower dynamic json paths
bill-ph Aug 28, 2026
9d56813
feat(hogql): lower addition alias
bill-ph Aug 28, 2026
efad11d
feat(ducklake): add clickhouse cityhash64
bill-ph Aug 28, 2026
65d737c
feat(hogql): route cityhash64 compatibility
bill-ph Aug 28, 2026
061f340
feat(hogql): lower limit by queries
bill-ph Aug 28, 2026
8872c8f
feat(hogql): lower map constructors and updates
bill-ph Aug 28, 2026
d661b55
fix(hogql): bound large set query lowering
bill-ph Aug 28, 2026
31a10c7
feat(hogql): bind scoped placeholders
bill-ph Aug 28, 2026
5fb929f
feat(ducklake): add readable time delta compatibility
bill-ph Aug 28, 2026
c899d7a
feat(hogql): lower template strings
bill-ph Aug 28, 2026
70f1446
feat(hogql): lower left any joins
bill-ph Aug 28, 2026
629ef0a
feat(hogql): support remaining week functions
bill-ph Aug 28, 2026
0bacabb
feat(hogql): lower hogqlx tags
bill-ph Aug 28, 2026
9d42e45
feat(hogql): lower nested expression aliases
bill-ph Aug 28, 2026
70bf7df
feat(hogql): expand scalar with aliases
bill-ph Aug 28, 2026
901c2dc
feat(hogql): lower inner any joins
bill-ph Aug 28, 2026
05f39a7
feat(hogql): lower subtract days
bill-ph Aug 28, 2026
748431e
feat(hogql): load exchange rate snapshots
bill-ph Aug 28, 2026
494bade
feat(ducklake): add exchange rate conversion engine
bill-ph Aug 28, 2026
4ae0352
fix(hogql): allow unaliased derived table columns
bill-ph Aug 28, 2026
b4a9dab
feat(hogql): lower currency conversions
bill-ph Aug 28, 2026
34b2da0
feat(hogql): execute pinned currency conversions
bill-ph Aug 28, 2026
edd2a6b
feat(hogql): compile catalog-backed corpus semantics
bill-ph Aug 28, 2026
8593ae8
feat(hogql): support typed emptiness checks
bill-ph Aug 28, 2026
6fa2666
test(hogql): validate corpus execution compatibility
bill-ph Aug 28, 2026
4669d75
fix(hogql): align semantic catalog payload limit
bill-ph Aug 28, 2026
ae63d02
fix(hogql): close corpus analyzer compatibility gaps
bill-ph Aug 28, 2026
58cedd9
chore: merge ducklake connector deployment updates
bill-ph Aug 28, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions core/docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,20 @@ RUN \
FROM registry.access.redhat.com/hi/core-runtime:latest
ARG JDK_VERSION
ARG ARCH
ARG TRINO_SOURCE_REVISION
ARG HOGQL_LANGUAGE_VERSION
ARG HOGQL_CATALOG_PROTOCOL_VERSION
ARG HOGQL_CATALOG_SCHEMA_VERSION
ARG TRINO_SERVER_SHA256
ARG TRINO_CLI_SHA256
LABEL org.opencontainers.image.revision="${TRINO_SOURCE_REVISION}" \
io.posthog.trino.ducklake.revision="${TRINO_SOURCE_REVISION}" \
io.posthog.trino.hogql.compiler-build="${TRINO_SOURCE_REVISION}" \
io.posthog.trino.hogql.language-version="${HOGQL_LANGUAGE_VERSION}" \
io.posthog.trino.hogql.catalog-protocol-version="${HOGQL_CATALOG_PROTOCOL_VERSION}" \
io.posthog.trino.hogql.catalog-schema-version="${HOGQL_CATALOG_SCHEMA_VERSION}" \
io.posthog.trino.server-sha256="${TRINO_SERVER_SHA256}" \
io.posthog.trino.cli-sha256="${TRINO_CLI_SHA256}"
ENV JAVA_HOME="/usr/lib/jvm/${JDK_VERSION}"
ENV PATH=$PATH:$JAVA_HOME/bin
ENV LANG=C.UTF-8
Expand Down
53 changes: 52 additions & 1 deletion core/docker/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@ TEMURIN_RELEASE=$("${SOURCE_DIR}/mvnw" -f "${SOURCE_DIR}/pom.xml" --quiet help:e
TEMURIN_DOWNLOAD_URL="https://api.adoptium.net/v3/binary/version/{release_name}/linux/{arch}/jdk/hotspot/normal/eclipse?project=jdk"

SKIP_TESTS=false
EXPLICIT_TRINO_SOURCE_REVISION="${TRINO_SOURCE_REVISION:-}"
TRINO_SOURCE_REVISION="${EXPLICIT_TRINO_SOURCE_REVISION}"
if [ -z "${TRINO_SOURCE_REVISION}" ] && git -C "${SOURCE_DIR}" rev-parse HEAD >/dev/null 2>&1; then
TRINO_SOURCE_REVISION="$(git -C "${SOURCE_DIR}" rev-parse HEAD)"
fi
TRINO_SOURCE_REVISION="${TRINO_SOURCE_REVISION:-unknown}"
HOGQL_LANGUAGE_VERSION="${HOGQL_LANGUAGE_VERSION:-1.0.0}"
HOGQL_CATALOG_PROTOCOL_VERSION="${HOGQL_CATALOG_PROTOCOL_VERSION:-1}"
HOGQL_CATALOG_SCHEMA_VERSION="${HOGQL_CATALOG_SCHEMA_VERSION:-2}"

while getopts ":a:h:r:p:t:j:x" o; do
case "${o}" in
Expand Down Expand Up @@ -72,13 +81,26 @@ while getopts ":a:h:r:p:t:j:x" o; do
done
shift $((OPTIND - 1))

if [ -n "${TRINO_VERSION}" ] && [ -z "${EXPLICIT_TRINO_SOURCE_REVISION}" ]; then
echo >&2 "TRINO_SOURCE_REVISION must be set when building downloaded release artifacts"
exit 1
fi

function check_environment() {
if ! command -v jq &> /dev/null; then
echo >&2 "Please install jq"
exit 1
fi
}

function sha256_file() {
if command -v sha256sum &> /dev/null; then
sha256sum "$1" | awk '{print $1}'
else
shasum -a 256 "$1" | awk '{print $1}'
fi
}

function temurin_download_uri() {
local RELEASE_NAME="${1}"
local ARCH="${2}"
Expand Down Expand Up @@ -112,6 +134,8 @@ else
trino_server="${SOURCE_DIR}/core/${SERVER_ARTIFACT}/target/${SERVER_ARTIFACT}-${TRINO_VERSION}.tar.gz"
trino_client="${SOURCE_DIR}/client/trino-cli/target/trino-cli-${TRINO_VERSION}-executable.jar"
fi
TRINO_SERVER_SHA256="$(sha256_file "${trino_server}")"
TRINO_CLI_SHA256="$(sha256_file "${trino_client}")"

echo "🧱 Preparing the image build context directory"
WORK_DIR="$(mktemp -d)"
Expand All @@ -138,11 +162,39 @@ for arch in "${ARCHITECTURES[@]}"; do
--build-arg ARCH="${arch}" \
--build-arg JDK_VERSION="${TEMURIN_RELEASE}" \
--build-arg JDK_DOWNLOAD_LINK="${JDK_DOWNLOAD_LINK}" \
--build-arg TRINO_SOURCE_REVISION="${TRINO_SOURCE_REVISION}" \
--build-arg HOGQL_LANGUAGE_VERSION="${HOGQL_LANGUAGE_VERSION}" \
--build-arg HOGQL_CATALOG_PROTOCOL_VERSION="${HOGQL_CATALOG_PROTOCOL_VERSION}" \
--build-arg HOGQL_CATALOG_SCHEMA_VERSION="${HOGQL_CATALOG_SCHEMA_VERSION}" \
--build-arg TRINO_SERVER_SHA256="${TRINO_SERVER_SHA256}" \
--build-arg TRINO_CLI_SHA256="${TRINO_CLI_SHA256}" \
--platform "linux/$arch" \
-f Dockerfile \
-t "${TAG}-$arch"
done

function require_image_label() {
local image="$1"
local name="$2"
local expected="$3"
local actual
actual="$(docker image inspect --format "{{index .Config.Labels \"${name}\"}}" "${image}")"
if [ "${actual}" != "${expected}" ]; then
echo >&2 "Image label ${name} is ${actual}, expected ${expected}"
exit 1
fi
}

for arch in "${ARCHITECTURES[@]}"; do
image="${TAG}-${arch}"
require_image_label "${image}" "org.opencontainers.image.revision" "${TRINO_SOURCE_REVISION}"
require_image_label "${image}" "io.posthog.trino.hogql.language-version" "${HOGQL_LANGUAGE_VERSION}"
require_image_label "${image}" "io.posthog.trino.hogql.catalog-protocol-version" "${HOGQL_CATALOG_PROTOCOL_VERSION}"
require_image_label "${image}" "io.posthog.trino.hogql.catalog-schema-version" "${HOGQL_CATALOG_SCHEMA_VERSION}"
require_image_label "${image}" "io.posthog.trino.server-sha256" "${TRINO_SERVER_SHA256}"
require_image_label "${image}" "io.posthog.trino.cli-sha256" "${TRINO_CLI_SHA256}"
done

echo "🧹 Cleaning up the build context directory"
rm -r "${WORK_DIR}"

Expand All @@ -157,4 +209,3 @@ else
docker image inspect -f '🚀 Built {{.RepoTags}} {{.Id}}' "${TAG}-$arch"
done
fi

220 changes: 220 additions & 0 deletions core/trino-hogql-compiler/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
# Native HogQL compiler

This module compiles HogQL directly to Trino's public SQL AST. It deliberately
does not render an intermediate SQL string or add HogQL nodes to Trino's
analyzer and planner.

The implementation is split into two modules:

- `trino-hogql-parser` owns the HogQL grammar and a private, source-located
parser AST. It has no dependency on Trino's SQL tree.
- `trino-hogql-compiler` is the only translation boundary. It converts every
parser node into an `io.trino.sql.tree` node.

The coordinator submits the resulting statement through the standard Trino
analysis, planning, scheduling, paging, and cancellation paths. The original
HogQL text remains the query text used by limits, history, and resource-group
selection.

## M0 contract

M0 accepts a deliberately small grammar:

```text
SELECT <projection> [, ...] [FROM <qualified physical table>]
```

Projections can be `*`, qualified column references, integers, strings,
booleans, or `NULL`. Identifiers can be unquoted, double quoted, or backquoted.
The parser rejects unsupported clauses and multiple statements instead of
silently interpreting them as SQL.

## M1 syntax contract

`HogQlParser.parseSyntax` accepts the complete canonical read-only query entry
point and returns an immutable, source-located tree containing grammar rules,
ANTLR alternative labels when present, and tokens. The tree contains no ANTLR
or Trino SQL objects. It classifies declarative HogQLX separately from read-only
queries.

This syntax contract is intentionally independent from executable lowering.
`HogQlParser.parseStatement` and `HogQlCompiler.compile` continue to return an
explicit error for valid constructs that do not yet have a stock Trino AST
mapping. Adding syntax support therefore cannot silently claim semantic or
execution parity.

## Executable contract

The MVP lowers a frozen, fail-closed subset directly to stock Trino AST nodes:

- logical `events` and `persons` tables supplied by a pinned Duckgres manifest;
- scalar VARCHAR JSON property reads and the `events.person` lazy relationship;
- parameters, CTEs, subqueries, joins, set operations, arrays, maps, rows,
intervals, grouping, ordering, limits, and windows that have exact stock
Trino representations;
- `LIMIT BY` over explicit projected outputs, lowered through a partitioned
`row_number` query while preserving global ordering and pagination;
- numeric/conditional/string functions (`abs`, `coalesce`, `if`, `lower`, `upper`, `length`,
`concat`, `replace`), collection functions (`map`, `arraySort`,
`arrayDistinct`, `arrayFlatten`, `arrayStringConcat`), date functions
(`dateAdd`, `dateDiff`, `dateTrunc`), aggregates (`count`, `sum`, `min`,
`max`, `avg`, `any`, `argMin`, `argMax`, `array_agg`), and windows
(`first_value`, `rank`, `row_number`).

The compatibility extension also lowers conditional aggregates (`countIf`,
`sumIf`, `minIf`, `maxIf`, `avgIf`, `anyIf`, `argMaxIf`, `groupArrayIf`,
`uniqIf`, `uniqExactIf`, and `groupUniqArrayIf`), distinct aggregates
(`uniqExact`, `countDistinct`, and `groupUniqArray`), and `multiIf` directly to
stock Trino aggregate filters, DISTINCT aggregates, and searched CASE
expressions.
Aggregate rewrites preserve `OVER` specifications when the target Trino
aggregate is used as a window function.
JSON extraction lowers literal and runtime string/integer segments to Trino
JSON paths with HogQL-compatible defaults. The compatibility profile also
supports the corpus's typed map and key/value extraction forms through checked
JSON-to-map casts.
Date/time compatibility includes calendar arithmetic, interval-day values,
epoch conversion, timezone attachment/conversion, formatting, and checked
best-effort timestamp parsing.
Array-form membership and the nullish operator lower to stock `IN`, `IF`, and
`COALESCE` nodes, including nullable empty-membership behavior.
Function-form boolean/comparison operators and common string/math aliases
lower to their equivalent stock operators and functions. Checked/defaulting
float conversions, Decimal64 casts, and integer division lower to stock casts
and arithmetic.
Literal regex extraction preserves HogQL's capture-group and empty-default
behavior; matching and replace-all lower to Trino regex functions.
The extended profile also lowers extract-all and first-match replacement, plus
boolean, unsigned-integer, raw-array, and nested raw-map JSON extraction.
Common array transforms, predicates, indexing, summation, ranges, tuple
indexing, splitting, and membership lower to Trino higher-order functions.
Map key/value constructors and `mapUpdate` lower to stock map construction and
last-map-wins concatenation.
The row-expanding `arrayJoin` function is hoisted to a generated lateral
`CROSS JOIN UNNEST`; repeated calls remain independent row expansions.
Range and membership rewrites preserve empty-range and null-search behavior.
Typed defaults for out-of-range and no-match element lookups require resolved
element types and remain outside the frozen compatibility subset.
Expression-form comparison, arithmetic, membership, tuples, nullability
assertions, string splitting, month arithmetic, and common window aliases also
lower to stock Trino nodes.
Additional scalar coverage includes array slicing/enumeration, UUID and integer
conversion, JSON existence/value/serialization, hashing, powers, UTF-8
substrings, banker-rounding aliases, and conditional median aggregation.
Simple floor, calendar-part, map construction, and null-predicate aliases are
mapped to their stock equivalents. Two-bound ranges, comparison and
subtraction aliases, calendar month/year extraction, ceiling aliases, narrow
integer casts, and JSON object-key extraction also lower to stock expressions.
The static-ID, single-choice `getSurveyResponse(index, question_id)` macro
prefers the modern response property and falls back to the legacy index key.
Parametric quantiles lower to Trino percentile aggregates, and limited
conditional group arrays lower to filtered `array_agg` plus `slice`.
Algorithm-level parity for `quantileExact` remains a compatibility-validation
item even though its query shape has a stock AST lowering.

Function aliases are resolved before Trino analysis. Unknown functions fail as
HogQL resolution errors. The corpus compatibility extension also accepts every
logical table declared by the pinned manifest and expands declarative actions
by name or ID into stock predicates or relation membership. Cohorts, saved
queries, explicit modifiers without an enabled behavior, HogQLX,
PIVOT/UNPIVOT execution, unsupported ClickHouse clauses, and complete
type/function parity remain outside the endpoint profile.

Set `hogql.enabled=true` on the coordinator to register `POST /v1/hogql`. The
request body is the versioned JSON envelope containing the raw HogQL query,
language/protocol versions, and optional typed bindings. The response uses
Trino's existing statement protocol. Follow-up result and cancellation URIs
remain under `/v1/statement`.
The endpoint is absent when the property is false, which is the default.
Production compilation uses a dedicated fixed-size executor with a bounded
queue and the `hogql.compilation-timeout` wall-time limit. Saturation and
timeout return retryable insufficient-resource errors; standard SQL bypasses
the compiler executor.

Development is based on the fork's `ducklake-connector` integration branch. At
the start of this milestone its head was `posthog-484-ducklake.9`, commit
`3065d56e4d5e256962c8297b4299909db8301c0a`.

Charts `main` still provides the deployment compatibility baseline:
`posthog-484-ducklake.6` at commit
`3bb054e5b80bc6ad740b26f6748b7b3f5548ff32`, published as
`ghcr.io/posthog/trino:484-ducklake.6`. Its linux/arm64 digest is
`sha256:85d2b37dfb7c966a1bfe7b0470efaa6a0116c86cb6a05d14a6bdc8c02f7a6787`.

## Fork maintenance

The `ducklake-connector` branch's common ancestor with `trinodb/trino` is
`67f588f0c81b21b425e1a43b05d70f9cf8798d6c`. The first nine PostHog commits
produce the Charts `main` `.6` baseline:

1. `a002cc56980` adds the DuckLake connector and PostHog image workflow.
2. `4cd0573a57f` adds column-name mapping.
3. `500cdf40aa3` fixes Parquet millisecond timestamp reads.
4. `c03df89358a` reads fully visible partial files.
5. `6ef914e4149` splits large data files.
6. `09690b4fc8b` pools metadata connections and supports password files.
7. `e6c3fbd9d83` adds the PostgreSQL catalog store.
8. `0bab82c7520` counts rows from catalog metadata.
9. `3bb054e5b80` reads Parquet footers using the recorded size.

The rolling integration branch continues through `.7`-`.9` with the DuckLake
write path, Trino views and schema evolution, partitioned-table reads, field-ID
based reads, and missing-file-column handling. Merge commits and CI maintenance
also live on this line; inspect the exact range from the upstream common
ancestor rather than assuming the release-tag history is linear.

Keep native HogQL changes as a separate ordered stack above those commits:
parser/compiler modules, coordinator submission seam, metadata provider,
optional functions, then packaging and tests. During an upstream update, fetch
`trinodb/trino`, identify the new common ancestor, rebase the DuckLake series,
then rebase the HogQL series onto `ducklake-connector`. Resolve AST API changes
in `TrinoAstFactory` and submission conflicts in `QueuedStatementResource`,
`DispatchManager`, and `QueryPreparer`; do not introduce HogQL branches into
later execution stages.
Run the unchanged SQL/coordinator suites, the complete DuckLake suite, and the
HogQL suite before creating a release tag.

`.github/workflows/docker-publish-posthog.yml` publishes linux/arm64 images.
Pushing `posthog-<image-tag>` builds the complete distribution and publishes
`ghcr.io/posthog/trino:<image-tag>`; a manual workflow dispatch accepts the same
image-tag without the `posthog-` prefix. The workflow intentionally skips tests
and checks, so its source commit must already have passed the suites above.

## Validation

On a fresh checkout, install their reactor dependencies without running tests:

```shell
./mvnw -pl :trino-hogql-parser,:trino-hogql-compiler,:trino-main -am install \
-DskipTests
```

Then run the parser, compiler, and coordinator tests together:

```shell
./mvnw -pl :trino-hogql-parser,:trino-hogql-compiler,:trino-main test \
-Dtest=TestHogQlParser,TestHogQlCompiler,TestQueryPreparer,TestHogQlConfig,TestHogQlStatementResource \
-Dsurefire.failIfNoSpecifiedTests=false
```

The compiler tests compare the shared SQL subset with Trino's SQL parser,
format and reparse the generated tree, verify source locations, and assert that
no private HogQL AST node crosses the compiler boundary.

Measure the standard SQL preparation path with and without the compiler
available using `BenchmarkQueryPreparer`. On JDK 25, enable annotation
processing when generating the JMH benchmark index:

```shell
./mvnw -pl :trino-main clean test-compile exec:exec \
-Dmaven.compiler.proc=full \
-Dexec.executable=java \
-Dexec.classpathScope=test \
-Dexec.args='-cp %classpath io.trino.execution.BenchmarkQueryPreparer'
```

On 2026-08-26, one linux/arm64 Temurin 25 fork measured standard SQL
preparation at `3.792 ± 0.096 us/op` with the HogQL compiler available and
`3.708 ± 0.066 us/op` without it. The confidence intervals overlap; this M0
sample does not show a distinguishable unused-path regression. Retain the
benchmark for repeated measurements on release hardware.
Loading
Loading