{"record":{"id":"af0aceb36110bf6b","repo":"influxdata/influxdb","slug":"unexpected-physical-type-for-timestamp-column","errorCode":null,"errorMessage":"unexpected physical type for timestamp column","messagePattern":"unexpected physical type for timestamp column","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/parquet_file/src/metadata.rs","lineNumber":581,"sourceCode":"/// metadata.\n///\n/// [`RecordBatch`]: arrow::record_batch::RecordBatch\npub fn derive_min_max_time(stats: Vec<ColumnSummary>) -> TimestampRange {\n    let time_summary = stats\n        .into_iter()\n        .find(|v| v.name == TIME_COLUMN_NAME)\n        .expect(\"no time column in metadata statistics\");\n\n    assert_eq!(time_summary.influxdb_type, InfluxDbType::Timestamp);\n\n    // Extract the min/max timestamps.\n    match time_summary.stats {\n        Statistics::I64(stats) => {\n            let min = Timestamp::new(stats.min.expect(\"no min time statistic\"));\n            let max = Timestamp::new(stats.max.expect(\"no max time statistic\"));\n            TimestampRange { min, max }\n        }\n        _ => panic!(\"unexpected physical type for timestamp column\"),\n    }\n}\n/// Parquet metadata with IOx-specific wrapper.\n#[derive(Clone, PartialEq, Eq)]\npub struct IoxParquetMetaData {\n    /// [Apache Parquet] metadata as freestanding [Apache Thrift]-encoded, and [Zstandard]-compressed bytes.\n    ///\n    /// This can be used to store metadata separate from the related payload data. The usage of [Apache Thrift] allows the\n    /// same stability guarantees as the usage of an ordinary [Apache Parquet] file. To encode a thrift message into bytes\n    /// the [Thrift Compact Protocol] is used.\n    ///\n    /// [Apache Parquet]: https://parquet.apache.org/\n    /// [Apache Thrift]: https://thrift.apache.org/\n    /// [Thrift Compact Protocol]: https://github.com/apache/thrift/blob/master/doc/specs/thrift-compact-protocol.md\n    /// [Zstandard]: http://facebook.github.io/zstd/\n    data: Vec<u8>,\n}\n","sourceCodeStart":563,"sourceCodeEnd":599,"githubUrl":"https://github.com/influxdata/influxdb/blob/06200ef96ba82c5f6727e5038a83af8e722c6875/core/parquet_file/src/metadata.rs#L563-L599","documentation":"derive_min_max_time only handles Statistics::I64 for the timestamp column (IOx stores time as i64 nanoseconds); any other physical type triggers a panic. A non-I64 time column means the file was not produced by IOx's normal write path.","triggerScenarios":"Calling derive_min_max_time on a Parquet file whose 'time' column physical type is not INT64 (e.g. TimestampMicrosecond stored differently, string, or int32).","commonSituations":"Writing the time column as Arrow Timestamp with non-nanosecond unit, foreign Parquet files, schema drift after an arrow/parquet upgrade.","solutions":["Ensure the time column is written as Arrow Timestamp(Nanosecond, None) so it maps to Parquet INT64","Convert non-nanosecond time columns before encoding: cast to TimeValueNanosecond","Extend derive_min_max_time to handle the observed physical type if intentional"],"exampleFix":"// before\nlet time: TimestampMillisecondArray = ...;\n// after\nlet time: TimestampNanosecondArray = time.cast_to(&ArrowDataType::Timestamp(TimeUnit::Nanosecond, None))?;","handlingStrategy":"validation","validationCode":"let dt = batch.schema().field_with_name(\"time\")?.data_type();\nif *dt != ArrowDataType::Timestamp(TimeUnit::Nanosecond, None) { return Err(anyhow!(\"time must be ns timestamp\")); }","typeGuard":"fn is_i64_time(dt: &ArrowDataType) -> bool {\n    matches!(dt, ArrowDataType::Timestamp(TimeUnit::Nanosecond, None))\n}","tryCatchPattern":null,"preventionTips":["Write time as Timestamp(Nanosecond, None) so Parquet stores INT64","Cast time columns to nanoseconds before encoding","Add a unit test asserting the encoded physical type is INT64"],"tags":["parquet","panic","type-mismatch","timestamp"],"backgroundTag":"type-mismatch","analyzedSha":"06200ef96ba82c5f6727e5038a83af8e722c6875","analyzedAt":"2026-09-19T12:55:30.003Z","contentChangedAt":"2026-09-19T12:55:30.003Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}