From 31a074c7a5635f84992e2e9839802748aad54b0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alja=C5=BE=20Mur=20Er=C5=BEen?= Date: Tue, 2 Jul 2024 19:41:28 +0200 Subject: [PATCH] fix: empty relational literals Closes #4421 --- prqlc/prqlc/src/sql/gen_query.rs | 28 ++++++++++----- prqlc/prqlc/tests/integration/sql.rs | 51 +++++++++++++++++++++++++++- 2 files changed, 69 insertions(+), 10 deletions(-) diff --git a/prqlc/prqlc/src/sql/gen_query.rs b/prqlc/prqlc/src/sql/gen_query.rs index 4d13dec9fabe..2e01688b3eb5 100644 --- a/prqlc/prqlc/src/sql/gen_query.rs +++ b/prqlc/prqlc/src/sql/gen_query.rs @@ -425,6 +425,25 @@ fn translate_cte(cte: Cte, ctx: &mut Context) -> Result<(sql_ast::Cte, bool)> { fn translate_relation_literal(data: RelationLiteral, ctx: &Context) -> Result { // TODO: this could be made to use VALUES instead of SELECT UNION ALL SELECT // I'm not sure about compatibility though. + // edit: probably not, because VALUES has no way of setting names of the columns + // Postgres will just name them column1, column2 as so on. + // Which means we can use VALUES, but only if this is not the top-level statement, + // where they really matter. + + if data.rows.is_empty() { + return Ok(default_query(sql_ast::SetExpr::Select(Box::new(Select { + projection: data + .columns + .iter() + .map(|col_name| SelectItem::ExprWithAlias { + expr: sql_ast::Expr::Value(sql_ast::Value::Null), + alias: translate_ident_part(col_name.clone(), ctx), + }) + .collect(), + selection: Some(sql_ast::Expr::Value(sql_ast::Value::Boolean(false))), + ..default_select() + })))); + } let mut selects = Vec::with_capacity(data.rows.len()); @@ -444,15 +463,6 @@ fn translate_relation_literal(data: RelationLiteral, ctx: &Context) -> Result