@@ -114,18 +114,33 @@ public void Column_WithCollate_RoundTripsViaInformationSchema()
114114 "SELECT COLLATION_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE COLUMN_NAME = 'b'" ) ) ;
115115 }
116116
117+ /// <summary>
118+ /// Names structurally valid but absent from the catalog raise
119+ /// <c>NotSupportedException</c>. <c>Mapudungan_BIN</c> has a known
120+ /// prefix and a recognized suffix grammar but the specific pair
121+ /// doesn't ship in real SQL Server (probed 2026-05-21: Mapudungan is
122+ /// v100-only).
123+ /// </summary>
117124 [ TestMethod ]
118125 public void Column_Collate_UnrecognizedName_RaisesNotSupported ( )
119126 {
120127 var ex = Throws < NotSupportedException > ( ( ) => new Simulation ( ) . ExecuteNonQuery (
121- "CREATE TABLE t (a nvarchar(50) COLLATE Japanese_CI_AS )" ) ) ;
122- Contains ( "Japanese_CI_AS " , ex . Message ) ;
128+ "CREATE TABLE t (a nvarchar(50) COLLATE Mapudungan_BIN )" ) ) ;
129+ Contains ( "Mapudungan_BIN " , ex . Message ) ;
123130 Contains ( "recognized list" , ex . Message ) ;
124131 }
125132
133+ /// <summary>
134+ /// The simulator's catalog matches real SQL Server's
135+ /// <c>sys.fn_helpcollations()</c> count — 77 SQL_* names + 5463
136+ /// non-SQL_* names = 5540 total, probed against SQL Server 2025 on
137+ /// 2026-05-21. The parser validates names against the per-prefix
138+ /// tail-set catalog so phantom combinations (grammar-valid but never
139+ /// shipped) are rejected.
140+ /// </summary>
126141 [ TestMethod ]
127142 public void FnHelpCollations_ListsRecognized ( )
128- => AreEqual ( 26 , new Simulation ( ) . ExecuteScalar (
143+ => AreEqual ( 5540 , new Simulation ( ) . ExecuteScalar (
129144 "SELECT COUNT(*) FROM sys.fn_helpcollations()" ) ) ;
130145
131146 [ TestMethod ]
@@ -151,6 +166,39 @@ public void FnHelpCollations_ColumnsAreNameAndDescription()
151166 "SELECT name FROM sys.fn_helpcollations WHERE name = 'Latin1_General_100_CI_AS'" ) ) ;
152167 }
153168
169+ /// <summary>
170+ /// Parser-driven catalog accepts the full breadth of real SQL Server
171+ /// 2025 names — locale × version × flag combinations beyond the 26
172+ /// hand-tuned entries the prior implementation maintained. Probed
173+ /// names from each pattern bucket: a v100-only locale (Pattern_0), a
174+ /// versioned-and-unversioned locale (Pattern_1), a SQL_* CP1250
175+ /// variant, and a v140 + VSS combo (Pattern_6).
176+ /// </summary>
177+ [ TestMethod ]
178+ [ DataRow ( "Albanian_100_CI_AS" , "Albanian-100, case-insensitive, accent-sensitive, kanatype-insensitive, width-insensitive" ) ]
179+ [ DataRow ( "Greek_BIN2" , "Greek, binary code point comparison sort" ) ]
180+ [ DataRow ( "SQL_Polish_CP1250_CS_AS" , "Polish, case-sensitive, accent-sensitive, kanatype-insensitive, width-insensitive for Unicode Data, SQL Server Sort Order 87 on Code Page 1250 for non-Unicode Data" ) ]
181+ [ DataRow ( "Japanese_XJIS_140_CI_AS_KS_WS_VSS" , "Japanese-XJIS-140, case-insensitive, accent-sensitive, kanatype-sensitive, width-sensitive, supplementary characters, variation selector sensitive" ) ]
182+ [ DataRow ( "German_PhoneBook_100_CI_AS_KS_WS_SC_UTF8" , "German-PhoneBook-100, case-insensitive, accent-sensitive, kanatype-sensitive, width-sensitive, supplementary characters, UTF8" ) ]
183+ public void FnHelpCollations_Description_MatchesProbedSqlServer ( string name , string description )
184+ => AreEqual ( description , new Simulation ( ) . ExecuteScalar (
185+ $ "SELECT description FROM sys.fn_helpcollations WHERE name = '{ name } '") ) ;
186+
187+ /// <summary>
188+ /// Grammar-valid but never-shipped name combinations reject — the
189+ /// parser validates against the per-prefix tail-set catalog, not just
190+ /// the suffix grammar. <c>Pashto_CI_AS</c> (unversioned form of a
191+ /// v100-only locale) and <c>Latin1_General_140_BIN</c> (v140 doesn't
192+ /// have BIN/BIN2) are both phantom; both reject.
193+ /// </summary>
194+ [ TestMethod ]
195+ [ DataRow ( "Pashto_CI_AS" ) ]
196+ [ DataRow ( "Latin1_General_140_BIN" ) ]
197+ [ DataRow ( "Albanian_BIN2_UTF8" ) ]
198+ public void PhantomCollationName_RejectedByParser ( string name )
199+ => Throws < NotSupportedException > ( ( ) => new Simulation ( ) . ExecuteNonQuery (
200+ $ "CREATE TABLE t (a nvarchar(50) COLLATE { name } )") ) ;
201+
154202 [ TestMethod ]
155203 public void SysDatabases_RowShape_CarriesCompatibilityAndIsolation ( )
156204 {
0 commit comments