Files
Elmi Ahmadov 164952e52d Text index: Support hasPhrase function in the text index
Currently, `hasPhrase` does not utilize the text index in any way.
This PR adds the missing support for it. However it does not store the
positional information yet, intead the `HINT` mode would be used.

The query internally would be converted from:

```sql
WHERE hasPhrase(text_column, 'token1 token2')
```

to:

```sql
WHERE hasAllTokens(text_column, 'token1 token2) AND hasPhrase(text_column, 'token1 token2')
```.

The added `hasAllTokens` condition would filter out rows do not contains
all tokens.

The proper positional information for the phrase search would be added
in the follow-up PRs.
2026-04-11 01:36:24 +02:00

60 lines
4.1 KiB
XML

<test>
<settings>
<use_skip_indexes_on_data_read>1</use_skip_indexes_on_data_read>
<query_plan_direct_read_from_text_index>1</query_plan_direct_read_from_text_index>
<force_data_skipping_indices>idx_sp</force_data_skipping_indices>
</settings>
<fill_query>ALTER TABLE hits_10m_single ADD INDEX idx_sp(SearchPhrase) TYPE text(tokenizer = 'splitByNonAlpha')</fill_query>
<fill_query>ALTER TABLE hits_10m_single MATERIALIZE INDEX idx_sp</fill_query>
<!-- The terms are ordered in the decreasing frequency -->
<query>SELECT count() FROM hits_10m_single WHERE hasToken(SearchPhrase, 'video')</query>
<query>SELECT count() FROM hits_10m_single WHERE hasToken(SearchPhrase, 'yandex')</query>
<query>SELECT count() FROM hits_10m_single WHERE hasToken(SearchPhrase, 'google')</query>
<query>SELECT count() FROM hits_10m_single WHERE hasToken(SearchPhrase, 'world')</query>
<query>SELECT count() FROM hits_10m_single WHERE hasToken(SearchPhrase, 'market')</query>
<query>SELECT count() FROM hits_10m_single WHERE hasToken(SearchPhrase, 'mail')</query>
<query>SELECT count() FROM hits_10m_single WHERE NOT hasToken(SearchPhrase, 'mail')</query>
<query>SELECT count() FROM hits_10m_single WHERE hasToken(SearchPhrase, 'mail') OR hasToken(SearchPhrase, 'market')</query>
<query>SELECT count() FROM hits_10m_single WHERE hasToken(SearchPhrase, 'mail') AND hasToken(SearchPhrase, 'market')</query>
<query>SELECT count() FROM hits_10m_single WHERE hasToken(SearchPhrase, 'acompletelynonexistentwordxyz')</query>
<query>SELECT count() FROM hits_10m_single WHERE hasAllTokens(SearchPhrase, ['the'])</query>
<query>SELECT count() FROM hits_10m_single WHERE hasAllTokens(SearchPhrase, ['the', 'video'])</query>
<query>SELECT count() FROM hits_10m_single WHERE hasAllTokens(SearchPhrase, ['the', 'video', 'world', 'market'])</query>
<query>SELECT count() FROM hits_10m_single WHERE NOT hasAllTokens(SearchPhrase, ['the', 'video', 'world', 'market'])</query>
<query>SELECT count() FROM hits_10m_single WHERE hasAnyTokens(SearchPhrase, ['mail'])</query>
<query>SELECT count() FROM hits_10m_single WHERE hasAnyTokens(SearchPhrase, ['the', 'video', 'world', 'market'])</query>
<query>SELECT count() FROM hits_10m_single WHERE NOT hasAnyTokens(SearchPhrase, ['the', 'video', 'world', 'market'])</query>
<query>SELECT count() FROM hits_10m_single WHERE hasToken(SearchPhrase, 'video') AND WatchID &gt;= 10 </query>
<query>SELECT count() FROM hits_10m_single WHERE hasAllTokens(SearchPhrase, ['video']) AND WatchID &gt;= 10 </query>
<query>SELECT count() FROM hits_10m_single WHERE hasAnyTokens(SearchPhrase, ['video']) AND WatchID &gt;= 10 </query>
<query>SELECT count() FROM hits_10m_single WHERE hasToken(SearchPhrase, '')</query>
<query>SELECT count() FROM hits_10m_single WHERE hasAnyTokens(SearchPhrase, [''])</query>
<query>SELECT count() FROM hits_10m_single WHERE hasAllTokens(SearchPhrase, [''])</query>
<query>SELECT count() FROM hits_10m_single WHERE hasAnyTokens(SearchPhrase, [])</query>
<query>SELECT count() FROM hits_10m_single WHERE hasAllTokens(SearchPhrase, [])</query>
<query>SELECT count() FROM hits_10m_single WHERE hasPhrase(SearchPhrase, '2014 фото')</query>
<query>SELECT count() FROM hits_10m_single WHERE hasPhrase(SearchPhrase, '2014 года')</query>
<query>SELECT count() FROM hits_10m_single WHERE hasPhrase(SearchPhrase, 'ru -> eng')</query>
<query>SELECT count() FROM hits_10m_single WHERE hasPhrase(SearchPhrase, 'google.com')</query>
<query>SELECT count() FROM hits_10m_single WHERE hasPhrase(SearchPhrase, 'yandex.ru')</query>
<query>SELECT count() FROM hits_10m_single WHERE hasPhrase(SearchPhrase, 'video world')</query>
<query>SELECT count() FROM hits_10m_single WHERE hasPhrase(SearchPhrase, 'puma oxygen')</query>
<query>SELECT count() FROM hits_10m_single WHERE hasPhrase(SearchPhrase, 'master video')</query>
<query>SELECT count() FROM hits_10m_single WHERE hasPhrase(SearchPhrase, 'grand world')</query>
<query>SELECT token, cardinality FROM mergeTreeTextIndex(currentDatabase(), hits_10m_single, idx_sp) FORMAT Null</query>
<drop_query>ALTER TABLE hits_10m_single DROP INDEX idx_sp</drop_query>
</test>