{"record":{"id":"b644adc0b523572a","repo":"hs-web/hsweb-framework","slug":"valueslist-valueslist-must-have-alias","errorCode":null,"errorMessage":"valuesList[\" + valuesList + \"] must have alias","messagePattern":"valuesList\\[\" \\+ valuesList \\+ \"\\] must have alias","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/query/QueryAnalyzerImpl.java","lineNumber":357,"sourceCode":"    }\n\n    @Override\n    public void visit(SubJoin subjoin) {\n        for (net.sf.jsqlparser.statement.select.Join join : subjoin.getJoinList()) {\n            join.getRightItem().accept(this);\n        }\n    }\n\n    @Override\n    public void visit(LateralSubSelect lateralSubSelect) {\n        this.visit(lateralSubSelect.getSubSelect(),\n                   lateralSubSelect.getAlias() == null ? null : lateralSubSelect.getAlias().getName());\n    }\n\n    @Override\n    public void visit(ValuesList valuesList) {\n        if (valuesList.getAlias() == null) {\n            throw new IllegalArgumentException(\"valuesList[\" + valuesList + \"] must have alias\");\n        }\n        String name = parsePlainName(valuesList.getAlias().getName());\n        FakeTable view = new FakeTable();\n        view.setSchema(database.getMetadata().getCurrentSchema());\n        if (valuesList.getColumnNames() != null) {\n            //获取会自动创建列\n            for (String columnName : valuesList.getColumnNames()) {\n                RDBColumnMetadata ignore = view.getColumn(parsePlainName(columnName)).orElse(null);\n            }\n        }\n\n        if (valuesList.getAlias().getAliasColumns() != null) {\n            for (Alias.AliasColumn alias : valuesList.getAlias().getAliasColumns()) {\n                RDBColumnMetadata ignore = view.getColumn(parsePlainName(alias.name)).orElse(null);\n            }\n        }\n\n        view.setName(name);","sourceCodeStart":339,"sourceCodeEnd":375,"githubUrl":"https://github.com/hs-web/hsweb-framework/blob/b2cfc85a57c70bf5b5cf6e7edae2d37102652ec8/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/query/QueryAnalyzerImpl.java#L339-L375","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Add an alias to the VALUES table in the SQL: FROM (VALUES (1),(2)) AS t(name).","When building ValuesList programmatically, call setAlias before analysis.","Catch IllegalArgumentException and report the malformed SQL to the caller/author.","Add SQL lint/tests for ad-hoc VALUES queries before runtime."],"exampleFix":"// before\nSELECT * FROM (VALUES (1),(2));\n\n// after\nSELECT * FROM (VALUES (1),(2)) AS v(num);","handlingStrategy":"validation","validationCode":"// Java\nif (valuesList.getAlias() == null) {\n    valuesList.setAlias(new Alias(\"v\")); // or reject the query early\n}","typeGuard":null,"tryCatchPattern":"// Java\ntry {\n    analyzer.analyze(sql);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"must have alias\")) {\n        throw new MalformedSqlException(\"VALUES table requires an alias\", sql);\n    }\n    throw e;\n}","preventionTips":["Always alias derived tables, including VALUES lists, in generated SQL.","Lint hand-written SQL for unaliased subqueries before runtime.","When building JSqlParser AST nodes programmatically, set aliases immediately after construction."],"tags":["java","sql","values","alias","illegal-argument"],"backgroundTag":"missing-required-argument","analyzedSha":"b2cfc85a57c70bf5b5cf6e7edae2d37102652ec8","analyzedAt":"2026-09-13T09:05:02.172Z","contentChangedAt":"2026-09-13T09:05:02.172Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}