diff --git a/core/translate/select.rs b/core/translate/select.rs index 4e67f4659..50dd6ddf9 100644 --- a/core/translate/select.rs +++ b/core/translate/select.rs @@ -206,6 +206,14 @@ fn prepare_one_select_plan( let mut table_references = TableReferences::new(vec![], outer_query_refs.to_vec()); + if from.is_none() { + for column in &columns { + if matches!(column, ResultColumn::Star) { + crate::bail_parse_error!("no tables specified"); + } + } + } + // Parse the FROM clause into a vec of TableReferences. Fold all the join conditions expressions into the WHERE clause. parse_from( schema, diff --git a/testing/select.test b/testing/select.test index d3142be3e..6471254e3 100755 --- a/testing/select.test +++ b/testing/select.test @@ -285,6 +285,18 @@ do_execsql_test_on_specific_db {:memory:} select-union-all-with-filters { 6 10} +do_execsql_test_error select-star-no-from { + SELECT *; +} {no tables specified} + +do_execsql_test_error select-star-and-constant-no-from { + SELECT *, 1; +} {no tables specified} + +do_execsql_test_error select-star-subquery { + SELECT 1 FROM (SELECT *); +} {no tables specified} + if {[info exists ::env(SQLITE_EXEC)] && ($::env(SQLITE_EXEC) eq "scripts/limbo-sqlite3-index-experimental" || $::env(SQLITE_EXEC) eq "sqlite3")} { do_execsql_test_on_specific_db {:memory:} select-union-1 { CREATE TABLE t(x TEXT, y TEXT);