hs-web/hsweb-framework · error · IllegalArgumentException

valuesList[" + valuesList + "] must have alias

Error message

valuesList[" + valuesList + "] must have alias

What it means

When the analyzer walks a VALUES list (JSqlParser ValuesList), the values table must have an alias because it becomes a derived table in the query. If getAlias() is null, QueryAnalyzerImpl throws this IllegalArgumentException since it cannot derive a table name for the fake table.

Solutions

  1. Add an alias to the VALUES table in the SQL: FROM (VALUES (1),(2)) AS t(name).
  2. When building ValuesList programmatically, call setAlias before analysis.
  3. Catch IllegalArgumentException and report the malformed SQL to the caller/author.
  4. Add SQL lint/tests for ad-hoc VALUES queries before runtime.

Example fix

// before
SELECT * FROM (VALUES (1),(2));

// after
SELECT * FROM (VALUES (1),(2)) AS v(num);
Defensive patterns

Strategy: validation

Validate before calling

// Java
if (valuesList.getAlias() == null) {
    valuesList.setAlias(new Alias("v")); // or reject the query early
}

Try / catch

// Java
try {
    analyzer.analyze(sql);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("must have alias")) {
        throw new MalformedSqlException("VALUES table requires an alias", sql);
    }
    throw e;
}

Prevention

When it happens

Trigger: Parsing/analyzing SQL like SELECT * FROM (VALUES (1),(2)) without an alias, or VALUES lists built programmatically without setting an alias before handing them to the analyzer.

Common situations: Hand-written inline VALUES table SQL missing the AS name; SQL generator building ValuesList AST nodes and forgetting the alias; queries copied from databases that allow unaliased VALUES but the analyzer (and standard SQL) requires one.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of hs-web/hsweb-framework@b2cfc85a57 (2026-09-13). Data as JSON: /api/errors/b644adc0b523572a. Report an issue: GitHub.

Appendix: source

Thrown at hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/query/QueryAnalyzerImpl.java:357

    }

    @Override
    public void visit(SubJoin subjoin) {
        for (net.sf.jsqlparser.statement.select.Join join : subjoin.getJoinList()) {
            join.getRightItem().accept(this);
        }
    }

    @Override
    public void visit(LateralSubSelect lateralSubSelect) {
        this.visit(lateralSubSelect.getSubSelect(),
                   lateralSubSelect.getAlias() == null ? null : lateralSubSelect.getAlias().getName());
    }

    @Override
    public void visit(ValuesList valuesList) {
        if (valuesList.getAlias() == null) {
            throw new IllegalArgumentException("valuesList[" + valuesList + "] must have alias");
        }
        String name = parsePlainName(valuesList.getAlias().getName());
        FakeTable view = new FakeTable();
        view.setSchema(database.getMetadata().getCurrentSchema());
        if (valuesList.getColumnNames() != null) {
            //获取会自动创建列
            for (String columnName : valuesList.getColumnNames()) {
                RDBColumnMetadata ignore = view.getColumn(parsePlainName(columnName)).orElse(null);
            }
        }

        if (valuesList.getAlias().getAliasColumns() != null) {
            for (Alias.AliasColumn alias : valuesList.getAlias().getAliasColumns()) {
                RDBColumnMetadata ignore = view.getColumn(parsePlainName(alias.name)).orElse(null);
            }
        }

        view.setName(name);

View on GitHub (pinned to b2cfc85a57)