One major "weakness" of rdbms is that all internals are black blocks.
You can do "SELECT * FROM table"
but, weirdly, can't "SELECT * FROM A_Index".
NOTHING in the relational model requiere this limitation. Is purely accidental.
BTW, I'm building a relational lang and also, very long time ago, try to port lucene to Delphi.
So, what you need to support FTS and other kind of structures is... support them.
For interfacing, you can consider ANY key-value as a relation of exactly 2 columns. Any scalar, a relation of 1 column, 1 row. You can put relations in relations, so you can do recursive data.
Maybe the hardest is to have not only storage of btrees but also other stuff. I think you can fit FTS data in btrees anyway, but probably tweak it.
When building the relational lang I stumble upon how support a n-column data inside a btree. You can split:
pk=key
values=col1 col2 col3
or as I later "get", just store the full row and change the functions that do the comparing. In rust start with:
pub struct Tree {
index: usize, <--signal which column as key
data: BTreeSet<Vec<...>>, <-- Store all row
}