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
13 changes: 7 additions & 6 deletions core/src/main/java/io/questdb/cairo/TableWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@
import io.questdb.std.BinarySequence;
import io.questdb.std.Chars;
import io.questdb.std.Decimal256;
import io.questdb.std.Decimals;
import io.questdb.std.DirectIntList;
import io.questdb.std.DirectLongList;
import io.questdb.std.Files;
Expand Down Expand Up @@ -3164,22 +3165,22 @@ private static void configureNullSetters(ObjList<Runnable> nullers, int columnTy
nullers.add(() -> dataMem.putLong(GeoHashes.NULL));
break;
case ColumnType.DECIMAL8:
nullers.add(() -> dataMem.putByte(Byte.MIN_VALUE));
nullers.add(() -> dataMem.putByte(Decimals.DECIMAL8_NULL));
break;
case ColumnType.DECIMAL16:
nullers.add(() -> dataMem.putShort(Short.MIN_VALUE));
nullers.add(() -> dataMem.putShort(Decimals.DECIMAL16_NULL));
break;
case ColumnType.DECIMAL32:
nullers.add(() -> dataMem.putInt(Integer.MIN_VALUE));
nullers.add(() -> dataMem.putInt(Decimals.DECIMAL32_NULL));
break;
case ColumnType.DECIMAL64:
nullers.add(() -> dataMem.putLong(Long.MIN_VALUE));
nullers.add(() -> dataMem.putLong(Decimals.DECIMAL64_NULL));
break;
case ColumnType.DECIMAL128:
nullers.add(() -> dataMem.putDecimal128(Long.MIN_VALUE, -1));
nullers.add(() -> dataMem.putDecimal128(Decimals.DECIMAL128_HI_NULL, Decimals.DECIMAL128_LO_NULL));
break;
case ColumnType.DECIMAL256:
nullers.add(() -> dataMem.putDecimal256(Long.MIN_VALUE, -1, -1, -1));
nullers.add(() -> dataMem.putDecimal256(Decimals.DECIMAL256_HH_NULL, Decimals.DECIMAL256_HL_NULL, Decimals.DECIMAL256_LH_NULL, Decimals.DECIMAL256_LL_NULL));
break;
default:
nullers.add(NOOP);
Expand Down
13 changes: 7 additions & 6 deletions core/src/main/java/io/questdb/cairo/wal/WalWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
import io.questdb.std.BoolList;
import io.questdb.std.Chars;
import io.questdb.std.Decimal256;
import io.questdb.std.Decimals;
import io.questdb.std.Files;
import io.questdb.std.FilesFacade;
import io.questdb.std.IntList;
Expand Down Expand Up @@ -787,22 +788,22 @@ private static void configureNullSetters(ObjList<Runnable> nullers, int type, Me
nullers.add(() -> dataMem.putLong128(Numbers.LONG_NULL, Numbers.LONG_NULL));
break;
case ColumnType.DECIMAL8:
nullers.add(() -> dataMem.putByte(Byte.MIN_VALUE));
nullers.add(() -> dataMem.putByte(Decimals.DECIMAL8_NULL));
break;
case ColumnType.DECIMAL16:
nullers.add(() -> dataMem.putShort(Short.MIN_VALUE));
nullers.add(() -> dataMem.putShort(Decimals.DECIMAL16_NULL));
break;
case ColumnType.DECIMAL32:
nullers.add(() -> dataMem.putInt(Integer.MIN_VALUE));
nullers.add(() -> dataMem.putInt(Decimals.DECIMAL32_NULL));
break;
case ColumnType.DECIMAL64:
nullers.add(() -> dataMem.putLong(Long.MIN_VALUE));
nullers.add(() -> dataMem.putLong(Decimals.DECIMAL64_NULL));
break;
case ColumnType.DECIMAL128:
nullers.add(() -> dataMem.putDecimal128(Long.MIN_VALUE, -1));
nullers.add(() -> dataMem.putDecimal128(Decimals.DECIMAL128_HI_NULL, Decimals.DECIMAL128_LO_NULL));
break;
case ColumnType.DECIMAL256:
nullers.add(() -> dataMem.putDecimal256(Long.MIN_VALUE, -1, -1, -1));
nullers.add(() -> dataMem.putDecimal256(Decimals.DECIMAL256_HH_NULL, Decimals.DECIMAL256_HL_NULL, Decimals.DECIMAL256_LH_NULL, Decimals.DECIMAL256_LL_NULL));
break;
default:
throw new UnsupportedOperationException("unsupported column type: " + ColumnType.nameOf(type));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -921,6 +921,49 @@ public void onTableOrMatViewCreated(SecurityContext securityContext, TableToken
});
}

