From 9904c101fe9e2ee2754e550b12799deef0930a98 Mon Sep 17 00:00:00 2001 From: Edward Neal <55035479+edwardneal@users.noreply.github.com> Date: Fri, 29 May 2026 00:04:14 +0100 Subject: [PATCH 01/13] Add skeleton to create the ReservedWords table --- .../SqlMetaDataFactory.ReservedWords.cs | 85 +++++++++++++++++++ .../Data/SqlClient/SqlMetaDataFactory.cs | 15 +--- 2 files changed, 86 insertions(+), 14 deletions(-) create mode 100644 src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.ReservedWords.cs diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.ReservedWords.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.ReservedWords.cs new file mode 100644 index 0000000000..4287647e4f --- /dev/null +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.ReservedWords.cs @@ -0,0 +1,85 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Data; +using System.Data.Common; + +#nullable enable + +namespace Microsoft.Data.SqlClient; + +internal sealed partial class SqlMetaDataFactory +{ + /// + /// Adds reserved words to the indicated metadata DataSet. + /// + /// The metadata DataSet to contain the reserved words. + /// + /// These reserved words are defined by the server, and vary depending upon the version + /// and edition. + /// + /// + private static void LoadReservedWordsDataTables(DataSet metaDataCollectionsDataSet) + { + DataTable reservedWordsDataTable = CreateReservedWordsDataTable(); + + reservedWordsDataTable.BeginLoadData(); + + // @TODO: These have been ported from the existing XML resource file, but they don't perfectly + // align with the referenced link. These need to be reviewed, and if it's correct to add + // the new keywords then they need to indicate which version of SQL Server introduced them. + // @TODO: Azure Synapse Analytics also has an extra reserved keyword. This isn't included at + // the moment, but if we choose to do so then we need a way to identify such. Doing so may + // be non-trivial, depending upon whether we query SERVERPROPERTY('EngineEdition') or use a + // similar approach to ADP.IsAzureSynapseOnDemandEndpoint (i.e. check the data source string.) + + // Add reserved keywords used by SQL Server and Azure Synapse Analytics. + AddReservedWords(minVersion: null, maxVersion: null); + + // Add ODBC reserved keywords. + AddReservedWords(minVersion: null, maxVersion: null); + + // Add future reserved keywords. + AddReservedWords(minVersion: null, maxVersion: null); + + reservedWordsDataTable.EndLoadData(); + reservedWordsDataTable.AcceptChanges(); + + metaDataCollectionsDataSet.Tables.Add(reservedWordsDataTable); + + void AddReservedWords(string? minVersion, string? maxVersion, params ReadOnlySpan reservedWords) + { + foreach (string reservedWord in reservedWords) + { + DataRow wordRow = reservedWordsDataTable.NewRow(); + + wordRow[DbMetaDataColumnNames.ReservedWord] = reservedWord; + + if (minVersion is not null) + { + wordRow[MinimumVersionKey] = minVersion; + } + + if (maxVersion is not null) + { + wordRow[MaximumVersionKey] = maxVersion; + } + + reservedWordsDataTable.Rows.Add(wordRow); + } + } + } + + private static DataTable CreateReservedWordsDataTable() + => new(DbMetaDataCollectionNames.ReservedWords) + { + Columns = + { + new DataColumn(DbMetaDataColumnNames.ReservedWord, typeof(string)), + new DataColumn(MinimumVersionKey, typeof(string)), + new DataColumn(MaximumVersionKey, typeof(string)) + } + }; +} diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.cs index 1d9ceebafd..b5c4627f22 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.cs @@ -715,6 +715,7 @@ private DataSet LoadDataSetFromXml(Stream XmlStream) }; LoadDataTypesDataTables(metaDataCollectionsDataSet); + LoadReservedWordsDataTables(metaDataCollectionsDataSet); XmlReaderSettings settings = new() { @@ -765,9 +766,6 @@ private DataSet LoadDataSetFromXml(Stream XmlStream) dataTable = CreateDataSourceInformationDataTable(); rowFixup = FixUpDataSourceInformationRow; break; - case "ReservedWordsTable": - dataTable = CreateReservedWordsDataTable(); - break; default: Debug.Fail($"Unexpected table element name: {reader.Name}"); break; @@ -897,17 +895,6 @@ private static DataTable CreateDataSourceInformationDataTable() new DataColumn(DbMetaDataColumnNames.SupportedJoinOperators, typeof(SupportedJoinOperators)) } }; - - private static DataTable CreateReservedWordsDataTable() - => new(DbMetaDataCollectionNames.ReservedWords) - { - Columns = - { - new DataColumn(DbMetaDataColumnNames.ReservedWord, typeof(string)), - new DataColumn(MinimumVersionKey, typeof(string)), - new DataColumn(MaximumVersionKey, typeof(string)) - } - }; #endregion } } From 2548f25743d607947aab76c6e2829990bd095603 Mon Sep 17 00:00:00 2001 From: Edward Neal <55035479+edwardneal@users.noreply.github.com> Date: Fri, 29 May 2026 23:59:08 +0100 Subject: [PATCH 02/13] Batch 1 --- .../SqlMetaDataFactory.ReservedWords.cs | 7 +- .../Microsoft.Data.SqlClient.SqlMetaData.xml | 135 ------------------ 2 files changed, 6 insertions(+), 136 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.ReservedWords.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.ReservedWords.cs index 4287647e4f..3c552256ed 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.ReservedWords.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.ReservedWords.cs @@ -36,7 +36,12 @@ private static void LoadReservedWordsDataTables(DataSet metaDataCollectionsDataS // similar approach to ADP.IsAzureSynapseOnDemandEndpoint (i.e. check the data source string.) // Add reserved keywords used by SQL Server and Azure Synapse Analytics. - AddReservedWords(minVersion: null, maxVersion: null); + AddReservedWords(minVersion: null, maxVersion: null, + "ADD", "ALL", "ALTER", "AND", "ANY", "AS", "ASC", "AUTHORIZATION", "BACKUP", + "BEGIN", "BETWEEN", "BREAK", "BROWSE", "BULK", "BY", "CASCADE", "CASE", "CHECK", + "CHECKPOINT", "CLOSE", "CLUSTERED", "COALESCE", "COLLATE", "COLUMN", "COMMIT", "COMPUTE", "CONSTRAINT", + "CONTAINS", "CONTAINSTABLE", "CONTINUE", "CONVERT", "CREATE", "CROSS", "CURRENT", "CURRENT_DATE", "CURRENT_TIME", + "CURRENT_TIMESTAMP", "CURRENT_USER", "CURSOR", "DATABASE", "DBCC", "DEALLOCATE", "DECLARE", "DEFAULT", "DELETE"); // Add ODBC reserved keywords. AddReservedWords(minVersion: null, maxVersion: null); diff --git a/src/Microsoft.Data.SqlClient/src/Resources/Microsoft.Data.SqlClient.SqlMetaData.xml b/src/Microsoft.Data.SqlClient/src/Resources/Microsoft.Data.SqlClient.SqlMetaData.xml index 494e9a9106..1a64ab8d33 100644 --- a/src/Microsoft.Data.SqlClient/src/Resources/Microsoft.Data.SqlClient.SqlMetaData.xml +++ b/src/Microsoft.Data.SqlClient/src/Resources/Microsoft.Data.SqlClient.SqlMetaData.xml @@ -581,405 +581,270 @@ - - ADD - EXCEPT PERCENT - - ALL - EXEC PLAN - - ALTER - EXECUTE PRECISION - - AND - EXISTS PRIMARY - - ANY - EXIT PRINT - - AS - FETCH PROC - - ASC - FILE PROCEDURE - - AUTHORIZATION - FILLFACTOR PUBLIC - - BACKUP - FOR RAISERROR - - BEGIN - FOREIGN READ - - BETWEEN - FREETEXT READTEXT - - BREAK - FREETEXTTABLE RECONFIGURE - - BROWSE - FROM REFERENCES - - BULK - FULL REPLICATION - - BY - FUNCTION RESTORE - - CASCADE - GOTO RESTRICT - - CASE - GRANT RETURN - - CHECK - GROUP REVOKE - - CHECKPOINT - HAVING RIGHT - - CLOSE - HOLDLOCK ROLLBACK - - CLUSTERED - IDENTITY ROWCOUNT - - COALESCE - IDENTITY_INSERT ROWGUIDCOL - - COLLATE - IDENTITYCOL RULE - - COLUMN - IF SAVE - - COMMIT - IN SCHEMA - - COMPUTE - INDEX SELECT - - CONSTRAINT - INNER SESSION_USER - - CONTAINS - INSERT SET - - CONTAINSTABLE - INTERSECT SETUSER - - CONTINUE - INTO SHUTDOWN - - CONVERT - IS SOME - - CREATE - JOIN STATISTICS - - CROSS - KEY SYSTEM_USER - - CURRENT - KILL TABLE - - CURRENT_DATE - LEFT TEXTSIZE - - CURRENT_TIME - LIKE THEN - - CURRENT_TIMESTAMP - LINENO TO - - CURRENT_USER - LOAD TOP - - CURSOR - NATIONAL TRAN - - DATABASE - NOCHECK TRANSACTION - - DBCC - NONCLUSTERED TRIGGER - - DEALLOCATE - NOT TRUNCATE - - DECLARE - NULL TSEQUAL - - DEFAULT - NULLIF UNION - - DELETE - OF From b498de04e15fbaf21addba8adf6bf42272e6b52c Mon Sep 17 00:00:00 2001 From: Edward Neal <55035479+edwardneal@users.noreply.github.com> Date: Sat, 30 May 2026 00:10:06 +0100 Subject: [PATCH 03/13] Batch 2 --- .../SqlMetaDataFactory.ReservedWords.cs | 8 +- .../Microsoft.Data.SqlClient.SqlMetaData.xml | 132 ------------------ 2 files changed, 7 insertions(+), 133 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.ReservedWords.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.ReservedWords.cs index 3c552256ed..c63511ea12 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.ReservedWords.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.ReservedWords.cs @@ -41,7 +41,13 @@ private static void LoadReservedWordsDataTables(DataSet metaDataCollectionsDataS "BEGIN", "BETWEEN", "BREAK", "BROWSE", "BULK", "BY", "CASCADE", "CASE", "CHECK", "CHECKPOINT", "CLOSE", "CLUSTERED", "COALESCE", "COLLATE", "COLUMN", "COMMIT", "COMPUTE", "CONSTRAINT", "CONTAINS", "CONTAINSTABLE", "CONTINUE", "CONVERT", "CREATE", "CROSS", "CURRENT", "CURRENT_DATE", "CURRENT_TIME", - "CURRENT_TIMESTAMP", "CURRENT_USER", "CURSOR", "DATABASE", "DBCC", "DEALLOCATE", "DECLARE", "DEFAULT", "DELETE"); + "CURRENT_TIMESTAMP", "CURRENT_USER", "CURSOR", "DATABASE", "DBCC", "DEALLOCATE", "DECLARE", "DEFAULT", "DELETE", + "DENY", "DESC", "DISK", "DISTINCT", "DISTRIBUTED", "DOUBLE", "DROP", "DUMP", "ELSE", + // @TODO: Missing keyword: EXTERNAL + "END", "ERRLVL", "ESCAPE", "EXCEPT", "EXEC", "EXECUTE", "EXISTS", "EXIT", /* "EXTERNAL", */ + "FETCH", "FILE", "FILLFACTOR", "FOR", "FOREIGN", "FREETEXT", "FREETEXTTABLE", "FROM", "FULL", + "FUNCTION", "GOTO", "GRANT", "GROUP", "HAVING", "HOLDLOCK", "IDENTITY", "IDENTITY_INSERT", "IDENTITYCOL", + "IF", "IN", "INDEX", "INNER", "INSERT", "INTERSECT", "INTO", "IS", "JOIN"); // Add ODBC reserved keywords. AddReservedWords(minVersion: null, maxVersion: null); diff --git a/src/Microsoft.Data.SqlClient/src/Resources/Microsoft.Data.SqlClient.SqlMetaData.xml b/src/Microsoft.Data.SqlClient/src/Resources/Microsoft.Data.SqlClient.SqlMetaData.xml index 1a64ab8d33..49586c6edf 100644 --- a/src/Microsoft.Data.SqlClient/src/Resources/Microsoft.Data.SqlClient.SqlMetaData.xml +++ b/src/Microsoft.Data.SqlClient/src/Resources/Microsoft.Data.SqlClient.SqlMetaData.xml @@ -581,195 +581,99 @@ - - EXCEPT - PERCENT - - EXEC - PLAN - - EXECUTE - PRECISION - - EXISTS - PRIMARY - - EXIT - PRINT - - FETCH - PROC - - FILE - PROCEDURE - - FILLFACTOR - PUBLIC - - FOR - RAISERROR - - FOREIGN - READ - - FREETEXT - READTEXT - - FREETEXTTABLE - RECONFIGURE - - FROM - REFERENCES - - FULL - REPLICATION - - FUNCTION - RESTORE - - GOTO - RESTRICT - - GRANT - RETURN - - GROUP - REVOKE - - HAVING - RIGHT - - HOLDLOCK - ROLLBACK - - IDENTITY - ROWCOUNT - - IDENTITY_INSERT - ROWGUIDCOL - - IDENTITYCOL - RULE - - IF - SAVE - - IN - SCHEMA - - INDEX - SELECT - - INNER - SESSION_USER - - INSERT - SET - - INTERSECT - SETUSER - - INTO - SHUTDOWN - - IS - SOME - - JOIN - STATISTICS @@ -851,63 +755,42 @@ UNIQUE - - DENY - OFF UPDATE - - DESC - OFFSETS UPDATETEXT - - DISK - ON USE - - DISTINCT - OPEN USER - - DISTRIBUTED - OPENDATASOURCE VALUES - - DOUBLE - OPENQUERY VARYING - - DROP - OPENROWSET @@ -923,45 +806,30 @@ WAITFOR - - DUMP - OPTION WHEN - - ELSE - OR WHERE - - END - ORDER WHILE - - ERRLVL - OUTER WITH - - ESCAPE - OVER From b55abf1555b7c33bd7de3548f951863050f07f5d Mon Sep 17 00:00:00 2001 From: Edward Neal <55035479+edwardneal@users.noreply.github.com> Date: Sat, 30 May 2026 00:20:50 +0100 Subject: [PATCH 04/13] Batch 3 --- .../SqlMetaDataFactory.ReservedWords.cs | 9 +- .../Microsoft.Data.SqlClient.SqlMetaData.xml | 129 ------------------ 2 files changed, 8 insertions(+), 130 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.ReservedWords.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.ReservedWords.cs index c63511ea12..2aaa445e22 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.ReservedWords.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.ReservedWords.cs @@ -47,7 +47,14 @@ private static void LoadReservedWordsDataTables(DataSet metaDataCollectionsDataS "END", "ERRLVL", "ESCAPE", "EXCEPT", "EXEC", "EXECUTE", "EXISTS", "EXIT", /* "EXTERNAL", */ "FETCH", "FILE", "FILLFACTOR", "FOR", "FOREIGN", "FREETEXT", "FREETEXTTABLE", "FROM", "FULL", "FUNCTION", "GOTO", "GRANT", "GROUP", "HAVING", "HOLDLOCK", "IDENTITY", "IDENTITY_INSERT", "IDENTITYCOL", - "IF", "IN", "INDEX", "INNER", "INSERT", "INTERSECT", "INTO", "IS", "JOIN"); + "IF", "IN", "INDEX", "INNER", "INSERT", "INTERSECT", "INTO", "IS", "JOIN", + // @TODO: Missing keyword: MERGE + "KEY", "KILL", "LEFT", "LIKE", "LINENO", "LOAD", /* "MERGE", */ "NATIONAL", "NOCHECK", + "NONCLUSTERED", "NOT", "NULL", "NULLIF", "OF", "OFF", "OFFSETS", "ON", "OPEN", + "OPENDATASOURCE", "OPENQUERY", "OPENROWSET", "OPENXML", "OPTION", "OR", "ORDER", "OUTER", "OVER", + // @TODO: Missing keyword: PIVOT + "PERCENT", /* "PIVOT", */ "PLAN", "PRECISION", "PRIMARY", "PRINT", "PROC", "PROCEDURE", "PUBLIC", + "RAISERROR", "READ", "READTEXT", "RECONFIGURE", "REFERENCES", "REPLICATION", "RESTORE", "RESTRICT", "RETURN"); // Add ODBC reserved keywords. AddReservedWords(minVersion: null, maxVersion: null); diff --git a/src/Microsoft.Data.SqlClient/src/Resources/Microsoft.Data.SqlClient.SqlMetaData.xml b/src/Microsoft.Data.SqlClient/src/Resources/Microsoft.Data.SqlClient.SqlMetaData.xml index 49586c6edf..4c35a77f19 100644 --- a/src/Microsoft.Data.SqlClient/src/Resources/Microsoft.Data.SqlClient.SqlMetaData.xml +++ b/src/Microsoft.Data.SqlClient/src/Resources/Microsoft.Data.SqlClient.SqlMetaData.xml @@ -581,57 +581,6 @@ - - PERCENT - - - PLAN - - - PRECISION - - - PRIMARY - - - PRINT - - - PROC - - - PROCEDURE - - - PUBLIC - - - RAISERROR - - - READ - - - READTEXT - - - RECONFIGURE - - - REFERENCES - - - REPLICATION - - - RESTORE - - - RESTRICT - - - RETURN - REVOKE @@ -677,162 +626,84 @@ STATISTICS - - KEY - SYSTEM_USER - - KILL - TABLE - - LEFT - TEXTSIZE - - LIKE - THEN - - LINENO - TO - - LOAD - TOP - - NATIONAL - TRAN - - NOCHECK - TRANSACTION - - NONCLUSTERED - TRIGGER - - NOT - TRUNCATE - - NULL - TSEQUAL - - NULLIF - UNION - - OF - UNIQUE - - OFF - UPDATE - - OFFSETS - UPDATETEXT - - ON - USE - - OPEN - USER - - OPENDATASOURCE - VALUES - - OPENQUERY - VARYING - - OPENROWSET - VIEW DUMMY - - OPENXML - WAITFOR - - OPTION - WHEN - - OR - WHERE - - ORDER - WHILE - - OUTER - WITH - - OVER - WRITETEXT From d52c02549f6410ad7f3ab4ae80cbba050270ff0a Mon Sep 17 00:00:00 2001 From: Edward Neal <55035479+edwardneal@users.noreply.github.com> Date: Sat, 30 May 2026 00:39:33 +0100 Subject: [PATCH 05/13] Batch 4 --- .../SqlMetaDataFactory.ReservedWords.cs | 15 ++- .../Microsoft.Data.SqlClient.SqlMetaData.xml | 123 ------------------ 2 files changed, 14 insertions(+), 124 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.ReservedWords.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.ReservedWords.cs index 2aaa445e22..63e5774e79 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.ReservedWords.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.ReservedWords.cs @@ -54,7 +54,20 @@ private static void LoadReservedWordsDataTables(DataSet metaDataCollectionsDataS "OPENDATASOURCE", "OPENQUERY", "OPENROWSET", "OPENXML", "OPTION", "OR", "ORDER", "OUTER", "OVER", // @TODO: Missing keyword: PIVOT "PERCENT", /* "PIVOT", */ "PLAN", "PRECISION", "PRIMARY", "PRINT", "PROC", "PROCEDURE", "PUBLIC", - "RAISERROR", "READ", "READTEXT", "RECONFIGURE", "REFERENCES", "REPLICATION", "RESTORE", "RESTRICT", "RETURN"); + "RAISERROR", "READ", "READTEXT", "RECONFIGURE", "REFERENCES", "REPLICATION", "RESTORE", "RESTRICT", "RETURN", + // @TODO: Missing keyword: REVERT + /* "REVERT", */ "REVOKE", "RIGHT", "ROLLBACK", "ROWCOUNT", "ROWGUIDCOL", "RULE", "SAVE", "SCHEMA", + // @TODO: Missing keywords: SECURITYAUDIT, SEMANTICKEYPHRASETABLE, SEMANTICSIMILARITYDETAILSTABLE + /* "SECURITYAUDIT", */ "SELECT", /* "SEMANTICKEYPHRASETABLE", "SEMANTICSIMILARITYDETAILSTABLE", */ + // @TODO: Missing keyword: SEMANTICSIMILARITYTABLE + /* "SEMANTICSIMILARITYTABLE", */ "SESSION_USER", "SET", "SETUSER", "SHUTDOWN", + // @TODO: Missing keyword: TABLESAMPLE + "SOME", "STATISTICS", "SYSTEM_USER", "TABLE", /* "TABLESAMPLE", */ "TEXTSIZE", "THEN", "TO", "TOP", + // @TODO: Missing keywords: TRY_CONVERT, UNPIVOT + "TRAN", "TRANSACTION", "TRIGGER", "TRUNCATE", /* "TRY_CONVERT", */ "TSEQUAL", "UNION", "UNIQUE", /* "UNPIVOT", */ + "UPDATE", "UPDATETEXT", "USE", "USER", "VALUES", "VARYING", "VIEW", "WAITFOR", "WHEN", + // @TODO: Missing keyword: WITHIN GROUP + "WHERE", "WHILE", "WITH", /* "WITHIN GROUP", */ "WRITETEXT"); // Add ODBC reserved keywords. AddReservedWords(minVersion: null, maxVersion: null); diff --git a/src/Microsoft.Data.SqlClient/src/Resources/Microsoft.Data.SqlClient.SqlMetaData.xml b/src/Microsoft.Data.SqlClient/src/Resources/Microsoft.Data.SqlClient.SqlMetaData.xml index 4c35a77f19..7472f45fd5 100644 --- a/src/Microsoft.Data.SqlClient/src/Resources/Microsoft.Data.SqlClient.SqlMetaData.xml +++ b/src/Microsoft.Data.SqlClient/src/Resources/Microsoft.Data.SqlClient.SqlMetaData.xml @@ -581,132 +581,9 @@ - - REVOKE - - - RIGHT - - - ROLLBACK - - - ROWCOUNT - - - ROWGUIDCOL - - - RULE - - - SAVE - - - SCHEMA - - - SELECT - - - SESSION_USER - - - SET - - - SETUSER - - - SHUTDOWN - - - SOME - - - STATISTICS - - - SYSTEM_USER - - - TABLE - - - TEXTSIZE - - - THEN - - - TO - - - TOP - - - TRAN - - - TRANSACTION - - - TRIGGER - - - TRUNCATE - - - TSEQUAL - - - UNION - - - UNIQUE - - - UPDATE - - - UPDATETEXT - - - USE - - - USER - - - VALUES - - - VARYING - - - VIEW - DUMMY - - WAITFOR - - - WHEN - - - WHERE - - - WHILE - - - WITH - - - WRITETEXT - ABSOLUTE From e0d8c0f768aca52249bc7d76df96ce725edceaeb Mon Sep 17 00:00:00 2001 From: Edward Neal <55035479+edwardneal@users.noreply.github.com> Date: Sat, 30 May 2026 01:01:08 +0100 Subject: [PATCH 06/13] Batch 5 Also enabled EXTERNAL - present in both categories. --- .../SqlMetaDataFactory.ReservedWords.cs | 12 +- .../Microsoft.Data.SqlClient.SqlMetaData.xml | 138 ------------------ 2 files changed, 8 insertions(+), 142 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.ReservedWords.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.ReservedWords.cs index 63e5774e79..ca411c0775 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.ReservedWords.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.ReservedWords.cs @@ -43,8 +43,7 @@ private static void LoadReservedWordsDataTables(DataSet metaDataCollectionsDataS "CONTAINS", "CONTAINSTABLE", "CONTINUE", "CONVERT", "CREATE", "CROSS", "CURRENT", "CURRENT_DATE", "CURRENT_TIME", "CURRENT_TIMESTAMP", "CURRENT_USER", "CURSOR", "DATABASE", "DBCC", "DEALLOCATE", "DECLARE", "DEFAULT", "DELETE", "DENY", "DESC", "DISK", "DISTINCT", "DISTRIBUTED", "DOUBLE", "DROP", "DUMP", "ELSE", - // @TODO: Missing keyword: EXTERNAL - "END", "ERRLVL", "ESCAPE", "EXCEPT", "EXEC", "EXECUTE", "EXISTS", "EXIT", /* "EXTERNAL", */ + "END", "ERRLVL", "ESCAPE", "EXCEPT", "EXEC", "EXECUTE", "EXISTS", "EXIT", "EXTERNAL", "FETCH", "FILE", "FILLFACTOR", "FOR", "FOREIGN", "FREETEXT", "FREETEXTTABLE", "FROM", "FULL", "FUNCTION", "GOTO", "GRANT", "GROUP", "HAVING", "HOLDLOCK", "IDENTITY", "IDENTITY_INSERT", "IDENTITYCOL", "IF", "IN", "INDEX", "INNER", "INSERT", "INTERSECT", "INTO", "IS", "JOIN", @@ -69,8 +68,13 @@ private static void LoadReservedWordsDataTables(DataSet metaDataCollectionsDataS // @TODO: Missing keyword: WITHIN GROUP "WHERE", "WHILE", "WITH", /* "WITHIN GROUP", */ "WRITETEXT"); - // Add ODBC reserved keywords. - AddReservedWords(minVersion: null, maxVersion: null); + // Add ODBC reserved keywords. Some of these overlap with the previous category, and are not included. + AddReservedWords(minVersion: null, maxVersion: null, + "ABSOLUTE", "ACTION", "ADA", "ALLOCATE", "ARE", "ASSERTION", "AT", "AVG", "BIT", + "BIT_LENGTH", "BOTH", "CASCADED", "CAST", "CATALOG", "CHAR", "CHAR_LENGTH", "CHARACTER", "CHARACTER_LENGTH", + "COLLATION", "CONNECT", "CONNECTION", "CONSTRAINTS", "CORRESPONDING", "COUNT", "DATE", "DAY", "DECIMAL", + "DEFERRABLE", "DEFERRED", "DESCRIBE", "DESCRIPTOR", "DIAGNOSTICS", "DISCONNECT", "DOMAIN", "END-EXEC", "EXCEPTION", + "EXTRACT", "FALSE", "FIRST", "FLOAT", "FORTRAN", "FOUND", "GET", "GLOBAL", "GO"); // Add future reserved keywords. AddReservedWords(minVersion: null, maxVersion: null); diff --git a/src/Microsoft.Data.SqlClient/src/Resources/Microsoft.Data.SqlClient.SqlMetaData.xml b/src/Microsoft.Data.SqlClient/src/Resources/Microsoft.Data.SqlClient.SqlMetaData.xml index 7472f45fd5..084a81efdb 100644 --- a/src/Microsoft.Data.SqlClient/src/Resources/Microsoft.Data.SqlClient.SqlMetaData.xml +++ b/src/Microsoft.Data.SqlClient/src/Resources/Microsoft.Data.SqlClient.SqlMetaData.xml @@ -584,18 +584,9 @@ DUMMY - - ABSOLUTE - - - FOUND - PRESERVE - - ACTION - FREE @@ -614,42 +605,27 @@ AFTER - - GET - READS AGGREGATE - - GLOBAL - REAL ALIAS - - GO - RECURSIVE - - ALLOCATE - GROUPING REF - - ARE - HOST @@ -665,18 +641,12 @@ RELATIVE - - ASSERTION - IGNORE RESULT - - AT - IMMEDIATE @@ -701,9 +671,6 @@ ROLLUP - - BIT - INITIALLY @@ -728,9 +695,6 @@ ROWS - - BOTH - INT @@ -755,45 +719,30 @@ SCOPE - - CASCADED - ISOLATION SEARCH - - CAST - ITERATE SECOND - - CATALOG - LANGUAGE SECTION - - CHAR - LARGE SEQUENCE - - CHARACTER - LAST @@ -818,9 +767,6 @@ SIZE - - COLLATION - LESS @@ -836,27 +782,18 @@ SPACE - - CONNECT - LIMIT SPECIFIC - - CONNECTION - LOCAL SPECIFICTYPE - - CONSTRAINTS - LOCALTIME @@ -872,9 +809,6 @@ SQLEXCEPTION - - CORRESPONDING - LOCATOR @@ -926,18 +860,12 @@ STATIC - - DATE - MODULE STRUCTURE - - DAY - MONTH @@ -953,27 +881,18 @@ TERMINATE - - DECIMAL - NATURAL THAN - - DEFERRABLE - NCHAR TIME - - DEFERRED - NCLOB @@ -998,18 +917,12 @@ TIMEZONE_MINUTE - - DESCRIBE - NO TRAILING - - DESCRIPTOR - NONE @@ -1052,27 +965,18 @@ UNKNOWN - - DIAGNOSTICS - OPERATION UNNEST - - DISCONNECT - ORDINALITY USAGE - - DOMAIN - OUT @@ -1097,9 +1001,6 @@ VARCHAR - - END-EXEC - PARAMETER @@ -1124,72 +1025,33 @@ WITHOUT - - EXCEPTION - PATH WORK - - EXTERNAL - POSTFIX WRITE - - FALSE - PREFIX YEAR - - FIRST - PREORDER ZONE - - FLOAT - PREPARE - - ADA - - - AVG - - - BIT_LENGTH - - - CHAR_LENGTH - - - CHARACTER_LENGTH - - - COUNT - - - EXTRACT - - - FORTRAN - INCLUDE From 3245b690fab53b094a9abcc6e6c4b03df3d4b7a6 Mon Sep 17 00:00:00 2001 From: Edward Neal <55035479+edwardneal@users.noreply.github.com> Date: Sat, 30 May 2026 01:15:47 +0100 Subject: [PATCH 07/13] Batch 6 --- .../SqlMetaDataFactory.ReservedWords.cs | 7 +- .../Microsoft.Data.SqlClient.SqlMetaData.xml | 135 ------------------ 2 files changed, 6 insertions(+), 136 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.ReservedWords.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.ReservedWords.cs index ca411c0775..aae4fa835e 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.ReservedWords.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.ReservedWords.cs @@ -74,7 +74,12 @@ private static void LoadReservedWordsDataTables(DataSet metaDataCollectionsDataS "BIT_LENGTH", "BOTH", "CASCADED", "CAST", "CATALOG", "CHAR", "CHAR_LENGTH", "CHARACTER", "CHARACTER_LENGTH", "COLLATION", "CONNECT", "CONNECTION", "CONSTRAINTS", "CORRESPONDING", "COUNT", "DATE", "DAY", "DECIMAL", "DEFERRABLE", "DEFERRED", "DESCRIBE", "DESCRIPTOR", "DIAGNOSTICS", "DISCONNECT", "DOMAIN", "END-EXEC", "EXCEPTION", - "EXTRACT", "FALSE", "FIRST", "FLOAT", "FORTRAN", "FOUND", "GET", "GLOBAL", "GO"); + "EXTRACT", "FALSE", "FIRST", "FLOAT", "FORTRAN", "FOUND", "GET", "GLOBAL", "GO", + "HOUR", "IMMEDIATE", "INCLUDE", "INDICATOR", "INITIALLY", "INPUT", "INSENSITIVE", "INT", "INTEGER", + "INTERVAL", "ISOLATION", "LANGUAGE", "LAST", "LEADING", "LEVEL", "LOCAL", "LOWER", "MATCH", + "MAX", "MIN", "MINUTE", "MODULE", "MONTH", "NAMES", "NATURAL", "NCHAR", "NEXT", + "NO", "NONE", "NUMERIC", "OCTET_LENGTH", "ONLY", "OUTPUT", "OVERLAPS", "PAD", "PASCAL", + "POSITION", "PREPARE", "PRESERVE", "PRIOR", "PRIVILEGES", "REAL", "RELATIVE", "ROWS", "SCROLL"); // Add future reserved keywords. AddReservedWords(minVersion: null, maxVersion: null); diff --git a/src/Microsoft.Data.SqlClient/src/Resources/Microsoft.Data.SqlClient.SqlMetaData.xml b/src/Microsoft.Data.SqlClient/src/Resources/Microsoft.Data.SqlClient.SqlMetaData.xml index 084a81efdb..31e41f210d 100644 --- a/src/Microsoft.Data.SqlClient/src/Resources/Microsoft.Data.SqlClient.SqlMetaData.xml +++ b/src/Microsoft.Data.SqlClient/src/Resources/Microsoft.Data.SqlClient.SqlMetaData.xml @@ -584,24 +584,15 @@ DUMMY - - PRESERVE - FREE - - PRIOR - ADMIN GENERAL - - PRIVILEGES - AFTER @@ -611,9 +602,6 @@ AGGREGATE - - REAL - ALIAS @@ -635,30 +623,18 @@ ARRAY - - HOUR - - - RELATIVE - IGNORE RESULT - - IMMEDIATE - RETURNS BEFORE - - INDICATOR - ROLE @@ -671,9 +647,6 @@ ROLLUP - - INITIALLY - ROUTINE @@ -689,39 +662,18 @@ BOOLEAN - - INPUT - - - ROWS - - - INT - SAVEPOINT BREADTH - - INTEGER - - - SCROLL - CALL - - INTERVAL - SCOPE - - ISOLATION - SEARCH @@ -731,9 +683,6 @@ SECOND - - LANGUAGE - SECTION @@ -743,9 +692,6 @@ SEQUENCE - - LAST - SESSION @@ -761,9 +707,6 @@ CLOB - - LEADING - SIZE @@ -776,9 +719,6 @@ COMPLETION - - LEVEL - SPACE @@ -788,9 +728,6 @@ SPECIFIC - - LOCAL - SPECIFICTYPE @@ -827,18 +764,12 @@ CURRENT_PATH - - MATCH - START CURRENT_ROLE - - MINUTE - STATE @@ -860,36 +791,21 @@ STATIC - - MODULE - STRUCTURE - - MONTH - TEMPORARY DEC - - NAMES - TERMINATE - - NATURAL - THAN - - NCHAR - TIME @@ -911,30 +827,18 @@ DEREF - - NEXT - TIMEZONE_MINUTE - - NO - TRAILING - - NONE - TRANSLATION DESTROY - - NUMERIC - TREAT @@ -959,9 +863,6 @@ DICTIONARY - - ONLY - UNKNOWN @@ -986,18 +887,12 @@ DYNAMIC - - OUTPUT - VALUE EACH - - PAD - VARCHAR @@ -1049,36 +944,6 @@ ZONE - - PREPARE - - - INCLUDE - - - INSENSITIVE - - - LOWER - - - MAX - - - MIN - - - OCTET_LENGTH - - - OVERLAPS - - - PASCAL - - - POSITION - SQLCA From 5dd317d075c9878a8e2c96781ef485f64fedd79c Mon Sep 17 00:00:00 2001 From: Edward Neal <55035479+edwardneal@users.noreply.github.com> Date: Sat, 30 May 2026 01:26:24 +0100 Subject: [PATCH 08/13] Batch 7 --- .../SqlMetaDataFactory.ReservedWords.cs | 6 +- .../Microsoft.Data.SqlClient.SqlMetaData.xml | 105 ------------------ 2 files changed, 5 insertions(+), 106 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.ReservedWords.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.ReservedWords.cs index aae4fa835e..1ecce2a4a5 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.ReservedWords.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.ReservedWords.cs @@ -79,7 +79,11 @@ private static void LoadReservedWordsDataTables(DataSet metaDataCollectionsDataS "INTERVAL", "ISOLATION", "LANGUAGE", "LAST", "LEADING", "LEVEL", "LOCAL", "LOWER", "MATCH", "MAX", "MIN", "MINUTE", "MODULE", "MONTH", "NAMES", "NATURAL", "NCHAR", "NEXT", "NO", "NONE", "NUMERIC", "OCTET_LENGTH", "ONLY", "OUTPUT", "OVERLAPS", "PAD", "PASCAL", - "POSITION", "PREPARE", "PRESERVE", "PRIOR", "PRIVILEGES", "REAL", "RELATIVE", "ROWS", "SCROLL"); + "POSITION", "PREPARE", "PRESERVE", "PRIOR", "PRIVILEGES", "REAL", "RELATIVE", "ROWS", "SCROLL", + "SECOND", "SECTION", "SESSION", "SIZE", "SMALLINT", "SPACE", "SQL", "SQLCA", "SQLCODE", + "SQLERROR", "SQLSTATE", "SQLWARNING", "SUBSTRING", "SUM", "TEMPORARY", "TIME", "TIMESTAMP", "TIMEZONE_HOUR", + "TIMEZONE_MINUTE", "TRAILING", "TRANSLATE", "TRANSLATION", "TRIM", "TRUE", "UNKNOWN", "UPPER", "USAGE", + "USING", "VALUE", "VARCHAR", "WHENEVER", "WORK", "WRITE", "YEAR", "ZONE"); // Add future reserved keywords. AddReservedWords(minVersion: null, maxVersion: null); diff --git a/src/Microsoft.Data.SqlClient/src/Resources/Microsoft.Data.SqlClient.SqlMetaData.xml b/src/Microsoft.Data.SqlClient/src/Resources/Microsoft.Data.SqlClient.SqlMetaData.xml index 31e41f210d..db9847a213 100644 --- a/src/Microsoft.Data.SqlClient/src/Resources/Microsoft.Data.SqlClient.SqlMetaData.xml +++ b/src/Microsoft.Data.SqlClient/src/Resources/Microsoft.Data.SqlClient.SqlMetaData.xml @@ -680,21 +680,12 @@ ITERATE - - SECOND - - - SECTION - LARGE SEQUENCE - - SESSION - CLASS @@ -707,21 +698,12 @@ CLOB - - SIZE - LESS - - SMALLINT - COMPLETION - - SPACE - LIMIT @@ -734,9 +716,6 @@ LOCALTIME - - SQL - CONSTRUCTOR @@ -749,18 +728,12 @@ LOCATOR - - SQLSTATE - CUBE MAP - - SQLWARNING - CURRENT_PATH @@ -794,9 +767,6 @@ STRUCTURE - - TEMPORARY - DEC @@ -806,36 +776,18 @@ THAN - - TIME - NCLOB - - TIMESTAMP - DEPTH NEW - - TIMEZONE_HOUR - DEREF - - TIMEZONE_MINUTE - - - TRAILING - - - TRANSLATION - DESTROY @@ -848,9 +800,6 @@ OBJECT - - TRUE - DETERMINISTIC @@ -863,9 +812,6 @@ DICTIONARY - - UNKNOWN - OPERATION @@ -875,27 +821,15 @@ ORDINALITY - - USAGE - OUT - - USING - DYNAMIC - - VALUE - EACH - - VARCHAR - PARAMETER @@ -908,9 +842,6 @@ PARAMETERS - - WHENEVER - EVERY @@ -923,50 +854,14 @@ PATH - - WORK - POSTFIX - - WRITE - PREFIX - - YEAR - PREORDER - - ZONE - - - SQLCA - - - SQLCODE - - - SQLERROR - - - SUBSTRING - - - SUM - - - TRANSLATE - - - TRIM - - - UPPER - From 0a0b28e6d741812d8720d9a20e627c384abc2796 Mon Sep 17 00:00:00 2001 From: Edward Neal <55035479+edwardneal@users.noreply.github.com> Date: Sat, 30 May 2026 16:40:48 +0100 Subject: [PATCH 09/13] Batch 8 --- .../SqlMetaDataFactory.ReservedWords.cs | 14 ++- .../Microsoft.Data.SqlClient.SqlMetaData.xml | 87 ------------------- 2 files changed, 13 insertions(+), 88 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.ReservedWords.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.ReservedWords.cs index 1ecce2a4a5..9ffa6e53be 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.ReservedWords.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.ReservedWords.cs @@ -86,7 +86,19 @@ private static void LoadReservedWordsDataTables(DataSet metaDataCollectionsDataS "USING", "VALUE", "VARCHAR", "WHENEVER", "WORK", "WRITE", "YEAR", "ZONE"); // Add future reserved keywords. - AddReservedWords(minVersion: null, maxVersion: null); + AddReservedWords(minVersion: null, maxVersion: null, + // @TODO: Missing keywords: ASENSITIVE, ASYMMETRIC, ATOMIC + "ADMIN", "AFTER", "AGGREGATE", "ALIAS", "ARRAY", /* "ASENSITIVE", "ASYMMETRIC", "ATOMIC", */ "BEFORE", + // @TODO: Missing keyword: CALLED, CARDINALITY + "BINARY", "BLOB", "BOOLEAN", "BREADTH", "CALL", /* "CALLED", "CARDINALITY", */ "CLASS", "CLOB", + // @TODO: Missing keywords: COLLECT, CONDITION, CORR, COVAR_POP, COVAR_SAMP, CUME_DIST + /* "COLLECT", */ "COMPLETION", /* "CONDITION", */ "CONSTRUCTOR", /* "CORR", "COVAR_POP", "COVAR_SAMP", */ "CUBE", /* "CUME_DIST", */ + // @TODO: Missing keywords: CURRENT_CATALOG, CURRENT_DEFAULT_TRANSFORM_GROUP + /* "CURRENT_CATALOG", "CURRENT_DEFAULT_TRANSFORM_GROUP", */ "CURRENT_PATH", "CURRENT_ROLE", + // @TODO: Missing keywords: CURRENT_SCHEMA, CURRENT_TRANSFORM_GROUP_FOR_TYPE + /* "CURRENT_SCHEMA", "CURRENT_TRANSFORM_GROUP_FOR_TYPE", */ "CYCLE", "DATA", "DEC", + // @TODO: Missing keyword: ELEMENT + "DEPTH", "DEREF", "DESTROY", "DESTRUCTOR", "DETERMINISTIC", "DICTIONARY", "DYNAMIC", "EACH" /* "ELEMENT" */); reservedWordsDataTable.EndLoadData(); reservedWordsDataTable.AcceptChanges(); diff --git a/src/Microsoft.Data.SqlClient/src/Resources/Microsoft.Data.SqlClient.SqlMetaData.xml b/src/Microsoft.Data.SqlClient/src/Resources/Microsoft.Data.SqlClient.SqlMetaData.xml index db9847a213..035760f3c7 100644 --- a/src/Microsoft.Data.SqlClient/src/Resources/Microsoft.Data.SqlClient.SqlMetaData.xml +++ b/src/Microsoft.Data.SqlClient/src/Resources/Microsoft.Data.SqlClient.SqlMetaData.xml @@ -587,24 +587,12 @@ FREE - - ADMIN - GENERAL - - AFTER - READS - - AGGREGATE - - - ALIAS - RECURSIVE @@ -620,9 +608,6 @@ REFERENCING - - ARRAY - IGNORE @@ -632,15 +617,9 @@ RETURNS - - BEFORE - ROLE - - BINARY - INITIALIZE @@ -650,27 +629,15 @@ ROUTINE - - BLOB - INOUT ROW - - BOOLEAN - SAVEPOINT - - BREADTH - - - CALL - SCOPE @@ -686,24 +653,15 @@ SEQUENCE - - CLASS - LATERAL SETS - - CLOB - LESS - - COMPLETION - LIMIT @@ -716,9 +674,6 @@ LOCALTIME - - CONSTRUCTOR - LOCALTIMESTAMP @@ -728,36 +683,21 @@ LOCATOR - - CUBE - MAP - - CURRENT_PATH - START - - CURRENT_ROLE - STATE - - CYCLE - MODIFIES STATEMENT - - DATA - MODIFY @@ -767,9 +707,6 @@ STRUCTURE - - DEC - TERMINATE @@ -779,39 +716,21 @@ NCLOB - - DEPTH - NEW - - DEREF - - - DESTROY - TREAT - - DESTRUCTOR - OBJECT - - DETERMINISTIC - OLD UNDER - - DICTIONARY - OPERATION @@ -824,12 +743,6 @@ OUT - - DYNAMIC - - - EACH - PARAMETER From 55ae41c8af17841da100088f6747cff46cf451b9 Mon Sep 17 00:00:00 2001 From: Edward Neal <55035479+edwardneal@users.noreply.github.com> Date: Sat, 30 May 2026 17:02:08 +0100 Subject: [PATCH 10/13] Batch 9 --- .../SqlMetaDataFactory.ReservedWords.cs | 12 ++- .../Microsoft.Data.SqlClient.SqlMetaData.xml | 90 ------------------- 2 files changed, 11 insertions(+), 91 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.ReservedWords.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.ReservedWords.cs index 9ffa6e53be..ad2beabf3d 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.ReservedWords.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.ReservedWords.cs @@ -98,7 +98,17 @@ private static void LoadReservedWordsDataTables(DataSet metaDataCollectionsDataS // @TODO: Missing keywords: CURRENT_SCHEMA, CURRENT_TRANSFORM_GROUP_FOR_TYPE /* "CURRENT_SCHEMA", "CURRENT_TRANSFORM_GROUP_FOR_TYPE", */ "CYCLE", "DATA", "DEC", // @TODO: Missing keyword: ELEMENT - "DEPTH", "DEREF", "DESTROY", "DESTRUCTOR", "DETERMINISTIC", "DICTIONARY", "DYNAMIC", "EACH" /* "ELEMENT" */); + "DEPTH", "DEREF", "DESTROY", "DESTRUCTOR", "DETERMINISTIC", "DICTIONARY", "DYNAMIC", "EACH", /* "ELEMENT", */ + // @TODO: Missing keywords: FILTER, FULLTEXTTABLE, FUSION, HOLD + "EQUALS", "EVERY", /* "FILTER", */ "FREE", /* "FULLTEXTTABLE", "FUSION", */ "GENERAL", "GROUPING", /* "HOLD", */ + // @TODO: Missing keyword: INTERSECTION + "HOST", "IGNORE", "INITIALIZE", "INOUT", /* "INTERSECTION", */ "ITERATE", "LARGE", "LATERAL", "LESS", + // @TODO: Missing keywords: LIKE_REGEX, LN, MEMBER, METHOD + /* "LIKE_REGEX",*/ "LIMIT", /* "LN", */ "LOCALTIME", "LOCALTIMESTAMP", "LOCATOR", "MAP", /* "MEMBER", "METHOD", */ + // @TODO: Missing keywords: MOD, MULTISET, NORMALIZE, OCCURRENCES_REGEX + /* "MOD", */ "MODIFIES", "MODIFY", /* "MULTISET", */ "NCLOB", "NEW", /* "NORMALIZE", */ "OBJECT", /* "OCCURRENCES_REGEX", */ + // @TODO: Missing keyword: OVERLAY, PARTITION + "OLD", "OPERATION", "ORDINALITY", "OUT", /* "OVERLAY", */ "PARAMETER", "PARAMETERS", "PARTIAL" /*, "PARTITION" */); reservedWordsDataTable.EndLoadData(); reservedWordsDataTable.AcceptChanges(); diff --git a/src/Microsoft.Data.SqlClient/src/Resources/Microsoft.Data.SqlClient.SqlMetaData.xml b/src/Microsoft.Data.SqlClient/src/Resources/Microsoft.Data.SqlClient.SqlMetaData.xml index 035760f3c7..9ece8e6e39 100644 --- a/src/Microsoft.Data.SqlClient/src/Resources/Microsoft.Data.SqlClient.SqlMetaData.xml +++ b/src/Microsoft.Data.SqlClient/src/Resources/Microsoft.Data.SqlClient.SqlMetaData.xml @@ -584,33 +584,18 @@ DUMMY - - FREE - - - GENERAL - READS RECURSIVE - - GROUPING - REF - - HOST - REFERENCING - - IGNORE - RESULT @@ -620,18 +605,12 @@ ROLE - - INITIALIZE - ROLLUP ROUTINE - - INOUT - ROW @@ -644,63 +623,30 @@ SEARCH - - ITERATE - - - LARGE - SEQUENCE - - LATERAL - SETS - - LESS - - - LIMIT - SPECIFIC SPECIFICTYPE - - LOCALTIME - - - LOCALTIMESTAMP - SQLEXCEPTION - - LOCATOR - - - MAP - START STATE - - MODIFIES - STATEMENT - - MODIFY - STATIC @@ -713,54 +659,18 @@ THAN - - NCLOB - - - NEW - TREAT - - OBJECT - - - OLD - UNDER - - OPERATION - UNNEST - - ORDINALITY - - - OUT - - - PARAMETER - VARIABLE - - EQUALS - - - PARAMETERS - - - EVERY - - - PARTIAL - WITHOUT From ff260916e8d2977387a1aee2acb79466d3ddb406 Mon Sep 17 00:00:00 2001 From: Edward Neal <55035479+edwardneal@users.noreply.github.com> Date: Sat, 30 May 2026 17:27:04 +0100 Subject: [PATCH 11/13] Batch 10 --- .../SqlMetaDataFactory.ReservedWords.cs | 13 ++- .../Microsoft.Data.SqlClient.SqlMetaData.xml | 81 ------------------- 2 files changed, 12 insertions(+), 82 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.ReservedWords.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.ReservedWords.cs index ad2beabf3d..ac77a57d38 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.ReservedWords.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.ReservedWords.cs @@ -108,7 +108,18 @@ private static void LoadReservedWordsDataTables(DataSet metaDataCollectionsDataS // @TODO: Missing keywords: MOD, MULTISET, NORMALIZE, OCCURRENCES_REGEX /* "MOD", */ "MODIFIES", "MODIFY", /* "MULTISET", */ "NCLOB", "NEW", /* "NORMALIZE", */ "OBJECT", /* "OCCURRENCES_REGEX", */ // @TODO: Missing keyword: OVERLAY, PARTITION - "OLD", "OPERATION", "ORDINALITY", "OUT", /* "OVERLAY", */ "PARAMETER", "PARAMETERS", "PARTIAL" /*, "PARTITION" */); + "OLD", "OPERATION", "ORDINALITY", "OUT", /* "OVERLAY", */ "PARAMETER", "PARAMETERS", "PARTIAL", /* "PARTITION" */ + // @TODO: Missing keywords: PERCENT_RANK, PERCENTILE_CONT, PERCENTILE_DISC, POSITION_REGEX, RANGE + "PATH", "POSTFIX", "PREFIX", "PREORDER", /* "PERCENT_RANK", "PERCENTILE_CONT", "PERCENTILE_DISC", "POSITION_REGEX", "RANGE", */ + "READS", "RECURSIVE", "REF", "REFERENCING", + // @TODO: Missing keywords: REGR_AVGX, REGR_AVGY, REGR_COUNT, REGR_INTERCEPT, REGR_R2, REGR_SLOPE + /* "REGR_AVGX", "REGR_AVGY", "REGR_COUNT", "REGR_INTERCEPT", "REGR_R2", "REGR_SLOPE", */ + // @TODO: Missing keywords: REGR_SXX, REGR_SXY, REGR_SYY, RELEASE + /* "REGR_SXX", "REGR_SXY", "REGR_SYY", "RELEASE", */ "RESULT", "RETURNS", "ROLE", "ROLLUP", "ROUTINE", + // @TODO: Missing keywords: SENSITIVE, SIMILAR + "ROW", "SAVEPOINT", "SCOPE", "SEARCH", /* "SENSITIVE", */ "SEQUENCE", "SETS", /* "SIMILAR", */ "SPECIFIC", + // @TODO: Missing keywords: STDDEV_POP, STDDEV_SAMP + "SPECIFICTYPE", "SQLEXCEPTION", "START", "STATE", "STATEMENT", "STATIC", /* "STDDEV_POP", "STDDEV_SAMP", */ "STRUCTURE"); reservedWordsDataTable.EndLoadData(); reservedWordsDataTable.AcceptChanges(); diff --git a/src/Microsoft.Data.SqlClient/src/Resources/Microsoft.Data.SqlClient.SqlMetaData.xml b/src/Microsoft.Data.SqlClient/src/Resources/Microsoft.Data.SqlClient.SqlMetaData.xml index 9ece8e6e39..ad779243fd 100644 --- a/src/Microsoft.Data.SqlClient/src/Resources/Microsoft.Data.SqlClient.SqlMetaData.xml +++ b/src/Microsoft.Data.SqlClient/src/Resources/Microsoft.Data.SqlClient.SqlMetaData.xml @@ -584,75 +584,6 @@ DUMMY - - READS - - - RECURSIVE - - - REF - - - REFERENCING - - - RESULT - - - RETURNS - - - ROLE - - - ROLLUP - - - ROUTINE - - - ROW - - - SAVEPOINT - - - SCOPE - - - SEARCH - - - SEQUENCE - - - SETS - - - SPECIFIC - - - SPECIFICTYPE - - - SQLEXCEPTION - - - START - - - STATE - - - STATEMENT - - - STATIC - - - STRUCTURE - TERMINATE @@ -674,17 +605,5 @@ WITHOUT - - PATH - - - POSTFIX - - - PREFIX - - - PREORDER - From 38993d6fc92edbc4dbdb1fb84c360e1131759a23 Mon Sep 17 00:00:00 2001 From: Edward Neal <55035479+edwardneal@users.noreply.github.com> Date: Sat, 30 May 2026 18:00:03 +0100 Subject: [PATCH 12/13] Batch 11 This includes the "DUMMY" keyword as its own category. --- .../SqlMetaDataFactory.ReservedWords.cs | 17 +++++++++++- .../Microsoft.Data.SqlClient.SqlMetaData.xml | 26 ------------------- 2 files changed, 16 insertions(+), 27 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.ReservedWords.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.ReservedWords.cs index ac77a57d38..73b85f5d45 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.ReservedWords.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlMetaDataFactory.ReservedWords.cs @@ -119,7 +119,22 @@ private static void LoadReservedWordsDataTables(DataSet metaDataCollectionsDataS // @TODO: Missing keywords: SENSITIVE, SIMILAR "ROW", "SAVEPOINT", "SCOPE", "SEARCH", /* "SENSITIVE", */ "SEQUENCE", "SETS", /* "SIMILAR", */ "SPECIFIC", // @TODO: Missing keywords: STDDEV_POP, STDDEV_SAMP - "SPECIFICTYPE", "SQLEXCEPTION", "START", "STATE", "STATEMENT", "STATIC", /* "STDDEV_POP", "STDDEV_SAMP", */ "STRUCTURE"); + "SPECIFICTYPE", "SQLEXCEPTION", "START", "STATE", "STATEMENT", "STATIC", /* "STDDEV_POP", "STDDEV_SAMP", */ "STRUCTURE", + + // @TODO: Missing keywords: SUBMULTISET, SUBSTRING_REGEX, SYMMETRIC, SYSTEM, TRANSLATE_REGEX, UESCAPE + /* "SUBMULTISET", "SUBSTRING_REGEX", "SYMMETRIC", "SYSTEM", */ "TERMINATE", "THAN", /* "TRANSLATE_REGEX", */ "TREAT", /* "UESCAPE", */ + // @TODO: Missing keywords: VAR_POP, VAR_SAMP, WIDTH_BUCKET, WINDOW, WITHIN + "UNDER", "UNNEST", /* "VAR_POP", "VAR_SAMP", */ "VARIABLE", /* "WIDTH_BUCKET", */ "WITHOUT" /* , "WINDOW", "WITHIN", */ + // @TODO: Missing keywords: XMLAGG, XMLATTRIBUTES, XMLBINARY, XMLCAST, XMLCOMMENT, XMLCONCAT, XMLDOCUMENT, XMLELEMENT, XMLEXISTS + /* "XMLAGG", "XMLATTRIBUTES", "XMLBINARY", "XMLCAST", "XMLCOMMENT", "XMLCONCAT", "XMLDOCUMENT", "XMLELEMENT", "XMLEXISTS", */ + // @TODO: Missing keywords: XMLFOREST, XMLITERATE, XMLNAMESPACES, XMLPARSE, XMLPI, XMLQUERY, XMLSERIALIZE, XMLTABLE, XMLTEXT + /* "XMLFOREST", "XMLITERATE", "XMLNAMESPACES", "XMLPARSE", "XMLPI", "XMLQUERY", "XMLSERIALIZE", "XMLTABLE", "XMLTEXT", */ + // @TODO: Missing keyword: XMLVALIDATE + /* "XMLVALIDATE" */); + + // Keywords which appear in the SQL Server 2000 documentation but not in newer versions. + // Preserved for backwards compatibility purposes. + AddReservedWords(minVersion: null, maxVersion: null, "DUMMY"); reservedWordsDataTable.EndLoadData(); reservedWordsDataTable.AcceptChanges(); diff --git a/src/Microsoft.Data.SqlClient/src/Resources/Microsoft.Data.SqlClient.SqlMetaData.xml b/src/Microsoft.Data.SqlClient/src/Resources/Microsoft.Data.SqlClient.SqlMetaData.xml index ad779243fd..dc9fae7d43 100644 --- a/src/Microsoft.Data.SqlClient/src/Resources/Microsoft.Data.SqlClient.SqlMetaData.xml +++ b/src/Microsoft.Data.SqlClient/src/Resources/Microsoft.Data.SqlClient.SqlMetaData.xml @@ -580,30 +580,4 @@ 15 - - - DUMMY - - - TERMINATE - - - THAN - - - TREAT - - - UNDER - - - UNNEST - - - VARIABLE - - - WITHOUT - - From 52c8a202c53e0c16202257ebc269a6abf4d4636a Mon Sep 17 00:00:00 2001 From: Edward Neal <55035479+edwardneal@users.noreply.github.com> Date: Sat, 30 May 2026 20:39:43 +0100 Subject: [PATCH 13/13] Add verification test --- .../ConnectionSchemaTest.cs | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataBaseSchemaTest/ConnectionSchemaTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataBaseSchemaTest/ConnectionSchemaTest.cs index 028447251c..44f51ac161 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataBaseSchemaTest/ConnectionSchemaTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataBaseSchemaTest/ConnectionSchemaTest.cs @@ -55,6 +55,15 @@ public static async Task GetIndexesFromSchema() await VerifySchemaTable(SqlClientMetaDataCollectionNames.Indexes, new string[] { "index_name", "constraint_name" }); } + [ConditionalFact(nameof(CanRunSchemaTests))] + public static async Task GetReservedWordsFromSchema() + { + (DataTable syncReservedWordTable, DataTable asyncReservedWordsTable) = await VerifySchemaTable(DbMetaDataCollectionNames.ReservedWords, new string[] { "ReservedWord" }); + + VerifyReservedWordsTable(syncReservedWordTable); + VerifyReservedWordsTable(asyncReservedWordsTable); + } + [ConditionalFact(nameof(CanRunSchemaTests))] public static async Task GetIndexColumnsFromSchema() { @@ -198,5 +207,36 @@ private static void VerifyDataTypesTable(DataTable dataTypesTable) // SQL Azure reports a version of 12.x but supports JSON, so SqlClient doesn't include it in the list of types. Assert.Equal(DataTestUtility.IsJsonSupported && DataTestUtility.IsNotAzureServer(), actualTypes.Contains("json")); } + + private static void VerifyReservedWordsTable(DataTable reservedWordsTable) + { + // This set contains four example words from each of the categories of reserved words + string[] sampleReservedWords = [ + // SQL Server reserved words + "SELECT", "FROM", "WHERE", "NATIONAL", + // ODBC reserved words + "GO", "COUNT", "SQLCODE", "SMALLINT", + // Future reserved keywords + "AGGREGATE", "ALIAS", "DATA", "LOCALTIME", + // Older keyword + "DUMMY" + ]; + HashSet actualReservedWords = []; + + // Assert that every reserved word is unique. + foreach (DataRow row in reservedWordsTable.Rows) + { + string reservedWord = row[DbMetaDataColumnNames.ReservedWord] as string; + + Assert.False(string.IsNullOrEmpty(reservedWord)); + // Older versions of SqlClient included a keyword of "NATIONAL " (note the trailing space.) + // Verify that this is no longer possible. + Assert.Equal(reservedWord.Trim(), reservedWord); + Assert.True(actualReservedWords.Add(reservedWord)); + } + + Assert.All(sampleReservedWords, reservedWord => Assert.Contains(reservedWord, actualReservedWords)); + Assert.Equal(393, actualReservedWords.Count); + } } }