apache/shardingsphere · error · UnsupportedSQLOperationException

Can not use different encryptor for %s and %s in %s

Error message

Can not use different encryptor for %s and %s in %s

What it means

checkEncryptorIsSame in SubqueryNestedInBinaryOperationEncryptorChecker requires that two compared columns (e.g. a row-expression column from the outer query and a projection column from a nested subquery) use equivalent encryptor configurations. EncryptorComparator.isEquivalentFilterSame returning false throws UnsupportedSQLOperationException naming both ColumnSegmentBoundInfos and the scenario.

Source

Thrown at features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/checker/cryptographic/SubqueryNestedInBinaryOperationEncryptorChecker.java:143

        return projection instanceof ColumnProjectionSegment
                ? ((ColumnProjectionSegment) projection).getColumn().getColumnBoundInfo()
                : new ColumnSegmentBoundInfo(new IdentifierValue(projection.getColumnLabel()));
    }
    
    private static boolean isNotColumnAndSubquery(final ExpressionSegment expression) {
        return !(expression instanceof ColumnSegment) && !(expression instanceof RowExpression) && !isSubquerySegment(expression);
    }
    
    private static boolean isSubquerySegment(final ExpressionSegment expression) {
        return expression instanceof SubqueryExpressionSegment || expression instanceof SubquerySegment || expression instanceof QuantifySubqueryExpression;
    }
    
    private static void checkEncryptorIsSame(final ColumnSegmentBoundInfo leftColumnInfo, final ColumnSegmentBoundInfo rightColumnInfo, final EncryptRule encryptRule, final String scenario) {
        if (EncryptorComparator.isEquivalentFilterSame(encryptRule, leftColumnInfo, rightColumnInfo)) {
            return;
        }
        String reason = "Can not use different encryptor for " + leftColumnInfo + " and " + rightColumnInfo + " in " + scenario;
        throw new UnsupportedSQLOperationException(reason);
    }
}

View on GitHub (pinned to e952770a21)

Solutions

  1. Align the encryptor type, key and assisted/like-query configuration for both compared columns in encrypt rules
  2. Make both sides plain (unencrypted) if encryption is not required for the comparison
  3. Restructure the SQL to compare in application code instead of across mismatched encrypted columns
  4. After aligning, verify with a simple equality query before re-running the original row/subquery SQL

Example fix

# before
tables:
  t1: {columns: {a: {encryptor: {name: AES, props: {aes-key-value: k1}}}}}
  t2: {columns: {b: {encryptor: {name: AES, props: {aes-key-value: k2}}}}}
# after (same key for compared columns)
  t2: {columns: {b: {encryptor: {name: AES, props: {aes-key-value: k1}}}}}
Defensive patterns

Strategy: validation

Validate before calling

void checkPair(RuleColumn a, RuleColumn b) { if (!a.encryptorType.equals(b.encryptorType) || !Objects.equals(a.key, b.key)) throw new ConfigException("encryptors differ: " + a + " vs " + b); }

Try / catch

catch (UnsupportedSQLOperationException e) { if (e.getMessage().startsWith("Can not use different encryptor")) { /* fix rule config, no retry until aligned */ } }

Prevention

When it happens

Trigger: SQL such as WHERE (t1.col_a) = (SELECT t2.col_b ...) where col_a uses one encrypt algorithm/key and col_b uses a different one (or one is encrypted and the other is not, or assisted-query configurations differ), on a rule set that enables this checker.

Common situations: Columns with the same name in different tables configured with different encryptors; key rotation applied to one table only; adding encryption to one side of an existing join/subquery comparison; differing assisted-query (like-query) setups between the pair.

Related errors


AI-assisted analysis of apache/shardingsphere@e952770a21 (2026-08-14). Data as JSON: /api/errors/1feb33cf427f4f48. Report an issue: GitHub.