Skip to content

Commit

Permalink
#5183 Fixed completer proposals in the column names of the INSERT INT…
Browse files Browse the repository at this point in the history
…O statement.; System tables (sqlite_*) are now pushed further in the competer proposals.
  • Loading branch information
pawelsalawa committed Dec 27, 2024
1 parent 50bd388 commit 29ef515
Show file tree
Hide file tree
Showing 10 changed files with 2,716 additions and 2,602 deletions.
2 changes: 2 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# ChangeLog

### 3.4.13
- BUGFIX: #5183 Fixed completer proposals in the column names of the INSERT INTO statement.
- BUGFIX: System tables (sqlite_*) are now pushed further in the competer proposals.
- BUGFIX: Restored missing completer entries: string, number, BLOB literal.

### 3.4.12
Expand Down
13 changes: 13 additions & 0 deletions SQLiteStudio3/Tests/ParserTest/tst_parsertest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class ParserTest : public QObject
void testBigNum();
void testSelectWith();
void testInsertWithDoubleQuoteValues();
void testInsertIncompleteOnColumnName();
void testParseAndRebuildAlias();
void testRebuildTokensUpdate();
void testRebuildTokensInsertUpsert();
Expand Down Expand Up @@ -469,6 +470,18 @@ void ParserTest::testInsertWithDoubleQuoteValues()
QVERIFY(sql.replace(" ", "") == detokenized);
}

void ParserTest::testInsertIncompleteOnColumnName()
{
QString sql = "INSERT INTO tabName (";
bool res = parser3->parse(sql, true);
QVERIFY(res);
QVERIFY(parser3->getErrors().isEmpty());

const SqliteInsertPtr insert = parser3->getQueries().first().dynamicCast<SqliteInsert>();
QVERIFY(insert->table == "tabName");
QVERIFY(insert->columnNames.isEmpty());
}

