prestodb/presto · error · SemanticException

WILDCARD_WITHOUT_FROM

WILDCARD_WITHOUT_FROM

Error message

SELECT * not allowed in queries without FROM clause

What it means

A bare SELECT * is only valid when the query has a FROM clause providing columns to expand. If the analyzer sees SELECT * with no prefix and the statement has no FROM clause, it throws WILDCARD_WITHOUT_FROM because there is no relation whose columns the star could represent. Without FROM there is also no implicit single-row relation to select from in this position.

Source

Thrown at presto-main-base/src/main/java/com/facebook/presto/sql/analyzer/StatementAnalyzer.java:4653

        }

        private List<Expression> analyzeSelect(QuerySpecification node, Scope scope)
        {
            ImmutableList.Builder<Expression> outputExpressionBuilder = ImmutableList.builder();

            for (SelectItem item : node.getSelect().getSelectItems()) {
                if (item instanceof AllColumns) {
                    // expand * and T.*
                    Optional<QualifiedName> starPrefix = ((AllColumns) item).getPrefix();

                    RelationType relationType = scope.getRelationType();
                    List<Field> fields = relationType.resolveFieldsWithPrefix(starPrefix);
                    if (fields.isEmpty()) {
                        if (starPrefix.isPresent()) {
                            throw new SemanticException(MISSING_TABLE, item, "Table '%s' not found", starPrefix.get());
                        }
                        if (!node.getFrom().isPresent()) {
                            throw new SemanticException(WILDCARD_WITHOUT_FROM, item, "SELECT * not allowed in queries without FROM clause");
                        }
                        throw new SemanticException(COLUMN_NAME_NOT_SPECIFIED, item, "SELECT * not allowed from relation that has no columns");
                    }

                    for (Field field : fields) {
                        int fieldIndex = relationType.indexOf(field);
                        FieldReference expression = new FieldReference(field.getNodeLocation(), fieldIndex);
                        outputExpressionBuilder.add(expression);
                        ExpressionAnalysis expressionAnalysis = analyzeExpression(expression, scope);

                        Type type = expressionAnalysis.getType(expression);
                        if (node.getSelect().isDistinct() && !type.isComparable()) {
                            throw new SemanticException(TYPE_MISMATCH, node.getSelect(), "DISTINCT can only be applied to comparable types (actual: %s)", type);
                        }
                    }
                }
                else if (item instanceof SingleColumn) {
                    SingleColumn column = (SingleColumn) item;

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Add a FROM clause, or replace the star with the explicit expressions/literals you actually want.
  2. If you just need a literal row, write SELECT 1 AS x instead of SELECT *.
  3. If generated, make the query builder emit SELECT * only when a FROM relation exists.

Example fix

// before
SELECT *;
// after
SELECT 1 AS one; -- or add: FROM my_table
Defensive patterns

Strategy: validation

Validate before calling

if (hasSelectStar(sql) && !hasFromClause(sql)) {
    throw new IllegalArgumentException("SELECT * requires a FROM clause");
}

Try / catch

try { execute(sql); } catch (SemanticException e) { if (e.getCode() == WILDCARD_WITHOUT_FROM) { /* add FROM or replace * with explicit expressions */ } else { throw e; } }

Prevention

When it happens

Trigger: Queries like SELECT *; or SELECT * with only expressions/literals and no FROM clause; generated SQL dropping the FROM clause; SELECT * inside a VALUES-only or tableless context.

Common situations: Programmatic query builders emitting star-selects without FROM; users expecting a dummy-table (Oracle DUAL) style query; template rendering that omits FROM when empty.

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/cab15326e093a29e. Report an issue: GitHub.