Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Features
Bug Fixes
--------
* Better respect case when `keyword_casing` is `auto`.
* Let favorite queries contain special commands.


1.47.0 (2026/01/24)
Expand Down
23 changes: 18 additions & 5 deletions mycli/packages/special/iocommands.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
from mycli.packages.prompt_utils import confirm_destructive_query
from mycli.packages.special.delimitercommand import DelimiterCommand
from mycli.packages.special.favoritequeries import FavoriteQueries
from mycli.packages.special.main import COMMANDS as SPECIAL_COMMANDS
from mycli.packages.special.main import ArgType, special_command
from mycli.packages.special.main import execute as special_execute
from mycli.packages.special.utils import handle_cd_command
from mycli.packages.sqlresult import SQLResult

Expand Down Expand Up @@ -281,12 +283,23 @@ def execute_favorite_query(cur: Cursor, arg: str, **_) -> Generator[SQLResult, N
for sql in sqlparse.split(query):
sql = sql.rstrip(";")
title = f"> {sql}" if is_show_favorite_query() else None
cur.execute(sql)
if cur.description:
headers = [x[0] for x in cur.description]
yield SQLResult(title=title, results=cur, headers=headers)
is_special = False
for special in SPECIAL_COMMANDS:
if sql.lower().startswith(special.lower()):
is_special = True
break
if is_special:
for result in special_execute(cur, sql):
result.title = title
# special_execute() already returns a SQLResult
yield result
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works great! Only suggestion would be adding a comment here to highlight that the special_execute function returns a SQLResult, so that is why it's just yielding the "result" var instead of a SQLResult object like the rest of the yields. Will approve as-is so feel free to add it or not

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

else:
yield SQLResult(title=title)
cur.execute(sql)
if cur.description:
headers = [x[0] for x in cur.description]
yield SQLResult(title=title, results=cur, headers=headers)
else:
yield SQLResult(title=title)


def list_favorite_queries() -> list[SQLResult]:
Expand Down
11 changes: 11 additions & 0 deletions test/test_special_iocommands.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,17 @@ def test_favorite_query():
assert next(mycli.packages.special.execute(cur, "\\f check")).title == "> " + query


@dbtest
@pytest.mark.skipif(os.name == "nt", reason="Bug: fails on Windows, needs fixing, singleton of FQ not working right")
def test_special_favorite_query():
with db_connection().cursor() as cur:
query = r'\?'
mycli.packages.special.execute(cur, rf"\fs special {query}")
assert (r'\G', r'\G', 'Display current query results vertically.') in next(
mycli.packages.special.execute(cur, r'\f special')
).results


def test_once_command():
with pytest.raises(TypeError):
mycli.packages.special.execute(None, "\\once")
Expand Down