Skip to content

[Java]Add Support for DateTime, Array, Tuple, Float32, Float64 in ClickHouseIO parseDefaultExpression (#33692) - #36059

Closed
Suvrat1629 wants to merge 6 commits into
apache:masterfrom
Suvrat1629:clickhouse
Closed

[Java]Add Support for DateTime, Array, Tuple, Float32, Float64 in ClickHouseIO parseDefaultExpression (#33692)#36059
Suvrat1629 wants to merge 6 commits into
apache:masterfrom
Suvrat1629:clickhouse

Conversation

@Suvrat1629

Copy link
Copy Markdown
Contributor

Please add a meaningful description for your change here


This PR fixes #33692 by adding support for DateTime, Array, Tuple, Float32, and Float64 in TableSchema.parseDefaultExpression for ClickHouseIO. The method now parses default expressions for these types, with recursive handling for Array and Tuple, ensuring compatibility with Beam schemas.

Thank you for your contribution! Follow this checklist to help us incorporate your contribution quickly and easily:

  • Mention the appropriate issue in your description (for example: addresses #123), if applicable. This will automatically add a link to the pull request in the issue. If you would like the issue to automatically close on merging the pull request, comment fixes #<ISSUE NUMBER> instead.
  • Update CHANGES.md with noteworthy changes.
  • If this contribution is large, please file an Apache Individual Contributor License Agreement.

See the Contributor Guide for more tips on how to make review process smoother.

To check the build health, please visit https://github.com/apache/beam/blob/master/.test-infra/BUILD_STATUS.md

GitHub Actions Tests Status (on master branch)

Build python source distribution and wheels
Python tests
Java tests
Go tests

See CI.md for more information about GitHub Actions CI or the workflows README to see a list of phrases to trigger workflows.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Summary of Changes

Hello @Suvrat1629, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly expands the data type handling capabilities within the ClickHouseIO connector. It enables the parseDefaultExpression method to correctly interpret and process default values for several complex and common data types, thereby improving the robustness and compatibility of data ingestion and processing with Beam schemas.

Highlights

  • New Data Type Support: Added support for DateTime, Array, Tuple, Float32, and Float64 in TableSchema.parseDefaultExpression for ClickHouseIO.
  • Recursive Parsing: Implemented recursive parsing logic for Array and Tuple types to correctly handle nested structures.
  • Beam Schema Compatibility: Enhanced parsing ensures better compatibility with Beam schemas for the newly supported data types.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@github-actions

github-actions Bot commented Sep 5, 2025

Copy link
Copy Markdown
Contributor

Checks are failing. Will not request review until checks are succeeding. If you'd like to override that behavior, comment assign set of reviewers

@github-actions

github-actions Bot commented Sep 5, 2025

Copy link
Copy Markdown
Contributor

Assigning reviewers:

R: @Abacn for label java.

Note: If you would like to opt out of this review, comment assign to next reviewer.

Available commands:

  • stop reviewer notifications - opt out of the automated review tooling
  • remind me after tests pass - tag the comment author after tests pass
  • waiting on author - shift the attention set back to the author (any comment or push by the author will return the attention set to the reviewers)

The PR bot will only process comments in the main thread (not review comments).

@Suvrat1629

Copy link
Copy Markdown
Contributor Author

@Abacn gentle ping could you please take a look at this.
Thank you.

@Abacn
Abacn self-requested a review September 9, 2025 17:14

@Abacn Abacn left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for working on this. Left a few comments. cc: @BentsiLeviav

throw new IllegalArgumentException("Invalid DateTime/Date format: " + value, e);
}
case ARRAY:
// ClickHouse Array format: '[1,2,3]' or '["a","b"]'

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I wonder if we can use a third party lib to parse array, or there is any tool within clickhouse library supporting this. This sounds fragile.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I think perhaps @BentsiLeviav could help with something as I myself do not have much experience with Clickhouse.

@BentsiLeviav

BentsiLeviav commented Sep 11, 2025

Copy link
Copy Markdown
Contributor

Hi folks

First, @Suvrat1629 , huge thanks for the contribution.

I needed to be more specific and detailed in #33692, my apologies.

As of today, this is the existing behavior:

  • We only take care of DEFAULT type (we don't take care of default types that are of the form of Materialization and Alias)
  • Even for Default, we have a small set of supported types
  • We don't use the defaults as of this moment - the RowBinary format doesn't use them, and they are just being ignored.
  • This functionality is not supposed to be handled on the client side (as it is impossible to materialize all ClickHouse expressions in Java), and ClickHouse created the RowBinaryWithDefaults format to move the defaults handling into the database itself.

Is there any other place we use this?

Yes.
When we implemented the BigQuery to ClickHouse Dataflow template, we received from BigQuery TableRow - a schemaless object. In order to convert it to schema schema-aware type, we fetched the schema from ClickHouse and used this function to convert each string value to the proper Java representation.

The original idea behind #33692 was not only to add these types, but also to solve/decouple the tension between the different needs (the first need is to evaluate defaults, the second is to evaluate primitive values).

As I commented here #33692 (comment), we plan to upgrade the ClickHouse client, support the use of RowBinaryWithDefaults, and refactor the parseDefaultExpression to work with primitive types only.

Suggested implementation in this PR

The main issue with the existing implementation (that is being extended with this PR) is that in case users use none primitive default values (which is usually the case), the entire pipe will collapse.

For instance, given the following target table:

CREATE OR REPLACE TABLE test
(
    id UInt64,
    updated_at DateTime DEFAULT now(),
    updated_at_date Date DEFAULT toDate(updated_at)
)
ENGINE = MergeTree
ORDER BY id;

The DESRIBE command output will be:

image

and the entire pipe will get broken (the code will try to create a DateTime object of the string now()).

So to conclude, the right solution for this problem would be to implement support for the RowBinaryWithDefaults format and refactor+rename the parseDefaultExpression to support only primitive objects.

@Suvrat1629 I really appreciate the time and effort you put into this, and my apologies for not being more detailed abou this in the original issue.

CC @Abacn

@Suvrat1629

Copy link
Copy Markdown
Contributor Author

@BentsiLeviav Thanks for the response
That is a lot of information to register but I have gone through the code and come up with an implementation. I want to verify the approach first as I do not have a lot of experience with Clickhouse and this would save me time also.
My approach:

In ClickHouseIO.java:

  • Change the format specification from RowBinary to RowBinaryWithDefaults
  • Update the method call to use the new primitive-only parsing method

In TableSchema.java:

  • Add a new method called parsePrimitiveValue that only handles simple literals
  • This method will detect complex expressions anything with parentheses, function names like "now", "toDate", etc. and return null for them
  • Mark the existing parseDefaultExpression method as deprecated
  • The deprecated method can delegate to the new one for backward compatibility

In ClickHouseWriter.java:

  • Completely rewrite the writeRow method to support the new format
  • Before writing each column value, write a flag byte
  • If we have no value and no client-side default, write the "use server default" flag
  • If we have a value either from input or client-side default, write the "use provided value" flag followed by the actual data

Does this fit right? Provide me comments to improve this @BentsiLeviav @Abacn

@BentsiLeviav

Copy link
Copy Markdown
Contributor

Hi @Suvrat1629,

After discussing internally, I need to share some important context:
The ClickHouse Java client V2 already includes:

  • Built-in schema implementation (replacing our custom one)
  • Native RowBinaryWithDefaults handling

This means implementing the current approach would create code we'd immediately need to remove.
Additionally, using the new Java client will require breaking the API. IIRC (@Abacn, please advise), this will require updating the Dataflow template (which shares a global Beam version), adding significant testing overhead and coordination complexity.

Given that we plan to start the V2 migration refactor in the near future, it would be more efficient for us to address this issue as part of that comprehensive update rather than implementing a temporary solution now.

I really appreciate your enthusiasm and the time you've invested in understanding this issue. Would you be interested in picking up a different issue that won't be affected by the upcoming refactor?

In addition, did you implement this due to limitations you have with ClickHouse and Beam related to default values? If so, can you share more about your use case and about the issues you encounter in your pipeline?

@Suvrat1629

Copy link
Copy Markdown
Contributor Author

@BentsiLeviav Ok sure I just picked up the issue because I thought I had found a fix for this but if you plan on implementing a fix for it yourself I am ok closing this pr :)

@Suvrat1629 Suvrat1629 closed this Sep 14, 2025
@Suvrat1629
Suvrat1629 deleted the clickhouse branch September 14, 2025 15:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Missing Type Implementations in parseDefaultExpression for ClickHouseIO

3 participants