SqliteTableModel: Remove comments from SQL queries

Remove any single line comments from the SQL queries to fix all those
problems ocurring when a query ending with such a comment is inserted
into the COUNT query.

Executing the query
SELECT * FROM table -- comment
would otherwise lead to this one being executed as well
SELECT COUNT(*) FROM (SELECT * FROM table -- comment);
This is obviously invalid SQL and therefore returns no data, sometimes
even crashing the application, even though the original statement by the
user is perfectly fine.

The code used in this commit is a bit of a workaround and should be
replaced as soon as there is a more complete SQL parser supporting SQL
comments in our grammar tools.

Closes #31.
This commit is contained in:
Martin Kleusberg
2013-09-06 14:08:33 +02:00
parent a98c96e314
commit 169eccbebb

View File

@@ -40,6 +40,38 @@ QString rtrimChar(const QString& s, QChar c) {
r.chop(1);
return r;
}
QString removeComments(QString s)
{
// Feel free to fix all the bugs this probably contains or just replace this function entirely by
// a 'simple' regular expression. I know there're better ways to do this...
// This function removes any single line comments (starting with '--') from a given string. It does
// so by going through the string character by character and trying to keep track of wether we currently
// are in a string or identifier and only removing those parts starting with '--' which are in neither.
QChar lastChar = 0;
QList<QChar> stringChars;
for(int i=0;i<s.length();i++)
{
if(lastChar != '\\' && (s.at(i) == '\'' || s.at(i) == '"' || s.at(i) == '`'))
{
if(!stringChars.empty() && stringChars.last() == s.at(i))
stringChars.removeLast();
else if(!(!stringChars.empty() && (stringChars.last() != '\'' || stringChars.last() != '"')) || stringChars.empty())
stringChars.push_back(s.at(i));
} else if(stringChars.empty() && s.at(i) == '-' && lastChar == '-') {
if(s.contains('\n'))
return removeComments(s.remove(i-1, s.indexOf('\n', i)-i));
else
return s.left(i-1);
}
lastChar = s.at(i);
}
return s;
}
}
void SqliteTableModel::setQuery(const QString& sQuery, bool dontClearHeaders)
@@ -52,7 +84,7 @@ void SqliteTableModel::setQuery(const QString& sQuery, bool dontClearHeaders)
if(!m_db->isOpen())
return;
m_sQuery = sQuery.trimmed();
m_sQuery = removeComments(sQuery).trimmed();
// do a count query to get the full row count in a fast manner
m_rowCount = getQueryRowCount();