Skip to content

Commit 7c37f74

Browse files
authored
Merge branch 'master' into fix-checkpoint-restore-handle-dropped-tables
2 parents c596996 + 8d51a22 commit 7c37f74

File tree

9 files changed

+291
-268
lines changed

9 files changed

+291
-268
lines changed

core/src/main/java/io/questdb/griffin/engine/table/ShowCreateTableRecordCursorFactory.java

Lines changed: 8 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ private void showCreateTable(CairoConfiguration config) {
210210
// CREATE TABLE table_name
211211
putCreateTable();
212212
// column_name TYPE
213-
putColumns(config);
213+
putColumns();
214214
// timestamp(ts)
215215
if (table.getTimestampIndex() != -1) {
216216
putTimestamp();
@@ -221,8 +221,6 @@ private void showCreateTable(CairoConfiguration config) {
221221
// (BYPASS) WAL
222222
putWal();
223223
}
224-
// WITH maxUncommittedRows=123, o3MaxLag=456s
225-
putWith();
226224
// IN VOLUME OTHER_VOLUME
227225
putInVolume(config);
228226
// DEDUP UPSERT(key1, key2)
@@ -236,36 +234,28 @@ private void showCreateTable(CairoConfiguration config) {
236234
protected void putAdditional() {
237235
}
238236

239-
protected void putColumn(CairoConfiguration config, CairoColumn column) {
237+
protected void putColumn(CairoColumn column) {
240238
sink.put('\t')
241239
.put(column.getName())
242240
.putAscii(' ')
243241
.put(ColumnType.nameOf(column.getType()));
244242

245243
if (column.getType() == ColumnType.SYMBOL) {
246-
// CAPACITY value (NO)CACHE
247-
int symbolCapacity = column.getSymbolCapacity();
248-
249-
// some older versions of QuestDB can have `0` written to the metadata file
250-
// this will produce an incorrect DDL if we print it
251-
// so we fall back to default capacity
252-
if (symbolCapacity < 2) {
253-
symbolCapacity = config.getDefaultSymbolCapacity();
244+
// omit capacity due to autoscaling
245+
if (!column.isSymbolCached()) {
246+
sink.putAscii(" NOCACHE");
254247
}
255248

256-
sink.putAscii(" CAPACITY ").put(symbolCapacity);
257-
sink.putAscii(column.isSymbolCached() ? " CACHE" : " NOCACHE");
258-
259249
if (column.isIndexed()) {
260250
// INDEX CAPACITY value
261251
sink.putAscii(" INDEX CAPACITY ").put(column.getIndexBlockCapacity());
262252
}
263253
}
264254
}
265255

266-
protected void putColumns(CairoConfiguration configuration) {
256+
protected void putColumns() {
267257
for (int i = 0, n = table.getColumnCount(); i < n; i++) {
268-
putColumn(configuration, table.getColumnQuiet(i));
258+
putColumn(table.getColumnQuiet(i));
269259
if (i < n - 1) {
270260
sink.putAscii(',');
271261
}
@@ -318,15 +308,8 @@ protected void putTimestamp() {
318308
protected void putWal() {
319309
if (!table.isWalEnabled()) {
320310
sink.putAscii(" BYPASS");
311+
sink.putAscii(" WAL");
321312
}
322-
sink.putAscii(" WAL");
323-
}
324-
325-
protected void putWith() {
326-
sink.putAscii('\n').putAscii("WITH ");
327-
sink.putAscii("maxUncommittedRows=").put(table.getMaxUncommittedRows());
328-
sink.put(", ");
329-
sink.putAscii("o3MaxLag=").put(table.getO3MaxLag()).putAscii("us");
330313
}
331314

332315
public class ShowCreateTableRecord implements Record {

core/src/test/java/io/questdb/test/TelemetryTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ public void testTelemetryTableUpgrade() throws Exception {
227227
"\torigin SHORT\n" +
228228
") timestamp(created)";
229229
String middle = " PARTITION BY NONE";
230-
String end = " BYPASS WAL\nWITH maxUncommittedRows=1000, o3MaxLag=300000000us;\n";
230+
String end = " BYPASS WAL;\n";
231231

232232
assertSql(start + middle + end, showCreateTable);
233233
try (TelemetryJob ignore = new TelemetryJob(engine)) {
@@ -304,7 +304,7 @@ public void testTelemetryWalTableUpgrade() throws Exception {
304304
") timestamp(created)";
305305
String midOld = " PARTITION BY MONTH";
306306
String midNew = " PARTITION BY DAY TTL 1 WEEK";
307-
String end = " BYPASS WAL\nWITH maxUncommittedRows=1000, o3MaxLag=300000000us;\n";
307+
String end = " BYPASS WAL;\n";
308308

309309
assertSql(start + midOld + end, showCreateTable);
310310
try (TelemetryJob ignore = new TelemetryJob(engine)) {

core/src/test/java/io/questdb/test/cairo/CreateTableTest.java

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,10 @@ public void testCreateTableArrayWithMismatchedBrackets() throws Exception {
8484
@Test
8585
public void testCreateTableAsSelectIndexSupportedColumnTypeAfterCast() throws Exception {
8686
assertQuery(
87-
"x\n" +
88-
"1\n",
87+
"""
88+
x
89+
1
90+
""",
8991
"select * from tab",
9092
"CREATE TABLE tab AS (" +
9193
"SELECT CAST(x as SYMBOL) AS x FROM long_sequence(1)" +
@@ -99,8 +101,10 @@ public void testCreateTableAsSelectIndexSupportedColumnTypeAfterCast() throws Ex
99101
@Test
100102
public void testCreateTableAsSelectIndexSupportedColumnTypeAfterCast2() throws Exception {
101103
assertQuery(
102-
"x\n" +
103-
"1\n",
104+
"""
105+
x
106+
1
107+
""",
104108
"select * from tab",
105109
"CREATE TABLE tab AS (" +
106110
"SELECT CAST(x as STRING) AS x FROM long_sequence(1)" +
@@ -611,11 +615,12 @@ public void testCreateTableParallelWal() throws Throwable {
611615
public void testCreateTableWithArrayColumn() throws Exception {
612616
assertMemoryLeak(() -> {
613617
execute("create table x (arr double[]);");
614-
assertSql("ddl\n" +
615-
"CREATE TABLE 'x' ( \n" +
616-
"\tarr DOUBLE[]\n" +
617-
")\n" +
618-
"WITH maxUncommittedRows=1000, o3MaxLag=300000000us;\n",
618+
assertSql("""
619+
ddl
620+
CREATE TABLE 'x' (\s
621+
\tarr DOUBLE[]
622+
);
623+
""",
619624
"show create table x;");
620625
});
621626
}
@@ -649,12 +654,13 @@ public void testCreateTableWithNoIndex() throws Exception {
649654
public void testCreateTableWithTimestampNSColumn() throws Exception {
650655
assertMemoryLeak(() -> {
651656
execute("create table x (ns timestamp_ns, s symbol) timestamp(ns) partition by DAY WAL;");
652-
assertSql("ddl\n" +
653-
"CREATE TABLE 'x' ( \n" +
654-
"\tns TIMESTAMP_NS,\n" +
655-
"\ts SYMBOL CAPACITY 128 CACHE\n" +
656-
") timestamp(ns) PARTITION BY DAY WAL\n" +
657-
"WITH maxUncommittedRows=1000, o3MaxLag=300000000us;\n",
657+
assertSql("""
658+
ddl
659+
CREATE TABLE 'x' (\s
660+
\tns TIMESTAMP_NS,
661+
\ts SYMBOL
662+
) timestamp(ns) PARTITION BY DAY;
663+
""",
658664
"show create table x;");
659665
execute("create table y (like x);");
660666
assertSql("ns\ts\n", "select * from x");
@@ -667,9 +673,8 @@ public void testCreateTableWithTimestampNSColumn() throws Exception {
667673
assertSql("ddl\n" +
668674
"CREATE TABLE 'y' ( \n" +
669675
"\tns TIMESTAMP_NS,\n" +
670-
"\ts SYMBOL CAPACITY 128 CACHE\n" +
671-
") timestamp(ns) PARTITION BY DAY WAL\n" +
672-
"WITH maxUncommittedRows=1000, o3MaxLag=300000000us;\n",
676+
"\ts SYMBOL\n" +
677+
") timestamp(ns) PARTITION BY DAY;\n",
673678
"show create table y;");
674679
assertSql(
675680
"column\ttype\tindexed\tindexBlockCapacity\tsymbolCached\tsymbolCapacity\tsymbolTableSize\tdesignated\tupsertKey\n" +
@@ -693,8 +698,7 @@ public void testCreateTableWithTimestampNSColumn() throws Exception {
693698
"\tns TIMESTAMP_NS,\n" +
694699
"\ta INT,\n" +
695700
"\tb STRING\n" +
696-
") timestamp(ns) PARTITION BY DAY WAL\n" +
697-
"WITH maxUncommittedRows=1000, o3MaxLag=300000000us\n" +
701+
") timestamp(ns) PARTITION BY DAY\n" +
698702
"DEDUP UPSERT KEYS(ns,a);\n",
699703
"show create table z;");
700704
});

core/src/test/java/io/questdb/test/cairo/TtlTest.java

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,11 @@
4141
@RunWith(Parameterized.class)
4242
public class TtlTest extends AbstractCairoTest {
4343
private final String wal;
44+
private final WalMode walMode;
4445

4546
public TtlTest(WalMode walMode) {
46-
this.wal = walMode == WalMode.WITH_WAL ? " WAL" : " BYPASS WAL";
47+
this.walMode = walMode;
48+
this.wal = walMode == WalMode.WITH_WAL ? " wal;" : " BYPASS WAL;";
4749
}
4850

4951
@Parameterized.Parameters(name = "{0}")
@@ -106,9 +108,8 @@ public void testAlterSyntaxInvalid() throws Exception {
106108

107109
@Test
108110
public void testAlterTableNotPartitioned() throws Exception {
109-
Assume.assumeTrue(wal.equals("BYPASS WAL"));
111+
Assume.assumeTrue(walMode == WalMode.NO_WAL);
110112
execute("CREATE TABLE tango (n LONG)");
111-
execute("ALTER TABLE tango SET TTL 0H"); // zero TTL is acceptable
112113
try {
113114
execute("ALTER TABLE tango SET TTL 1H");
114115
fail("Accepted TTL on a non-partitioned table");
@@ -139,18 +140,18 @@ public void testAlterTableSetTtl() throws Exception {
139140

140141
@Test
141142
public void testCreateSyntaxInvalid() {
142-
Assume.assumeTrue(wal.equals("BYPASS WAL"));
143+
Assume.assumeTrue(walMode == WalMode.NO_WAL);
143144
try {
144145
execute("CREATE TABLE tango (ts TIMESTAMP) TIMESTAMP(ts) PARTITION BY HOUR TTL");
145146
fail("Invalid syntax accepted");
146147
} catch (SqlException e) {
147-
assertEquals("[69] missing argument, should be TTL <number> <unit> or <number_with_unit>", e.getMessage());
148+
assertEquals("[69] missing argument, should be <number> <unit> or <number_with_unit>", e.getMessage());
148149
}
149150
try {
150151
execute("CREATE TABLE tango (ts TIMESTAMP) TIMESTAMP(ts) PARTITION BY HOUR TTL X");
151152
fail("Invalid syntax accepted");
152153
} catch (SqlException e) {
153-
assertEquals("[70] invalid syntax, should be TTL <number> <unit> but was TTL X", e.getMessage());
154+
assertEquals("[70] invalid syntax, should be <number> <unit> but was X", e.getMessage());
154155
}
155156
try {
156157
execute("CREATE TABLE tango (ts TIMESTAMP) TIMESTAMP(ts) PARTITION BY HOUR TTL 12");
@@ -169,14 +170,14 @@ public void testCreateSyntaxInvalid() {
169170
execute("CREATE TABLE tango (ts TIMESTAMP) TIMESTAMP(ts) PARTITION BY HOUR TTL HOURS");
170171
fail("Invalid syntax accepted");
171172
} catch (SqlException e) {
172-
assertEquals("[70] invalid argument, should be TTL <number> <unit> or <number_with_unit>",
173+
assertEquals("[70] invalid argument, should be <number> <unit> or <number_with_unit>",
173174
e.getMessage());
174175
}
175176
try {
176177
execute("CREATE TABLE tango (ts TIMESTAMP) TIMESTAMP(ts) PARTITION BY HOUR TTL H");
177178
fail("Invalid syntax accepted");
178179
} catch (SqlException e) {
179-
assertEquals("[70] invalid syntax, should be TTL <number> <unit> but was TTL H",
180+
assertEquals("[70] invalid syntax, should be <number> <unit> but was H",
180181
e.getMessage());
181182
}
182183
try {
@@ -190,11 +191,14 @@ public void testCreateSyntaxInvalid() {
190191

191192
@Test
192193
public void testCreateTableLike() throws Exception {
193-
execute("CREATE TABLE tango (ts TIMESTAMP) TIMESTAMP(ts) PARTITION BY HOUR TTL 2 HOURS" + wal);
194+
execute("CREATE TABLE tango (ts TIMESTAMP) TIMESTAMP(ts) PARTITION BY HOUR TTL 2 HOURS " + wal);
194195
execute("CREATE TABLE samba (LIKE tango)");
195-
assertSql("ddl\n" +
196-
"CREATE TABLE 'samba' ( \n\tts TIMESTAMP\n) timestamp(ts) PARTITION BY HOUR TTL 2 HOURS" + wal
197-
+ "\nWITH maxUncommittedRows=1000, o3MaxLag=300000000us;\n",
196+
assertSql("""
197+
ddl
198+
CREATE TABLE 'samba' (\s
199+
\tts TIMESTAMP
200+
) timestamp(ts) PARTITION BY HOUR TTL 2 HOURS%s
201+
""".formatted(walMode == WalMode.WITH_WAL ? ";" : wal),
198202
"SHOW CREATE TABLE samba");
199203
}
200204

@@ -324,7 +328,7 @@ public void testFutureTimestampDoesNotWipeTableNanos() throws Exception {
324328
public void testFutureTimestampWipesTableWhenWallClockDisabled() throws Exception {
325329
// This test verifies the opt-out behavior: when wall clock is disabled,
326330
// future timestamps will cause TTL to evict data based on maxTimestamp only
327-
Assume.assumeTrue(wal.equals(" BYPASS WAL")); // Only test in non-WAL mode for simplicity
331+
Assume.assumeTrue(walMode == WalMode.NO_WAL); // Only test in non-WAL mode for simplicity
328332

329333
node1.setProperty(PropertyKey.CAIRO_TTL_USE_WALL_CLOCK, false);
330334
try {
@@ -622,7 +626,7 @@ public void testRandomInsertion() throws Exception {
622626

623627
@Test
624628
public void testSyntaxJustWithinRange() throws Exception {
625-
Assume.assumeTrue(wal.equals("BYPASS WAL"));
629+
Assume.assumeTrue(walMode == WalMode.NO_WAL);
626630

627631
execute("CREATE TABLE tango (ts TIMESTAMP) TIMESTAMP(ts) PARTITION BY HOUR TTL 2_147_483_647 HOURS");
628632
execute("DROP TABLE tango");
@@ -637,20 +641,20 @@ public void testSyntaxJustWithinRange() throws Exception {
637641

638642
@Test
639643
public void testSyntaxOutOfRange() {
640-
Assume.assumeTrue(wal.equals("BYPASS WAL"));
644+
Assume.assumeTrue(walMode == WalMode.NO_WAL);
641645

642646
try {
643647
execute("CREATE TABLE tango (ts TIMESTAMP) TIMESTAMP(ts) PARTITION BY HOUR TTL -1 HOURS");
644648
fail("Invalid syntax accepted");
645649
} catch (SqlException e) {
646-
assertEquals("[70] invalid syntax, should be TTL <number> <unit> but was TTL -",
650+
assertEquals("[70] invalid syntax, should be <number> <unit> but was -",
647651
e.getMessage());
648652
}
649653
try {
650654
execute("CREATE TABLE tango (ts TIMESTAMP) TIMESTAMP(ts) PARTITION BY HOUR TTL 2_147_483_648 HOURS");
651655
fail("Invalid syntax accepted");
652656
} catch (SqlException e) {
653-
assertEquals("[70] TTL value out of range: 2147483648. Max value: 2147483647",
657+
assertEquals("[70] value out of range: 2147483648. Max value: 2147483647",
654658
e.getMessage());
655659
}
656660
try {
@@ -671,7 +675,7 @@ public void testSyntaxOutOfRange() {
671675
execute("CREATE TABLE tango (ts TIMESTAMP) TIMESTAMP(ts) PARTITION BY HOUR TTL 2_147_483_648 MONTHS");
672676
fail("Invalid syntax accepted");
673677
} catch (SqlException e) {
674-
assertEquals("[70] TTL value out of range: 2147483648. Max value: 2147483647",
678+
assertEquals("[70] value out of range: 2147483648. Max value: 2147483647",
675679
e.getMessage());
676680
}
677681
try {

core/src/test/java/io/questdb/test/cairo/view/ViewFuzzTest.java

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import io.questdb.std.Os;
3838
import io.questdb.std.Rnd;
3939
import io.questdb.std.str.Path;
40+
import io.questdb.std.str.StringSink;
4041
import io.questdb.test.cairo.fuzz.AbstractFuzzTest;
4142
import io.questdb.test.fuzz.FuzzTransaction;
4243
import io.questdb.test.sql.RandomSelectGenerator;
@@ -272,11 +273,15 @@ private void testViewFuzz(RandomSelectGenerator selectGenerator, Rnd rnd, String
272273
selectGenerator.registerTable(baseTableName);
273274

274275
final ObjList<String> viewSqls = new ObjList<>();
275-
for (final String viewName : viewNames) {
276-
final String viewSql = selectGenerator.generate();
277-
viewSqls.add(viewSql);
278-
createView(viewName, viewSql);
279-
selectGenerator.registerTable(viewName);
276+
try (ViewCompilerJob viewCompiler = new ViewCompilerJob(0, engine, 0)) {
277+
for (final String viewName : viewNames) {
278+
final String viewSql = selectGenerator.generate();
279+
viewSqls.add(viewSql);
280+
createView(viewName, viewSql);
281+
LOG.info().$("created view ").$(viewName).$(" as ").$(viewSql).$();
282+
viewCompiler.run(0); // compile the view before registering it. so if there is a dependant view it gets to see this view's metadata
283+
selectGenerator.registerTable(viewName);
284+
}
280285
}
281286

282287
AtomicBoolean stop = new AtomicBoolean();
@@ -304,22 +309,29 @@ private void testViewFuzz(RandomSelectGenerator selectGenerator, Rnd rnd, String
304309
final String viewName = viewNames[i];
305310
final String viewSql = viewSqls.getQuick(i);
306311

307-
int orderByColumnIndex = 0;
312+
// Order by ALL non-binary columns to ensure deterministic ordering.
313+
// Ordering by a single low-cardinality column can cause flaky failures
314+
// when multiple rows have the same value.
315+
StringSink orderByClause = new StringSink();
308316
final TableToken viewToken = engine.getTableTokenIfExists(viewName);
309317
try (TableMetadata metadata = engine.getTableMetadata(viewToken)) {
310318
for (int j = 0; j < metadata.getColumnCount(); j++) {
311319
if (metadata.getColumnType(j) != ColumnType.BINARY) {
312-
orderByColumnIndex = j + 1;
313-
break;
320+
if (!orderByClause.isEmpty()) {
321+
orderByClause.put(", ");
322+
}
323+
orderByClause.put(j + 1);
314324
}
315325
}
316326
}
327+
String orderBy = !orderByClause.isEmpty() ? " order by " + orderByClause : "";
317328

329+
LOG.info().$("asserting view ").$(viewName).$(" against ").$(viewSql).$(", order-by: ").$(orderBy).I$();
318330
TestUtils.assertSqlCursors(
319331
compiler,
320332
sqlExecutionContext,
321-
orderByColumnIndex > 0 ? "(" + viewSql + ") order by " + orderByColumnIndex : viewSql,
322-
orderByColumnIndex > 0 ? "(" + viewName + ") order by " + orderByColumnIndex : viewName,
333+
"(" + viewSql + ")" + orderBy,
334+
"(" + viewName + ")" + orderBy,
323335
LOG
324336
);
325337
}

core/src/test/java/io/questdb/test/cutlass/http/line/LineHttpSenderTest.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -664,8 +664,7 @@ public void testAutoCreationArrayType() throws Exception {
664664
CREATE TABLE 'arr_auto_creation_test' (\s
665665
\tarr DOUBLE[],
666666
\ttimestamp TIMESTAMP
667-
) timestamp(timestamp) PARTITION BY DAY WAL
668-
WITH maxUncommittedRows=500000, o3MaxLag=600000000us;
667+
) timestamp(timestamp) PARTITION BY DAY;
669668
""");
670669
}
671670
}

0 commit comments

Comments
 (0)