Skip to content

Commit 99c53a4

Browse files
committed
Fix positioning issues with multibyte characters in SQL executions
QScintilla counts characters for the index inside a line and number of bytes for the global positions. When we use index we have to use text lengths (number of characters) and when we use global position, we have to convert previously to byte arrays. Otherwise offsets are produced in executions containing non US-ASCII characters (accented letters, most symbols, etc). The bug could lead to final statements not executed by the execute-all action, more than one line executed by the execute line action and incorrect line references in the log.
1 parent a5d6b50 commit 99c53a4

File tree

1 file changed

+8
-7
lines changed

1 file changed

+8
-7
lines changed

src/MainWindow.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1220,22 +1220,22 @@ void MainWindow::executeQuery()
12201220

12211221
// Need to set the end position here before adjusting the start line
12221222
execute_to_line = execute_from_line;
1223-
execute_to_index = editor->lineLength(execute_to_line) - 1; // The -1 compensates for the line break at the end of the line
1223+
execute_to_index = editor->text(execute_to_line).length() - 1; // The -1 compensates for the line break at the end of the line
12241224
execute_to_position = editor->positionFromLineIndex(execute_to_line, execute_to_index);
12251225

1226-
QString firstPartEntireSQL = query.left(execute_from_position);
1226+
QByteArray firstPartEntireSQL = query.toUtf8().left(execute_from_position);
12271227
if(firstPartEntireSQL.lastIndexOf(';') != -1)
12281228
{
12291229
execute_from_position -= firstPartEntireSQL.length() - firstPartEntireSQL.lastIndexOf(';') - 1;
12301230
editor->lineIndexFromPosition(execute_from_position, &execute_from_line, &execute_from_index);
12311231
}
1232-
12331232
db.logSQL(tr("-- EXECUTING LINE IN '%1'\n--").arg(tabName), kLogMsg_User);
12341233
} break;
12351234
case All:
12361235
{
1237-
// Start position is the first character, end position the last
1238-
execute_to_position = editor->text().length();
1236+
// Start position is the first byte, end position the last.
1237+
// Note that we use byte positions that might differ from character positions.
1238+
execute_to_position = editor->length();
12391239
editor->lineIndexFromPosition(execute_to_position, &execute_to_line, &execute_to_index);
12401240
db.logSQL(tr("-- EXECUTING ALL IN '%1'\n--").arg(tabName), kLogMsg_User);
12411241
} break;
@@ -1256,7 +1256,7 @@ void MainWindow::executeQuery()
12561256
// Convert query to C string which we will use from now on, starting from the determined start position and
12571257
// until the end of the SQL code. By doing so we go further than the determined end position because in Line
12581258
// mode the last statement might go beyond that point.
1259-
QByteArray utf8Query = query.mid(execute_from_position).toUtf8();
1259+
QByteArray utf8Query = query.toUtf8().mid(execute_from_position);
12601260

12611261
// Remove any error indicators
12621262
editor->clearErrorIndicators();
@@ -1409,7 +1409,8 @@ void MainWindow::executeQuery()
14091409

14101410
// Special case: if the start position is at the end of a line, then move to the beggining of next line.
14111411
// Otherwise for the typical case, the line reference is one less than expected.
1412-
if (editor->lineLength(execute_from_line) == execute_from_index+1) {
1412+
// Note that execute_from_index uses character positions and not byte positions, so text().length() must be used.
1413+
if (editor->text(execute_from_line).length() == execute_from_index+1) {
14131414
execute_from_line++;
14141415
execute_from_index = 0;
14151416
}

0 commit comments

Comments
 (0)