This is an automated email from the ASF dual-hosted git repository.
ptupitsyn pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git
The following commit(s) were added to refs/heads/main by this push:
new 6871bba01b IGNITE-21568 Java thin: Pass client time zone to server
(#3737)
6871bba01b is described below
commit 6871bba01b3643cf6e0b45cde7d2f69151b6a835
Author: Pavel Tupitsyn <[email protected]>
AuthorDate: Mon May 13 11:26:09 2024 +0300
IGNITE-21568 Java thin: Pass client time zone to server (#3737)
---
.../handler/requests/sql/ClientSqlProperties.java | 10 +++++++-
.../ignite/internal/client/sql/ClientSql.java | 9 ++++---
.../internal/client/sql/ClientStatement.java | 28 ++++++++++++----------
.../client/sql/ClientStatementBuilder.java | 11 ++++++---
.../org/apache/ignite/client/ClientSqlTest.java | 3 +++
.../org/apache/ignite/client/fakes/FakeCursor.java | 2 ++
.../cpp/ignite/client/detail/sql/sql_impl.cpp | 1 +
.../platforms/cpp/ignite/odbc/query/data_query.cpp | 1 +
.../dotnet/Apache.Ignite.Tests/FakeServer.cs | 4 +++-
.../dotnet/Apache.Ignite.Tests/Sql/SqlTests.cs | 2 +-
.../dotnet/Apache.Ignite/Internal/Sql/Sql.cs | 2 ++
.../ignite/internal/sql/api/ItSqlApiBaseTest.java | 25 +++++++++++++++++++
12 files changed, 77 insertions(+), 21 deletions(-)
diff --git
a/modules/client-handler/src/main/java/org/apache/ignite/client/handler/requests/sql/ClientSqlProperties.java
b/modules/client-handler/src/main/java/org/apache/ignite/client/handler/requests/sql/ClientSqlProperties.java
index 785a973153..015f90d9dd 100644
---
a/modules/client-handler/src/main/java/org/apache/ignite/client/handler/requests/sql/ClientSqlProperties.java
+++
b/modules/client-handler/src/main/java/org/apache/ignite/client/handler/requests/sql/ClientSqlProperties.java
@@ -17,12 +17,13 @@
package org.apache.ignite.client.handler.requests.sql;
-import javax.annotation.Nullable;
+import java.time.ZoneId;
import org.apache.ignite.internal.client.proto.ClientMessageUnpacker;
import org.apache.ignite.internal.sql.api.IgniteSqlImpl;
import org.apache.ignite.internal.sql.engine.QueryProperty;
import org.apache.ignite.internal.sql.engine.property.SqlProperties;
import org.apache.ignite.internal.sql.engine.property.SqlPropertiesHelper;
+import org.jetbrains.annotations.Nullable;
class ClientSqlProperties {
private final @Nullable String schema;
@@ -33,11 +34,14 @@ class ClientSqlProperties {
private final long idleTimeout;
+ private final @Nullable String timeZoneId;
+
ClientSqlProperties(ClientMessageUnpacker in) {
schema = in.tryUnpackNil() ? null : in.unpackString();
pageSize = in.tryUnpackNil() ? IgniteSqlImpl.DEFAULT_PAGE_SIZE :
in.unpackInt();
queryTimeout = in.tryUnpackNil() ? 0 : in.unpackLong();
idleTimeout = in.tryUnpackNil() ? 0 : in.unpackLong();
+ timeZoneId = in.tryUnpackNil() ? null : in.unpackString();
// Skip properties - not used by SQL engine.
in.unpackInt(); // Number of properties.
@@ -68,6 +72,10 @@ class ClientSqlProperties {
builder.set(QueryProperty.DEFAULT_SCHEMA, schema);
}
+ if (timeZoneId != null) {
+ builder.set(QueryProperty.TIME_ZONE_ID, ZoneId.of(timeZoneId));
+ }
+
return builder.build();
}
}
diff --git
a/modules/client/src/main/java/org/apache/ignite/internal/client/sql/ClientSql.java
b/modules/client/src/main/java/org/apache/ignite/internal/client/sql/ClientSql.java
index 74095a4c8b..acfb230519 100644
---
a/modules/client/src/main/java/org/apache/ignite/internal/client/sql/ClientSql.java
+++
b/modules/client/src/main/java/org/apache/ignite/internal/client/sql/ClientSql.java
@@ -20,6 +20,7 @@ package org.apache.ignite.internal.client.sql;
import static org.apache.ignite.internal.client.table.ClientTable.writeTx;
import static org.apache.ignite.internal.util.ExceptionUtils.unwrapCause;
+import java.time.ZoneId;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
@@ -75,7 +76,7 @@ public class ClientSql implements IgniteSql {
/** {@inheritDoc} */
@Override
public Statement createStatement(String query) {
- return new ClientStatement(query, null, null, null);
+ return new ClientStatement(query, null, null, null, null);
}
/** {@inheritDoc} */
@@ -177,7 +178,7 @@ public class ClientSql implements IgniteSql {
@Nullable Object... arguments) {
Objects.requireNonNull(query);
- ClientStatement statement = new ClientStatement(query, null, null,
null);
+ ClientStatement statement = new ClientStatement(query, null, null,
null, null);
return executeAsync(transaction, statement, arguments);
}
@@ -200,7 +201,7 @@ public class ClientSql implements IgniteSql {
@Nullable Object... arguments) {
Objects.requireNonNull(query);
- ClientStatement statement = new ClientStatement(query, null, null,
null);
+ ClientStatement statement = new ClientStatement(query, null, null,
null, null);
return executeAsync(transaction, mapper, statement, arguments);
}
@@ -228,6 +229,7 @@ public class ClientSql implements IgniteSql {
w.out().packLongNullable(clientStatement.queryTimeoutNullable());
w.out().packLongNullable(0L); // defaultSessionTimeout
+ w.out().packString(clientStatement.timeZoneId().getId());
packProperties(w, null);
@@ -286,6 +288,7 @@ public class ClientSql implements IgniteSql {
w.out().packNil(); // pageSize
w.out().packNil(); // queryTimeout
w.out().packNil(); // sessionTimeout
+ w.out().packString(ZoneId.systemDefault().getId());
packProperties(w, null);
diff --git
a/modules/client/src/main/java/org/apache/ignite/internal/client/sql/ClientStatement.java
b/modules/client/src/main/java/org/apache/ignite/internal/client/sql/ClientStatement.java
index 42256f572b..de5ec90114 100644
---
a/modules/client/src/main/java/org/apache/ignite/internal/client/sql/ClientStatement.java
+++
b/modules/client/src/main/java/org/apache/ignite/internal/client/sql/ClientStatement.java
@@ -18,10 +18,10 @@
package org.apache.ignite.internal.client.sql;
import java.time.ZoneId;
-import java.time.ZoneOffset;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import org.apache.ignite.sql.Statement;
+import org.jetbrains.annotations.Nullable;
/**
* Client SQL statement.
@@ -31,13 +31,16 @@ public class ClientStatement implements Statement {
private final String query;
/** Default schema. */
- private final String defaultSchema;
+ private final @Nullable String defaultSchema;
/** Query timeout. */
- private final Long queryTimeoutMs;
+ private final @Nullable Long queryTimeoutMs;
/** Page size. */
- private final Integer pageSize;
+ private final @Nullable Integer pageSize;
+
+ /** Time-zone ID. */
+ private final ZoneId timeZoneId;
/**
* Constructor.
@@ -48,17 +51,19 @@ public class ClientStatement implements Statement {
* @param pageSize Page size.
*/
@SuppressWarnings("AssignmentOrReturnOfFieldWithMutableType")
- public ClientStatement(
+ ClientStatement(
String query,
- String defaultSchema,
- Long queryTimeoutMs,
- Integer pageSize) {
+ @Nullable String defaultSchema,
+ @Nullable Long queryTimeoutMs,
+ @Nullable Integer pageSize,
+ @Nullable ZoneId timeZoneId) {
Objects.requireNonNull(query);
this.query = query;
this.defaultSchema = defaultSchema;
this.queryTimeoutMs = queryTimeoutMs;
this.pageSize = pageSize;
+ this.timeZoneId = timeZoneId != null ? timeZoneId :
ZoneId.systemDefault();
}
/** {@inheritDoc} */
@@ -80,7 +85,7 @@ public class ClientStatement implements Statement {
*
* @return Query timeout.
*/
- public Long queryTimeoutNullable() {
+ @Nullable Long queryTimeoutNullable() {
return queryTimeoutMs;
}
@@ -93,8 +98,7 @@ public class ClientStatement implements Statement {
/** {@inheritDoc} */
@Override
public ZoneId timeZoneId() {
- // TODO: https://issues.apache.org/jira/browse/IGNITE-21568
- return ZoneOffset.UTC;
+ return timeZoneId;
}
/** {@inheritDoc} */
@@ -108,7 +112,7 @@ public class ClientStatement implements Statement {
*
* @return Page size.
*/
- public Integer pageSizeNullable() {
+ @Nullable Integer pageSizeNullable() {
return pageSize;
}
diff --git
a/modules/client/src/main/java/org/apache/ignite/internal/client/sql/ClientStatementBuilder.java
b/modules/client/src/main/java/org/apache/ignite/internal/client/sql/ClientStatementBuilder.java
index a61d763e7c..0ed4dbfbb1 100644
---
a/modules/client/src/main/java/org/apache/ignite/internal/client/sql/ClientStatementBuilder.java
+++
b/modules/client/src/main/java/org/apache/ignite/internal/client/sql/ClientStatementBuilder.java
@@ -39,6 +39,9 @@ public class ClientStatementBuilder implements
Statement.StatementBuilder {
/** Page size. */
private Integer pageSize;
+ /** Time-zone ID. */
+ private ZoneId timeZoneId;
+
/** {@inheritDoc} */
@Override
public StatementBuilder query(String query) {
@@ -75,8 +78,9 @@ public class ClientStatementBuilder implements
Statement.StatementBuilder {
@Override
public StatementBuilder timeZoneId(ZoneId timeZoneId) {
- // TODO: https://issues.apache.org/jira/browse/IGNITE-21568
- throw new UnsupportedOperationException("Not implemented yet");
+ this.timeZoneId = timeZoneId;
+
+ return this;
}
/** {@inheritDoc} */
@@ -86,6 +90,7 @@ public class ClientStatementBuilder implements
Statement.StatementBuilder {
query,
defaultSchema,
queryTimeoutMs,
- pageSize);
+ pageSize,
+ timeZoneId);
}
}
diff --git
a/modules/client/src/test/java/org/apache/ignite/client/ClientSqlTest.java
b/modules/client/src/test/java/org/apache/ignite/client/ClientSqlTest.java
index 9f9a5f77af..71419406e1 100644
--- a/modules/client/src/test/java/org/apache/ignite/client/ClientSqlTest.java
+++ b/modules/client/src/test/java/org/apache/ignite/client/ClientSqlTest.java
@@ -33,6 +33,7 @@ import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Period;
+import java.time.ZoneId;
import java.util.BitSet;
import java.util.Map;
import java.util.UUID;
@@ -84,6 +85,7 @@ public class ClientSqlTest extends AbstractClientTableTest {
.defaultSchema("SCHEMA2")
.queryTimeout(124, TimeUnit.SECONDS)
.pageSize(235)
+ .timeZoneId(ZoneId.of("Europe/London"))
.build();
AsyncResultSet<SqlRow> resultSet = client.sql().executeAsync(null,
statement).join();
@@ -94,6 +96,7 @@ public class ClientSqlTest extends AbstractClientTableTest {
assertEquals("SCHEMA2", props.get("schema"));
assertEquals("124000", props.get("timeout"));
assertEquals("235", props.get("pageSize"));
+ assertEquals("Europe/London", props.get("timeZoneId"));
}
@Test
diff --git
a/modules/client/src/test/java/org/apache/ignite/client/fakes/FakeCursor.java
b/modules/client/src/test/java/org/apache/ignite/client/fakes/FakeCursor.java
index 159099f5c6..2493f4d277 100644
---
a/modules/client/src/test/java/org/apache/ignite/client/fakes/FakeCursor.java
+++
b/modules/client/src/test/java/org/apache/ignite/client/fakes/FakeCursor.java
@@ -19,6 +19,7 @@ package org.apache.ignite.client.fakes;
import static
org.apache.ignite.internal.sql.engine.QueryProperty.DEFAULT_SCHEMA;
import static
org.apache.ignite.internal.sql.engine.QueryProperty.QUERY_TIMEOUT;
+import static org.apache.ignite.internal.sql.engine.QueryProperty.TIME_ZONE_ID;
import static
org.apache.ignite.internal.util.CompletableFutures.nullCompletedFuture;
import java.math.BigDecimal;
@@ -61,6 +62,7 @@ public class FakeCursor implements
AsyncSqlCursor<InternalSqlRow> {
rows.add(getRow("schema", properties.get(DEFAULT_SCHEMA)));
rows.add(getRow("timeout",
String.valueOf(properties.get(QUERY_TIMEOUT))));
+ rows.add(getRow("timeZoneId",
String.valueOf(properties.get(TIME_ZONE_ID))));
} else if ("SELECT META".equals(qry)) {
columns.add(new FakeColumnMetadata("BOOL", ColumnType.BOOLEAN));
columns.add(new FakeColumnMetadata("INT8", ColumnType.INT8));
diff --git a/modules/platforms/cpp/ignite/client/detail/sql/sql_impl.cpp
b/modules/platforms/cpp/ignite/client/detail/sql/sql_impl.cpp
index db7c5520be..7f15a72144 100644
--- a/modules/platforms/cpp/ignite/client/detail/sql/sql_impl.cpp
+++ b/modules/platforms/cpp/ignite/client/detail/sql/sql_impl.cpp
@@ -29,6 +29,7 @@ void write_statement(protocol::writer &writer, const
sql_statement &statement) {
writer.write(statement.page_size());
writer.write(std::int64_t(statement.timeout().count()));
writer.write_nil(); // Session timeout (unused, session is closed by the
server immediately).
+ writer.write_nil(); // TODO: IGNITE-21605 Time zone id.
const auto &properties = statement.properties();
auto props_num = std::int32_t(properties.size());
diff --git a/modules/platforms/cpp/ignite/odbc/query/data_query.cpp
b/modules/platforms/cpp/ignite/odbc/query/data_query.cpp
index 0eae298056..00b46b9e1c 100644
--- a/modules/platforms/cpp/ignite/odbc/query/data_query.cpp
+++ b/modules/platforms/cpp/ignite/odbc/query/data_query.cpp
@@ -274,6 +274,7 @@ sql_result data_query::make_request_execute() {
writer.write(m_connection.get_configuration().get_page_size().get_value());
writer.write(std::int64_t(m_connection.get_timeout()) * 1000);
writer.write_nil(); // Session timeout (unused, session is closed
by the server immediately).
+ writer.write_nil(); // TODO: IGNITE-21605 Time zone id.
// Properties are not used for now.
writer.write(0);
diff --git a/modules/platforms/dotnet/Apache.Ignite.Tests/FakeServer.cs
b/modules/platforms/dotnet/Apache.Ignite.Tests/FakeServer.cs
index 13a1ac3058..68d696f94c 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Tests/FakeServer.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Tests/FakeServer.cs
@@ -441,6 +441,7 @@ namespace Apache.Ignite.Tests
props["timeoutMs"] = timeoutMs;
props["sessionTimeoutMs"] = reader.TryReadNil() ? (long?)null :
reader.ReadInt64();
+ props["timeZoneId"] = reader.TryReadNil() ? null :
reader.ReadString();
// ReSharper restore RedundantCast
var propCount = reader.ReadInt32();
@@ -550,7 +551,8 @@ namespace Apache.Ignite.Tests
["schema"] = reader.TryReadNil() ? null : reader.ReadString(),
["pageSize"] = reader.TryReadNil() ? null : reader.ReadInt32(),
["timeoutMs"] = reader.TryReadNil() ? null :
reader.ReadInt64(),
- ["sessionTimeoutMs"] = reader.TryReadNil() ? null :
reader.ReadInt64()
+ ["sessionTimeoutMs"] = reader.TryReadNil() ? null :
reader.ReadInt64(),
+ ["timeZoneId"] = reader.TryReadNil() ? null :
reader.ReadString()
};
var propCount = reader.ReadInt32();
diff --git a/modules/platforms/dotnet/Apache.Ignite.Tests/Sql/SqlTests.cs
b/modules/platforms/dotnet/Apache.Ignite.Tests/Sql/SqlTests.cs
index d3f98d5336..c51560b9a2 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Tests/Sql/SqlTests.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Tests/Sql/SqlTests.cs
@@ -402,7 +402,7 @@ namespace Apache.Ignite.Tests.Sql
var props = rows.ToDictionary(x => (string)x["NAME"]!, x =>
(string)x["VAL"]!);
Assert.IsTrue(res.HasRowSet);
- Assert.AreEqual(8, props.Count);
+ Assert.AreEqual(9, props.Count);
Assert.AreEqual("schema-1", props["schema"]);
Assert.AreEqual("987", props["pageSize"]);
diff --git a/modules/platforms/dotnet/Apache.Ignite/Internal/Sql/Sql.cs
b/modules/platforms/dotnet/Apache.Ignite/Internal/Sql/Sql.cs
index 9b21a8a547..565b4835b3 100644
--- a/modules/platforms/dotnet/Apache.Ignite/Internal/Sql/Sql.cs
+++ b/modules/platforms/dotnet/Apache.Ignite/Internal/Sql/Sql.cs
@@ -238,6 +238,8 @@ namespace Apache.Ignite.Internal.Sql
w.Write(statement.PageSize);
w.Write((long)statement.Timeout.TotalMilliseconds);
w.WriteNil(); // Session timeout (unused, session is closed by the
server immediately).
+ w.WriteNil(); // TODO: IGNITE-21604 Time zone id.
+
WriteProperties(statement, ref w);
w.Write(statement.Query);
w.WriteObjectCollectionAsBinaryTuple(args);
diff --git
a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/api/ItSqlApiBaseTest.java
b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/api/ItSqlApiBaseTest.java
index 66b3da2a91..ff6ee40c92 100644
---
a/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/api/ItSqlApiBaseTest.java
+++
b/modules/sql-engine/src/integrationTest/java/org/apache/ignite/internal/sql/api/ItSqlApiBaseTest.java
@@ -29,6 +29,8 @@ import static
org.junit.jupiter.api.Assertions.assertInstanceOf;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
@@ -56,6 +58,7 @@ import org.apache.ignite.sql.SqlBatchException;
import org.apache.ignite.sql.SqlException;
import org.apache.ignite.sql.SqlRow;
import org.apache.ignite.sql.Statement;
+import org.apache.ignite.sql.Statement.StatementBuilder;
import org.apache.ignite.table.Table;
import org.apache.ignite.tx.Transaction;
import org.apache.ignite.tx.TransactionOptions;
@@ -840,6 +843,28 @@ public abstract class ItSqlApiBaseTest extends
BaseSqlIntegrationTest {
assertEquals(1, result.result().get(0).intValue(0));
}
+ @ParameterizedTest
+ @ValueSource(strings = {"", "UTC", "Europe/Athens", "America/New_York",
"Asia/Tokyo"})
+ public void testTimeZoneId(String timeZoneId) {
+ ZoneId zoneId = timeZoneId.isEmpty() ? ZoneId.systemDefault() :
ZoneId.of(timeZoneId);
+
+ StatementBuilder builder = igniteSql().statementBuilder()
+ .query("SELECT CURRENT_TIMESTAMP")
+ .timeZoneId(zoneId);
+
+ ResultSet<SqlRow> resultSet = igniteSql().execute(null,
builder.build());
+ SqlRow row = resultSet.next();
+
+ LocalDateTime ts = row.value(0);
+ assertNotNull(ts);
+
+ float tsMillis =
ts.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
+ float nowMillis =
LocalDateTime.now(zoneId).atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
+ float deltaMillis = 5000;
+
+ assertEquals(nowMillis, tsMillis, deltaMillis);
+ }
+
protected ResultSet<SqlRow> executeForRead(IgniteSql sql, String query,
Object... args) {
return executeForRead(sql, null, query, args);
}