@Test
public void testDecimalDefaultValuesWal() throws Exception {
TestUtils.assertMemoryLeak(() -> {
try (final TestServerMain serverMain = startWithEnvVariables(
PropertyKey.HTTP_RECEIVE_BUFFER_SIZE.getEnvVarName(), "512"
)) {
serverMain.execute("""
CREATE TABLE decimal_test (
dec8 DECIMAL(2, 0),
dec16 DECIMAL(4, 1),
dec32 DECIMAL(8, 2),
dec64 DECIMAL(16, 4),
dec128 DECIMAL(34, 8),
dec256 DECIMAL(64, 16),
value INT,
ts TIMESTAMP
) TIMESTAMP(ts) PARTITION BY DAY WAL
""");
serverMain.awaitTxn("decimal_test", 0);

int port = serverMain.getHttpServerPort();
try (Sender sender = Sender.builder(Sender.Transport.HTTP)
.address("localhost:" + port)
.autoFlushRows(Integer.MAX_VALUE) // we want to flush manually
.retryTimeoutMillis(0)
.build()
) {
sender.table("decimal_test")
.longColumn("value", 1)
.at(100000000000L, ChronoUnit.MICROS);
sender.flush();
}

serverMain.awaitTxn("decimal_test", 1);
serverMain.assertSql("decimal_test",
"""
dec8\tdec16\tdec32\tdec64\tdec128\tdec256\tvalue\tts
\t\t\t\t\t\t1\t1970-01-02T03:46:40.000000Z
""");
}
});
}

@Test
public void testEmptyArraysMultiDimensional() throws Exception {
TestUtils.assertMemoryLeak(() -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,43 @@ public void testCreateTimestampColumnsWithDesignatedNanosV2() throws Exception {
"1.111\t2025-11-19T10:55:24.123456789Z\t2025-11-19T10:55:24.123456Z\t2025-11-19T10:55:24.123000Z\t2025-11-19T10:55:24.123456799Z\t2025-11-20T10:55:24.123456789Z");
}

@Test
public void testDecimalDefaultValuesWithoutWal() throws Exception {
runInContext(r -> {
engine.execute("""
CREATE TABLE decimal_test (
dec8 DECIMAL(2, 0),
dec16 DECIMAL(4, 1),
dec32 DECIMAL(8, 2),
dec64 DECIMAL(16, 4),
dec128 DECIMAL(34, 8),
dec256 DECIMAL(64, 16),
value INT,
ts TIMESTAMP
) TIMESTAMP(ts) PARTITION BY DAY BYPASS WAL
""");
assertTableExists(engine, "decimal_test");

try (Sender sender = Sender.builder(Sender.Transport.TCP)
.address("127.0.0.1")
.port(bindPort)
.protocolVersion(PROTOCOL_VERSION_V3)
.build()
) {
sender.table("decimal_test")
.longColumn("value", 1)
.at(100_000, ChronoUnit.MICROS);
sender.flush();

assertTableSizeEventually(engine, "decimal_test", 1);
assertTable("""
dec8\tdec16\tdec32\tdec64\tdec128\tdec256\tvalue\tts
\t\t\t\t\t\t1\t1970-01-01T00:00:00.100000Z
""", "decimal_test");
}
});
}

@Test
public void testDouble_edgeValues() throws Exception {
final boolean isMicros = ColumnType.isTimestampMicro(timestampType.getTimestampType());
Expand Down Expand Up @@ -844,7 +881,6 @@ public void testInsertDecimalTextFormatInvalid() throws Exception {
});
}


@Test
public void testInsertDecimalTextFormatPrecisionOverflow() throws Exception {
runInContext(r -> {
Expand Down
Loading