@@ -194,4 +194,85 @@ public void testListDefaults() throws Exception
194194 assertEquals ("Fo" , result .data .get (0 ));
195195 assertEquals ("obar" , result .data .get (1 ));
196196 }
197+
198+ /*
199+ /**********************************************************************
200+ /* Tests for integer default precision (not stored as float)
201+ /**********************************************************************
202+ */
203+
204+ // Verify that int default values preserve precision (not stored as float)
205+ @ Test
206+ public void testIntDefaultValuePrecision () throws Exception
207+ {
208+ // V1 has x and y; V2 adds 'largeInt' with a default that exceeds float precision
209+ String v1Json = a2q ("{" +
210+ "'type':'record','name':'RootType'," +
211+ "'fields':[" +
212+ " {'name':'x','type':'int'}," +
213+ " {'name':'y','type':'int'}" +
214+ "]" +
215+ "}" );
216+ // Default value 20000001 exceeds float's 24-bit mantissa (max exact int: 16777216)
217+ String v2Json = a2q ("{" +
218+ "'type':'record','name':'RootType'," +
219+ "'fields':[" +
220+ " {'name':'x','type':'int'}," +
221+ " {'name':'largeInt','type':'int','default':20000001}," +
222+ " {'name':'y','type':'int'}" +
223+ "]" +
224+ "}" );
225+
226+ AvroSchema v1Schema = MAPPER .schemaFrom (v1Json );
227+ AvroSchema v2Schema = MAPPER .schemaFrom (v2Json );
228+
229+ // Write with V1 (no largeInt field)
230+ Map <String , Object > input = Map .of ("x" , 1 , "y" , 2 );
231+ byte [] bytes = MAPPER .writer (v1Schema ).writeValueAsBytes (input );
232+
233+ // Read with V2 — should get the default value for largeInt
234+ AvroSchema xlate = v1Schema .withReaderSchema (v2Schema );
235+ Map <String , Object > result = MAPPER .readerFor (Map .class )
236+ .with (xlate )
237+ .readValue (bytes );
238+ assertEquals (1 , result .get ("x" ));
239+ assertEquals (2 , result .get ("y" ));
240+ // The critical assertion: default 20000001 must survive float truncation
241+ assertEquals (20000001 , ((Number ) result .get ("largeInt" )).intValue (),
242+ "Integer default lost precision — likely stored as float" );
243+ }
244+
245+ // Verify that long default values preserve precision
246+ @ Test
247+ public void testLongDefaultValuePrecision () throws Exception
248+ {
249+ String v1Json = a2q ("{" +
250+ "'type':'record','name':'RootType'," +
251+ "'fields':[" +
252+ " {'name':'x','type':'int'}" +
253+ "]" +
254+ "}" );
255+ // Default value 9007199254740993 exceeds float AND double integer precision
256+ String v2Json = a2q ("{" +
257+ "'type':'record','name':'RootType'," +
258+ "'fields':[" +
259+ " {'name':'x','type':'int'}," +
260+ " {'name':'bigLong','type':'long','default':9007199254740993}" +
261+ "]" +
262+ "}" );
263+
264+ AvroSchema v1Schema = MAPPER .schemaFrom (v1Json );
265+ AvroSchema v2Schema = MAPPER .schemaFrom (v2Json );
266+
267+ Map <String , Object > input = Map .of ("x" , 1 );
268+ byte [] bytes = MAPPER .writer (v1Schema ).writeValueAsBytes (input );
269+
270+ AvroSchema xlate = v1Schema .withReaderSchema (v2Schema );
271+ Map <String , Object > result = MAPPER .readerFor (Map .class )
272+ .with (xlate )
273+ .readValue (bytes );
274+ assertEquals (1 , result .get ("x" ));
275+ assertEquals (9007199254740993L , ((Number ) result .get ("bigLong" )).longValue (),
276+ "Long default lost precision — likely stored as float" );
277+ }
197278}
0 commit comments