Skip to content

Commit

Permalink
Added support for SQL diagnostic functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
Teingi committed Jul 4, 2024
1 parent 6a4ac98 commit 6768696
Show file tree
Hide file tree
Showing 12 changed files with 29 additions and 22 deletions.
2 changes: 1 addition & 1 deletion handler/analyzer/sql/rule_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def analyze_sql_statement(self, sql_statement, stdio, level_str='notice') -> Lis
rule_results.append(suggestion)
else:
if level <= Level.OK:
suggestion = Result(rule_class.rule_name, Level.OK, "No issues found with this rule.")
suggestion = Result(rule_class.rule_name, Level.OK, "No issues found with this rule.", rule_class.rule_description)
rule_results.append(suggestion)
return rule_results

Expand Down
4 changes: 2 additions & 2 deletions handler/analyzer/sql/rules/result.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@


class Result(object):
def __init__(self, name, level, suggestion):
def __init__(self, name, level, suggestion, description):
self.class_name = name
self.rule_name = name
self.level = level
self.suggestion = suggestion
self.description = suggestion
self.description = description

def __str__(self):
return json.dumps({"class_name": self.rule_name, "rule_name": self.rule_name, "level": self.level.value, "suggestion": self.suggestion, "description": self.description}, indent=5)
5 changes: 3 additions & 2 deletions handler/analyzer/sql/rules/review/arithmetic.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ def visit_arithmetic_binary(self, node, context):
return visitor.match

