apache / apache/datafusion-sqlparser-rs

[PG Dialect] `SELECT ARRAY(SELECT 1)` fails to parse

Ouverte
#400 0 commentaires 0 réactions 0 personnes assignées Voir sur GitHub
Langage dominant
Rust
Étoiles
3.5k
Forks
772
Merge moyen
4 j 9 h
PR mergées (30 j)
17

Description

Whilst working on a project that uses `sqlparser` to parse some real SQL queries from a common PG client (PGAdmin 6.1) I found that the following query emitted by PGAdmin at startup fails to parse correctly:

```sql
SELECT
roles.oid as id, roles.rolname as name,
roles.rolsuper as is_superuser,
CASE WHEN roles.rolsuper THEN true ELSE roles.rolcreaterole END as
can_create_role,
CASE WHEN roles.rolsuper THEN true
ELSE roles.rolcreatedb END as can_create_db,
CASE WHEN 'pg_signal_backend'=ANY(ARRAY(WITH RECURSIVE cte AS (
SELECT pg_roles.oid,pg_roles.rolname FROM pg_roles
WHERE pg_roles.oid = roles.oid
UNION ALL
SELECT m.roleid,pgr.rolname FROM cte cte_1
JOIN pg_auth_members m ON m.member = cte_1.oid
JOIN pg_roles pgr ON pgr.oid = m.roleid)
SELECT rolname FROM cte)) THEN True
ELSE False END as can_signal_backend
FROM
pg_catalog.pg_roles as roles
WHERE
rolname = current_user
```

I poked around a bit and managed to reduce the failing query to:

```sql
SELECT ARRAY(SELECT 1))
```

which against PG 13 produces the following results:

```
edd=# SELECT ARRAY(SELECT 1);
array
-------
{1}
(1 row)
```

However, the following program panics:

```rust
use sqlparser;

let q = "SELECT ARRAY(SELECT 1)";
let dialect = sqlparser::dialect::PostgreSqlDialect {};
let ast = sqlparser::parser::Parser::parse_sql(&dialect, &q).unwrap();
```

with the following panic (due to an error being returned)

```
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: ParserError("Expected ), found: 1")
```

Finally, if I change the query to something that is _invalid_ in PG:

```sql
SELECT ARRAY(1);
```

then whilst this query fails against PG 13 it actually gets parsed by `sqlparser`:

```
[2022-01-06T18:38:38Z DEBUG sqlparser::parser] Parsing sql 'SELECT ARRAY(1)'...
[2022-01-06T18:38:38Z DEBUG sqlparser::parser] parsing expr
[2022-01-06T18:38:38Z DEBUG sqlparser::parser] parsing expr
[2022-01-06T18:38:38Z DEBUG sqlparser::parser] prefix: Value(Number("1", false))
[2022-01-06T18:38:38Z DEBUG sqlparser::parser] get_next_precedence() RParen
[2022-01-06T18:38:38Z DEBUG sqlparser::parser] next precedence: 0
[2022-01-06T18:38:38Z DEBUG sqlparser::parser] prefix: Function(Function { name: ObjectName([Ident { value: "ARRAY", quote_style: None }]), args: [Unnamed(Value(Number("1", false)))], over: None, distinct: false })
[2022-01-06T18:38:38Z DEBUG sqlparser::parser] get_next_precedence() EOF
[2022-01-06T18:38:38Z DEBUG sqlparser::parser] next precedence: 0
```

Guide de contribution

Aucun guide de contribution indexé pour ce dépôt

Piste de recherche

Commencez par exécuter Parser::parse_sql avec PostgreSqlDialect sur SELECT ARRAY(SELECT 1) et suivez le chemin d’analyse des expressions PostgreSQL qui gère ARRAY. Ajoutez une couverture de régression pour cette requête valide et confirmez que l’analyse réussit, tout en préservant le comportement existant pour l’exemple invalide ARRAY(1).

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
postgresql, rust, sql
Domaine
databases
Type d'issue
Bug
Difficulté
3/5
Temps estimé
1-2 jours
Activité
À l'abandon
Clarté
Plutôt claire
Accessibilité débutants
48/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.