Skip to content

Commit 74aaa99

Browse files
authored
fix(sql): make table column names case insensitive in where (questdb#1045)
1 parent 2764af9 commit 74aaa99

13 files changed

+138
-19
lines changed

core/src/main/java/io/questdb/cairo/BaseRecordMetadata.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,12 @@
2626

2727

2828
import io.questdb.cairo.sql.RecordMetadata;
29-
import io.questdb.std.CharSequenceIntHashMap;
29+
import io.questdb.std.LowerCaseCharSequenceIntHashMap;
3030
import io.questdb.std.ObjList;
3131

3232
public abstract class BaseRecordMetadata implements RecordMetadata {
3333
protected ObjList<TableColumnMetadata> columnMetadata;
34-
protected CharSequenceIntHashMap columnNameIndexMap;
34+
protected LowerCaseCharSequenceIntHashMap columnNameIndexMap;
3535
protected int timestampIndex;
3636
protected int columnCount;
3737

core/src/main/java/io/questdb/cairo/TableReaderMetadata.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public class TableReaderMetadata extends BaseRecordMetadata implements Closeable
3737
private final MappedReadOnlyMemory metaMem;
3838
private final Path path;
3939
private final FilesFacade ff;
40-
private final CharSequenceIntHashMap tmpValidationMap = new CharSequenceIntHashMap();
40+
private final LowerCaseCharSequenceIntHashMap tmpValidationMap = new LowerCaseCharSequenceIntHashMap();
4141
private int id;
4242
private MappedReadOnlyMemory transitionMeta;
4343

@@ -46,7 +46,7 @@ public TableReaderMetadata(FilesFacade ff) {
4646
this.ff = ff;
4747
this.metaMem = new SinglePageMappedReadOnlyPageMemory();
4848
this.columnMetadata = new ObjList<>(columnCount);
49-
this.columnNameIndexMap = new CharSequenceIntHashMap();
49+
this.columnNameIndexMap = new LowerCaseCharSequenceIntHashMap();
5050
}
5151

5252
public TableReaderMetadata(FilesFacade ff, Path path) {

core/src/main/java/io/questdb/cairo/TableUtils.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,7 @@ public static void txnPartitionConditionally(CharSink path, long txn) {
526526
}
527527
}
528528

529-
public static void validate(FilesFacade ff, MappedReadOnlyMemory metaMem, CharSequenceIntHashMap nameIndex) {
529+
public static void validate(FilesFacade ff, MappedReadOnlyMemory metaMem, LowerCaseCharSequenceIntHashMap nameIndex) {
530530
try {
531531
final int metaVersion = metaMem.getInt(TableUtils.META_OFFSET_VERSION);
532532
if (ColumnType.VERSION != metaVersion && metaVersion != 404) {

core/src/main/java/io/questdb/cairo/TableWriter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ public class TableWriter implements Closeable {
9797
private final CharSequence tableName;
9898
private final TableWriterMetadata metadata;
9999
private final CairoConfiguration configuration;
100-
private final CharSequenceIntHashMap validationMap = new CharSequenceIntHashMap();
100+
private final LowerCaseCharSequenceIntHashMap validationMap = new LowerCaseCharSequenceIntHashMap();
101101
private final FragileCode RECOVER_FROM_META_RENAME_FAILURE = this::recoverFromMetaRenameFailure;
102102
private final SOCountDownLatch indexLatch = new SOCountDownLatch();
103103
private final LongList indexSequences = new LongList();

core/src/main/java/io/questdb/cairo/TableWriterMetadata.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@
2626

2727
import io.questdb.cairo.vm.MappedReadOnlyMemory;
2828
import io.questdb.cairo.vm.VmUtils;
29-
import io.questdb.std.CharSequenceIntHashMap;
3029
import io.questdb.std.Chars;
3130
import io.questdb.std.FilesFacade;
31+
import io.questdb.std.LowerCaseCharSequenceIntHashMap;
3232
import io.questdb.std.ObjList;
3333

3434
public class TableWriterMetadata extends BaseRecordMetadata {
@@ -40,7 +40,7 @@ public class TableWriterMetadata extends BaseRecordMetadata {
4040

4141
public TableWriterMetadata(FilesFacade ff, MappedReadOnlyMemory metaMem) {
4242
this.columnCount = metaMem.getInt(TableUtils.META_OFFSET_COUNT);
43-
this.columnNameIndexMap = new CharSequenceIntHashMap(columnCount);
43+
this.columnNameIndexMap = new LowerCaseCharSequenceIntHashMap(columnCount);
4444
this.version = metaMem.getInt(TableUtils.META_OFFSET_VERSION);
4545
this.id = metaMem.getInt(TableUtils.META_OFFSET_TABLE_ID);
4646
this.maxUncommittedRows = metaMem.getInt(TableUtils.META_OFFSET_MAX_UNCOMMITTED_ROWS);

core/src/main/java/io/questdb/griffin/engine/join/JoinRecordMetadata.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@
3030
import io.questdb.cairo.map.MapKey;
3131
import io.questdb.cairo.map.MapValue;
3232
import io.questdb.cairo.sql.RecordMetadata;
33-
import io.questdb.std.CharSequenceIntHashMap;
3433
import io.questdb.std.Chars;
34+
import io.questdb.std.LowerCaseCharSequenceIntHashMap;
3535
import io.questdb.std.Misc;
3636
import io.questdb.std.ObjList;
3737
import io.questdb.std.str.CharSink;
@@ -49,7 +49,7 @@ public JoinRecordMetadata(CairoConfiguration configuration, int columnCount) {
4949
this.map = new FastMap(configuration.getSqlJoinMetadataPageSize(), keyTypes, valueTypes, columnCount * 2, 0.6, configuration.getSqlJoinMetadataMaxResizes());
5050
this.timestampIndex = -1;
5151
this.columnCount = 0;
52-
this.columnNameIndexMap = new CharSequenceIntHashMap(columnCount);
52+
this.columnNameIndexMap = new LowerCaseCharSequenceIntHashMap(columnCount);
5353
this.columnMetadata = new ObjList<>(columnCount);
5454
this.refCount = 1;
5555
}

core/src/main/java/io/questdb/std/CharSequenceIntHashMap.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,9 @@ public boolean putAt(int index, CharSequence key, int value) {
128128
public void putIfAbsent(CharSequence key, int value) {
129129
int index = keyIndex(key);
130130
if (index > -1) {
131-
putAt0(index, Chars.toString(key), value);
131+
String keyString = Chars.toString(key);
132+
putAt0(index, keyString, value);
133+
list.add(keyString);
132134
}
133135
}
134136

core/src/main/java/io/questdb/std/LowerCaseCharSequenceIntHashMap.java

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
public class LowerCaseCharSequenceIntHashMap extends AbstractLowerCaseCharSequenceHashSet {
3030
private static final int NO_ENTRY_VALUE = -1;
3131
private final int noEntryValue;
32-
protected int[] values;
32+
private int[] values;
3333
private final ObjList<CharSequence> list;
3434

3535
public LowerCaseCharSequenceIntHashMap() {
@@ -48,7 +48,8 @@ public LowerCaseCharSequenceIntHashMap(int initialCapacity, double loadFactor, i
4848
clear();
4949
}
5050

51-
public void clear() {
51+
@Override
52+
public final void clear() {
5253
super.clear();
5354
list.clear();
5455
Arrays.fill(values, noEntryValue);
@@ -60,6 +61,7 @@ protected void erase(int index) {
6061
values[index] = noEntryValue;
6162
}
6263

64+
@Override
6365
public void removeAt(int index) {
6466
if (index < 0) {
6567
int index1 = -index - 1;
@@ -90,16 +92,21 @@ public boolean putAt(int index, CharSequence key, int value) {
9092
values[-index - 1] = value;
9193
return false;
9294
}
93-
putAt0(index, key, value);
94-
list.add(key);
95+
final String keyString = Chars.toString(key);
96+
putAt0(index, keyString, value);
97+
list.add(keyString);
9598
return true;
9699
}
97100

98-
public void putIfAbsent(CharSequence key, int value) {
101+
public boolean putIfAbsent(CharSequence key, int value) {
99102
int index = keyIndex(key);
100103
if (index > -1) {
101-
putAt0(index, key, value);
104+
String keyStr = Chars.toString(key);
105+
putAt0(index, keyStr, value);
106+
list.add(keyStr);
107+
return true;
102108
}
109+
return false;
103110
}
104111

105112
@Override

core/src/test/java/io/questdb/griffin/AlterTableAddColumnTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ public void testAddColumnUpperCase() throws Exception {
302302
compiler.compile("alter table x add column D int", sqlExecutionContext);
303303
Assert.fail();
304304
} catch (SqlException e) {
305-
TestUtils.assertContains(e.getFlyweightMessage(), "could add column [error=Duplicate column name: D, errno=0]");
305+
TestUtils.assertContains(e.getFlyweightMessage(), "column 'D' already exists");
306306
}
307307
}
308308
);

core/src/test/java/io/questdb/griffin/KeyedAggregationTest.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,6 +1001,23 @@ public void testCountAggregationWithConst() throws Exception {
10011001
assertSqlWithTypes(sql, expected);
10021002
}
10031003

1004+
@Test
1005+
public void testCountCaseInsensitive() throws Exception {
1006+
try (TableModel tt1 = new TableModel(configuration, "tt1", PartitionBy.DAY)) {
1007+
tt1.col("tts", ColumnType.LONG).timestamp("ts")
1008+
.col("ID", ColumnType.LONG);
1009+
createPopulateTable(tt1, 100, "2020-01-01", 2);
1010+
}
1011+
1012+
String expected = "ts\tcount\n" +
1013+
"2020-01-01T00:28:47.990000Z:TIMESTAMP\t1:LONG\n" +
1014+
"2020-01-01T00:57:35.980000Z:TIMESTAMP\t1:LONG\n";
1015+
1016+
String sql = "select ts, count() from tt1 WHERE id > 0 LIMIT 2";
1017+
1018+
assertSqlWithTypes(sql, expected);
1019+
}
1020+
10041021
@Test
10051022
public void testFirstLastAggregationsNotSupported() {
10061023
String[] aggregateFunctions = {"first"};

0 commit comments

Comments
 (0)