def suggestion(self, root: Statement, catalog=None):
suggest_text = 'Consider simplifying your expressions by moving constants out of comparisons.'
if not self.match(root, catalog):
return Result(self.rule_name, Level.OK, "No improper field operations detected, query is optimized.")
return Result(self.rule_name, Level.OK, "No improper field operations detected, query is optimized.", self.rule_description)
else:
return Result(self.rule_name, Level.NOTICE, self.rule_description)
return Result(self.rule_name, Level.NOTICE, suggest_text, self.rule_description)
4 changes: 2 additions & 2 deletions handler/analyzer/sql/rules/review/full_scan.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ def visit_not_expression(self, node, context):
def suggestion(self, root: Statement, catalog=None) -> Result:
if self.match(root, catalog):
suggestion_text = "Detected a potential full table scan which may impact performance. " "Consider adding indexes, refining WHERE clauses, or restructuring the query to utilize existing indexes."
return Result(self.rule_name, Level.WARN, suggestion_text)
return Result(self.rule_name, Level.WARN, suggestion_text, self.rule_description)
else:
suggestion_text = "The query does not involve a full table scan. It appears to be well-optimized for the given conditions."
return Result(self.rule_name, Level.OK, suggestion_text)
return Result(self.rule_name, Level.OK, suggestion_text, self.rule_description)
4 changes: 2 additions & 2 deletions handler/analyzer/sql/rules/review/is_null.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def suggestion(self, root: Statement, catalog=None):
if self.match(root, catalog):
# 如果发现不正确的NULL比较,提供具体的修改建议
suggestion_text = "Detected comparison with NULL using =, !=, or <>. " "Use 'IS NULL' or 'IS NOT NULL' for correct NULL checks."
return Result(self.rule_name, Level.WARN, suggestion_text)
return Result(self.rule_name, Level.WARN, suggestion_text, self.rule_description)
else:
# 如果没有发现不正确比较,返回OK状态
return Result(self.rule_name, Level.OK, "No improper NULL comparisons found.")
return Result(self.rule_name, Level.OK, "No improper NULL comparisons found.", self.rule_description)
8 changes: 7 additions & 1 deletion handler/analyzer/sql/rules/review/large_in_clause.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ def suggestion(self, root: Statement, catalog=None):
self.rule_name,
Level.WARN,
f"The IN clause contains more than {LargeInClauseAdjustedRule.MAX_IN_ELEMENTS} elements, which may degrade query performance. " "Consider alternative strategies like breaking the query into smaller chunks or using EXISTS/JOIN clauses.",
self.rule_description,
)
else:
return Result(self.rule_name, Level.OK, "The IN clause does not exceed the recommended number of elements.")
return Result(
self.rule_name,
Level.OK,
"The IN clause does not exceed the recommended number of elements.",
self.rule_description,
)
4 changes: 2 additions & 2 deletions handler/analyzer/sql/rules/review/multi_table_join.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,8 @@ def suggestion(self, root: Statement, catalog=None) -> Result:
"- Ensure all joined columns are properly indexed for involved tables.\n"
"- If applicable, consider using materialized views or caching strategies for frequently accessed subsets of data."
)
return Result(self.rule_name, Level.WARN, suggestion_text)
return Result(self.rule_name, Level.WARN, suggestion_text, self.rule_description)
else:
# 如果没有超过,说明查询在推荐范围内
suggestion_text = "The number of joined tables is within the recommended limit. No further action needed."
return Result(self.rule_name, Level.OK, suggestion_text)
return Result(self.rule_name, Level.OK, suggestion_text, self.rule_description)
4 changes: 2 additions & 2 deletions handler/analyzer/sql/rules/review/select_all.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,6 @@ def visit_select(self, node, context):
def suggestion(self, root: Statement, catalog=None) -> Result:
if self.match(root, catalog):
suggestion_text = "Using 'SELECT *' can lead to unnecessary data retrieval and potentially impact query performance. " "Consider specifying only the necessary columns explicitly to optimize your query."
return Result(self.rule_name, Level.WARN, suggestion_text)
return Result(self.rule_name, Level.WARN, suggestion_text, self.rule_description)
else:
return Result(self.rule_name, Level.OK, "No 'SELECT *' usage detected, query is optimized for column selection.")
return Result(self.rule_name, Level.OK, "No 'SELECT *' usage detected, query is optimized for column selection.", self.rule_description)
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,6 @@ def suggestion(self, root: Statement, catalog=None) -> Result:
suggestion_text = (
"The use of multiple tables in UPDATE or DELETE operation is not recommended. " "Consider breaking down the operation into separate single-table statements or " "using transactions to manage the update/delete across multiple tables safely."
)
return Result(self.rule_name, Level.WARN, suggestion_text)
return Result(self.rule_name, Level.WARN, suggestion_text, self.rule_description)
else:
return Result(self.rule_name, Level.OK, "No multi-table UPDATE or DELETE operation detected, following best practices.")
return Result(self.rule_name, Level.OK, "No multi-table UPDATE or DELETE operation detected, following best practices.", self.rule_description)
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,6 @@ def suggestion(self, root: Statement, catalog=None) -> Result:
"can be extremely dangerous, potentially affecting all rows in the table. Please ensure a proper and "
"specific WHERE condition is used to limit the scope of the operation."
)
return Result(self.rule_name, Level.CRITICAL, suggestion_text)
return Result(self.rule_name, Level.CRITICAL, suggestion_text, self.rule_description)
else:
return Result(self.rule_name, Level.OK, "UPDATE or DELETE operations include a WHERE clause with a specific condition, adhering to best practices.")
return Result(self.rule_name, Level.OK, "UPDATE or DELETE operations include a WHERE clause with a specific condition, adhering to best practices.", self.rule_description)
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,6 @@ def suggestion(self, root: Statement, catalog=None):
if hasattr(self, '_fuzzy_matched_columns') and self._fuzzy_matched_columns:
column_list = ", ".join(self._fuzzy_matched_columns)
detailed_suggestion = f"Avoid using fuzzy or left fuzzy matches on these indexed columns: {column_list}"
return Result(self.rule_name, Level.WARN, self.rule_description + "\n" + detailed_suggestion)
return Result(self.rule_name, Level.WARN, detailed_suggestion, self.rule_description)
else:
return Result(self.rule_name, Level.OK, "No issues found with indexed column fuzzy matching.")
return Result(self.rule_name, Level.OK, "No issues found with indexed column fuzzy matching.", self.rule_description)
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,6 @@ def suggestion(self, root: Statement, catalog=None):
if hasattr(self, '_conversion_warnings_details') and self._conversion_warnings_details:
issue_list = "\n".join(self._conversion_warnings_details)
detailed_suggestion = f"The following indexed columns may be involved in implicit type conversions due to comparison or arithmetic operations:\n{issue_list}\nReview these to ensure optimal index usage."
return Result(self.rule_name, Level.WARN, self.rule_description + "\n" + detailed_suggestion)
return Result(self.rule_name, Level.WARN, detailed_suggestion, self.rule_description)
else:
return Result(self.rule_name, Level.OK, "No implicit type conversion warnings found for indexed columns.")
return Result(self.rule_name, Level.OK, "No implicit type conversion warnings found for indexed columns.", self.rule_description)

0 comments on commit 6768696

Please sign in to comment.