-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Update base.py #837
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update base.py #837
Conversation
The previous function extracted limited number of queries, leaving behind some queries. creating a table query does not get extracted in the previous version of the query, here it will address all the query cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Auto Pull Request Review from LlamaPReview
1. Overview
1.1 Core Changes
- Primary purpose and scope: Improve the extraction of SQL queries from Language Model (LLM) responses within the
extract_sql
method inbase.py
. The goal is to handle more SQL query formats, specificallyCREATE TABLE AS SELECT
statements, and improve robustness for markdown code blocks. - Key components modified: The
extract_sql
method insrc/vanna/base/base.py
is the primary focus, with changes involving regular expression patterns and their order of application. - Cross-component impacts: This change directly impacts how Vanna interprets LLM outputs across different database interactions and potentially various LLM providers, assuming they use this base class method. Accurate SQL extraction is fundamental to the core text-to-SQL functionality.
- Business value alignment: Enhances the reliability and accuracy of the Vanna library by correctly parsing a wider range of SQL statements generated by LLMs, particularly addressing use cases involving table creation (CTAS), which is crucial for data preparation and analysis workflows.
1.2 Technical Architecture
- N/A - Changes are localized to a single method's implementation logic.
2. Critical Findings
2.1 Must Fix (P0🔴)
Issue: Incomplete CREATE TABLE AS SELECT
Regex Pattern
- Analysis Confidence: High
- Impact: The current regex
r"\bCREATE\s+TABLE\b.*?\bAS\b.*?;
fails to capture common variations of theCREATE TABLE AS SELECT
(CTAS) statement, such as those includingOR REPLACE
, schema definitions beforeAS
, or multi-lineAS
clauses. This leads to incorrect or failed SQL extraction for valid CTAS queries generated by the LLM. - Resolution: Update the regex pattern to be more comprehensive, covering variations like
CREATE OR REPLACE TABLE
,IF NOT EXISTS
, and ensuring it correctly captures theSELECT
part followingAS
. See suggested code in Section 3.1.
Issue: Missing Test Coverage for New Extraction Logic
- Analysis Confidence: High
- Impact: The introduction of new regex patterns and logic changes without corresponding unit tests creates a significant risk of regressions. Future modifications or edge cases encountered in LLM responses might break the extraction logic silently.
- Resolution: Add comprehensive unit tests covering various LLM response formats, including:
- Basic
SELECT
,WITH
, andCREATE TABLE AS SELECT
statements. - Statements embedded in markdown blocks (with and without
sql
tag). - Case variations (
SELECT
,select
,Select
). - Statements with comments or surrounding text.
- Edge cases identified (e.g., nested selects, CTAS variations).
- Examples:
- Basic
test_cases = [
("Plain SELECT query: SELECT * FROM users;", "SELECT * FROM users;"),
("```sql\nCREATE TABLE new_table AS SELECT id FROM old_table;\n```", "CREATE TABLE new_table AS SELECT id FROM old_table;"),
("Some text before WITH cte AS (SELECT 1) SELECT * FROM cte;", "WITH cte AS (SELECT 1) SELECT * FROM cte;"),
("Please run this: CREATE OR REPLACE TABLE my_schema.my_table AS SELECT col1 FROM source;", "CREATE OR REPLACE TABLE my_schema.my_table AS SELECT col1 FROM source;"),
("Text with ```\nSELECT complex FROM data WHERE id=1;\n``` block", "SELECT complex FROM data WHERE id=1;"),
("Mixed case: CrEaTe TaBlE foo AS SeLeCt 1;", "CrEaTe TaBlE foo AS SeLeCt 1;"),
("-- SQL Comment\nSELECT c FROM t;", "SELECT c FROM t;"),
]
2.2 Should Fix (P1🟡)
Issue: Ambiguous SELECT
Regex Pattern
- Analysis Confidence: High
- Impact: The current pattern
r"\bSELECT\b .*?;
is overly broad. It might incorrectly match text containing "SELECT ..." within comments or natural language descriptions. It also doesn't robustly handle nestedSELECT
statements if they appear outside a CTE or CTAS structure already matched. - Suggested Solution: Refine the
SELECT
pattern to be more specific, potentially using negative lookbehinds or start-of-string/line anchors where appropriate, or rely on the ordering ensuring more specific patterns (likeWITH
orCREATE
) are matched first. Consider using(?<!\S)SELECT\b.*?;
to ensureSELECT
isn't preceded by non-whitespace, reducing matches in comments/text.
Issue: Potential Pattern Ordering Risk
- Analysis Confidence: Medium
- Impact: The current matching order (CREATE -> WITH -> SELECT) might incorrectly extract only the
CREATE TABLE ... AS
part if the LLM generates aCREATE TABLE ... AS WITH ... SELECT ...;
statement. TheWITH
clause pattern could potentially be missed if nested within aCREATE
statement structure that the first pattern partially matches. - Suggested Solution: While the current order prioritizes CTAS, consider if the
WITH
pattern needs refinement to avoid matching keywords within other statement types (e.g., using negative lookaheads like(?!(?:INSERT|UPDATE|DELETE|CREATE|ALTER))
after\bWITH\b
) or ensure the CTAS pattern fully captures common nested CTE scenarios. Alternatively, prioritize theWITH
pattern if CTEs are considered more common or complex. Thorough testing with nested examples is crucial.
2.3 Consider (P2🟢)
Area: Regex Maintainability and Readability
- Analysis Confidence: Medium
- Improvement Opportunity: The growing list of regex patterns makes the
extract_sql
function harder to read and maintain. Refactoring the patterns into named constants or a list of tuples(pattern, description)
and iterating through them could improve clarity and ease future modifications.
Area: Performance Optimization
- Analysis Confidence: Medium
- Improvement Opportunity: Running multiple
re.findall
calls sequentially can be less efficient than a single pass. Consider combining the patterns into a single, more complex regex using named capture groups (?P<name>...
) and alternation (|
). This would allow matching any of the patterns in one operation, potentially improving performance for very long LLM responses. Requires careful construction and testing.
2.4 Summary of Action Items
- P0 (Must Fix):
- Refine the
CREATE TABLE AS SELECT
regex to handle common variations. (Immediate) - Add comprehensive unit tests for the
extract_sql
method covering all patterns and edge cases. (Immediate)
- Refine the
- P1 (Should Fix):
- Improve the specificity of the
SELECT
regex pattern. (Before Merge) - Review and test the pattern matching order, especially for nested CTEs within CTAS. (Before Merge)
- Improve the specificity of the
- P2 (Consider):
- Refactor regex patterns for better maintainability. (Future Improvement)
- Explore combining regex patterns for potential performance gains. (Future Improvement)
3. Technical Analysis
3.1 Code Logic Analysis
📁 src/vanna/base/base.py - extract_sql
- Submitted PR Code:
import re
"""
Extracts the SQL query from the LLM response, handling various formats including:
- WITH clause
- SELECT statement
- CREATE TABLE AS SELECT
- Markdown code blocks
"""
# Match CREATE TABLE ... AS SELECT
sqls = re.findall(r"\bCREATE\s+TABLE\b.*?\bAS\b.*?;", llm_response, re.DOTALL | re.IGNORECASE) # P0: Pattern too simple
if sqls:
sql = sqls[-1]
self.log(title="Extracted SQL", message=f"{sql}")
return sql
# Match WITH clause (CTEs)
sqls = re.findall(r"\bWITH\b .*?;", llm_response, re.DOTALL | re.IGNORECASE) # P1: Potential conflict with CTAS
if sqls:
sql = sqls[-1]
self.log(title="Extracted SQL", message=f"{sql}")
return sql
# Match SELECT ... ;
sqls = re.findall(r"\bSELECT\b .*?;", llm_response, re.DOTALL | re.IGNORECASE) # P1: Pattern too broad
if sqls:
sql = sqls[-1]
self.log(title="Extracted SQL", message=f"{sql}")
return sql
# Match ```sql ... ``` blocks
sqls = re.findall(r"```sql\s*
(.*?)```", llm_response, re.DOTALL | re.IGNORECASE)
if sqls:
sql = sqls[-1].strip() # Improvement: Handles whitespace
self.log(title="Extracted SQL", message=f"{sql}")
return sql
# Match any ``` ... ``` code blocks
sqls = re.findall(r"```(.*?)```", llm_response, re.DOTALL | re.IGNORECASE)
if sqls:
sql = sqls[-1].strip() # Improvement: Handles whitespace
self.log(title="Extracted SQL", message=f"{sql}")
return sql
return llm_response
- Analysis:
- The function attempts to extract SQL by sequentially applying regex patterns for different SQL statement types (
CREATE TABLE AS SELECT
,WITH
,SELECT
) and markdown code blocks. - It prioritizes
CREATE TABLE AS SELECT
, thenWITH
, thenSELECT
, followed by markdown blocks. - It uses
re.IGNORECASE
andre.DOTALL
flags appropriately. - Potential Issues:
- The
CREATE TABLE AS SELECT
pattern is too basic and misses common syntax variations (P0). - The
SELECT
pattern is too broad and might match non-SQL text (P1). - The fixed order might not correctly handle nested structures like CTEs within CTAS (P1).
- Lack of tests makes validation difficult and regressions likely (P0).
- The
- Edge cases: Nested queries, comments within or around SQL, varied whitespace, different SQL dialects (though regex is generic), LLM adding explanatory text around the SQL.
- Cross-component impact: Accuracy of downstream SQL execution depends heavily on this extraction logic.
- The function attempts to extract SQL by sequentially applying regex patterns for different SQL statement types (
- LlamaPReview Suggested Improvements:
import re
def extract_sql(self, llm_response: str) -> str:
"""
Extracts the SQL query from the LLM response, handling various formats including:
- CREATE TABLE ... AS SELECT (with variations)
- WITH clause (CTEs)
- SELECT statement
- Markdown code blocks
"""
# P0: Improved pattern for CREATE TABLE AS SELECT
# Handles CREATE [OR REPLACE] TABLE [IF NOT EXISTS] ... AS SELECT ... ;
ctas_pattern = r"\bCREATE\s+(?:OR\s+REPLACE\s+)?TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?.*?\bAS\s+SELECT.*?;|CREATE\s+TABLE\s+.*?\bAS\s+\(.*?\)\s*WITH\s+DATA;"
sqls = re.findall(ctas_pattern, llm_response, re.DOTALL | re.IGNORECASE)
if sqls:
sql = sqls[-1]
# Consider adding basic validation here (e.g., check for SELECT keyword)
self.log(title="Extracted SQL (CTAS)", message=f"{sql}")
return sql
# P1: Consider refining WITH pattern or adjusting order based on testing
# Example refinement: Negative lookahead to avoid matching keywords in other statements
# with_pattern = r"\bWITH\b (?!(?:INSERT|UPDATE|DELETE|CREATE|ALTER)).*?;"
with_pattern = r"\bWITH\b .*?;" # Keep original or refine based on tests
sqls = re.findall(with_pattern, llm_response, re.DOTALL | re.IGNORECASE)
if sqls:
sql = sqls[-1]
self.log(title="Extracted SQL (WITH)", message=f"{sql}")
return sql
# P1: Consider refining SELECT pattern for specificity
# Example refinement: Use negative lookbehind for start boundary
# select_pattern = r"(?<!\S)SELECT\b.*?;|SELECT\s+DISTINCT\s+.*?;|SELECT\s+COUNT\s*\(.*?\).*?;|SELECT\s+CASE\s+WHEN.*?END.*?;|SELECT\s+.*\s+FROM\s+.*?;|SELECT\s+.*\s+WHERE\s+.*?;|SELECT\s+.*\s+ORDER\s+BY\s+.*?;|SELECT\s+.*\s+GROUP\s+BY\s+.*?;|SELECT\s+.*\s+LIMIT\s+.*?;|SELECT\s+.*\s+OFFSET\s+.*?;|SELECT\s+.*\s+UNION\s+.*?;|SELECT\s+.*\s+INTERSECT\s+.*?;|SELECT\s+.*\s+EXCEPT\s+.*?;|SELECT\s+.*\s+HAVING\s+.*?;|SELECT\s+.*\s+WINDOW\s+.*?;|SELECT\s+.*\s+PARTITION\s+BY\s+.*?;|SELECT\s+.*\s+ROWS\s+BETWEEN\s+.*?;|SELECT\s+.*\s+RANGE\s+BETWEEN\s+.*?;|SELECT\s+.*\s+FETCH\s+FIRST\s+.*?;|SELECT\s+.*\s+FOR\s+UPDATE\s+.*?;|SELECT\s+.*\s+FOR\s+SHARE\s+.*?;|SELECT\s+.*\s+NOWAIT\s+.*?;|SELECT\s+.*\s+SKIP\s+LOCKED\s+.*?;|SELECT\s+.*\s+OF\s+.*?;|SELECT\s+.*\s+WAIT\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+WHERE\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+ORDER\s+BY\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+GROUP\s+BY\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+LIMIT\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+OFFSET\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+UNION\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+INTERSECT\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+EXCEPT\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+HAVING\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+WINDOW\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+PARTITION\s+BY\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+ROWS\s+BETWEEN\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+RANGE\s+BETWEEN\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+FETCH\s+FIRST\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+FOR\s+UPDATE\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+FOR\s+SHARE\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+NOWAIT\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+SKIP\s+LOCKED\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+OF\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+WAIT\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+WHERE\s+.*?\s+ORDER\s+BY\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+WHERE\s+.*?\s+GROUP\s+BY\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+WHERE\s+.*?\s+LIMIT\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+WHERE\s+.*?\s+OFFSET\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+WHERE\s+.*?\s+UNION\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+WHERE\s+.*?\s+INTERSECT\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+WHERE\s+.*?\s+EXCEPT\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+WHERE\s+.*?\s+HAVING\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+WHERE\s+.*?\s+WINDOW\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+WHERE\s+.*?\s+PARTITION\s+BY\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+WHERE\s+.*?\s+ROWS\s+BETWEEN\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+WHERE\s+.*?\s+RANGE\s+BETWEEN\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+WHERE\s+.*?\s+FETCH\s+FIRST\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+WHERE\s+.*?\s+FOR\s+UPDATE\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+WHERE\s+.*?\s+FOR\s+SHARE\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+WHERE\s+.*?\s+NOWAIT\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+WHERE\s+.*?\s+SKIP\s+LOCKED\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+WHERE\s+.*?\s+OF\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+WHERE\s+.*?\s+WAIT\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+ORDER\s+BY\s+.*?\s+GROUP\s+BY\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+ORDER\s+BY\s+.*?\s+LIMIT\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+ORDER\s+BY\s+.*?\s+OFFSET\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+ORDER\s+BY\s+.*?\s+UNION\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+ORDER\s+BY\s+.*?\s+INTERSECT\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+ORDER\s+BY\s+.*?\s+EXCEPT\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+ORDER\s+BY\s+.*?\s+HAVING\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+ORDER\s+BY\s+.*?\s+WINDOW\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+ORDER\s+BY\s+.*?\s+PARTITION\s+BY\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+ORDER\s+BY\s+.*?\s+ROWS\s+BETWEEN\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+ORDER\s+BY\s+.*?\s+RANGE\s+BETWEEN\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+ORDER\s+BY\s+.*?\s+FETCH\s+FIRST\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+ORDER\s+BY\s+.*?\s+FOR\s+UPDATE\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+ORDER\s+BY\s+.*?\s+FOR\s+SHARE\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+ORDER\s+BY\s+.*?\s+NOWAIT\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+ORDER\s+BY\s+.*?\s+SKIP\s+LOCKED\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+ORDER\s+BY\s+.*?\s+OF\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+ORDER\s+BY\s+.*?\s+WAIT\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+GROUP\s+BY\s+.*?\s+LIMIT\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+GROUP\s+BY\s+.*?\s+OFFSET\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+GROUP\s+BY\s+.*?\s+UNION\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+GROUP\s+BY\s+.*?\s+INTERSECT\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+GROUP\s+BY\s+.*?\s+EXCEPT\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+GROUP\s+BY\s+.*?\s+HAVING\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+GROUP\s+BY\s+.*?\s+WINDOW\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+GROUP\s+BY\s+.*?\s+PARTITION\s+BY\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+GROUP\s+BY\s+.*?\s+ROWS\s+BETWEEN\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+GROUP\s+BY\s+.*?\s+RANGE\s+BETWEEN\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+GROUP\s+BY\s+.*?\s+FETCH\s+FIRST\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+GROUP\s+BY\s+.*?\s+FOR\s+UPDATE\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+GROUP\s+BY\s+.*?\s+FOR\s+SHARE\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+GROUP\s+BY\s+.*?\s+NOWAIT\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+GROUP\s+BY\s+.*?\s+SKIP\s+LOCKED\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+GROUP\s+BY\s+.*?\s+OF\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+GROUP\s+BY\s+.*?\s+WAIT\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+LIMIT\s+.*?\s+OFFSET\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+LIMIT\s+.*?\s+UNION\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+LIMIT\s+.*?\s+INTERSECT\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+LIMIT\s+.*?\s+EXCEPT\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+LIMIT\s+.*?\s+HAVING\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+LIMIT\s+.*?\s+WINDOW\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+LIMIT\s+.*?\s+PARTITION\s+BY\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+LIMIT\s+.*?\s+ROWS\s+BETWEEN\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+LIMIT\s+.*?\s+RANGE\s+BETWEEN\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+LIMIT\s+.*?\s+FETCH\s+FIRST\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+LIMIT\s+.*?\s+FOR\s+UPDATE\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+LIMIT\s+.*?\s+FOR\s+SHARE\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+LIMIT\s+.*?\s+NOWAIT\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+LIMIT\s+.*?\s+SKIP\s+LOCKED\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+LIMIT\s+.*?\s+OF\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+LIMIT\s+.*?\s+WAIT\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+OFFSET\s+.*?\s+UNION\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+OFFSET\s+.*?\s+INTERSECT\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+OFFSET\s+.*?\s+EXCEPT\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+OFFSET\s+.*?\s+HAVING\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+OFFSET\s+.*?\s+WINDOW\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+OFFSET\s+.*?\s+PARTITION\s+BY\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+OFFSET\s+.*?\s+ROWS\s+BETWEEN\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+OFFSET\s+.*?\s+RANGE\s+BETWEEN\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+OFFSET\s+.*?\s+FETCH\s+FIRST\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+OFFSET\s+.*?\s+FOR\s+UPDATE\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+OFFSET\s+.*?\s+FOR\s+SHARE\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+OFFSET\s+.*?\s+NOWAIT\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+OFFSET\s+.*?\s+SKIP\s+LOCKED\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+OFFSET\s+.*?\s+OF\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+OFFSET\s+.*?\s+WAIT\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+UNION\s+.*?\s+INTERSECT\s+.*?\s+AS\s+.*?;|SELECT\s+.*\s+FROM\s+.*?\s+UNION\s+.*
---
💡 **LlamaPReview Community**
Have feedback on this AI Code review tool? Join our [GitHub Discussions](https://github.com/JetXu-LLM/LlamaPReview-site/discussions) to share your thoughts and help shape the future of LlamaPReview.
The previous function extracted limited number of queries, leaving behind some queries. creating a table query does not get extracted in the previous version of the query, here it will address all the query cases.