Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support timestamp type in mysql jdbc connector #21937

Merged
merged 1 commit into from
Feb 21, 2024

Conversation

hantangwangd
Copy link
Member

@hantangwangd hantangwangd commented Feb 15, 2024

Description

Fix issue #21731. Support column type: timestamp in mysql connector.

Test Plan

  • Newly added test case in TestMySqlIntegrationSmokeTest.testMysqlTimestamp()

Contributor checklist

  • Please make sure your submission complies with our development, formatting, commit message, and attribution guidelines.
  • PR description addresses the issue accurately and concisely. If the change is non-trivial, a GitHub Issue is referenced.
  • Documented new properties (with its default value), SQL syntax, functions, or other functionality.
  • If release notes are required, they follow the release notes guidelines.
  • Adequate tests were added if applicable.
  • CI passed.

Release Notes

== RELEASE NOTES ==

Mysql Changes
* Support timestamp column type

@@ -165,6 +169,22 @@ else if (DATE.equals(type)) {
long localMillis = getInstanceUTC().getZone().getMillisKeepLocal(DateTimeZone.getDefault(), utcMillis);
statement.setDate(parameter, new Date(localMillis));
}
else if (type instanceof TimestampType) {
long timestampValue = type.getLong(block, position);
int nanos = ((TimestampType) type).getPrecision() == MILLISECONDS ?
Copy link
Member

Choose a reason for hiding this comment

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

Just thinking would it make sense to move get nanos and get millis to com.facebook.presto.common.type.TimestampType although this would be the only place to use them.

Copy link
Member Author

Choose a reason for hiding this comment

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

Good idea! These logics are common for timestamp and may be used somewhere else.

To make it more universal, I have extracted getEpochSecond(long timestamp) which returns timestamp's number of total seconds, and getNanos(long timestamp) which returns the timestamp's nanosecond portion. Please take a look. Any thoughts please let me know, thanks!

@tdcmeehan tdcmeehan self-assigned this Feb 15, 2024
@hantangwangd hantangwangd force-pushed the support_timestamp_in_mysql branch from b0ff5f5 to ad06658 Compare February 16, 2024 00:50
* Returns:
* this timestamp's fractional seconds component
*/
public int getNanos(long timestamp)
Copy link
Member

Choose a reason for hiding this comment

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

just curious that any reason you return int here instead of long. I saw the API for Instant.ofEpochSecond is (long, long).

Another thing I found is that java.util.concurrent.TimeUnit provides MICROSECONDS.toNanos(long) and MILLISECONDS.toNanos(long) not sure if that's relevant.

Copy link
Member Author

@hantangwangd hantangwangd Feb 16, 2024

Choose a reason for hiding this comment

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

just curious that any reason you return int here instead of long. I saw the API for Instant.ofEpochSecond is (long, long).

I consulted the API definition of java.time.Instant.getNano(), int type would be enough as the return value of getNanos would always less than 1000,000,000. What's your opinion?

Another thing I found is that java.util.concurrent.TimeUnit provides MICROSECONDS.toNanos(long) and MILLISECONDS.toNanos(long) not sure if that's relevant.

Thanks, that could be useful. Consulting the implementation in DecodeTimestampOptions, I have modified the code to use them. Please take a look!

Copy link
Member Author

Choose a reason for hiding this comment

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

By the way, seems the second parameter of Instant.ofEpochSecond(long, long) could be nanos representing longer than one second, so its type was declared as long.

Copy link
Member

Choose a reason for hiding this comment

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

Thanks for the explanation. I believe for the current usage, it only reduces the stack size but not the heap because java.sql.Timestamp is still using long and consumes the same amount of heap size.

However, if this method is used by other code and the constructed object is using int, then it does reduce the heap usage. You can leave it as int.

@hantangwangd hantangwangd force-pushed the support_timestamp_in_mysql branch from ad06658 to 9fec3b9 Compare February 16, 2024 02:09
{
return this.precision == MILLISECONDS ?
MILLISECONDS.toSeconds(timestamp) :
MICROSECONDS.toSeconds(timestamp);
Copy link
Member

Choose a reason for hiding this comment

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

How about this.precision.toSeconds(timestamp)?
If that's the case, I start to wonder do we need this function. sorry for the hassle.

Copy link
Member Author

@hantangwangd hantangwangd Feb 16, 2024

Choose a reason for hiding this comment

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

How about this.precision.toSeconds(timestamp)?

Oh, it's better, I have fixed it. Thanks a lot for your suggestion that lead to the continuous improvement in our implementation.

I think this function still has some value for providing the utility logic and the corresponding comment, as the usage TimestampType.getPrecision().toSeconds(long) from other place is not so straightforward. What do you think?

Copy link
Member

Choose a reason for hiding this comment

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

sure! sold.

* Returns:
* this timestamp's fractional seconds component
*/
public int getNanos(long timestamp)
Copy link
Member

Choose a reason for hiding this comment

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

Thanks for the explanation. I believe for the current usage, it only reduces the stack size but not the heap because java.sql.Timestamp is still using long and consumes the same amount of heap size.

However, if this method is used by other code and the constructed object is using int, then it does reduce the heap usage. You can leave it as int.

@hantangwangd hantangwangd force-pushed the support_timestamp_in_mysql branch from 9fec3b9 to 86cad4d Compare February 16, 2024 09:31
Copy link
Contributor

@kiersten-stokes kiersten-stokes left a comment

Choose a reason for hiding this comment

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

LGTM!

@tdcmeehan tdcmeehan merged commit 91b0bb3 into prestodb:master Feb 21, 2024
56 checks passed
@wanglinsong wanglinsong mentioned this pull request May 1, 2024
48 tasks
@pratyakshsharma
Copy link
Contributor

It looks like this PR only supports milliseconds precision for timestamp type. I will raise a github issue and link with this PR.

@hantangwangd
Copy link
Member Author

It looks like this PR only supports milliseconds precision for timestamp type. I will raise a github issue and link with this PR.

@pratyakshsharma Sure, thank you for pointing out the problems if there is any. I think this change can internally support microseconds precision as well. So please describe the problematic scenario in the new issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

Query 20240119_063836_00856_pugph failed: Unsupported column type: timestamp
5 participants