Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
See [Partial writes](https://docs.influxdata.com/influxdb3/core/write-data/http-api/v3-write-lp/#partial-writes) for more.
For InfluxDB Clustered version, set `useV2Api=true` for writing.

### Bug Fixes

1. [#384](https://github.com/InfluxCommunity/influxdb3-java/pull/384): Always set `precision` to `nanosecond` when
writing Points.

## 1.9.0 [2026-04-23]

### Features
Expand Down
12 changes: 9 additions & 3 deletions src/main/java/com/influxdb/v3/client/config/ClientConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,10 @@
* <li><code>authScheme</code> - authentication scheme</li>
* <li><code>organization</code> - organization to be used for operations</li>
* <li><code>database</code> - database to be used for InfluxDB operations</li>
* <li><code>writePrecision</code> - precision to use when writing points to InfluxDB</li>
* <li><code>writePrecision</code> - precision to use when writing to InfluxDB.
* This setting is ignored when writing {@link com.influxdb.v3.client.Point};
* for those writes, the client always sends {@link WritePrecision#NS}
* precision to the server.</li>
* <li><code>defaultTags</code> - defaultTags added when writing points to InfluxDB</li>
* <li><code>gzipThreshold</code> - threshold when gzip compression is used for writing points to InfluxDB</li>
* <li><code>writeNoSync</code> - skip waiting for WAL persistence on write</li>
Expand Down Expand Up @@ -547,8 +550,11 @@ public Builder database(@Nullable final String database) {
* Sets the default precision to use for the timestamp of points
* if no precision is specified in the write API call.
*
* @param writePrecision default precision to use for the timestamp of points
* if no precision is specified in the write API call
* @param writePrecision default precision to use for the timestamp
* if no precision is specified in the write API call.
* This setting is ignored when writing {@link com.influxdb.v3.client.Point};
* for those writes, the client always sends {@link WritePrecision#NS}
* precision to the server.
* @return this
*/
@Nonnull
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,14 @@ private <T> void writeData(@Nonnull final List<T> data, @Nonnull final WriteOpti
+ "or use default configuration at 'ClientConfig.database'.");
}

WritePrecision precision = options.precisionSafe(config);
WritePrecision precision;

if (isWritePoint(data)) {
// When writing Point(s), the timestamp is always converted to nanoseconds.
precision = WritePrecision.NS;
} else {
precision = options.precisionSafe(config);
Comment thread
NguyenHoangSon96 marked this conversation as resolved.
}
Comment thread
NguyenHoangSon96 marked this conversation as resolved.
Comment thread
NguyenHoangSon96 marked this conversation as resolved.
Comment thread
NguyenHoangSon96 marked this conversation as resolved.
Comment thread
NguyenHoangSon96 marked this conversation as resolved.
Comment thread
NguyenHoangSon96 marked this conversation as resolved.
Comment thread
NguyenHoangSon96 marked this conversation as resolved.
Comment thread
NguyenHoangSon96 marked this conversation as resolved.
Comment thread
NguyenHoangSon96 marked this conversation as resolved.
options.validate(config);
Comment thread
NguyenHoangSon96 marked this conversation as resolved.

String path;
Expand Down Expand Up @@ -472,4 +479,13 @@ private byte[] gzipData(@Nonnull final byte[] data) throws IOException {

return out.toByteArray();
}

private <T> boolean isWritePoint(@Nonnull final List<T> data) {
for (T writeAble : data) {
if (writeAble instanceof Point) {
return true;
}
}
return false;
}
}
44 changes: 35 additions & 9 deletions src/main/java/com/influxdb/v3/client/write/WriteOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@
* <ul>
* <li><code>database</code> - specifies the database to be used for InfluxDB operations</li>
* <li><code>organization</code> - specifies the organization to be used for InfluxDB operations</li>
* <li><code>precision</code> - specifies the precision to use for the timestamp of points</li>
* <li><code>precision</code> - specifies the precision to use for timestamps in line protocol records.
* This setting is ignored when writing {@link com.influxdb.v3.client.Point}; for those writes, the client
* always sends {@link WritePrecision#NS} precision to the server.</li>
* <li><code>defaultTags</code> - specifies tags to be added by default to all write operations using points.</li>
* <li><code>tagOrder</code> - specifies preferred tag order for point serialization.</li>
* <li><code>noSync</code> - skip waiting for WAL persistence on write</li>
Expand Down Expand Up @@ -122,8 +124,11 @@ public static WriteOptions defaultWriteOptions() {
*
* @param database The database to be used for InfluxDB operations.
* If it is not specified then use {@link ClientConfig#getDatabase()}.
* @param precision The precision to use for the timestamp of points.
* @param precision The precision to use for the timestamp.
* If it is not specified then use {@link ClientConfig#getWritePrecision()}.
* This setting is ignored when writing {@link com.influxdb.v3.client.Point};
* for those writes, the client always sends {@link WritePrecision#NS}
* precision to the server.
* @param gzipThreshold The threshold for compressing request body.
* If it is not specified then use {@link WriteOptions#DEFAULT_GZIP_THRESHOLD}.
*/
Expand All @@ -138,8 +143,11 @@ public WriteOptions(@Nullable final String database,
*
* @param database The database to be used for InfluxDB operations.
* If it is not specified then use {@link ClientConfig#getDatabase()}.
* @param precision The precision to use for the timestamp of points.
* @param precision The precision to use for the timestamp.
* If it is not specified then use {@link ClientConfig#getWritePrecision()}.
* This setting is ignored when writing {@link com.influxdb.v3.client.Point};
* for those writes, the client always sends {@link WritePrecision#NS}
* precision to the server.
* @param gzipThreshold The threshold for compressing request body.
* If it is not specified then use {@link WriteOptions#DEFAULT_GZIP_THRESHOLD}.
* @param defaultTags Default tags to be added when writing points.
Expand All @@ -156,8 +164,11 @@ public WriteOptions(@Nullable final String database,
*
* @param database The database to be used for InfluxDB operations.
* If it is not specified then use {@link ClientConfig#getDatabase()}.
* @param precision The precision to use for the timestamp of points.
* @param precision The precision to use for the timestamp.
* If it is not specified then use {@link ClientConfig#getWritePrecision()}.
* This setting is ignored when writing {@link com.influxdb.v3.client.Point};
* for those writes, the client always sends {@link WritePrecision#NS}
* precision to the server.
* @param gzipThreshold The threshold for compressing request body.
* If it is not specified then use {@link WriteOptions#DEFAULT_GZIP_THRESHOLD}.
* @param noSync Skip waiting for WAL persistence on write.
Expand Down Expand Up @@ -185,8 +196,11 @@ public WriteOptions(@Nullable final Map<String, String> headers) {
*
* @param database The database to be used for InfluxDB operations.
* If it is not specified then use {@link ClientConfig#getDatabase()}.
* @param precision The precision to use for the timestamp of points.
* @param precision The precision to use for the timestamp.
* If it is not specified then use {@link ClientConfig#getWritePrecision()}.
* This setting is ignored when writing {@link com.influxdb.v3.client.Point};
* for those writes, the client always sends {@link WritePrecision#NS}
* precision to the server.
* @param gzipThreshold The threshold for compressing request body.
* If it is not specified then use {@link WriteOptions#DEFAULT_GZIP_THRESHOLD}.
* @param defaultTags Default tags to be added when writing points.
Expand All @@ -207,8 +221,11 @@ public WriteOptions(@Nullable final String database,
*
* @param database The database to be used for InfluxDB operations.
* If it is not specified then use {@link ClientConfig#getDatabase()}.
* @param precision The precision to use for the timestamp of points.
* @param precision The precision to use for the timestamp.
* If it is not specified then use {@link ClientConfig#getWritePrecision()}.
* This setting is ignored when writing {@link com.influxdb.v3.client.Point};
* for those writes, the client always sends {@link WritePrecision#NS}
* precision to the server.
* @param gzipThreshold The threshold for compressing request body.
* If it is not specified then use {@link WriteOptions#DEFAULT_GZIP_THRESHOLD}.
* @param noSync Skip waiting for WAL persistence on write.
Expand All @@ -232,8 +249,11 @@ public WriteOptions(@Nullable final String database,
*
* @param database The database to be used for InfluxDB operations.
* If it is not specified then use {@link ClientConfig#getDatabase()}.
* @param precision The precision to use for the timestamp of points.
* @param precision The precision to use for the timestamp.
* If it is not specified then use {@link ClientConfig#getWritePrecision()}.
* This setting is ignored when writing {@link com.influxdb.v3.client.Point};
* for those writes, the client always sends {@link WritePrecision#NS}
* precision to the server.
* @param gzipThreshold The threshold for compressing request body.
* If it is not specified then use {@link WriteOptions#DEFAULT_GZIP_THRESHOLD}.
* @param noSync Skip waiting for WAL persistence on write.
Expand Down Expand Up @@ -263,8 +283,11 @@ public WriteOptions(@Nullable final String database,
*
* @param database The database to be used for InfluxDB operations.
* If it is not specified then use {@link ClientConfig#getDatabase()}.
* @param precision The precision to use for the timestamp of points.
* @param precision The precision to use for the timestamp.
* If it is not specified then use {@link ClientConfig#getWritePrecision()}.
* This setting is ignored when writing {@link com.influxdb.v3.client.Point};
* for those writes, the client always sends {@link WritePrecision#NS}
* precision to the server.
* @param gzipThreshold The threshold for compressing request body.
* If it is not specified then use {@link WriteOptions#DEFAULT_GZIP_THRESHOLD}.
* @param noSync Skip waiting for WAL persistence on write.
Expand Down Expand Up @@ -305,8 +328,11 @@ public WriteOptions(@Nullable final String database,
*
* @param database The database to be used for InfluxDB operations.
* If it is not specified then use {@link ClientConfig#getDatabase()}.
* @param precision The precision to use for the timestamp of points.
* @param precision The precision to use for the timestamp.
* If it is not specified then use {@link ClientConfig#getWritePrecision()}.
* This setting is ignored when writing {@link com.influxdb.v3.client.Point};
* for those writes, the client always sends {@link WritePrecision#NS}
* precision to the server.
* @param gzipThreshold The threshold for compressing request body.
* If it is not specified then use {@link WriteOptions#DEFAULT_GZIP_THRESHOLD}.
* @param noSync Skip waiting for WAL persistence on write.
Expand Down
47 changes: 45 additions & 2 deletions src/test/java/com/influxdb/v3/client/InfluxDBClientWriteTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,10 @@ void writePointWithDefaultWriteOptionsCustomConfig() throws Exception {
client.writePoint(point);
}

checkWriteCalled("/api/v3/write_lp", "DB", "second", true, "true", null, true);
// When writing Point, precision sent to the server is always nanosecond
var expectedPrecision = "nanosecond";

checkWriteCalled("/api/v3/write_lp", "DB", expectedPrecision, true, "true", null, true);
}

@Test
Expand Down Expand Up @@ -447,7 +450,47 @@ void writePointsWithDefaultWriteOptionsCustomConfig() throws Exception {
client.writePoints(List.of(point));
}

checkWriteCalled("/api/v3/write_lp", "DB", "second", true, "true", null, true);
// When writing Point, precision sent to the server is always nanosecond
var expectedPrecision = "nanosecond";

checkWriteCalled("/api/v3/write_lp", "DB", expectedPrecision, true, "true", null, true);
}

Comment thread
NguyenHoangSon96 marked this conversation as resolved.
@ParameterizedTest(name = "{0}")
@MethodSource("pointPrecisionIgnoredCases")
void pointWritesIgnoreWriteOptionsPrecision(
@Nonnull final String name,
@Nonnull final WritePrecision configuredPrecision,
final boolean manyPoints) throws Exception {
mockServer.enqueue(createResponse(200));
ClientConfig cfg = new ClientConfig.Builder()
.host(baseURL)
.token("TOKEN".toCharArray())
.database("DB")
.build();
try (InfluxDBClient client = InfluxDBClient.getInstance(cfg)) {
Point point = new Point("mem");
point.setTag("tag", "one");
point.setField("value", 1.0);
WriteOptions options = new WriteOptions.Builder()
.precision(configuredPrecision)
.build();
if (manyPoints) {
client.writePoints(List.of(point), options);
} else {
client.writePoint(point, options);
}
}
checkWriteCalled("/api/v3/write_lp", "DB", "nanosecond", true, null, null, false);
}

private static Stream<Arguments> pointPrecisionIgnoredCases() {
return Stream.of(
Arguments.of("writePoint precision=S", WritePrecision.S, false),
Arguments.of("writePoint precision=MS", WritePrecision.MS, false),
Arguments.of("writePoints precision=S", WritePrecision.S, true),
Arguments.of("writePoints precision=US", WritePrecision.US, true)
);
}

private void checkWriteCalled(final String expectedPath, final String expectedDB,
Expand Down
37 changes: 35 additions & 2 deletions src/test/java/com/influxdb/v3/client/integration/E2ETest.java
Original file line number Diff line number Diff line change
Expand Up @@ -595,10 +595,43 @@ public void testMultipleQueries() throws Exception {
}
}
}


}

@EnabledIfEnvironmentVariable(named = "TESTING_INFLUXDB_URL", matches = ".*")
@EnabledIfEnvironmentVariable(named = "TESTING_INFLUXDB_TOKEN", matches = ".*")
@EnabledIfEnvironmentVariable(named = "TESTING_INFLUXDB_DATABASE", matches = ".*")
@Test
Comment thread
NguyenHoangSon96 marked this conversation as resolved.
public void testWriteWithDifferentTimeUnit() throws Exception {
try (InfluxDBClient client = InfluxDBClient.getInstance(
System.getenv("TESTING_INFLUXDB_URL"),
System.getenv("TESTING_INFLUXDB_TOKEN").toCharArray(),
System.getenv("TESTING_INFLUXDB_DATABASE"),
null)) {
var writeOptions = new WriteOptions.Builder().precision(WritePrecision.MS).build();
String measurement = "test_" + UUID.randomUUID();
List<Point> points = List.of(
Point.measurement(measurement)
.setTag("type", "test")
.setFloatField("rads", 3.14)
.setIntegerField("life", 42)
.setTimestamp(Instant.now().toEpochMilli(), WritePrecision.MS),
Point.measurement(measurement)
.setTag("type", "test")
.setFloatField("rads", 3.14)
.setIntegerField("life", 12)
.setTimestamp(Instant.now().plusSeconds(1).getEpochSecond(), WritePrecision.S),
Point.measurement(measurement)
.setTag("type", "test")
.setFloatField("rads", 3.14)
.setIntegerField("life", 432)
.setTimestamp(Instant.now().plusSeconds(2).toEpochMilli() * 1000, WritePrecision.US)
Comment thread
NguyenHoangSon96 marked this conversation as resolved.
);
client.writePoints(points, writeOptions);
var results = client.queryPoints(String.format("select * from \"%s\"", measurement))
.collect(Collectors.toList());
Assertions.assertThat(results).hasSize(3);
Comment thread
NguyenHoangSon96 marked this conversation as resolved.
}
Comment thread
NguyenHoangSon96 marked this conversation as resolved.
Comment thread
NguyenHoangSon96 marked this conversation as resolved.
}

private void assertGetDataSuccess(@Nonnull final InfluxDBClient influxDBClient) {
influxDBClient.writePoint(
Expand Down
Loading