{"record":{"id":"45316af5d7a7cce9","repo":"apache/cassandra","slug":"changing-from-datetype-to-timestamptype-is-allowed","errorCode":null,"errorMessage":"Changing from DateType to TimestampType is allowed, but be wary that they sort differently for pre-unix-epoch timestamps (negative timestamp values) and thus this change will corrupt your data if you have such negative timestamp. So unless you know that you don't have *any* pre-unix-epoch timestamp you should change back to DateType","messagePattern":"Changing from DateType to TimestampType is allowed, but be wary that they sort differently for pre-unix-epoch timestamps \\(negative timestamp values\\) and thus this change will corrupt your data if you have such negative timestamp\\. So unless you know that you don't have \\*any\\* pre-unix-epoch timestamp you should change back to DateType","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/java/org/apache/cassandra/db/marshal/TimestampType.java","lineNumber":144,"sourceCode":"    {\n        return date != null ? TimestampSerializer.getJsonDateFormatter().format(date.toInstant()) : \"\";\n    }\n\n    @Override\n    public String toJSONString(ByteBuffer buffer, ProtocolVersion protocolVersion)\n    {\n        return '\"' + toString(TimestampSerializer.instance.deserialize(buffer)) + '\"';\n    }\n\n    @Override\n    public boolean isCompatibleWith(AbstractType<?> previous)\n    {\n        if (super.isCompatibleWith(previous))\n            return true;\n\n        if (previous instanceof DateType)\n        {\n            logger.warn(\"Changing from DateType to TimestampType is allowed, but be wary that they sort differently for pre-unix-epoch timestamps \"\n                      + \"(negative timestamp values) and thus this change will corrupt your data if you have such negative timestamp. So unless you \"\n                      + \"know that you don't have *any* pre-unix-epoch timestamp you should change back to DateType\");\n            return true;\n        }\n\n        return false;\n    }\n\n    @Override\n    public boolean isValueCompatibleWithInternal(AbstractType<?> otherType)\n    {\n        return this == otherType || otherType == DateType.instance || otherType == LongType.instance;\n    }\n\n    public CQL3Type asCQL3Type()\n    {\n        return CQL3Type.Native.TIMESTAMP;\n    }","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/db/marshal/TimestampType.java#L126-L162","documentation":"TimestampType.isCompatibleWith allows changing a column from DateType to TimestampType since encodings are byte-compatible, but sort order differs for negative (pre-1970) values, so on-disk sorted data would be corrupted if such values exist. Cassandra logs this warning and permits the change so operators can correct a prior accidental switch.","triggerScenarios":"ALTER TABLE ... ALTER <column> TYPE timestamp on a column whose comparator is DateType, typically to undo an earlier accidental DateType migration, via CQL ALTER or schema-restore of old metadata.","commonSituations":"Correcting a legacy schema; restoring schema snapshots from very old clusters where DateType was default for date-like columns; blind schema migrations without auditing pre-1970 data.","solutions":["Audit the column for pre-unix-epoch values (negative timestamps) before altering","If pre-1970 values exist, do not alter; instead rewrite data into a new timestamp column","If no negative values exist, proceed with the ALTER; the warning can be ignored","Document the type change so future restores do not ping-pong between the two types"],"exampleFix":"// before: blind alter\nALTER TABLE events ALTER at TYPE timestamp;\n// after: pre-check for pre-epoch values\nSELECT at FROM events WHERE at < toTimestamp('1970-01-01') LIMIT 1 ALLOW FILTERING; // empty -> safe","handlingStrategy":"validation","validationCode":"// pre-check before DateType -> TimestampType alter\nResultSet rs = session.execute(\"SELECT pk FROM t WHERE at < '1970-01-01' ALLOW FILTERING\");\nif (!rs.isEmpty()) throw new IllegalStateException(\"Pre-epoch values exist; altering will corrupt sort order\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Audit pre-1970 data before comparator type changes","Keep one canonical temporal type per dataset","Capture schema snapshots before ALTERs","Rehearse migrations on restored test data"],"tags":["schema","comparator","data-corruption-risk"],"backgroundTag":"incompatible-source-type","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}