apache/seatunnel · error · IotdbConnectorException

CommonErrorCodeDeprecated.ILLEGAL_ARGUMENT

CommonErrorCodeDeprecated.ILLEGAL_ARGUMENT

Error message

sql should not contain more than one where

What it means

The IoTDB split enumerator splits the user's query SQL on the WHERE keyword to generate per-split range queries. If the SQL contains more than one WHERE clause than the expected count, the split logic cannot safely rewrite it, so it throws IotdbConnectorException(ILLEGAL_ARGUMENT).

Source

Thrown at seatunnel-connectors-v2/connector-iotdb/src/main/java/org/apache/seatunnel/connectors/seatunnel/iotdb/source/IoTDBSourceSplitEnumerator.java:144

        // no need numPartitions, use one partition
        if (!conf.getOptional(NUM_PARTITIONS).isPresent()) {
            iotDBSourceSplits.add(new IoTDBSourceSplit(DEFAULT_PARTITIONS, sql));
            return iotDBSourceSplits;
        }
        long start = conf.get(LOWER_BOUND);
        long end = conf.get(UPPER_BOUND);
        int numPartitions = conf.get(NUM_PARTITIONS);
        String sqlBase = sql;
        String sqlAlign = null;
        String sqlCondition = null;
        String[] sqls = sqlBase.split("(?i)" + SQL_ALIGN);
        if (sqls.length > 1) {
            sqlBase = sqls[0];
            sqlAlign = sqls[1];
        }
        sqls = sqlBase.split("(?i)" + SQL_WHERE);
        if (sqls.length > SQL_WHERE_SPLIT_LENGTH) {
            throw new IotdbConnectorException(
                    CommonErrorCodeDeprecated.ILLEGAL_ARGUMENT,
                    "sql should not contain more than one where");
        }
        if (sqls.length > 1) {
            sqlBase = sqls[0];
            sqlCondition = sqls[1];
        }
        long size = (end - start) / numPartitions + 1;
        long remainder = (end + 1 - start) % numPartitions;
        if (end - start < numPartitions) {
            numPartitions = (int) (end - start);
        }
        long currentStart = start;
        int i = 0;
        while (i < numPartitions) {
            String query =
                    " where ("
                            + RESERVED_TIME

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Rewrite the query to use at most one top-level WHERE clause; move extra conditions into the single WHERE with AND/OR.
  2. Avoid subqueries with their own WHERE in the configured SQL.
  3. Escape or reword string literals containing the word WHERE.
  4. Use the query's base table directly and express filtering in one WHERE block.

Example fix

// before
query = "select * from root.sg.d1 where a > 1; select * from root.sg.d2 where b < 2"
// after
query = "select * from root.sg.d1 where a > 1"
Defensive patterns

Strategy: validation

Validate before calling

String sql = config.query(); int whereCount = sql.split("(?i)\\bWHERE\\b").length - 1; if (whereCount > 1) throw new IllegalArgumentException("query may contain at most one WHERE clause");

Try / catch

catch (IotdbConnectorException e) { if (e.getErrorCode() == CommonErrorCodeDeprecated.ILLEGAL_ARGUMENT) { /* fix configured query SQL */ } }

Prevention

When it happens

Trigger: getIotDBSplit() (via newSplits()) splits the configured query SQL on case-insensitive ' WHERE ' and finds more segments than SQL_WHERE_SPLIT_LENGTH allows — e.g. a query containing two WHERE keywords (nested/subquery or one inside a string literal).

Common situations: Users write complex align-by queries with subqueries containing WHERE; a WHERE keyword appears inside quoted string values or comments; copy-pasted SQL with duplicated conditions.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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