apache / apache/datafusion-sqlparser-rs

Keywords are parsed as functions in select statements

Abierto
#1,909 0 comentarios 0 reacciones 0 asignados Ver en GitHub
Lenguaje dominante
Rust
Estrellas
3.5k
Forks
772
Merge medio
4 d 9 h
PR fusionados (30 d)
17

Descripción

# Abstract
Qualified names like of the form `.` are sometimes parsed as functions, like in:

```sql
SELECT t.user FROM t;
```

# Current Behavior
This is done with `cargo run --example cli -- test.sql --generic`:

```sql
select t.user from t;
```

results in:

```text
[
Query(
Query {
with: None,
body: Select(
Select {
select_token: TokenWithSpan {
token: Word(
Word {
value: "select",
quote_style: None,
keyword: SELECT,
},
),
span: Span(Location(1,1)..Location(1,7)),
},
distinct: None,
top: None,
top_before_distinct: false,
projection: [
UnnamedExpr(
Function(
Function {
name: ObjectName(
[
Identifier(
Ident {
value: "t",
quote_style: None,
span: Span(Location(1,8)..Location(1,9)),
},
),
Identifier(
Ident {
value: "user",
quote_style: None,
span: Span(Location(1,10)..Location(1,14)),
},
),
],
),
uses_odbc_syntax: false,
parameters: None,
args: None,
filter: None,
null_treatment: None,
over: None,
within_group: [],
},
),
),
],
into: None,
from: [
TableWithJoins {
relation: Table {
name: ObjectName(
[
Identifier(
Ident {
value: "t",
quote_style: None,
span: Span(Location(1,20)..Location(1,21)),
},
),
],
),
alias: None,
args: None,
with_hints: [],
version: None,
with_ordinality: false,
partitions: [],
json_path: None,
sample: None,
index_hints: [],
},
joins: [],
},
],
lateral_views: [],
prewhere: None,
selection: None,
group_by: Expressions(
[],
[],
),
cluster_by: [],
distribute_by: [],
sort_by: [],
having: None,
named_window: [],
qualify: None,
window_before_qualify: false,
value_table_mode: None,
connect_by: None,
flavor: Standard,
},
),
order_by: None,
limit_clause: None,
fetch: None,
locks: [],
for_clause: None,
settings: None,
format_clause: None,
pipe_operators: [],
},
),
]
```

and `cargo run --example cli -- test.sql --postgres` is the same:

```text
[
Query(
Query {
with: None,
body: Select(
Select {
select_token: TokenWithSpan {
token: Word(
Word {
value: "select",
quote_style: None,
keyword: SELECT,
},
),
span: Span(Location(1,1)..Location(1,7)),
},
distinct: None,
top: None,
top_before_distinct: false,
projection: [
UnnamedExpr(
Function(
Function {
name: ObjectName(
[
Identifier(
Ident {
value: "t",
quote_style: None,
span: Span(Location(1,8)..Location(1,9)),
},
),
Identifier(
Ident {
value: "user",
quote_style: None,
span: Span(Location(1,10)..Location(1,14)),
},
),
],
),
uses_odbc_syntax: false,
parameters: None,
args: None,
filter: None,
null_treatment: None,
over: None,
within_group: [],
},
),
),
],
into: None,
from: [
TableWithJoins {
relation: Table {
name: ObjectName(
[
Identifier(
Ident {
value: "t",
quote_style: None,
span: Span(Location(1,20)..Location(1,21)),
},
),
],
),
alias: None,
args: None,
with_hints: [],
version: None,
with_ordinality: false,
partitions: [],
json_path: None,
sample: None,
index_hints: [],
},
joins: [],
},
],
lateral_views: [],
prewhere: None,
selection: None,
group_by: Expressions(
[],
[],
),
cluster_by: [],
distribute_by: [],
sort_by: [],
having: None,
named_window: [],
qualify: None,
window_before_qualify: false,
value_table_mode: None,
connect_by: None,
flavor: Standard,
},
),
order_by: None,
limit_clause: None,
fetch: None,
locks: [],
for_clause: None,
settings: None,
format_clause: None,
pipe_operators: [],
},
),
]
```

# Expected Behavior
I think this should parse similar to

```sql
select t.foo from t;
```

with `cargo run --example cli -- test.sql --generic`:

```text
[
Query(
Query {
with: None,
body: Select(
Select {
select_token: TokenWithSpan {
token: Word(
Word {
value: "select",
quote_style: None,
keyword: SELECT,
},
),
span: Span(Location(1,1)..Location(1,7)),
},
distinct: None,
top: None,
top_before_distinct: false,
projection: [
UnnamedExpr(
CompoundIdentifier(
[
Ident {
value: "t",
quote_style: None,
span: Span(Location(1,8)..Location(1,9)),
},
Ident {
value: "foo",
quote_style: None,
span: Span(Location(1,10)..Location(1,13)),
},
],
),
),
],
into: None,
from: [
TableWithJoins {
relation: Table {
name: ObjectName(
[
Identifier(
Ident {
value: "t",
quote_style: None,
span: Span(Location(1,19)..Location(1,20)),
},
),
],
),
alias: None,
args: None,
with_hints: [],
version: None,
with_ordinality: false,
partitions: [],
json_path: None,
sample: None,
index_hints: [],
},
joins: [],
},
],
lateral_views: [],
prewhere: None,
selection: None,
group_by: Expressions(
[],
[],
),
cluster_by: [],
distribute_by: [],
sort_by: [],
having: None,
named_window: [],
qualify: None,
window_before_qualify: false,
value_table_mode: None,
connect_by: None,
flavor: Standard,
},
),
order_by: None,
limit_clause: None,
fetch: None,
locks: [],
for_clause: None,
settings: None,
format_clause: None,
pipe_operators: [],
},
),
]
```

# Others
Also see PostgreSQL:

```text
psql (17.5 (Debian 17.5-1.pgdg120+1))
Type "help" for help.

postgres=# create table t(a int, "user" text);
CREATE TABLE
postgres=# insert into t values (1, 'foo');
INSERT 0 1
postgres=# select t.user from t;
user
------
foo
(1 row)
```

Interestingly, even the plain `user` works:

```text
postgres=# select user from t;
user
----------
postgres
(1 row)
```

# References
- a potentially valid case of treating `user` as a function: #1658
- downstream: https://github.com/apache/datafusion/issues/14141

Guía de contribución

No hay ninguna guía de contribución indexada para este repositorio

Línea de trabajo

Reproduce el problema con el comando mencionado cargo run --example cli usando test.sql y tanto --generic como --postgres. Rastrea el análisis de la expresión SQL que clasifica t.user como Function en lugar del CompoundIdentifier mostrado para t.foo; después, añade cobertura para la consulta que falla y verifica que ambos dialectos produzcan la forma de análisis esperada.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
rust, sql
Área
compilers
Tipo de issue
Error
Dificultad
3/5
Tiempo estimado
1-2 días
Estado de actividad
Estancado
Claridad
Bastante claro
Aptitud para principiantes
45/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.