PRQL / prql

PRQL is a modern language for transforming data — a simple, powerful, pipelined SQL replacement
https://prql-lang.org
Apache License 2.0
9.87k stars 216 forks source link

Ambiguous name: better error message #2951

Closed richb-hanover closed 1 year ago

richb-hanover commented 1 year ago

What's up?

I was writing the query below and was stumped by the "Ambiguous name" error message. As a newcomer, the terms "frame", "item", or "infer" don't help me know what to do.

Could the message say something like, Ambiguous name. Try adding a tablename: e.g. tablename.billing_city

Thanks.

from inv=invoices
join side:left item=invoice_items (==invoice_id) # join using column "invoice_id" in both tables
select [
  billing_city
]
Error: 
   ╭─[:4:3]
   │
 4 │   billing_city
   │   ──────┬──────  
   │         ╰──────── Ambiguous name. Could be from any of _frame.item._infer, _frame.inv._infer
───╯
aljazerzen commented 1 year ago

This is about to change to:

Error: 
   ╭─[:4:3]
   │
 4 │   billing_city
   │   ──────┬──────  
   │         ╰──────── Ambiguous name. Could be from any of this.item._infer, that.inv._infer
───╯

A bit better, but a not good enough.

richb-hanover commented 1 year ago

Hmmm... In the main branch (2bdb1b51), the example query above yields the following message (after substituting "{" for "[", etc):

Error: 
   ╭─[:4:3]
   │
 4 │   billing_city
   │   ──────┬─────  
   │         ╰─────── Unknown name
───╯

Yet if I leave off the select ... statement, I clearly see the "billing_city" column from table "inv", and if I change the query to select inv.billing_city, I see the expected values.

Would it be reasonable to have the error message suggest adding a tablename? Perhaps, Unknown name. Might be resolved by adding its tablename, e.g., tablename.billing_city

aljazerzen commented 1 year ago

You are probably using 0.8 syntax.

aljazerzen commented 1 year ago

It turns out that in the process of changing how name resolution works, I've butchered this error message.

This is the fixed error message:

    Error:
       ╭─[:4:12]
       │
     4 │     select billing_city
       │            ┬-----------
       │            ╰── Ambiguous name. Could be in any of: this.inv, this.item
    ───╯
richb-hanover commented 1 year ago
select billing_city
       ┬-----------
       ╰── Ambiguous name. Could be in any of: this.inv, this.item

@aljazerzen I still find the hint about this.inv or this.item to be confusing. I see now that I could type this.inv.billing_city to get what I want. But the presence of this (in "this.inv") isn't something that I recognize right away.

If PRQL is going to call out the names of the potentially ambiguous tables, it seems better to show the newcomer what to write, for example:

Ambiguous name. Could be any of inv.billing_city, item.billing_city

The good news is that the message already enumerates all the table names when the query joins multiple tables (see example below). Including the column name makes the choices appear more recognizable.

Ambiguous name. Could be any of: i4.billing_city, inv.billing_city, i3.billing_city, item.billing_city, i2.billing_city

If including the column name makes the error message too long, I would accept adding "etc..." after the third.

Ambiguous name. Could be any of: i4.billing_city, inv.billing_city, i3.billing_city, etc...
from inv=invoices
join side:left item=invoice_items (==invoice_id) # join using column "invoice_id" in both tables
join side:left i2=items2 (item.invoice_id==i2.invoice_id) # join using column "invoice_id" in both tables
join side:left i3=items2 (item.invoice_id==i3.invoice_id) # join using column "invoice_id" in both tables
join side:left i4=items2 (item.invoice_id==i4.invoice_id) # join using column "invoice_id" in both tables
select billing_city

Thanks for listening.

richb-hanover commented 1 year ago

I was amused to see that the same problem crops up in the join criteria. I had originally written the second join with (==invoice_id) and got the ambiguous name error.

The same solution (writing out the tablename.columnname possibilities) applies in this situation as well. Thanks again.

aljazerzen commented 1 year ago

Attempt number 2:

from inv=invoices
join item=invoice_items (==invoice_id)
select {
  billing_city
}

Error:
     ╭─[:106:3]
     │
 106 │   billing_city
     │   ──────┬─────
     │         ╰─────── Ambiguous name
     │
     │ Help: could be any of: inv.billing_city, item.billing_city
─────╯

and:

from inv=invoices
join item=invoice_items (id == invoice_id)

Error:
     ╭─[:104:26]
     │
 104 │ join item=invoice_items (id == invoice_id)
     │                          ─┬
     │                           ╰── Ambiguous name
     │
     │ Help: could be any of: that.item.id, this.inv.id
─────╯

and:

from invoices
join invoices (id == id)

Error:
     ╭─[:104:16]
     │
 104 │ join invoices (id == id)
     │                ─┬
     │                 ╰── Ambiguous name
     │
     │ Help: could be any of: that.invoices.id, this.invoices.id
─────╯
richb-hanover commented 1 year ago

Thank You! This addresses my simple (first) case nicely.

I like that the "Help:" is on a separate line.

I note the "this" and "that". Let's proceed like this and see what other questions arise. Thanks again

richb-hanover commented 1 year ago

Didn't mean to close this 'til it was committed...

vanillajonathan commented 1 year ago

See the screenshot at https://www.jetbrains.com/datagrip/

DataGrip