{"record":{"id":"3ed80fbfaefa2ccc","repo":"apache/cassandra","slug":"changing-from-timestamptype-to-datetype-is-allowed","errorCode":null,"errorMessage":"Changing from TimestampType to DateType 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. There is no reason to switch from DateType to TimestampType except if you were using DateType in the first place and switched to TimestampType by mistake.","messagePattern":"Changing from TimestampType to DateType 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\\. There is no reason to switch from DateType to TimestampType except if you were using DateType in the first place and switched to TimestampType by mistake\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/java/org/apache/cassandra/db/marshal/DateType.java","lineNumber":113,"sourceCode":"                    parsed.getClass().getSimpleName(), parsed));\n        }\n    }\n\n    @Override\n    public String toJSONString(ByteBuffer buffer, ProtocolVersion protocolVersion)\n    {\n        return '\"' + TimestampSerializer.getJsonDateFormatter().format(TimestampSerializer.instance.deserialize(buffer).toInstant()) + '\"';\n    }\n\n    @Override\n    public boolean isCompatibleWith(AbstractType<?> previous)\n    {\n        if (super.isCompatibleWith(previous))\n            return true;\n\n        if (previous instanceof TimestampType)\n        {\n            logger.warn(\"Changing from TimestampType to DateType 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. There is no \"\n                      + \"reason to switch from DateType to TimestampType except if you were using DateType in the first place and switched to \"\n                      + \"TimestampType by mistake.\");\n            return true;\n        }\n\n        return false;\n    }\n\n    @Override\n    public boolean isValueCompatibleWithInternal(AbstractType<?> otherType)\n    {\n        return this == otherType || otherType == TimestampType.instance || otherType == LongType.instance;\n    }\n\n    @Override\n    public CQL3Type asCQL3Type()\n    {","sourceCodeStart":95,"sourceCodeEnd":131,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/db/marshal/DateType.java#L95-L131","documentation":"DateType.isCompatibleWith permits schema evolution from TimestampType back to DateType because their binary encodings are compatible (both 8-byte values), but they order bytes differently for negative (pre-1970) timestamps. Cassandra warns because changing comparator order corrupts sorted data on disk if any negative timestamp values exist.","triggerScenarios":"Executing ALTER TABLE ... ALTER <column> TYPE date (or updating a comparator/validation class) on a column previously of TimestampType (org.apache.cassandra.db.marshal.TimestampType) when the table uses DateType ordering.","commonSituations":"Migrating legacy schema where a column was accidentally created as timestamp and the operator wants date semantics; schema imports from old clusters (pre-2.0 thrift metadata).","solutions":["First confirm no negative (pre-unix-epoch) timestamp values exist: SELECT the column and check for dates before 1970-01-01","If negative values exist, migrate data to a new column/table instead of altering the type in place","If values are safe, re-run the ALTER and ignore the warning","Keep the type as TimestampType if unsure - the warning is the safer path"],"exampleFix":"// before: blindly alter\nALTER TABLE events ALTER occurred_at TYPE date;\n// after: verify first\nSELECT occurred_at FROM events WHERE occurred_at < 0 LIMIT 1 ALLOW FILTERING; // none -> safe to alter","handlingStrategy":"validation","validationCode":"// reject the schema change if pre-epoch values may exist\nResultSet rs = session.execute(\"SELECT pk FROM t WHERE ts_col < 0 ALLOW FILTERING\");\nif (!rs.isEmpty()) throw new IllegalStateException(\"Pre-1970 timestamps present; do not alter to date\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Audit for negative timestamps before DateType/TimestampType swaps","Prefer timestamp for all new schemas","Never alternate types back and forth across migrations","Test schema changes on a staging copy of 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"}