int columns to long. Schema evolution is off by default and runs only on the periodic-watcher sync path.
Added and renamed columns have been supported since StarTree Cloud 0.16.0. Type widening is new in 0.18.0.
All API paths below are relative to your data-plane base URL. Set export BASE_URL=https://dp.<data-plane-id>.cp.<region>.startree.cloud/api/pinot.
Supported changes
How the sync handles each kind of source schema change (all rows assumeschemaEvolution.enabled=true):
When an update is rejected, the run either fails or keeps going with the old schema.
schemaEvolution.failFast decides which.
Type widening (INT → LONG)
Type widening lets the sync follow an Icebergint → long change instead of rejecting it. It’s the only supported widening, and it has its own switch, off by default.
Before StarTree Cloud 0.18.0, or with type widening off: the sync tries to update the Pinot schema, and Pinot rejects the update because the column’s data type changed. The table keeps the old INT schema. If the same update also adds columns, those are rejected too.
With type widening on: the sync updates the Pinot schema so the column is LONG, then reloads every segment of the table.
- Pinot schema. The column’s
dataTypechanges fromINTtoLONG. The column name stays the same. - Existing segments. No data is rewritten. An External Table segment reads its values from the source Parquet file, and the reader serves an old
int32file through theLONGpath. On reload, each old segment only updates its own column metadata: the data type becomesLONG, and the stored null default becomes the schema’sLONGdefault. - New segments. Segments created after the schema update are
LONGfrom the start. - Reload. The schema update starts a reload of all the table’s segments automatically. You only need to reload by hand if a segment didn’t pick up the new type (see Verify).
- When it happens. The sync compares schemas when it ingests a snapshot. The widening is picked up by the first sync of a snapshot written under the new Iceberg schema. An
ALTER TABLEon its own creates no snapshot, so the change lands after the next data commit to the Iceberg table.
Requirements
- StarTree Cloud 0.18.0 or later for type widening. Added and renamed columns need 0.16.0 or later.
- An Iceberg catalog:
catalogType=iceberg-rest. Catalogs that don’t return the Iceberg schema history skip schema evolution. - The periodic-watcher sync path:
executor=controllerandenabled=truein theExternalTableSyncTaskconfig. The snapshot path (executor=controllerwith noenabledkey, the default) never updates the schema, whatever theschemaEvolution.*keys say. schemaEvolution.enabled=true. For type widening, alsoschemaEvolution.typeWidening.enabled=true; that key has no effect on its own.
enable_schema_evolution option in CREATE EXTERNAL TABLE is accepted but has no effect. Set the task config keys below instead.
Enable or disable
All keys go intask.taskTypeConfigsMap.ExternalTableSyncTask, as strings.
With
failFast=false, the run keeps ingesting files with the old schema. With true, the run fails before it creates any segments, and the status API reports failurePhase: UPDATING_SCHEMA. Because the sync re-checks the schema on every run, every following run fails the same way until you fix the cause. failFast also covers two other schema-evolution failures: the catalog metadata can’t be loaded, or the snapshot’s schema version can’t be found.
To turn widening off, set schemaEvolution.typeWidening.enabled to false or remove it. Later widenings are then rejected. Turning it off doesn’t undo a widening that was already applied; the Pinot schema stays LONG.
To turn off all schema evolution, set schemaEvolution.enabled to false. The sync then never changes the Pinot schema.
Example: widen INT to LONG
The Iceberg tablelake.sales.orders has a column qty int. The External Table is orders_ext.
-
Turn on widening in the table config and apply it. Only the relevant keys are shown; keep the table’s other
ExternalTableSyncTaskkeys as they are. -
Check the schema before the change:
-
Widen the column in Spark SQL, then write data so a snapshot exists under the new schema:
-
The next sync logs this on the controller:
Each server logs one line per old segment as it reloads:
-
The schema now shows
LONG: -
The reload starts on its own. To run it again, for example after a server was down:
Query during a widening
During the widening. Until every segment has reloaded, old segments reportINT and new or reloaded segments report LONG. Queries that read qty from both kinds of segment can go wrong:
ORDER BY qty,GROUP BY qtyandDISTINCT qtyfail.- A plain
SELECT qty ...can drop the rows from segments on the other type and returns an exception in the response. - Aggregations such as
SUM(qty)andCOUNT(*)aren’t affected. - Queries that touch only old or only new segments aren’t affected.
LONG, and every query works as it did before. Values from old files come back as the same numbers, now typed LONG. Use LONG literals and functions in new queries.
Check that all segments reloaded. Run a query that fails while types are mixed:
LONG.
Indexes
The type update runs in the reload before any index is built. An index built during that reload reads the column asLONG. Columns that Pinot generated itself, such as derived or default-filled columns, keep their type until Pinot rebuilds them.
Verify
GET $BASE_URL/schemas/orders_extshows"dataType": "LONG"for the column.- The controller log contains
Applying source type widening for orders_ext_OFFLINE on columns [qty]followed byUpdated Pinot schema for orders_ext_OFFLINE ... forced=true. - Each server log contains
Reconciled widened column types in segment ...for the old segments. - The
GROUP BY ... ORDER BYquery in Query during a widening returns with no exceptions. - If a server logs
Failed to reconcile widened column types for segment ..., reload the table again. Nothing changes if you reload a segment that already has the new type.
Limits
- Only
int→long.float→doubleanddecimalprecision changes aren’t supported. - Only the periodic-watcher path with an Iceberg catalog. Tables on the snapshot path never update their schema from the source.
- The periodic-watcher path doesn’t import partition pruning, and it doesn’t turn on segment groups by default.
- A widening is all or nothing per schema update. If the same update also carries a change that isn’t supported (a dropped column, a single-value/multi-value flip, another type change), nothing is applied.
- The schema is built from the Iceberg schema’s columns. A column in the Pinot schema that isn’t in the Iceberg schema counts as dropped and blocks every schema update.
- The widening applies only after a snapshot is written under the new Iceberg schema. A schema-only
ALTER TABLEwith no new data changes nothing. - Queries that sort, group or deduplicate on the widened column can fail until every segment reloads.
- A widening can’t be undone from Pinot. Narrowing
LONGback toINTis rejected.

