public string Rewrite(string query)
{
string result;
// Stored proc calls, remove args
if ((result = Matching(query, "\\A\\s*((?:exec|execute)\\s+\\S+)", group: 1)) != null)
{
return result.ToLower();
}
// Remove one line comments
query = Substitute(query, "(?:--|#)[^'\\r\\n]*([\\r\\n]|\\Z)", "");
// Remove multiline comments
query = Substitute(query, "/\\*[^!].*?\\*/", "", DefaultOption | RegexOption.DotAll | RegexOption.MultiLine);
// Generalize use
query = Substitute(query, "\\A\\s*use \\S+\\Z", "use ?");
// Quoted strings
query = Substitute(query, "\\\\[\"']", "");
query = Substitute(query, "\".*?\"", "?", DefaultOption | RegexOption.DotAll);
query = Substitute(query, "'.*?'", "?", DefaultOption | RegexOption.DotAll);
// MD5s
query = Substitute(query, "([._-])[a-f0-9]{32}", "?");
// Numbers
query = Substitute(query, "\\b[0-9+-][0-9a-f.xb+-]*", "?");
// Tidy
query = Substitute(query, "[xb+-]\\?", "?");
// Remove leading ws
query = Substitute(query, "\\A\\s+", "");
// Remove trailing ws
query = Substitute(query, "[\\r\\n\\s]+$", "");
// Collapse internal ws
query = Substitute(query, "[ \\n\\t\\r\\f]+", " ", DefaultOption | RegexOption.DotAll);
// Null
query = Substitute(query, "\\bnull\\b", "?");
query = Substitute(query, "\\bis\\s+not\\s+\\?", "?null?");
query = Substitute(query, "\\bis\\s+\\?", "?null?");
// Collapse IN
query = Substitute(query, "\\bin(?:[\\s,]*\\([\\s?,]*\\))+", "in (?)");
// Collapse VALUES
query = Substitute(query, "\\bvalues(?:[\\s,]*\\([\\s?,]*\\))+", "values (?)");
// Collapse repeated select UNION
query = Substitute(query, "\\b(select\\s.*?)(?:(\\sunion(?:\\sall)?)\\s\\1)+", "$1");
// Tighten up operators
query = Substitute(query, "\\s?([,=+*/-])\\s?", "#1");
return query.ToLower();
}