hs-web/hsweb-framework · error · IllegalArgumentException

table function[" + tableFunction + "] must have alias

Error message

table function[" + tableFunction + "] must have alias

What it means

QueryAnalyzerImpl visits a JSqlParser TableFunction in the FROM clause and requires it to carry an alias, because the analyzer resolves every result column to an owner alias. A table function has no real table name, so without an alias there is no stable identifier to bind columns against, and the analyzer fails fast with IllegalArgumentException.

Solutions

  1. Add an alias to the table function in the SQL: `FROM generate_series(1,10) AS gs`.
  2. If the SQL is generated by your code, append the alias programmatically before calling the analyzer.
  3. If you do not actually need a table function, replace it with a plain table or a CTE (WITH ...) that is already aliased.

Example fix

// before
String dql = "select * from generate_series(1,3)";
// after
String dql = "select * from generate_series(1,3) as gs";
Defensive patterns

Strategy: validation

Validate before calling

if (sql.toLowerCase().matches(".*\\bfrom\\s+[a-z_0-9]+\\s*\\(.*") && !sql.toLowerCase().matches(".*\\bfrom\\s+[a-z_0-9]+\\s*\\([^)]*\\)\\s+(as\\s+)?[a-z_][a-z_0-9]*.*")) { throw new IllegalArgumentException("table function in FROM must have an alias"); }

Prevention

When it happens

Trigger: Executing a dynamic query (e.g. via QueryHelper/dql) whose FROM clause contains a table function such as `generate_series(...)`, `unnest(...)`, or a custom table-valued function without `AS alias`, causing visit(TableFunction) to throw.

Common situations: Hand-written dynamic SQL snippets that work in a raw psql/MySQL console (where aliasing is optional) are fed into the hsweb query analyzer; users porting SQL from other frameworks forget the mandatory alias rule.

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/1b97baab7b3eb12c. Report an issue: GitHub.

Appendix: source

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

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

        view.setName(name);
        view.setRealName(name);
        view.setSchema(database.getMetadata().getCurrentSchema());
        view.setAlias(name);

        Table table = new Table(name, view);

        select = new QueryAnalyzer.Select(new ArrayList<>(), table);
    }

    @Override
    public void visit(TableFunction tableFunction) {
        if (tableFunction.getAlias() == null) {
            throw new IllegalArgumentException("table function[" + tableFunction + "] must have alias");
        }
        String name = parsePlainName(tableFunction.getAlias().getName());

        FakeTable view = new FakeTable();

        view.setName(name);
        view.setSchema(database.getMetadata().getCurrentSchema());
        view.setAlias(name);

        Table table = new Table(name, view);

        select = new QueryAnalyzer.Select(new ArrayList<>(), table);

    }

    @Override
    public void visit(ParenthesisFromItem aThis) {
        aThis.getFromItem().accept(this);

View on GitHub (pinned to b2cfc85a57)