From 7345b5be47692ec5fa782793a910f86155765d4c Mon Sep 17 00:00:00 2001 From: He Wang Date: Fri, 5 Jun 2026 13:44:58 +0800 Subject: [PATCH 1/3] fix(reflection): parse OceanBase FTS_INDEX_TYPE in SHOW CREATE TABLE fix: - Allow optional spaces around `=` for PARSER_PROPERTIES (align with BLOCK_SIZE style) - Parse FTS_INDEX_TYPE clause to avoid SAWarning on unknown schema content during reflect Co-authored-by: Cursor --- pyobvector/schema/reflection.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pyobvector/schema/reflection.py b/pyobvector/schema/reflection.py index acf5b07..1ce38ec 100644 --- a/pyobvector/schema/reflection.py +++ b/pyobvector/schema/reflection.py @@ -60,7 +60,8 @@ def _prep_regexes(self): r"(?: +USING +(?P\S+))?" r"(?: +WITH +\((?P[^)]+)\))?" r"(?: +WITH PARSER +(?P\S+))?" - r"(?: +PARSER_PROPERTIES=\((?P[^)]+)\))?" + r"(?: +PARSER_PROPERTIES *[ =]? *\((?P[^)]+)\))?" + r"(?: +FTS_INDEX_TYPE *[ =]? *(?P\S+))?" r"(?: +(KEY_)?BLOCK_SIZE *[ =]? *(?P\S+) *(LOCAL)?)?" r"(?: +COMMENT +(?P(\x27\x27|\x27([^\x27])*?\x27)+))?" r"(?: +/\*(?P.+)\*/ *)?" From 369223f10864e6234d0cafa400f102ffc5afb037 Mon Sep 17 00:00:00 2001 From: He Wang Date: Fri, 5 Jun 2026 14:00:18 +0800 Subject: [PATCH 2/3] test(reflection): cover analyzer FTS_INDEX_TYPE and spaced PARSER_PROPERTIES test: - Add regression for FULLTEXT KEY with PARSER_PROPERTIES = (...) and FTS_INDEX_TYPE = PHRASE_MATCH Co-authored-by: Cursor --- tests/test_reflection.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/test_reflection.py b/tests/test_reflection.py index bf8b85f..7ad0eeb 100644 --- a/tests/test_reflection.py +++ b/tests/test_reflection.py @@ -51,3 +51,20 @@ def test_customized_fulltext_parser(self): state = dialect._tabledef_parser.parse(ddl, "utf8") assert len(state.columns) == 4 assert len(state.keys) == 3 + + def test_analyzer_fulltext_parser_properties_and_fts_index_type(self): + dialect = OceanBaseDialect() + ddl = """CREATE TABLE `t_fts_analyzer` ( + `id` bigint NOT NULL, + `question_tks` longtext DEFAULT NULL, + PRIMARY KEY (`id`), + FULLTEXT KEY `fts_idx_question_tks` (`question_tks`) WITH PARSER analyzer PARSER_PROPERTIES = (analysis = '{\\"analyzer\\": \\"standard\\"}') FTS_INDEX_TYPE = PHRASE_MATCH BLOCK_SIZE 16384 +) DEFAULT CHARSET = utf8mb4 +""" + state = dialect._tabledef_parser.parse(ddl, "utf8") + assert len(state.columns) == 2 + assert len(state.keys) == 2 + fts_key = next(k for k in state.keys if k.get("parser") == "analyzer") + assert fts_key["name"] == "fts_idx_question_tks" + assert "standard" in fts_key["parser_properties"] + assert fts_key["fts_index_type"] == "PHRASE_MATCH" From e7d6af1859b8107ac5dc6110e814f1086f803909 Mon Sep 17 00:00:00 2001 From: He Wang Date: Fri, 5 Jun 2026 14:10:46 +0800 Subject: [PATCH 3/3] test(reflection): format analyzer FTS DDL for line-length readability test: - Build FULLTEXT KEY line via concatenation to stay within pylint line limits - Use readable parser_properties JSON instead of nested escapes in SQL literal Co-authored-by: Cursor --- tests/test_reflection.py | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/tests/test_reflection.py b/tests/test_reflection.py index 7ad0eeb..bf46f83 100644 --- a/tests/test_reflection.py +++ b/tests/test_reflection.py @@ -54,13 +54,21 @@ def test_customized_fulltext_parser(self): def test_analyzer_fulltext_parser_properties_and_fts_index_type(self): dialect = OceanBaseDialect() - ddl = """CREATE TABLE `t_fts_analyzer` ( - `id` bigint NOT NULL, - `question_tks` longtext DEFAULT NULL, - PRIMARY KEY (`id`), - FULLTEXT KEY `fts_idx_question_tks` (`question_tks`) WITH PARSER analyzer PARSER_PROPERTIES = (analysis = '{\\"analyzer\\": \\"standard\\"}') FTS_INDEX_TYPE = PHRASE_MATCH BLOCK_SIZE 16384 -) DEFAULT CHARSET = utf8mb4 -""" + parser_properties = 'analysis = \'{"analyzer": "standard"}\'' + fulltext_key = ( + " FULLTEXT KEY `fts_idx_question_tks` (`question_tks`)" + " WITH PARSER analyzer" + f" PARSER_PROPERTIES = ({parser_properties})" + " FTS_INDEX_TYPE = PHRASE_MATCH BLOCK_SIZE 16384" + ) + ddl = ( + "CREATE TABLE `t_fts_analyzer` (\n" + " `id` bigint NOT NULL,\n" + " `question_tks` longtext DEFAULT NULL,\n" + " PRIMARY KEY (`id`),\n" + f"{fulltext_key}\n" + ") DEFAULT CHARSET = utf8mb4\n" + ) state = dialect._tabledef_parser.parse(ddl, "utf8") assert len(state.columns) == 2 assert len(state.keys) == 2