-
Notifications
You must be signed in to change notification settings - Fork 37
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
Add time-related types to the storage and transactional interfaces. #2437
base: add_time_related_types
Are you sure you want to change the base?
Conversation
1360d38
to
be37237
Compare
0e70eb5
to
57cbb31
Compare
@@ -45,4 +50,25 @@ protected boolean isParallelDdlSupported() { | |||
} | |||
return super.isParallelDdlSupported(); | |||
} | |||
|
|||
@Override | |||
protected Stream<Arguments> provideColumnsForCNFConditionsTest() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Modified the test DistributedStorageCrossPartitionScanIntegrationTestBase.scan_WithConjunctiveNormalFormConditionsShouldReturnProperResult
for Oracle, SQLServer, and SQLite to reduce the size of the condition
getColumns().entrySet().stream() | ||
.collect( | ||
Collectors.toMap( | ||
Entry::getKey, e -> ScalarDbUtils.toValue(e.getValue()))))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we do not add the implementation of the Value<T>
type for time-related types because it is deprecated.
I removed any code from src/main
that use Value<?>
objects. Some unit and integration tests still use it extensively but that will need to be taken care of later on.
@@ -690,6 +690,42 @@ public enum CoreError implements ScalarDbError { | |||
""), | |||
DATA_LOADER_ERROR_METHOD_NULL_ARGUMENT( | |||
Category.USER_ERROR, "0151", "Method null argument not allowed", "", ""), | |||
OUT_OF_RANGE_COLUMN_VALUE_FOR_DATE( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add some error codes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@josh-wong Could you please take a look at these error messages?
* calendar system, such as 16:15:30, and can be expressed with microsecond precision. | ||
*/ | ||
@Immutable | ||
public class TimeColumn implements Column<LocalTime> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add the TimeColumn
type. Its value is backed by a LocalTime
object.
* calendar system, such as 2007-12-03 | ||
*/ | ||
@Immutable | ||
public class DateColumn implements Column<LocalDate> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add the DateColumn
type. Its value is backed by the LocalDate
object.
return LocalDateTime.of( | ||
config.getOracleTimeColumnDefaultDateComponent(), column.getTimeValue()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Encode any TIME value in Oracle with the default date component set in the configuration.
@@ -131,4 +143,56 @@ default String getPattern(LikeExpression likeExpression) { | |||
default @Nullable String getSchemaName(String namespace) { | |||
return namespace; | |||
} | |||
|
|||
default Object encodeDate(DateColumn column) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The encoding of time-related types for JDBC is not straightforward as some drivers have specificities regarding time-zone handling or the use of dates before the transition from the Julian to the Gregorian Calendar on October 15th, 1582.
} | ||
|
||
@Test | ||
public void |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added two integration tests put_WithProblematicDateBecauseOfJulianToGregorianCalendarTransition_ShouldPutCorrectly
and put_forTimeRelatedTypesWithVariousJvmTimezone_ShouldPutCorrectly
to cover for some corner cases.
See the comment in the test for more details.
@@ -31,7 +31,7 @@ subprojects { | |||
commonsDbcp2Version = '2.13.0' | |||
mysqlDriverVersion = '8.4.0' | |||
postgresqlDriverVersion = '42.7.4' | |||
oracleDriverVersion = '21.16.0.0' | |||
oracleDriverVersion = '23.6.0.24.10' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Upgrade the Oracle driver to the latest version to facilitate the handling of dates before October 15th, 1582.
@@ -93,10 +111,32 @@ protected String getNamespaceBaseName() { | |||
} | |||
|
|||
private void createTables() throws ExecutionException { | |||
TableMetadata.Builder tableMetadata = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Up until now DistributedTransactionIntegrationTestBase
was performing tests on a table composed of columns of INT type only.
I updated several tests that targeted the most generic use case for each operation to target all data types.
return super.getPartitionKeyTypes().stream() | ||
.filter( | ||
type -> { | ||
if (JdbcTestUtils.isOracle(rdbEngine) && type == DataType.TIMESTAMPTZ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this logic is a bit complicated and shouldn't be duplicated. How about moving this to a util class to reuse it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right, I created a util method JdbcTestUtils.filterDataTypes(...)
. Thank you.
adcbfde
|
||
@Override | ||
protected final void finalize() throws Throwable { | ||
// TODO delete this method once https://github.com/scalar-labs/scalardb/pull/2421 is merge |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#2421 is merged 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I will do that in a separate PR because rebasing the feature branch add_time_related_types now would mess up this PR I think 🤔
@Override | ||
public DateTimeOffset encodeTimestampTZ(TimestampTZColumn column) { | ||
assert column.getTimestampTZValue() != null; | ||
// When using SQLServer DATETIMEOFFSET data type, we should use the SQLServer JDBC driver's |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this mean using Instant or LocalDateTime fails with SQLServer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, for encoding data, only using the SQLServer driver microsoft.sql.DateTimeOffset
type worked for the range of data I tested.
Decoding through a Java java.time.OffsetDateTime
object worked, if my memory is correct, microsoft.sql.DateTimeOffset
was ok too.
core/src/main/java/com/scalar/db/storage/jdbc/RdbEngineStrategy.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! 👍
Great work!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall LGTM. Left several comments. Please take a look when you have time!
...ain/java/com/scalar/db/api/DistributedStorageSingleClusteringKeyScanIntegrationTestBase.java
Show resolved
Hide resolved
@@ -690,6 +690,42 @@ public enum CoreError implements ScalarDbError { | |||
""), | |||
DATA_LOADER_ERROR_METHOD_NULL_ARGUMENT( | |||
Category.USER_ERROR, "0151", "Method null argument not allowed", "", ""), | |||
OUT_OF_RANGE_COLUMN_VALUE_FOR_DATE( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@josh-wong Could you please take a look at these error messages?
/** | ||
* This class provides utility methods for encoding and decoding time related column value for | ||
* DynamoDB, CosmosDB and SQLite | ||
*/ | ||
public final class TimeRelatedColumnEncodingUtils { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you please move this class under com.scalar.db.util
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Thank you!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added some comments and suggestions. PTAL!
Co-authored-by: Josh Wong <[email protected]>
…tion on time-related columns
…scalardb into add_time_related_types_CRUD # Conflicts: # core/src/main/java/com/scalar/db/common/error/CoreError.java
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, there was one minor thing I noticed about the wording, so I've added some suggestions. PTAL!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall, looking good to me. Thank you!
I left a few comments. PTAL!
* precision. | ||
*/ | ||
@Immutable | ||
public class TimestampTZColumn implements Column<Instant> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
public class TimestampTZColumn implements Column<Instant> { | |
public class TimestampTzColumn implements Column<Instant> { |
Probably? (based on the naming convention in the style guide)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also hesitated between TimestampTZ
and TimestampTz
but chose the first one for the following reasons:
- My understanding of the Google Java style guide differs from yours. Since
time zone
is written in two words, it recommends capitalizing theT
and theZ
. - Compared to
TimestampColumn
,TimestampTZColumn
stands out more thanTimestampTzColumn
. So, it is easier to spot the difference between the two types when reading code and writing code using auto-completion. - I could only find two Java classes with a similar naming and both used the capital letter version. For example in Apache Hive and Spark
What do you think?
import javax.annotation.Nullable; | ||
|
||
/** | ||
* An interface to hide the difference between underlying JDBC SQL engines in SQL dialects, error | ||
* codes, and so on. It's NOT responsible for actually connecting to underlying engines. | ||
*/ | ||
public interface RdbEngineStrategy { | ||
public interface RdbEngineStrategy<T_DATE, T_TIME, T_TIMESTAMP, T_TIMESTAMPTZ> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have a strong opinion, but having four time-related generics in this interface might be too much since this handles many other data types.
How about pushing the time-related type things to other interface and classes?
For example, how about creating a time-specific strategy that converts the default type to a DB-specific type?
For example, we can create RdbEngineTimeTypeStrategy
, and it converts time-related types as necessary as follows.
preparedStatement.setObject(index++, rdbEngineTimeType.convert(rdbEngine.encodeTimestampTZ(column)));
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It sounds good, thank you.
I reverted an earlier commit based on @komamitsu suggestion in 0eee567 then added your suggestion in
fe3be8d
This reverts commit be71af5.
Co-authored-by: Josh Wong <[email protected]>
…scalardb into add_time_related_types_CRUD
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Thank you!🙇🏻♂️
Does this PR need to have labels and projects selected? Or is it not necessary since it'll be merged into an existing branch where other work is being done?
Yes, the current PR is merged into a temporary feature branch, so we don't add labels or projects. I will add tags and labels to the PR to merge the feature branch into master. |
Description
This implements the CRUD interface for the DATE, TIME, TIMESTAMP, and TIMESTAMPTZ types.
The limitations are:
Remaining work:
Related issues and/or PRs
Changes made
Added support to CRUD operation of the storage and transactional interface for the
DateColumn
,TimeColumn
,TimestampColumn
andTimestampTZColumn
Checklist
Additional notes (optional)
Sorry for the huge number of changes, most of them concern constructor or builder method but I commented on the area that require more careful review.
This PR will be merged into the feature branch add_time_related_types
Release notes
N/A