question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Allow read only CTEs in query reports

See original GitHub issue

Description of the issue

There is a check in frappe/core/doctype/report/report.py to make sure, the query starts with a SELECT statement. My query looks like this and is therefore not accepted:

WITH recursive Calendar AS (
   SELECT '2022-03-01' AS CalendarDate
   UNION ALL
   SELECT DATE_ADD(CalendarDate, INTERVAL 1 DAY)
   FROM   Calendar
   WHERE  CalendarDate < '2022-03-10'
)
SELECT c.CalendarDate
       , SUM( IF(t.modified > c.CalendarDate OR t.status = 'To Deliver and Bill', t.total, 0) ) AS TotalValue
FROM   Calendar c INNER JOIN `tabSales Order` t
            ON t.creation <= c.CalendarDate
            AND (t.modified >= c.CalendarDate OR t.status = 'To Deliver and Bill')         
GROUP BY c.CalendarDate 
ORDER BY c.CalendarDate
;

Context information (for bug reports)

Output of bench version

v12.22.0

Observed result

frappe.exceptions.ValidationError: Query must be a SELECT

Expected result

Execution of the query report.

Stacktrace / full error message

Traceback (most recent call last):
  File "apps/frappe/frappe/app.py", line 68, in application
    response = frappe.api.handle()
  File "apps/frappe/frappe/api.py", line 55, in handle
    return frappe.handler.handle()
  File "apps/frappe/frappe/handler.py", line 31, in handle
    data = execute_cmd(cmd)
  File "apps/frappe/frappe/handler.py", line 68, in execute_cmd
    return frappe.call(method, **frappe.form_dict)
  File "apps/frappe/frappe/__init__.py", line 1213, in call
    return fn(*args, **newargs)
  File "apps/frappe/frappe/__init__.py", line 629, in wrapper_fn
    retval = fn(*args, **get_newargs(fn, kwargs))
  File "apps/frappe/frappe/desk/query_report.py", line 244, in run
    result = generate_report_result(report, filters, user, custom_columns, is_tree, parent_field)
  File "apps/frappe/frappe/__init__.py", line 629, in wrapper_fn
    retval = fn(*args, **get_newargs(fn, kwargs))
  File "apps/frappe/frappe/desk/query_report.py", line 86, in generate_report_result
    res = get_report_result(report, filters) or []
  File "apps/frappe/frappe/desk/query_report.py", line 67, in get_report_result
    res = report.execute_query_report(filters)
  File "apps/frappe/frappe/core/doctype/report/report.py", line 117, in execute_query_report
    frappe.throw(_("Query must be a SELECT"), title=_('Report Document Error'))
  File "apps/frappe/frappe/__init__.py", line 444, in throw
    msgprint(msg, raise_exception=exc, title=title, indicator='red', is_minimizable=is_minimizable, wide=wide, as_list=as_list)
  File "apps/frappe/frappe/__init__.py", line 423, in msgprint
    _raise_exception()
  File "apps/frappe/frappe/__init__.py", line 378, in _raise_exception
    raise raise_exception(msg)
frappe.exceptions.ValidationError: Query must be a SELECT

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:6 (6 by maintainers)

github_iconTop GitHub Comments

2reactions
carstenbltcommented, Mar 18, 2022

Also, I believe MariaDB only supports WITH with SELECT: https://mariadb.com/kb/en/with/ (I just tried to work around it with a helper table expecting WITH … AS … INSERT INTO to work, which doesn’t.) So I guess enabling it for MariaDB would be fine.

2reactions
carstenbltcommented, Mar 18, 2022

Postgres, and not writing to a table, but an example I recently used to reset auto increment values:

select SETVAL(pg_get_serial_sequence('public.table', 'id'), (SELECT MAX(id) FROM public.table));

At least there you can execute a SETVAL().

Read more comments on GitHub >

github_iconTop Results From Across the Web

CTEs in SQL Server; Querying Common Table Expressions
This article gives overview of a convenient way to query data Common Table Expressions(CTE) in SQL Server.
Read more >
WITH common_table_expression (Transact-SQL) - SQL Server
Cursors may be defined on queries using CTEs. The CTE is the select_statement argument that defines the result set of the cursor. Only...
Read more >
How to Use 2 CTEs in a Single SQL Query | LearnSQL.com
Have you ever wondered how to use multiple CTEs in one SQL query? Read this article and find out about recursive CTEs.
Read more >
Working with CTEs (Common Table Expressions)
Recursive CTEs enable you to process hierarchical data, such as a parts explosion (component, sub-components) or a management hierarchy (manager, employees).
Read more >
Solved: Custom query with CTE not supported (bug?)
2) COPY/PASTE the dataset with the CTE, and Edit the query in the new one so that it selects out the same columns...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found