Class SchemaReconciliation

java.lang.Object
org.elasticsearch.xpack.esql.datasources.SchemaReconciliation

public final class SchemaReconciliation extends Object
Schema reconciliation algorithms for multi-file external sources.

Supports three strategies:

  • FIRST_FILE_WINS — use the first file's schema (existing behavior, no reconciliation)
  • STRICT — validate all files share the exact same schema
  • UNION_BY_NAME — merge schemas by column name with safe type widening

Type widening is intentionally conservative: only lossless promotions are allowed. This is NOT EsqlDataTypeConverter.commonType(), which allows LONG→DOUBLE (lossy above 2^53).

  • Method Details

    • schemaWiden

      @Nullable public static DataType schemaWiden(DataType a, DataType b)
      Safe type widening for schema reconciliation. Only lossless promotions are allowed; returns null if no safe supertype exists.

      Widening rules:

      • INTEGER + LONG → LONG (lossless: int32 ⊆ int64)
      • INTEGER + DOUBLE → DOUBLE (lossless: int32 ≤ 2^31 < 2^53)
      • DATETIME + DATE_NANOS → DATE_NANOS (more precise type wins)
      All other cross-type pairs return null (incompatible).
      Returns:
      the widened type, or null if no safe supertype exists
    • reconcileStrict

      public static SchemaReconciliation.Result reconcileStrict(StoragePath referenceFile, Map<StoragePath,SourceMetadata> fileMetadata)
      STRICT reconciliation: validate all files share the exact same schema. Nullability differences are tolerated; all other differences produce an error.
      Parameters:
      referenceFile - path of the first (reference) file
      fileMetadata - ordered map of file path → metadata (first entry is the reference)
      Returns:
      reconciliation result with the reference schema and per-file info
      Throws:
      IllegalArgumentException - if any file's schema doesn't match
    • reconcileUnionByName

      public static SchemaReconciliation.Result reconcileUnionByName(Map<StoragePath,SourceMetadata> fileMetadata)
      UNION_BY_NAME reconciliation: merge schemas from all files into a superset. Missing columns are NULL-filled; type differences are resolved by safe widening.
      Parameters:
      fileMetadata - ordered map of file path → metadata (insertion order = file sort order)
      Returns:
      reconciliation result with unified schema and per-file mappings
      Throws:
      IllegalArgumentException - if types are incompatible