)]}'
{
  "commit": "31601eee4a6d63e11abd9c7bc30f2f37ae93860d",
  "tree": "fc3892d54d69857405a0fb80c001279f8f802621",
  "parents": [
    "1b9c662fab6bfe0342221d535e9085feeda77d92"
  ],
  "author": {
    "name": "CritasWang",
    "email": "critas@outlook.com",
    "time": "Mon Jul 13 14:27:34 2026 +0800"
  },
  "committer": {
    "name": "GitHub",
    "email": "noreply@github.com",
    "time": "Mon Jul 13 14:27:34 2026 +0800"
  },
  "message": "fix: DATE values encoded as days-since-epoch instead of INT32 yyyyMMdd (#15)\n\n* fix: encode DATE as INT32 yyyyMMdd instead of days-since-epoch\n\nIoTDB\u0027s DATE wire format is an INT32 encoded as year*10000 + month*100 + day\n(e.g. 2026-07-13 -\u003e 20260713), matching the Java client\u0027s\nDateUtils.parseDateExpressionToInt and the C# client. The Node.js client was\nwriting and reading days-since-epoch, so DATE values written via tablets were\ncorrupted and unreadable by other clients (and vice versa).\n\nAdjudicated against a live IoTDB 2.0.6 server: a row inserted via SQL literal\n\u00272026-07-13\u0027 reads back as INT32 20260713 on the wire.\n\nChanges:\n- Add shared parseDateToInt / parseIntToDate utils in src/utils/DataTypes.ts\n  (UTC calendar components, matching Java LocalDate semantics) and export them\n- Session.serializeColumn case 9: write yyyyMMdd (was days-since-epoch)\n- FastSerializer.serializeDateColumn: same fix on the fast path\n- Session.deserializeColumn case 9 (TSQueryDataSet): decode yyyyMMdd -\u003e Date\n- ColumnDecoder Int32ArrayColumnDecoder: decode DATE (type 9) columns to Date\n- Session.parseTsBlock: DATE columns arrive typed as INT32 (1) in the TsBlock\n  header; convert them to Date using the metadata dataTypeList\n- Unit tests: yyyyMMdd round-trip, exact wire bytes for 2026-07-13\n  (0x01352769), TsBlock decode; updated existing DATE serialization tests\n\nVerified: tablet-written Date and SQL-literal date now read back identical\nagainst a live IoTDB 2.0.6 (both 2026-07-13T00:00:00.000Z).\n\n* fix: address review feedback on DATE yyyyMMdd encoding\n\nAddresses three review comments from HTHou on PR #15:\n\n1. parseTsBlock DATE conversion now respects\n   columnIndex2TsBlockColumnIndexList. dataTypeList is ordered by LOGICAL\n   response columns while physical TsBlock columns may be deduplicated or\n   reordered, so converting physical column i based on dataTypes[i] could\n   convert the wrong column. The mapping (logical -\u003e physical, -1 \u003d time\n   column) is now passed into parseQueryResult from both call sites\n   (executeQueryStatement initial batch and SessionDataSet.fetchNextBatch)\n   and inverted into per-physical-column logical types. DATE conversion\n   only applies when a physical column\u0027s logical type is unambiguously\n   DATE; conflicting duplicate mappings log a warning and skip conversion\n   instead of crashing. Absent mapping keeps identity behavior.\n\n2. Docs updated to the yyyyMMdd contract: docs/data-types.md and the\n   English/Chinese tree user guides no longer describe numeric DATE as\n   days since epoch; they now document the INT32 yyyyMMdd encoding with\n   examples (20240101 for 2024-01-01).\n\n3. parseDateToInt/parseIntToDate now validate like the Java client\u0027s\n   DateUtils/LocalDate: invalid Date objects (NaN time), non-integer or\n   non-finite numbers, years outside 1000-9999, and impossible calendar\n   dates (e.g. 20230229, month 13, day 0) throw a descriptive Error\n   instead of being silently normalized or serialized as garbage.\n   null/undefined handling is unchanged (callers filter nulls first).\n\nUnit tests added: non-identity mapping TsBlock conversion (crafted\nTsBlock buffers with INT32 wire columns + DATE logical type), dedup and\nconflicting-mapping cases, and validation boundary tests (leap day\n20240229 ok, 20230229/20241301/20240100/year 999/year 10000/NaN\nDate/non-integer/legacy days-epoch 19723 all throw).",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "55d08f35ec214a9f76af1b73a770f9a1fa34273d",
      "old_mode": 33188,
      "old_path": "docs/data-types.md",
      "new_id": "4589a0e45c3c1b20fbd30f4e66f6524d23cdf564",
      "new_mode": 33188,
      "new_path": "docs/data-types.md"
    },
    {
      "type": "modify",
      "old_id": "3b67d93559c307a80ab0bc5220b75db8912dd966",
      "old_mode": 33188,
      "old_path": "docs/user-guide-tree-zh.md",
      "new_id": "695603d12b651829578212bab53ff5686acdf0bb",
      "new_mode": 33188,
      "new_path": "docs/user-guide-tree-zh.md"
    },
    {
      "type": "modify",
      "old_id": "10173a0dff64f389dd9d1dd91e7490a03b0ae27c",
      "old_mode": 33188,
      "old_path": "docs/user-guide-tree.md",
      "new_id": "83ac5b25f3d87aa4ddac0602f438e3a660996c41",
      "new_mode": 33188,
      "new_path": "docs/user-guide-tree.md"
    },
    {
      "type": "modify",
      "old_id": "52701cc21022b19481ef9f86b1f6825e052b95f4",
      "old_mode": 33188,
      "old_path": "src/client/ColumnDecoder.ts",
      "new_id": "25d5c1318151d9d5304b39c025b7b690b7fe9826",
      "new_mode": 33188,
      "new_path": "src/client/ColumnDecoder.ts"
    },
    {
      "type": "modify",
      "old_id": "879f62ef88ced16a61929ae2b4ecbd1618895da1",
      "old_mode": 33188,
      "old_path": "src/client/Session.ts",
      "new_id": "5c8cffc6cb3e8eac9f7a182e8b194caef308e795",
      "new_mode": 33188,
      "new_path": "src/client/Session.ts"
    },
    {
      "type": "modify",
      "old_id": "346ddde5432c7ae1a6f80f6e6323232f3fe8e73a",
      "old_mode": 33188,
      "old_path": "src/client/SessionDataSet.ts",
      "new_id": "ecaeb8a5deb74c7c8dce75fad4bb50f1f587a240",
      "new_mode": 33188,
      "new_path": "src/client/SessionDataSet.ts"
    },
    {
      "type": "modify",
      "old_id": "54fdee40fcaf55dbb5e0f0da66e001aee1f9e7b1",
      "old_mode": 33188,
      "old_path": "src/index.ts",
      "new_id": "76a29653e66e5d0500e40570460cdb7b2caffacd",
      "new_mode": 33188,
      "new_path": "src/index.ts"
    },
    {
      "type": "modify",
      "old_id": "a497e8b794cf06c99c51a5157253df4b808b9e11",
      "old_mode": 33188,
      "old_path": "src/utils/DataTypes.ts",
      "new_id": "6fd2de30e921f8a6c6a99c3a0916adecb064ebd1",
      "new_mode": 33188,
      "new_path": "src/utils/DataTypes.ts"
    },
    {
      "type": "modify",
      "old_id": "a87f9b3f9c6e83238bedc55b3d4a433510f9b082",
      "old_mode": 33188,
      "old_path": "src/utils/FastSerializer.ts",
      "new_id": "76ae9ede984c591091bfca0f1cebecde9c48902f",
      "new_mode": 33188,
      "new_path": "src/utils/FastSerializer.ts"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "fd300a27fe5f0aef6a9b9066818991f895314921",
      "new_mode": 33188,
      "new_path": "tests/unit/DataTypes.test.ts"
    },
    {
      "type": "modify",
      "old_id": "4f2b7ba70428f97aeceb129a1aa8f860de59f256",
      "old_mode": 33188,
      "old_path": "tests/unit/FastSerializer.test.ts",
      "new_id": "f6e673d4f9e6889c4ec5c86856d39839b19dd348",
      "new_mode": 33188,
      "new_path": "tests/unit/FastSerializer.test.ts"
    },
    {
      "type": "modify",
      "old_id": "fb867061c7ba3849baad0301f0202fc920b1d3f3",
      "old_mode": 33188,
      "old_path": "tests/unit/TabletSerialization.test.ts",
      "new_id": "620a4320f4f7335272f1927d7c690c2883e144fe",
      "new_mode": 33188,
      "new_path": "tests/unit/TabletSerialization.test.ts"
    }
  ]
}
