Find the last sql keyword in an SQL statement Returns the value of the last keyword, and the text of the query with everything after the last keyword stripped
(sql, n_skip=0)
| 67 | |
| 68 | |
| 69 | def find_prev_keyword(sql, n_skip=0): |
| 70 | """Find the last sql keyword in an SQL statement |
| 71 | |
| 72 | Returns the value of the last keyword, and the text of the query with |
| 73 | everything after the last keyword stripped |
| 74 | """ |
| 75 | if not sql.strip(): |
| 76 | return None, "" |
| 77 | |
| 78 | parsed = sqlparse.parse(sql)[0] |
| 79 | flattened = list(parsed.flatten()) |
| 80 | flattened = flattened[: len(flattened) - n_skip] |
| 81 | |
| 82 | logical_operators = ("AND", "OR", "NOT", "BETWEEN") |
| 83 | |
| 84 | for t in reversed(flattened): |
| 85 | if t.value == "(" or (t.is_keyword and (t.value.upper() not in logical_operators)): |
| 86 | # Find the location of token t in the original parsed statement |
| 87 | # We can't use parsed.token_index(t) because t may be a child token |
| 88 | # inside a TokenList, in which case token_index throws an error |
| 89 | # Minimal example: |
| 90 | # p = sqlparse.parse('select * from foo where bar') |
| 91 | # t = list(p.flatten())[-3] # The "Where" token |
| 92 | # p.token_index(t) # Throws ValueError: not in list |
| 93 | idx = flattened.index(t) |
| 94 | |
| 95 | # Combine the string values of all tokens in the original list |
| 96 | # up to and including the target keyword token t, to produce a |
| 97 | # query string with everything after the keyword token removed |
| 98 | text = "".join(tok.value for tok in flattened[: idx + 1]) |
| 99 | return t, text |
| 100 | |
| 101 | return None, "" |
| 102 | |
| 103 | |
| 104 | # Postgresql dollar quote signs look like `$$` or `$tag$` |
no outgoing calls