docs/plans/SCENARIOS-mysql-advisor-omni.md
Goal: Migrate all 87 MySQL advisor rules from ANTLR tree walking to omni AST type switches Verification:
go test -count=1 ./backend/plugin/advisor/mysql/...passes with identical advice output;grep -r "GetANTLRAST" backend/plugin/advisor/mysql/returns zero matches after completion Reference sources: PG omni migration (backend/plugin/advisor/pg/generic_checker_omni.go,utils_omni.go), omni MySQL AST (github.com/bytebase/omni/mysql/ast)
Status: [ ] pending, [x] passing, [~] partial
Build the omni rule infrastructure and prove it works with one representative rule from each major category.
OmniRule interface with OnStatement(node ast.Node), Name(), GetAdviceList()OmniBaseRule struct with Level, Title, Advice, BaseLine, StmtText fieldsSetStatement(baseLine int, stmtText string) sets context for position calculationsAddAdvice() adds advice with BaseLine offset adjustmentLocToLine(loc ast.Loc) converts omni byte offset to 1-based line numberRunOmniRules() dispatcher iterates statements, extracts omni node, dispatches to rulesFindLineByName(name string) searches identifier in statement text, returns lineomniTableName(ref *ast.TableRef) extracts table nameomniColumnNames(constraint *ast.Constraint) extracts column name list from constraintomniIndexColumns(cols []*ast.IndexColumn) extracts column names from index column listomniDataTypeName(dt *ast.DataType) extracts normalized type name stringomniIsNullable(col *ast.ColumnDef) checks if column allows NULLomniHasDefault(col *ast.ColumnDef) checks if column has DEFAULTomniIsAutoIncrement(col *ast.ColumnDef) checks if column is AUTO_INCREMENTomniColumnComment(col *ast.ColumnDef) extracts column COMMENT stringomniTableOptionValue(opts []*ast.TableOption, name string) extracts table option by nameomniConstraintsByType(constraints []*ast.Constraint, typ ast.ConstraintType) filters constraintsrule_table_require_pk migrated — DDL-table representative (CreateTable + AlterTable + DropTable)rule_column_no_null migrated — DDL-column representative (CreateTable + AlterTable column inspection)rule_index_no_duplicate_column migrated — DDL-index representative (CreateTable + AlterTable + CreateIndex)rule_naming_table migrated — naming representative (CreateTable + AlterTable + RenameTable)rule_stmt_no_select_all migrated — DML representative (SelectStmt target list inspection)rule_column_auto_increment_initial_value — AUTO_INCREMENT initial value checkrule_column_auto_increment_must_integer — AUTO_INCREMENT must be integer typerule_column_auto_increment_must_unsigned — AUTO_INCREMENT must be UNSIGNEDrule_column_current_time_count_limit — limit CURRENT_TIMESTAMP columnsrule_column_maximum_character_length — CHAR length limitrule_column_maximum_varchar_length — VARCHAR length limitrule_column_type_disallow_list — disallowed column typesrule_table_text_fields_total_length — total text field length limitrule_column_no_null — (already migrated in Phase 1, skip)rule_column_require_default — columns must have DEFAULTrule_column_set_default_for_not_null — NOT NULL columns must have DEFAULTrule_column_required — required columns must existrule_column_comment_convention — column COMMENT conventionrule_column_disallow_changing — disallow column changesrule_column_disallow_changing_order — disallow column reorderingrule_column_disallow_changing_type — disallow column type changesrule_column_disallow_drop — disallow column dropsrule_column_disallow_drop_in_index — disallow dropping indexed columnsrule_column_disallow_set_charset — disallow column-level charsetrule_column_require_charset — require column charsetrule_column_require_collation — require column collationrule_table_require_pk — (already migrated in Phase 1, skip)rule_table_comment_convention — table COMMENT conventionrule_table_disallow_partition — disallow partitioningrule_table_disallow_set_charset — disallow table-level charsetrule_table_require_charset — require table charsetrule_table_require_collation — require table collationrule_table_limit_size — table size limit checkrule_table_disallow_ddl — disallow DDL on specific tablesrule_table_disallow_dml — disallow DML on specific tablesrule_table_drop_naming_convention — drop table naming conventionrule_use_innodb — require InnoDB enginerule_index_no_duplicate_column — (already migrated in Phase 1, skip)rule_index_key_number_limit — max columns per indexrule_index_pk_type — primary key type restrictionsrule_index_primary_key_type_allowlist — PK type allowlistrule_index_total_number_limit — max indexes per tablerule_index_type_allow_list — index type allowlistrule_index_type_no_blob — disallow BLOB in indexrule_table_no_duplicate_index — no duplicate indexesrule_table_no_fk — disallow foreign keysrule_charset_allowlist — charset allowlistrule_collation_allowlist — collation allowlistrule_database_drop_empty_db — only drop empty databasesrule_view_disallow_create — disallow view creationrule_disallow_procedure — disallow procedure creationrule_event_disallow_create — disallow event creationrule_function_disallow_create — disallow function creationrule_function_disallowed_list — disallowed function listrule_table_disallow_trigger — disallow trigger creationrule_migration_compatibility — backward compatibility checksrule_online_migration — online migration checksrule_naming_table — (already migrated in Phase 1, skip)rule_naming_column — column naming conventionrule_naming_auto_increment_column — auto-increment column namingrule_naming_identifier_no_keyword — no reserved keywords as identifiersrule_naming_index_convention — index naming conventionrule_naming_foreign_key_convention — foreign key naming conventionrule_naming_unique_key_convention — unique key naming conventionrule_stmt_where_requirement_for_select — SELECT requires WHERErule_stmt_where_requirement_for_update_delete — UPDATE/DELETE requires WHERErule_stmt_no_leading_wildcard_like — no leading wildcard in LIKErule_statement_where_no_equal_null — no = NULL (use IS NULL)rule_statement_where_disallow_using_function — no functions in WHERErule_statement_where_maximum_logical_operator_count — max logical operators in WHERErule_stmt_no_select_all — (already migrated in Phase 1, skip)rule_stmt_disallow_limit — disallow LIMIT in DMLrule_stmt_disallow_order_by — disallow ORDER BY in DMLrule_stmt_disallow_commit — disallow COMMIT statementrule_statement_merge_alter_table — merge multiple ALTER TABLErule_statement_maximum_limit_value — max LIMIT valuerule_statement_maximum_join_table_count — max JOIN table countrule_statement_maximum_statements_in_transaction — max statements in transactionrule_stmt_max_execution_time — max execution time hintrule_stmt_require_algorithm_or_lock_options — require ALGORITHM/LOCK in ALTERrule_statement_add_column_without_position — ADD COLUMN without FIRST/AFTERrule_statement_join_strict_column_attrs — strict JOIN column attribute matchingrule_insert_must_specify_column — INSERT must specify columnsrule_insert_row_limit — INSERT row count limitrule_insert_disallow_order_by_rand — no ORDER BY RAND() in INSERTrule_statement_affected_row_limit — affected row limitrule_statement_dml_dry_run — DML dry run checkrule_statement_select_full_table_scan — detect full table scansrule_statement_disallow_using_filesort — detect filesort usagerule_statement_disallow_using_temporary — detect temporary table usagerule_builtin_prior_backup_check migrated — backup check before DDLrule_statement_query_minimum_plan_level migrated — query plan level checkGetANTLRAST calls remain in backend/plugin/advisor/mysql/GenericChecker ANTLR dispatcher removed or deprecatedAsANTLRAST() fallback removed from OmniASTparseSingleStatementLenient() removedParseMySQL() callers migrated or removed