Docs & Rules

apache/pinotGitHubLast refreshed Oct 3, 2026

This is a public, read-only report. Striff reads this repository's docs, turns each sentence that makes a claim about the code into a rule, and checks the rule against the code on the default branch. How this works

master4e27013listed 1h ago

Is this yours? Install to manage it

Once installed, Striff checks every pull request.

39
10
10
3
3
3
3
26
24
2
25 docs, listed Oct 3
apache/pinotOpen repository

apache/pinot — documented rules

39 of 39 rules, printed October 3, 2026.

The sentence in your docs
Read Oct 3
user-supplied SQL, source-table reference, source partition expressions, rewriteEnabled, stalenessThresholdMs.
MaterializedViewDefinitionMetadata has rewriteEnabled
Holds
Read Oct 3
user-supplied SQL, source-table reference, source partition expressions, rewriteEnabled, stalenessThresholdMs.
MaterializedViewDefinitionMetadata has stalenessThresholdMs
Holds
Read Oct 3
watermarkMs plus a Map<Long, PartitionInfo> keyed by bucketStartMs.
MaterializedViewRuntimeMetadata has watermarkMs
Holds
Read Oct 3
The public entry point onBaseTableFullInvalidation(rawTableName) exists today (PR 1 shipped it for the time-MV "unknown range" case);
MaterializedViewConsistencyManager has an onBaseTableFullInvalidation method
Holds
Read Oct 3
Interface MaterializedViewRuntimeMetadata, State today _partitions Map<Long, PartitionInfo>, Action needed when fixed-MV lands Generalize to Map<PartitionKey, PartitionInfo> (or Map<String, …> with a separate PartitionKind )
MaterializedViewRuntimeMetadata has _partitions
Holds
Read Oct 3
State today _watermarkMs long, Action needed when fixed-MV lands Make optional populated only for TIME
MaterializedViewRuntimeMetadata has _watermarkMs
Holds
Read Oct 3
Interface MaterializedViewAnalyzer.validateSourceTable, State today Time-MV only, Action needed when fixed-MV lands Sibling validator for CATEGORICAL require partition column existence and (optional) frozen key list
MaterializedViewAnalyzer has validateSourceTable
Holds
Read Oct 3
Interface MaterializedViewAnalyzer.validateTaskConfigs, State today Hard-requires bucketTimePeriod, Action needed when fixed-MV lands Make required-on- TIME optional / absent on CATEGORICAL
MaterializedViewAnalyzer has validateTaskConfigs
Holds
Read Oct 3
Interface MaterializedViewTaskScheduler.generateTasks, State today Watermark + APPEND, Action needed when fixed-MV lands Branch on partitionKind CATEGORICAL goes through FIFO-STALE + refresh-interval logic
MaterializedViewTaskScheduler has generateTasks
Holds
Read Oct 3
Interface MaterializedViewTaskExecutor.executeTask, State today Window-based, Action needed when fixed-MV lands Branch on task-config partitionKey shape segment building is unchanged
MaterializedViewTaskExecutor has executeTask
Holds
Read Oct 3
JSONMessageDecoder — a StreamMessageDecoder for real-time (streaming) ingestion.
JSONMessageDecoder implements StreamMessageDecoder
Holds
Read Oct 3
JSONRecordReader — a RecordReader for batch ingestion of newline-delimited JSON files.
JSONRecordReader implements RecordReader
Holds
Read Oct 3
JSONRecordExtractor — the shared extractor that turns a parsed JSON object into a Pinot GenericRow.
JSONRecordExtractor depends on GenericRow
Holds
Read Oct 3
DdlCompiler.compile(String sql) — single static entry point, returns a CompiledDdl discriminated by DdlOperation.
DdlCompiler has a compile method
Holds
Read Oct 3
The IR is what populates the Schema (via toFieldSpec) and the TableConfig (via PropertyMapping.apply).
PropertyMapping has apply
Holds
Read Oct 3
DataTypeMapper.resolve(String) is case-insensitive (Locale.ROOT) and accepts both ANSI-SQL and Pinot-native names:
DataTypeMapper has a resolve method
Holds
Read Oct 3
The compiler runs dataType.convert(literalString) and surfaces a DdlCompilationException mapped to HTTP 400 if it fails.
DataType has a convert method
Holds
Read Oct 3
validateTableConfig is then called against the **stored** schema (when one exists), not the compiled schema, so upsert/dedup PK validation sees the canonical PK list rather than the synthesized empty list from the DDL column-list-only projection.
TableConfigValidationUtils has validateTableConfig
Holds
Read Oct 3
TableConfigTunerUtils.applyTunerConfigs runs **before** validation, mirroring POST /tables.
TableConfigTunerUtils has applyTunerConfigs
Holds
Read Oct 3
CanonicalDdlEmitter.emit(schema, tableConfig, databaseName?) produces a deterministic DDL string.
CanonicalDdlEmitter has an emit method
Holds
Read Oct 3
PropertyExtractor calls PropertyMapping.isReservedRoundTripKey(lowerKey) on every custom-config entry it encounters.
PropertyMapping has an isReservedRoundTripKey method
Holds
Read Oct 3
The SPI invariant TableConfigUtils.validateMaterializedViewInvariants keeps the flag and the task.MaterializedViewTask.definedSQL body consistent, so the dispatch never has to inspect the task block to decide identity.
TableConfigUtils has validateMaterializedViewInvariants
Holds
Read Oct 3
MaterializedViewPropertyRouter.periodToCron rewrites every accepted REFRESH EVERY '<N><unit>' value into a Quartz cron expression that the scheduler ingests.
MaterializedViewPropertyRouter has periodToCron
Holds
Read Oct 3
The reverse direction (cronToPeriod) must be the **exact inverse**:
MaterializedViewPropertyRouter has cronToPeriod
Holds
Read Oct 3
Adding a knob to MaterializedViewPropertyRouter.TASK_CONFIG_KEYS (the forward-router map; the reverse extractor consults it via canonicalKnobName(...)) is the **only** edit needed to promote a future knob to bare-DDL form.
MaterializedViewPropertyRouter has TASK_CONFIG_KEYS
Holds
Read Oct 3
The compiler stores the user's definedSQL as the **verbatim substring** of the original DDL covered by the AS <query> parser node (see DdlCompiler.extractDefinedSql).
DdlCompiler has extractDefinedSql
Holds
Read Oct 3
The check lives in the controller (PinotDdlRestletResource.executeShowCreate / executeShowCreateMaterializedView) and delegates to the canonical TableConfig#isMaterializedView flag — the same predicate the emitter dispatches on — so a config that the emitter would have routed through the MV branch is caught before any rendering happens.
PinotDdlRestletResource has executeShowCreate
Holds
Read Oct 3
The check lives in the controller (PinotDdlRestletResource.executeShowCreate / executeShowCreateMaterializedView) and delegates to the canonical TableConfig#isMaterializedView flag — the same predicate the emitter dispatches on — so a config that the emitter would have routed through the MV branch is caught before any rendering happens.
PinotDdlRestletResource has executeShowCreateMaterializedView
Holds
Read Oct 3
**Compile.** DdlCompiler.compile(sql) → CompiledDdl.
DdlCompiler depends on CompiledDdl
Holds
Read Oct 3
**MV-specific compile route.** DdlCompiler.compileCreateMaterializedView routes REFRESH EVERY '<period>', AS <query>, and MV-specific knobs through MaterializedViewPropertyRouter before invoking the shared validateTableConfig (see §4 / §5.2).
DdlCompiler has compileCreateMaterializedView
Holds
Read Oct 3
**MV-specific compile route.** DdlCompiler.compileCreateMaterializedView routes REFRESH EVERY '<period>', AS <query>, and MV-specific knobs through MaterializedViewPropertyRouter before invoking the shared validateTableConfig (see §4 / §5.2).
DdlCompiler depends on MaterializedViewPropertyRouter
Holds
Read Oct 3
Both §6.4 and §6.7 share the same canonical TableConfig#isMaterializedView flag the emitter dispatches on, so the controller never asks the emitter to render a form that disagrees with the underlying TableConfig shape.
TableConfig has isMaterializedView
Holds
Read Oct 3
Cleanup is delegated entirely to PinotHelixResourceManager#deleteTable for the same reason PR4's SHOW CREATE was deliberately small: that path is already the single source of truth for "drop a Pinot table, including any MV metadata it carries" — adding a parallel cleanup in the controller would risk drift between the two doors.
PinotHelixResourceManager has deleteTable
Holds
Read Oct 3
**No ZK schema change.** DdlCompiler returns a stock (Schema, TableConfig) pair and persists them through the existing PinotHelixResourceManager paths.
DdlCompiler depends on Schema
Holds
Read Oct 3
**No ZK schema change.** DdlCompiler returns a stock (Schema, TableConfig) pair and persists them through the existing PinotHelixResourceManager paths.
DdlCompiler depends on TableConfig
Holds
Read Oct 3
ZK writes (addSchema, addTable, deleteTable) go through the existing PinotHelixResourceManager paths — no new ZK write surface introduced.
PinotHelixResourceManager has addSchema
Holds
Read Oct 3
ZK writes (addSchema, addTable, deleteTable) go through the existing PinotHelixResourceManager paths — no new ZK write surface introduced.
PinotHelixResourceManager has addTable
Holds
Read Oct 3
Sub-package compile/, Responsibility Forward path AST → (Schema, TableConfig) Entry point DdlCompiler
DdlCompiler is in org.apache.pinot.sql.ddl.compile
Holds
Read Oct 3
Sub-package reverse/, Responsibility Reverse path stored (Schema, TableConfig) → canonical DDL string Entry point CanonicalDdlEmitter
CanonicalDdlEmitter is in org.apache.pinot.sql.ddl.reverse
Holds
39 rules from 4 docs

See these where the change is. The browser extension puts a pull request's doc findings, and a diagram of what it changed, on the GitHub page itself, so the code and what your docs say about it are side by side.