Skip to content

Commit aca738b

Browse files
committed
test(postgres): rewrite fulltext tests to reflect tsvector search capability
The TestFulltextNotSupported class previously assumed PostgreSQL opposes ALL fulltext features and that the format_* helpers raise UnsupportedFeatureError. That contract is stale: PostgresIndexMixin overrides supports_fulltext_search/supports_fulltext_boolean_mode to return True (queried via tsvector @@ tsquery), and format_fulltext_match / format_create_fulltext_index_statement / format_drop_fulltext_index_statement return working SQL (plainto_tsquery / to_tsquery / CREATE INDEX USING GIN / DROP INDEX). - Rename to TestFulltextDdlNotSupportedSearchSupported to express the decoupled DDL-vs-query contract introduced by core PR #110. - Keep the still-unsupported DDL flags (supports_fulltext_index, supports_fulltext_parser, supports_fulltext_query_expansion) as False. - Add positive coverage for supports_fulltext_search, supports_fulltext_boolean_mode. - Add tsvector/tsquery SQL-shape assertions for natural-language mode, boolean mode, and multi-column variants. - Add CREATE INDEX ... USING GIN / DROP INDEX shape assertions (with and without IF [NOT] EXISTS), constructing CreateFulltextIndexExpression / DropFulltextIndexExpression with a dialect instance as required by BaseExpression.
1 parent e45fc79 commit aca738b

1 file changed

Lines changed: 88 additions & 14 deletions

File tree

  • tests/rhosocial/activerecord_postgres_test/feature/backend/postgres

‎tests/rhosocial/activerecord_postgres_test/feature/backend/postgres/test_index_pg.py‎

Lines changed: 88 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@
2020
from rhosocial.activerecord.backend.expression.statements.ddl_table import IndexDefinition
2121

2222
from rhosocial.activerecord.backend.expression.statements.ddl_index import (
23+
CreateFulltextIndexExpression,
2324
CreateIndexExpression,
25+
DropFulltextIndexExpression,
2426
DropIndexExpression,
2527
)
2628
from rhosocial.activerecord.backend.impl.postgres.dialect import PostgresDialect
@@ -472,32 +474,104 @@ def test_get_supported_index_types(self):
472474
assert types == ["BTREE", "HASH", "GIST", "GIN", "SPGIST", "BRIN"]
473475

474476

475-
class TestFulltextNotSupported:
476-
"""PostgreSQL does not support MySQL-style FULLTEXT indexes."""
477+
class TestFulltextDdlNotSupportedSearchSupported:
478+
"""PostgreSQL full-text search via tsvector/tsquery, not MySQL-style DDL.
479+
480+
PostgreSQL does NOT support ``CREATE FULLTEXT INDEX`` (MySQL-style) —
481+
it uses ``CREATE INDEX ... USING GIN (to_tsvector(...))`` instead.
482+
However, full-text *search querying* IS supported through
483+
``tsvector @@ tsquery`` operators, so the dialect reports
484+
``supports_fulltext_search()`` True independently of the DDL capability.
485+
"""
486+
487+
# --- DDL capability (MySQL-style CREATE FULLTEXT INDEX) ---
477488

478489
def test_supports_fulltext_index(self):
479490
assert PostgresDialect().supports_fulltext_index() is False
480491

481492
def test_supports_fulltext_parser(self):
482493
assert PostgresDialect().supports_fulltext_parser() is False
483494

484-
def test_supports_fulltext_boolean_mode(self):
485-
assert PostgresDialect().supports_fulltext_boolean_mode() is False
486-
487495
def test_supports_fulltext_query_expansion(self):
488496
assert PostgresDialect().supports_fulltext_query_expansion() is False
489497

490-
def test_format_fulltext_match_raises(self):
491-
with pytest.raises(UnsupportedFeatureError):
492-
PostgresDialect().format_fulltext_match(["col"], "search")
498+
# --- Query capability (tsvector @@ tsquery) ---
499+
500+
def test_supports_fulltext_search(self):
501+
assert PostgresDialect().supports_fulltext_search() is True
502+
503+
def test_supports_fulltext_boolean_mode(self):
504+
# to_tsquery() supports &, |, ! — equivalent to MySQL BOOLEAN MODE.
505+
assert PostgresDialect().supports_fulltext_boolean_mode() is True
506+
507+
def test_format_fulltext_match_natural_language(self):
508+
sql, params = PostgresDialect().format_fulltext_match(["col"], "search")
509+
assert "to_tsvector" in sql
510+
assert "plainto_tsquery" in sql
511+
assert "@@" in sql
512+
assert params == ("search",)
513+
514+
def test_format_fulltext_match_boolean(self):
515+
sql, params = PostgresDialect().format_fulltext_match(["col"], "a & b", mode="BOOLEAN")
516+
assert "to_tsvector" in sql
517+
assert "to_tsquery" in sql
518+
assert "plainto_tsquery" not in sql
519+
assert params == ("a & b",)
520+
521+
def test_format_fulltext_match_multi_column(self):
522+
sql, params = PostgresDialect().format_fulltext_match(["a", "b"], "search")
523+
assert " || " in sql
524+
assert "to_tsvector" in sql
525+
assert params == ("search",)
526+
527+
def test_format_create_fulltext_index_statement_uses_gin(self):
528+
dialect = PostgresDialect()
529+
expr = CreateFulltextIndexExpression(
530+
dialect,
531+
index_name="idx_ft",
532+
table_name="articles",
533+
columns=["body"],
534+
)
535+
sql, params = dialect.format_create_fulltext_index_statement(expr)
536+
assert sql.startswith("CREATE INDEX")
537+
assert "USING GIN" in sql
538+
assert "to_tsvector" in sql
539+
assert "articles" in sql
540+
assert params == ()
541+
542+
def test_format_create_fulltext_index_statement_if_not_exists(self):
543+
dialect = PostgresDialect()
544+
expr = CreateFulltextIndexExpression(
545+
dialect,
546+
index_name="idx_ft",
547+
table_name="articles",
548+
columns=["body"],
549+
if_not_exists=True,
550+
)
551+
sql, _ = dialect.format_create_fulltext_index_statement(expr)
552+
assert "IF NOT EXISTS" in sql
493553

494-
def test_format_create_fulltext_index_statement_raises(self):
495-
with pytest.raises(UnsupportedFeatureError):
496-
PostgresDialect().format_create_fulltext_index_statement(None)
554+
def test_format_drop_fulltext_index_statement(self):
555+
dialect = PostgresDialect()
556+
expr = DropFulltextIndexExpression(
557+
dialect,
558+
index_name="idx_ft",
559+
table_name="articles",
560+
)
561+
sql, _ = dialect.format_drop_fulltext_index_statement(expr)
562+
assert sql.startswith("DROP INDEX")
563+
assert "idx_ft" in sql
497564

498-
def test_format_drop_fulltext_index_statement_raises(self):
499-
with pytest.raises(UnsupportedFeatureError):
500-
PostgresDialect().format_drop_fulltext_index_statement(None)
565+
def test_format_drop_fulltext_index_statement_if_exists(self):
566+
dialect = PostgresDialect()
567+
expr = DropFulltextIndexExpression(
568+
dialect,
569+
index_name="idx_ft",
570+
table_name="articles",
571+
if_exists=True,
572+
)
573+
sql, _ = dialect.format_drop_fulltext_index_statement(expr)
574+
assert "IF EXISTS" in sql
501575

502576

503577
class TestCreateIndexExpression:

0 commit comments

Comments
 (0)