void ParserTest::testParseAndRebuildAlias()
{
QString sql = "SELECT x AS [\"abc\".\"def\"];";
Expand Down
17 changes: 14 additions & 3 deletions SQLiteStudio3/coreSQLiteStudio/completioncomparer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ bool CompletionComparer::compareColumns(const ExpectedTokenPtr& token1, const Ex
case CompletionHelper::Context::UPDATE_WHERE:
result = compareColumnsForUpdateCol(token1, token2, &ok);
break;
case CompletionHelper::Context::INSERT_COLUMNS:
result = compareColumnsForInsertCol(token1, token2, &ok);
case CompletionHelper::Context::DELETE_WHERE:
result = compareColumnsForDeleteCol(token1, token2, &ok);
break;
Expand Down Expand Up @@ -195,7 +197,7 @@ bool CompletionComparer::compareColumnsForUpdateCol(const ExpectedTokenPtr &toke
if (token1->contextInfo == token2->contextInfo)
return compareValues(token1->value, token2->value);

return compareByContext(token1->contextInfo, token2->contextInfo, contextTables);
return compareByContext(token1->contextInfo, token2->contextInfo, contextTables, true);
}

bool CompletionComparer::compareColumnsForDeleteCol(const ExpectedTokenPtr &token1, const ExpectedTokenPtr &token2, bool *result)
Expand All @@ -204,7 +206,16 @@ bool CompletionComparer::compareColumnsForDeleteCol(const ExpectedTokenPtr &toke
if (token1->contextInfo == token2->contextInfo)
return compareValues(token1->value, token2->value);

return compareByContext(token1->contextInfo, token2->contextInfo, contextTables);
return compareByContext(token1->contextInfo, token2->contextInfo, contextTables, true);
}

bool CompletionComparer::compareColumnsForInsertCol(const ExpectedTokenPtr &token1, const ExpectedTokenPtr &token2, bool *result)
{
*result = true;
if (token1->contextInfo == token2->contextInfo)
return compareValues(token1->value, token2->value);

return compareByContext(token1->contextInfo, token2->contextInfo, contextTables, true);
}

bool CompletionComparer::compareColumnsForCreateTable(const ExpectedTokenPtr& token1, const ExpectedTokenPtr& token2, bool* result)
Expand Down Expand Up @@ -307,7 +318,7 @@ bool CompletionComparer::compareValues(const ExpectedTokenPtr &token1, const Exp

bool CompletionComparer::compareValues(const QString &token1, const QString &token2, bool handleSystemNames)
{
//qDebug() << "comparing" << token1 << "and" << token2 << "=" << token1.compare(token2, Qt::CaseInsensitive);
// qDebug() << "comparing" << token1 << "and" << token2 << "=" << token1.compare(token2, Qt::CaseInsensitive);
if (handleSystemNames)
{
bool firstIsSystem = token1.toLower().startsWith("sqlite_");
Expand Down
1 change: 1 addition & 0 deletions SQLiteStudio3/coreSQLiteStudio/completioncomparer.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class CompletionComparer
bool compareColumnsForSelectResCol(const ExpectedTokenPtr& token1, const ExpectedTokenPtr& token2, bool* result);
bool compareColumnsForUpdateCol(const ExpectedTokenPtr& token1, const ExpectedTokenPtr& token2, bool* result);
bool compareColumnsForDeleteCol(const ExpectedTokenPtr& token1, const ExpectedTokenPtr& token2, bool* result);
bool compareColumnsForInsertCol(const ExpectedTokenPtr& token1, const ExpectedTokenPtr& token2, bool* result);
bool compareColumnsForCreateTable(const ExpectedTokenPtr& token1, const ExpectedTokenPtr& token2, bool* result);
bool compareColumnsForReturning(const ExpectedTokenPtr& token1, const ExpectedTokenPtr& token2, bool* result);
bool compareTables(const ExpectedTokenPtr& token1, const ExpectedTokenPtr& token2);
Expand Down
27 changes: 27 additions & 0 deletions SQLiteStudio3/coreSQLiteStudio/completionhelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1070,6 +1070,10 @@ void CompletionHelper::extractQueryAdditionalInfo()
{
context = Context::EXPR;
}
else if (isInInsertColumns())
{
context = Context::INSERT_COLUMNS;
}
else if (isInUpdateReturning())
{
context = Context::UPDATE_RETURNING;
Expand Down Expand Up @@ -1179,6 +1183,29 @@ bool CompletionHelper::isInInsertReturning()
return isIn(SqliteQueryType::Insert, "returning", "RETURNING");
}

bool CompletionHelper::isInInsertColumns()
{
if (isIn(SqliteQueryType::Insert, "idlist_opt", QString()))
return true;

if (!parsedQuery)
return false;

if (parsedQuery->queryType != SqliteQueryType::Insert)
return false;

if (parsedQuery->tokensMap.contains("rp_opt"))
{
TokenList rpTokens = parsedQuery->tokensMap["rp_opt"];
if (rpTokens.isEmpty())
return parsedQuery->tokensMap["LP"][0]->start <= cursorPosition;
else
return rpTokens[0]->start >= cursorPosition;
}

return false;
}

bool CompletionHelper::isIn(SqliteQueryType queryType, const QString &tokenMapKey, const QString &prefixKeyword)
{
if (!parsedQuery)
Expand Down
2 changes: 2 additions & 0 deletions SQLiteStudio3/coreSQLiteStudio/completionhelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ class API_EXPORT CompletionHelper : public QObject
CREATE_TABLE,
CREATE_TRIGGER,
EXPR,
INSERT_COLUMNS,
INSERT_RETURNING,
UPDATE_RETURNING,
DELETE_RETURNING
Expand Down Expand Up @@ -142,6 +143,7 @@ class API_EXPORT CompletionHelper : public QObject
bool isInDeleteWhere();
bool isInCreateTable();
bool isInCreateTrigger();
bool isInInsertColumns();
bool isInUpdateReturning();
bool isInDeleteReturning();
bool isInInsertReturning();
Expand Down
6 changes: 6 additions & 0 deletions SQLiteStudio3/coreSQLiteStudio/parser/compile_lemon.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/sh
LEMON=~/lemon
GCC=gcc

$GCC -o $LEMON lemon.c

2 changes: 1 addition & 1 deletion SQLiteStudio3/coreSQLiteStudio/parser/run_lemon.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/bin/sh

#lemon -l -q -s sqlite3_parse.y
lemon -l -q sqlite3_parse.y
~/lemon -l -q sqlite3_parse.y
mv sqlite3_parse.c sqlite3_parse.cpp
Loading

0 comments on commit 29ef515

Please sign in to comment.