{"record":{"id":"bcde2292d756af10","repo":"apache/seatunnel","slug":"source-table-must-be-specified-in-sql-insertsql","errorCode":null,"errorMessage":"Source table must be specified in SQL: <insertSql>","messagePattern":"Source table must be specified in SQL: <insertSql>","errorType":"exception","errorClass":"ParserException","httpStatus":null,"severity":"error","filePath":"seatunnel-config/seatunnel-config-sql/src/main/java/org/apache/seatunnel/config/sql/SqlConfigBuilder.java","lineNumber":382,"sourceCode":"            throw new ParserException(\"Insert sql must not have columns\");\n        }\n        TransformConfig transformConfig = new TransformConfig();\n        Select select = insertSql.getSelect();\n        if (select == null\n                || select.getSelectBody() == null\n                || !(select.getSelectBody() instanceof PlainSelect)) {\n            throw new ParserException(\"Insert sql must have select statement\");\n        }\n        String targetTableName = insertSql.getTable().getName();\n        if (select.getSelectBody() instanceof PlainSelect) {\n            PlainSelect plainSelect = (PlainSelect) select.getSelectBody();\n\n            String pluginInputIdentifier;\n            String pluginOutputIdentifier;\n            if (plainSelect.getFromItem() == null) {\n                List<SelectItem<?>> selectItems = plainSelect.getSelectItems();\n                if (selectItems.size() != 1) {\n                    throw new ParserException(\n                            \"Source table must be specified in SQL: \" + insertSql);\n                }\n                SelectItem<?> selectItem = selectItems.get(0);\n                Column column = (Column) selectItem.getExpression();\n                pluginInputIdentifier = column.getColumnName();\n                pluginOutputIdentifier = pluginInputIdentifier;\n            } else {\n                if (!(plainSelect.getFromItem() instanceof Table)) {\n                    throw new ParserException(\"Unsupported syntax: \" + insertSql);\n                }\n                Table table = (Table) plainSelect.getFromItem();\n                pluginInputIdentifier = table.getName();\n                pluginOutputIdentifier =\n                        pluginInputIdentifier\n                                + TEMP_TABLE_SUFFIX\n                                + tempTableIndex.getAndIncrement();\n                String query = select.toString();\n                transformConfig.setPluginInputIdentifier(pluginInputIdentifier);","sourceCodeStart":364,"sourceCodeEnd":400,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-config/seatunnel-config-sql/src/main/java/org/apache/seatunnel/config/sql/SqlConfigBuilder.java#L364-L400","documentation":"Thrown by parseInsertSql when a SELECT without a FROM clause does not consist of exactly one select item. The dialect supports 'INSERT INTO sink SELECT column_name' (bare table-name-as-column shorthand) but only with a single expression, and it must be a Column.","triggerScenarios":"INSERT INTO sink_t SELECT 1 (no FROM and multiple/complex expressions); INSERT ... SELECT a, b with no FROM; a non-column expression like a function call in the no-FROM form.","commonSituations":"Trying constant-only inserts (SELECT 1,'x') without a FROM; adding extra literals alongside the source-table shorthand.","solutions":["Add 'FROM source_table' and move constants/literals into the SELECT projection","When using the no-FROM shorthand, keep exactly one select item that is the source table name","Split constant generation into a dedicated source table instead"],"exampleFix":"// before\nINSERT INTO sink_t SELECT 1, 'a'\n// after\nINSERT INTO sink_t SELECT 1, 'a' FROM fake_source","handlingStrategy":"validation","validationCode":"// for FROM-less SELECT in INSERT, require exactly one column item\nPattern p = Pattern.compile(\"(?si)INSERT\\\\s+INTO\\\\s+\\\\w+\\\\s+SELECT\\\\s+([^\\\\s;]+)\\\\s*;\");\n// if SELECT has no FROM, ensure it has a single plain column reference","typeGuard":null,"tryCatchPattern":"try {\n    SeaTunnelConfig c = SqlConfigBuilder.of(sql);\n} catch (ParserException e) {\n    if (e.getMessage().startsWith(\"Source table must be specified\")) {\n        // add 'FROM source_table' to the INSERT SELECT\n    }\n}","preventionTips":["Always include FROM in INSERT SELECT queries; use the bare-table-name shorthand only for single-column passthrough","Never mix literals with the no-FROM shorthand","Prefer explicit source tables over FROM-less expressions"],"tags":["sql","parser","insert","invalid-syntax"],"backgroundTag":"invalid-argument-format","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}