I'm trying to execute "toUnixTimestamp(now())" against system.local table (AstraDB Serverless).
It works fine when I execute it inside AstraDB CQL Console: SELECT toUnixTimestamp(now()) FROM
system.local
;
The problem is that I cannot execute it successfully using Astra CLI or Java-driver:
command: SELECT toUnixTimestamp(now()) FROM
system.local
;
error output:
com.datastax.oss.driver.api.core.servererrors.InvalidQueryException: unexpected argument type for function call 'toUnixTimestamp(...)' in select statementat com.datastax.oss.driver.api.core.servererrors.InvalidQueryException.copy(InvalidQueryException.java:48) at com.datastax.oss.driver.internal.core.util.concurrent.CompletableFutures.getUninterruptibly(CompletableFutures.java:149)
I'm able to execute it using a custom table (Astra CLI / Java-driver): SELECT toUnixTimestamp(now()) FROM
demo.example
;
But for my use case, I need to execute it agains system.local.
The scenario is the same for the following functions: toUnixTimestamp(), toTimestamp() and dateOf().
Only now() function works with every approach: AstraDB CQL console, Astra CLI and Java-driver (SELECT now() FROM
system.local
;
).
Are there any restrictions on what can be accessed inside system.local using AstraDB CQL Console but cannot be accessed using Astra CLI or Java-driver?
That's really strange. I'd be curious to know how you're building your CQL statements in code, because that should work.
I have it working here with Java 21 and the 4.17.0 version of the Java driver:
try (CqlSession session = CqlSession.builder()
.withCloudSecureConnectBundle(Paths.get(secureConnectBundlePath))
.withAuthCredentials(username,password)
.withKeyspace("system")
.build()) {
ResultSet rs = session.execute("select release_version from system.local");
Row row = rs.one();
System.out.println(row.getString(0));
ResultSet rs2 = session.execute("select now() from system.local");
Row row2 = rs2.one();
System.out.println(row2.getUuid(0));
ResultSet rs3 = session.execute("SELECT toUnixTimestamp(now()) FROM system.local;");
Row row3 = rs3.one();
System.out.println(row3.getLong(0));
}
I also built an async example, just to make sure that I didn't miss anything:
CompletionStage<CqlSession> sessionStage = CqlSession.builder()
.withCloudSecureConnectBundle(Paths.get(secureConnectBundlePath))
.withAuthCredentials(username,password)
.withKeyspace("system")
.buildAsync();
CompletionStage<AsyncResultSet> result = sessionStage.thenCompose(
session -> session.executeAsync("SELECT toUnixTimestamp(now()) FROM system.local;"));
CompletionStage<Long> unixTimeResult = result.thenApply(resultSet -> resultSet.one().getLong(0));
unixTimeResult.whenComplete(
(unixtime, error) -> {
if (error != null) {
System.out.println(error);
} else {
System.out.println(unixtime);
}
});
Results:
4.0.11-09ec37c912ed
556541c0-5980-11ef-b3cf-fdfdcd27eb44
1723559319596
1723559324300
If you have any additional questions, I put this code into a Git repo to make it easy to find: https://github.com/aar0np/TestAstra/blob/main/src/main/java/testastra/TestAstra.java
Edit 20240815
Talked with the Astra Engineering folks about this. Turns out that going forward Astra will be using different routing/handling for queries to system.local
and system.peers
. The now()
function may still continue to work, but nesting now()
inside of another function (ex: toUnixTimestamp()
) will not. We are also in the middle of rolling out this routing change, which is why it still works in GCP, but will no longer work in AWS.
The official recommendation is to use a one-row dummy table for this, as opposed to direct queries on system.local
.