canonical
The version with _ written as ., which is what goes in the history table and in a report.
A class name cannot hold a ., so V2_1__Add_indexes writes its version with an underscore - and without this, that spelling would leak out of Kotlin's grammar and into a column people read and query. Trailing zeroes are left alone: 1.0 is stored as 1.0, because collapsing it to 1 would print one odd row in a project whose versions are all 1.0, 1.1, 1.2. Whether two versions are the same is settled by their parts, never by this string.