MyCATApache/Mycat-Server · error · java.lang.UnsupportedOperationException

unsupport

Error message

unsupport ${bindValue.value}

What it means

ServerPrepareHandler.visit performs server-side parameter substitution for prepared statements. When a bind value's type is not supported for in-place SQL replacement (the code only handles String values via SQLCharExpr before falling back to SQLExprUtils.fromJavaObject), it throws UnsupportedOperationException naming the unsupported bind value.

Solutions

  1. Convert the parameter to a supported type (e.g. String) on the client, or cast it in SQL.
  2. Use text protocol (non-prepared) execution instead of COM_STMT_EXECUTE if the driver allows it.
  3. Patch ServerPrepareHandler.visit to handle the specific value type via SQLExprUtils.fromJavaObject.
  4. Upgrade Mycat to a version with broader prepared-statement type support.

Example fix

// before
ps.setObject(1, new byte[]{1,2});
// after
ps.setString(1, new String(new byte[]{1,2}));
Defensive patterns

Strategy: try-catch

Validate before calling

// check bind value types before prepare/execute
for (Object v : bindValues) {
    if (!(v instanceof String || v instanceof Number || v instanceof java.util.Date || v == null))
        throw new IllegalArgumentException("unsupported bind type: " + v.getClass());
}

Type guard

// java
static boolean isSupportedBindValue(Object v) {
    return v == null || v instanceof String || v instanceof Number || v instanceof Boolean || v instanceof java.util.Date || v instanceof byte[];
}

Try / catch

try { executePrepared(stmt, bindValues); } catch (UnsupportedOperationException e) { log.warn("unsupported bind value, falling back to text protocol", e); executeTextProtocol(sql, bindValues); }

Prevention

When it happens

Trigger: Using COM_STMT_EXECUTE / prepared-statement execution where the bound parameter value is of a Java type the visitor cannot convert into a SQL expression (e.g. unusual object types from client bind payloads).

Common situations: Drivers sending non-standard bind types; Mycat's prepare handler lacking support for a type supported by real MySQL; passing byte arrays or temporal types through the prepared-statement path.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.


AI-assisted analysis of MyCATApache/Mycat-Server@65f8d8beb7 (2026-09-11). Data as JSON: /api/errors/9d163628ff6faff8. Report an issue: GitHub.

Appendix: source

Thrown at src/main/java/io/mycat/server/handler/ServerPrepareHandler.java:284

                        case Fields.FIELD_TYPE_DATE:
                        case Fields.FIELD_TYPE_DATETIME:
                        case Fields.FIELD_TYPE_TIMESTAMP:
                            o = bindValue.value;
                            break;
                        default:
                            if (bindValue.value instanceof byte[]) {
                                SQLReplaceable parent = (SQLReplaceable) x.getParent();
                                byte[] bytes = (byte[]) bindValue.value;
                                parent.replace(x, new SQLCharExpr(new String(bytes)));
                                return false;
                            }
                            if (bindValue.value instanceof String) {
                                SQLReplaceable parent = (SQLReplaceable) x.getParent();
                                String value = (String) bindValue.value;
                                parent.replace(x, new SQLCharExpr(value));
                                return false;
                            }
                            throw new UnsupportedOperationException("unsupport " + bindValue.value);
                    }

                    SQLReplaceable parent = (SQLReplaceable) x.getParent();
                    parent.replace(x, SQLExprUtils.fromJavaObject(o));
                    return false;
                }
            }

        });
        return sqlStatement.toString();
    }
}

View on GitHub (pinned to 65f8d8beb7)