prql icon indicating copy to clipboard operation
prql copied to clipboard

Preserve comments in the SQL output

Open vanillajonathan opened this issue 2 years ago • 11 comments

What's up?

There should be a way to preserve comments in the output.

# Preserved? Nope!
## Preserved? Nope!
### Preserved? Nope!
from invoices

Output:

SELECT
  *
FROM
  invoices

Maybe a triple quote comment?

"""Triple quotes! Preserved? Nope!"""
from invoices

Nope, that didn't work either!

expected a function, but found `default_db.invoices`

I'll be sneaky and try a s-string!

s"-- A sneaky s-string! Preserved? Nope!"
from invoices

Nope, that didn't work either.

vanillajonathan avatar Jul 03 '23 19:07 vanillajonathan

Would be doable, but this is not high priority. If someone finds a neat use-case, feel free to upvote the issue.

aljazerzen avatar Jul 04 '23 07:07 aljazerzen

This would allow use cases such as comments like "Warning! This query is really heavy, don't run it in production!" or "Important! Make sure you change the filter clause prior to running this query!".

Having the comment available in the abstract syntax tree would also allow a documentation generator to generate a HTML or a PDF which include the comments but for that the concept of "doc block" would need to be introduced which would be useful for std.prql to document what functions do, what input parameters there are, and what the function returns.

Function documentation and documentation generation #1759

vanillajonathan avatar Jul 04 '23 11:07 vanillajonathan

documentation generator to generate a HTML or a PDF

That's a great idea! We must eventually build something for this.

We will probably have some other syntax than regular comments, because doc comments can only appear at specific locations (probably just before variable definitions) and are thus easier to place into AST.

Generating SQL with comments is even more complicated, because in some cases, a node in PRQL is duplicated in SQL and sometimes it is not even there. This makes injecting comments much harder to do consistently.

aljazerzen avatar Jul 04 '23 11:07 aljazerzen

... but if we have just the variable doc comments, this will always map into some SELECT statement, which could bear that doc comment.

Jup, this would not require much work on top of parsing doc comments for variables (which we should do anyway).

aljazerzen avatar Jul 04 '23 11:07 aljazerzen

Would be doable, but this is not high priority. If someone finds a neat use-case, feel free to upvote the issue.

In case someone needs to add magic comments for optimization or other purposes. For instance: https://dev.mysql.com/doc/refman/8.0/en/optimizer-hints.html

zhicwu avatar Jul 05 '23 07:07 zhicwu

My use case would be preserving the comment header to each query for sqlc to inspect and generate Go code from.

lsh-0 avatar Sep 25 '23 02:09 lsh-0

EF Core have the concept of query tags which inserts comments that is used to correlate queries in logs.

vanillajonathan avatar Sep 25 '23 09:09 vanillajonathan

@PorcoRosso85, Rich was asking for examples of how you'd map the comments in PRQL into SQL https://github.com/PRQL/prql/issues/4650#issuecomment-2184340831

If I start with an example, this PRQL source

# a comment on sample_albums
let sample_albums = (
  from albums 
  take 10 # an inline comment within sample_albums
  join artists (==artist_id)
)

# comment of main pipeline
from sample_albums
take 3 # an inline comment within main
aggregate {count = std.count this}

... compiles to:

WITH table_1 AS (
  SELECT
    *
  FROM
    albums
  LIMIT
    10
), sample_albums AS (
  SELECT
    table_1.*,
    artists.*
  FROM
    table_1
    JOIN artists ON table_1.artist_id = artists.artist_id
),
table_0 AS (
  SELECT
    NULL
  FROM
    sample_albums
  LIMIT
    3
)
SELECT
  COUNT(*) AS count
FROM
  table_0

-- Generated by PRQL compiler version:0.12.2 (https://prql-lang.org)

Where would we want to place the comments at?

aljazerzen avatar Jun 24 '24 07:06 aljazerzen

I think for doc comments — which specifically refer to the item below them — we could make a guess.

#! a comment on sample_albums
let sample_albums = (
  from albums 
  take 10 # an inline comment within sample_albums
  join artists (==artist_id)
)

#! comment of main pipeline
from sample_albums
take 3 # an inline comment within main
aggregate {count = std.count this}

(note the change from # to #!)

+ --comment of main pipeline
WITH table_1 AS (
  SELECT
    *
  FROM
    albums
  LIMIT
    10
), 
+ --a comment on sample_albums
sample_albums AS (
  SELECT
    table_1.*,
    artists.*
  FROM
    table_1
    JOIN artists ON table_1.artist_id = artists.artist_id
),
table_0 AS (
  SELECT
    NULL
  FROM
    sample_albums
  LIMIT
    3
)
SELECT
  COUNT(*) AS count
FROM
  table_0

 -- Generated by PRQL compiler version:0.12.2 (https://prql-lang.org)

max-sixty avatar Jun 24 '24 17:06 max-sixty

Sorry it took me so long to reply. I think the example given by @max-sixty is great. Good enough for me currently.

Is this something that can be tried already in the 0.12.2 version?

PorcoRosso85 avatar Jul 12 '24 20:07 PorcoRosso85

No but I'm reasonably close to having half of it working — to be able to parse into our AST. So watch this space...

max-sixty avatar Jul 12 '24 20:07 max-sixty