diff --git a/scripts/create_tables.py b/scripts/create_tables.py index 4030b5c..ff41e8d 100644 --- a/scripts/create_tables.py +++ b/scripts/create_tables.py @@ -205,13 +205,50 @@ CREATE TABLE IF NOT EXISTS pipeline_git_locks ( def split_ddl(ddl): - """按分号分割 DDL,跳过注释行和空语句。""" + """按分号分割 DDL,跳过注释行和空语句。 + + 引号感知:单引号字符串内的分号不作为分隔符(实测事故 2026-09-07: + llm_usage 的 COMMENT '记账状态(三态:...;仅status=SUCCEEDED...)' 注释含分号, + 裸 split(';') 把 CREATE TABLE 拦腰截断 → 语法错误 → 该模块建表整段中止)。 + """ stmts = [] - for raw in ddl.split(';'): - lines = [l for l in raw.split('\n') if not l.strip().startswith('--')] - s = '\n'.join(lines).strip() - if s: - stmts.append(s) + cur = [] + in_str = False + i = 0 + n = len(ddl) + while i < n: + ch = ddl[i] + if in_str: + cur.append(ch) + if ch == "'": + # '' 是转义的单引号,仍在串内 + if i + 1 < n and ddl[i + 1] == "'": + cur.append("'") + i += 1 + else: + in_str = False + elif ch == '\\' and i + 1 < n: + # 反斜杠转义(MySQL 风格) + cur.append(ddl[i + 1]) + i += 1 + elif ch == "'": + in_str = True + cur.append(ch) + elif ch == ';': + raw = ''.join(cur) + lines = [l for l in raw.split('\n') if not l.strip().startswith('--')] + s = '\n'.join(lines).strip() + if s: + stmts.append(s) + cur = [] + else: + cur.append(ch) + i += 1 + raw = ''.join(cur) + lines = [l for l in raw.split('\n') if not l.strip().startswith('--')] + s = '\n'.join(lines).strip() + if s: + stmts.append(s) return stmts @@ -357,11 +394,9 @@ async def main(): _llm_ddl = '\n'.join( _l for _l in _f.read().splitlines() if not _l.strip().startswith('--')) _n = 0 - for _stmt in _llm_ddl.split(';'): - _stmt = _stmt.strip() - if _stmt: - await sor.execute(_stmt, {}) - _n += 1 + for _stmt in split_ddl(_llm_ddl): + await sor.execute(_stmt, {}) + _n += 1 print(f' tables: pipeline-llm ensured ({_n} statements, idempotent)') else: print(' WARN: pkgs/pipeline-llm/mysql.ddl.sql not found (skip llm_ tables)')