Commit ·
c3eb2cc
1
Parent(s): 4546914
fix: validator false-positive on EXTRACT(YEAR FROM col) + remove hardcoded SQL hints
Browse files- Agent/agentic_workflow.py +9 -18
Agent/agentic_workflow.py
CHANGED
|
@@ -1648,9 +1648,12 @@ def enhanced_validate_sql(query: str) -> Dict[str, Any]:
|
|
| 1648 |
issues.append("Missing SELECT or FROM clause")
|
| 1649 |
|
| 1650 |
# Extract referenced tables (rough pattern)
|
|
|
|
|
|
|
| 1651 |
referenced_tables = set()
|
| 1652 |
try:
|
| 1653 |
-
|
|
|
|
| 1654 |
for base, _alias in table_tokens:
|
| 1655 |
referenced_tables.add(base.lower())
|
| 1656 |
except Exception:
|
|
@@ -3390,24 +3393,12 @@ def query_craft(question: str) -> str:
|
|
| 3390 |
print('[MICRO-HINT] Using micro-generated gender pay gap SQL as LLM hint only.')
|
| 3391 |
question = f"{question}\n\n# HINT: The following SQL may help, but do not copy blindly.\n{v}"
|
| 3392 |
# 7c) Trend over time / over the years (temporal aggregation)
|
| 3393 |
-
#
|
|
|
|
|
|
|
|
|
|
| 3394 |
if re.search(r"trend over the years|changed over time|over time|over the years|by year|per year", question.lower()):
|
| 3395 |
-
|
| 3396 |
-
q_lower = question.lower()
|
| 3397 |
-
if "hiring" in q_lower or "hire" in q_lower:
|
| 3398 |
-
if 'employee' not in available_tables:
|
| 3399 |
-
return None
|
| 3400 |
-
return "SELECT CAST(EXTRACT(YEAR FROM hire_date) AS INTEGER) AS hire_year, COUNT(*) AS employees_hired FROM employee GROUP BY hire_year ORDER BY hire_year;"
|
| 3401 |
-
elif "salary" in q_lower or "salaries" in q_lower:
|
| 3402 |
-
if 'salary' not in available_tables:
|
| 3403 |
-
return None
|
| 3404 |
-
# NOTE: No to_date filter — we want ALL historical records for trend analysis
|
| 3405 |
-
return "SELECT CAST(EXTRACT(YEAR FROM from_date) AS INTEGER) AS year, AVG(salary) AS avg_salary FROM salary GROUP BY year ORDER BY year;"
|
| 3406 |
-
return None
|
| 3407 |
-
v = gen_trend_hint()
|
| 3408 |
-
if v:
|
| 3409 |
-
print('[MICRO-HINT] Injecting temporal trend hint (EXTRACT YEAR + GROUP BY)')
|
| 3410 |
-
question = f"{question}\n\n# HINT: The following SQL may help, but do not copy blindly. You MUST use EXTRACT(YEAR FROM date_column) and GROUP BY the year.\n{v}"
|
| 3411 |
|
| 3412 |
# 8) maximum and minimum salary overall or for a specific department (user question may use max/min or maximum/minimum)
|
| 3413 |
ql = question.lower()
|
|
|
|
| 1648 |
issues.append("Missing SELECT or FROM clause")
|
| 1649 |
|
| 1650 |
# Extract referenced tables (rough pattern)
|
| 1651 |
+
# IMPORTANT: Strip EXTRACT(...FROM...) expressions first to prevent false table detection.
|
| 1652 |
+
# e.g. EXTRACT(YEAR FROM hire_date) would otherwise match 'hire_date' as a table name.
|
| 1653 |
referenced_tables = set()
|
| 1654 |
try:
|
| 1655 |
+
query_for_table_scan = re.sub(r'\bEXTRACT\s*\([^)]+\)', '', query, flags=re.IGNORECASE)
|
| 1656 |
+
table_tokens = re.findall(r'(?:from|join)\s+([a-zA-Z_][a-zA-Z0-9_]*)(?:\s+as)?\s*([a-zA-Z_][a-zA-Z0-9_]*)?', query_for_table_scan, flags=re.IGNORECASE)
|
| 1657 |
for base, _alias in table_tokens:
|
| 1658 |
referenced_tables.add(base.lower())
|
| 1659 |
except Exception:
|
|
|
|
| 3393 |
print('[MICRO-HINT] Using micro-generated gender pay gap SQL as LLM hint only.')
|
| 3394 |
question = f"{question}\n\n# HINT: The following SQL may help, but do not copy blindly.\n{v}"
|
| 3395 |
# 7c) Trend over time / over the years (temporal aggregation)
|
| 3396 |
+
# NOTE: No hardcoded SQL hints here — the semantic clarifier at line ~3511 already rewrites
|
| 3397 |
+
# the question with explicit EXTRACT(YEAR FROM ...) and GROUP BY instructions, which is
|
| 3398 |
+
# sufficient for the LLM. Hardcoded hints were removed to avoid schema coupling.
|
| 3399 |
+
# The validator fix (strip EXTRACT from table-scan) ensures valid EXTRACT queries pass.
|
| 3400 |
if re.search(r"trend over the years|changed over time|over time|over the years|by year|per year", question.lower()):
|
| 3401 |
+
print('[MICRO-HINT] Temporal trend query detected — semantic clarifier will inject EXTRACT(YEAR) instruction.')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3402 |
|
| 3403 |
# 8) maximum and minimum salary overall or for a specific department (user question may use max/min or maximum/minimum)
|
| 3404 |
ql = question.lower()
|