Usage ===== Blocking a destructive statement --------------------------------- .. code-block:: python from sql_query_tagger import SQLClassifier classifier = SQLClassifier(engine="mysql", version="8.0") result = classifier.classify_query("SELECT 1; DROP TABLE users;") print(result.security_analysis.risk_level) # RiskLevel.CRITICAL print(result.security_analysis.is_suspicious) # True print(result.security_analysis.detected_patterns) # ['stacked_queries_multiple_statements', 'stacked_queries_dangerous_followup', ...] Engine-specific dangerous function ------------------------------------ .. code-block:: python classifier = SQLClassifier(engine="sqlserver", version="2022") result = classifier.classify_query("EXEC xp_cmdshell 'dir'") print(result.security_analysis.engine_specific_risks) # ['dangerous_function_xp_cmdshell'] Classifying query type only ------------------------------ .. code-block:: python classifier = SQLClassifier(engine="postgresql", version="16") for sql in ["CREATE TABLE t (id INT)", "INSERT INTO t VALUES (1)", "SELECT * FROM t"]: result = classifier.classify_query(sql) print(sql, "->", result.query_type) # CREATE TABLE t (id INT) -> QueryType.DDL # INSERT INTO t VALUES (1) -> QueryType.DML # SELECT * FROM t -> QueryType.DQL Handling invalid input and unknown engines --------------------------------------------- .. code-block:: python from sql_query_tagger import SQLClassifier, UnsupportedEngineError try: classifier = SQLClassifier(engine="db2", version="11.5") except UnsupportedEngineError as e: print(f"Unsupported engine: {e}") classifier = SQLClassifier(engine="postgresql", version="16") try: classifier.classify_query("") except ValueError as e: print(f"Invalid query: {e}") Performance and caching ------------------------ ``classify_query`` memoizes its security analysis and query-type classification per :class:`~sql_query_tagger.SQLClassifier` instance, keyed by the cleaned query text (the part that calls into ``sqlglot`` and runs the regex scans). Tune or disable it with ``SQLClassifier(..., analysis_cache_size=N)`` (``0`` disables caching). Run the benchmark yourself: .. code-block:: bash python benchmarks/bench_classify.py Limitations ----------- * Static analysis only — it inspects query *text*, not a live schema, so it cannot tell you whether referenced tables/columns exist. * The stacked-query check splits on ``;`` without parsing string literals, so a benign query containing a semicolon inside a string (e.g. ``'a; b'``) may be flagged as multiple statements. Treat the risk score as a signal, not a verdict.