apache/seatunnel · error · RuntimeException

Failed to parse select columns:

Error message

Failed to parse select columns: 

What it means

ExpressionUtils.parseSelectColumns() parses a SELECT SQL string with JSQLParser to extract select items. If the SQL cannot be parsed (JSQLParserException), it wraps it in a RuntimeException with this message. Typically this is used for delete-SQL conversion, so a malformed query breaks expression translation.

Source

Thrown at seatunnel-connectors-v2/connector-iceberg/src/main/java/org/apache/seatunnel/connectors/seatunnel/iceberg/utils/ExpressionUtils.java:87

            new DateTimeFormatterBuilder()
                    .parseCaseInsensitive()
                    .append(ISO_LOCAL_DATE)
                    .appendLiteral(' ')
                    .append(ISO_LOCAL_TIME)
                    .toFormatter();

    public static List<String> parseSelectColumns(String selectQuery) {
        if (StringUtils.isNotBlank(selectQuery)) {
            try {
                Statement statement = CCJSqlParserUtil.parse(selectQuery);
                PlainSelect select = (PlainSelect) statement;
                if (CollectionUtils.isNotEmpty(select.getSelectItems())) {
                    return select.getSelectItems().stream()
                            .map(selectItem -> selectItem.toString())
                            .collect(Collectors.toList());
                }
            } catch (JSQLParserException e) {
                throw new RuntimeException("Failed to parse select columns: " + e.getMessage());
            }
        }
        return new ArrayList<>();
    }

    public static Expression parseWhereClauseToIcebergExpression(String selectQuery)
            throws JSQLParserException {
        // use the JsqlParser to parse the where clause
        Statement statement = CCJSqlParserUtil.parse(selectQuery);
        PlainSelect select = (PlainSelect) statement;
        return convert(select.getWhere(), null);
    }

    public static Expression convertDeleteSQL(String sql) throws JSQLParserException {
        Statement statement = CCJSqlParserUtil.parse(sql);
        Delete delete = (Delete) statement;
        return convert(delete.getWhere(), null);
    }

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Print the wrapped cause (e.getMessage() already includes JSQLParser's error) and fix the SQL syntax
  2. Simplify the query — remove dialect-specific syntax (e.g. functions, comments) that JSQLParser doesn't support
  3. Ensure a valid SELECT statement is passed (SELECT cols FROM table), not a bare column list or WHERE clause
  4. Check the JSQLParser version bundled with the connector supports your SQL constructs; upgrade if needed

Example fix

// before
parseSelectColumns("FROM my_table")
// after
parseSelectColumns("SELECT * FROM my_table")
Defensive patterns

Strategy: validation

Validate before calling

// Basic sanity check before invoking the parser
if (sql == null || !sql.trim().toLowerCase().startsWith("select")) throw new IllegalArgumentException("expected a SELECT statement");

Try / catch

try { cols = parseSelectColumns(sql); } catch (RuntimeException e) { if (e.getMessage().startsWith("Failed to parse select columns")) { /* fix SQL, log e.getMessage() for parser detail */ } throw e; }

Prevention

When it happens

Trigger: Passing SQL that JSQLParser cannot parse into parseSelectColumns — syntax errors, unsupported SQL dialect constructs, missing clauses, or non-SELECT statements.

Common situations: Hand-written delete/select queries with typos; dialect-specific SQL (backticks, functions) unsupported by the bundled JSQLParser version; passing a table name or WHERE-only fragment instead of a full SELECT.

Understand the failure class

Background: "query failed", "%w: SQL error" — wrapped database query errors in Go libraries explained — this error's family across 3 libraries.

Related errors


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/bc0f00c47daf23e1. Report an issue: GitHub.