Skip to content

Commit f1806e9

Browse files
authored
Improve handling of FTS5 hidden columns (#717)
* Define more precise synthesized columns for different FTS extension versions * Test that it's possible to query and order by rank if using an fts5 virtual table. * Update CHANGELOG.md
1 parent 9a64a85 commit f1806e9

File tree

4 files changed

+50
-13
lines changed

4 files changed

+50
-13
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## Unreleased
44

5-
5+
- Improve handling of FTS5 hidden columns (https://github.com/sqldelight/sql-psi/pull/717)
66

77
## [0.7.0] - 2025-09-02
88
[0.7.0]: https://github.com/sqldelight/sql-psi/releases/tag/0.7.0

core/src/main/kotlin/com/alecstrong/sql/psi/core/psi/mixins/CreateVirtualTableMixin.kt

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -45,18 +45,31 @@ internal abstract class CreateVirtualTableMixin(
4545
)
4646
.mapNotNull { it.moduleArgumentDef?.moduleColumnDef?.columnName ?: it.moduleArgumentDef?.columnDef?.columnName }
4747

48-
val synthesizedColumns = if (usesFtsModule) {
49-
val columnNames = columnNameElements.map { it.name }
50-
51-
listOf(
52-
SynthesizedColumn(
53-
table = this,
54-
acceptableValues = listOf("docid", "rowid", "oid", "_rowid_", tableName.name)
55-
.filter { it !in columnNames },
56-
),
57-
)
58-
} else {
59-
emptyList()
48+
val synthesizedColumns = when {
49+
usesFts3Module || usesFts4Module -> {
50+
val columnNames = columnNameElements.map { it.name }
51+
52+
listOf(
53+
SynthesizedColumn(
54+
table = this,
55+
acceptableValues = listOf("docid", "rowid", "oid", "_rowid_", tableName.name)
56+
.filter { it !in columnNames },
57+
),
58+
)
59+
}
60+
usesFts5Module -> {
61+
val columnNames = columnNameElements.map { it.name }
62+
63+
listOf(
64+
SynthesizedColumn(
65+
table = this,
66+
acceptableValues = listOf("rowid", "_row_id_", "rank", tableName.name)
67+
.filter { it !in columnNames },
68+
),
69+
)
70+
}
71+
72+
else -> emptyList()
6073
}
6174

6275
return LazyQuery(tableName) {
@@ -77,3 +90,12 @@ internal class CreateVirtualTableElementType(name: String) :
7790

7891
val SqlCreateVirtualTableStmt.usesFtsModule: Boolean
7992
get() = this.moduleName?.text?.startsWith(prefix = "fts", ignoreCase = true) == true
93+
94+
val SqlCreateVirtualTableStmt.usesFts3Module: Boolean
95+
get() = this.moduleName?.text?.startsWith(prefix = "fts3", ignoreCase = true) == true
96+
97+
val SqlCreateVirtualTableStmt.usesFts4Module: Boolean
98+
get() = this.moduleName?.text?.startsWith(prefix = "fts4", ignoreCase = true) == true
99+
100+
val SqlCreateVirtualTableStmt.usesFts5Module: Boolean
101+
get() = this.moduleName?.text?.startsWith(prefix = "fts5", ignoreCase = true) == true
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
CREATE VIRTUAL TABLE data USING fts5(text, content=other_table, content_rowid=rowid, prefix='2 3 4 5 6');
2+
3+
SELECT rank, rowid
4+
FROM data
5+
WHERE text MATCH 'fts5';
6+
7+
SELECT rank, rowid
8+
FROM data
9+
WHERE text MATCH 'fts5' ORDER BY rank;
10+
11+
-- Expected failure - it's not valid to query for oid or docid in FTS5 tables.
12+
SELECT oid
13+
FROM data
14+
WHERE text MATCH 'fts5';
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Test.s line 12:7 - No column found with name oid

0 commit comments

Comments
 (0)