Skip to content

Conversation

@matt-metivier
Copy link

@matt-metivier matt-metivier commented Jan 25, 2026

Problem

Users cannot use CAST(column AS Type) syntax in HogQL. The immediate need is casting String columns to JSON type for the Query API. We intentionally avoid exposing raw CAST syntax to keep type strings non-user-controlled.

Flow:

  1. User writes HogQL: toJSON(properties)
  2. Parser: Creates ast.Call(name="toJSON", args=[properties])
  3. Function Registry: conversions.py registers "toJSON": HogQLFunctionMeta("toJSON", 1, 1)
  4. Printer (base.py line 523): Special handling converts to CAST({expr} AS JSON)
  5. Output: CAST(events.properties AS JSON)

Closes #29816

Changes

  • Added toJSON(x) HogQL function that prints CAST(x AS JSON) in ClickHouse
  • Kept CAST(expr AS type) syntax unsupported to avoid user-controlled type strings
  • Added parser test asserting CAST syntax is rejected
  • Added printer test asserting toJSON() outputs CAST(... AS JSON)

How did you test this code?

Added unit tests in:

  • posthog/hogql/test/_test_parser.py - parser test for CAST rejection
  • posthog/hogql/printer/test/test_printer.py - printer test for toJSON() output

Publish to changelog?

Yes

Notes

@matt-metivier matt-metivier requested a review from a team as a code owner January 25, 2026 17:03
Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3 files reviewed, 3 comments

Edit Code Review Agent Settings | Greptile

@matt-metivier matt-metivier changed the title [#29816](https://github.com/PostHog/posthog/issues/29816): Add CAST to list of supported ClickHouse functions [#29816]: Add CAST to list of supported ClickHouse functions Jan 25, 2026
@matt-metivier
Copy link
Author

@sakce or @orian Whenever you've time, can you give me a review. First time doing any work on PostHog, please let me know if their is anything you want different to match posthog style.

I did review this before writing the pr- https://posthog.com/handbook/engineering/conventions/backend-coding

@rafaeelaudibert
Copy link
Member

Pinginfg @Gilbert09 since I considered doing this in the past and was told this was possibly too dangerous

@matt-metivier
Copy link
Author

Pinginfg @Gilbert09 since I considered doing this in the past and was told this was possibly too dangerous

I was taking another look through the code, I do see y'all hardcode in conversions.py to make sure the type string is never user-controlled.

I guess the risk with CAST(expr AS Type) is that the type is a raw string that gets inserted into the SQL. Even with validation, there's that risk.

@matt-metivier
Copy link
Author

Going to update the code to instead of CAST(x AS JSON), add explicit functions:

"castToJSON": HogQLFunctionMeta("CAST", 1, 1, suffix_args=[ast.Constant(value="JSON")]),
"castToString": HogQLFunctionMeta("CAST", 1, 1, suffix_args=[ast.Constant(value="String")]),

Then a user would write: castToJSON(properties) instead of CAST(properties AS JSON)

@matt-metivier matt-metivier force-pushed the feature/add-cast-function branch 2 times, most recently from e40ce21 to e126c1c Compare January 25, 2026 18:07
@matt-metivier matt-metivier force-pushed the feature/add-cast-function branch from e126c1c to ba13a06 Compare January 25, 2026 18:17
@georgemunyoro
Copy link
Contributor

georgemunyoro commented Jan 25, 2026

@matt-metivier Appreciate the contribution! I don’t have full ClickHouse context here (Tom will have more insight), but language-wise you’ll also need to update the c++ parser. While we keep the parsers in sync, in practice we currently really only use the c++ one.

That said, we’re in the middle of transitioning to a new, language-agnostic parser that outputs JSON instead of python objects. Because of that, there’s no need to update the legacy c++ parser, just the new JSON one.

@matt-metivier matt-metivier force-pushed the feature/add-cast-function branch from ba13a06 to 61e88fd Compare January 25, 2026 18:22
@matt-metivier
Copy link
Author

matt-metivier commented Jan 25, 2026

  • contents/docs/sql/clickhouse-functions.mdx

Didn't realize this, thank you for mentioning it. I updated it and I opened a pr to update the docs in case we decide to go with this path pending @Gilbert09 approval.
PostHog/posthog.com#14549

Flow:

  1. User writes HogQL: toJSON(properties)
  2. Parser: Creates ast.Call(name="toJSON", args=[properties])
  3. Function Registry: conversions.py registers "toJSON": HogQLFunctionMeta("toJSON", 1, 1)
  4. Printer (base.py line 523): Special handling converts to CAST({expr} AS JSON)
  5. Output: CAST(events.properties AS JSON)

matt-metivier added a commit to matt-metivier/posthog.com that referenced this pull request Jan 25, 2026
Related to PostHog/posthog#45876 which adds the toJSON function
for converting values to the ClickHouse JSON type.
matt-metivier added a commit to matt-metivier/posthog.com that referenced this pull request Jan 25, 2026
Related to PostHog/posthog#45876 which adds the toJSON function
for converting values to the ClickHouse JSON type.
matt-metivier added a commit to matt-metivier/posthog.com that referenced this pull request Jan 25, 2026
- Added toJSON to clickhouse-functions.mdx type conversions list
- Added toJSON to data-access.mdx type conversion functions list
- Added toJSON example in useful-functions.mdx JSON section

Related to PostHog/posthog#45876
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.

Feature Request: Add CAST to list of supported ClickHouse functions

3 participants