diff --git a/src/Strata.SqlTools.Snowflake/Breakdowns/InsertBreakdown.cs b/src/Strata.SqlTools.Snowflake/Breakdowns/InsertBreakdown.cs index 89f3d06..777c677 100644 --- a/src/Strata.SqlTools.Snowflake/Breakdowns/InsertBreakdown.cs +++ b/src/Strata.SqlTools.Snowflake/Breakdowns/InsertBreakdown.cs @@ -143,21 +143,12 @@ public class InsertBreakdown : SqlServerInsertBreakdown return false; } - // Parse INSERT statement using regex - var insertMatch = System.Text.RegularExpressions.Regex.Match(sql, - @"INSERT\s+INTO\s+([^\(\s]+)\s*\(([^\)]*)\)\s*VALUES\s*\(([^\)]*)\)", - System.Text.RegularExpressions.RegexOptions.IgnoreCase | System.Text.RegularExpressions.RegexOptions.Singleline, Strata.SqlTools.SqlBreakdown.Utilities.RegexDefaults.MatchTimeout); - - if (!insertMatch.Success) + if (!Strata.SqlTools.Statements.SqlServer.ParsePreparation.TryMatchInsertSql( + sql, out var tableName, out var columnsClause, out var valuesClause, out errorMessage)) { - errorMessage = "Could not parse INSERT statement. Expected format: INSERT INTO table (columns) VALUES (values)"; return false; } - var tableName = insertMatch.Groups[1].Value.Trim(); - var columnsClause = insertMatch.Groups[2].Value.Trim(); - var valuesClause = insertMatch.Groups[3].Value.Trim(); - result = new InsertBreakdown(tableName, columnsClause, valuesClause, isMicrosoftSql: false) { SetupClauses = setupClauses, diff --git a/src/Strata.SqlTools.Snowflake/Breakdowns/UpdateBreakdown.cs b/src/Strata.SqlTools.Snowflake/Breakdowns/UpdateBreakdown.cs index 5895dc1..056fc64 100644 --- a/src/Strata.SqlTools.Snowflake/Breakdowns/UpdateBreakdown.cs +++ b/src/Strata.SqlTools.Snowflake/Breakdowns/UpdateBreakdown.cs @@ -44,35 +44,8 @@ public class UpdateBreakdown : SqlServerUpdateBreakdown WhereClause.Comment = whereComments.Count > 0 ? string.Join(" ", whereComments) : null; } - /// - /// Gets the SQL breakdown as a string for Snowflake. - /// - /// The UPDATE SQL statement. - protected override string GetSqlBreakdown() - { - var sb = new StringBuilder(); - - sb.AppendLine("UPDATE "); - sb.AppendLine($" {TableName.Clause}"); - - sb.AppendLine("SET "); - sb.AppendLine($" {SetClause.Clause}"); - - if (IsUsingFromClause) - { - // Snowflake supports FROM clause in UPDATE - sb.AppendLine("FROM "); - sb.AppendLine($" {FromClause.Clause}"); - } - - if (IsUsingWhereClause) - { - sb.AppendLine("WHERE "); - sb.AppendLine($" {WhereClause.Clause}"); - } - - return sb.ToString(); - } + // GetSqlBreakdown() inherited from SqlServer.UpdateBreakdown — Snowflake's UPDATE syntax + // (including the optional FROM clause) is identical at the formatter level, so no override needed. #region Parse Methods diff --git a/src/Strata.SqlTools.SqlServer/Breakdowns/InsertBreakdown.cs b/src/Strata.SqlTools.SqlServer/Breakdowns/InsertBreakdown.cs index dd77b77..20198b9 100644 --- a/src/Strata.SqlTools.SqlServer/Breakdowns/InsertBreakdown.cs +++ b/src/Strata.SqlTools.SqlServer/Breakdowns/InsertBreakdown.cs @@ -152,22 +152,12 @@ public class InsertBreakdown : SqlBreakdownBase return false; } - // Parse INSERT statement using regex - // Pattern: INSERT INTO table (columns) VALUES (values) - var insertMatch = System.Text.RegularExpressions.Regex.Match(sql, - @"INSERT\s+INTO\s+([^\(\s]+)\s*\(([^\)]*)\)\s*VALUES\s*\(([^\)]*)\)", - System.Text.RegularExpressions.RegexOptions.IgnoreCase | System.Text.RegularExpressions.RegexOptions.Singleline, Strata.SqlTools.SqlBreakdown.Utilities.RegexDefaults.MatchTimeout); - - if (!insertMatch.Success) + if (!Strata.SqlTools.Statements.SqlServer.ParsePreparation.TryMatchInsertSql( + sql, out var tableName, out var columnsClause, out var valuesClause, out errorMessage)) { - errorMessage = "Could not parse INSERT statement. Expected format: INSERT INTO table (columns) VALUES (values)"; return false; } - var tableName = insertMatch.Groups[1].Value.Trim(); - var columnsClause = insertMatch.Groups[2].Value.Trim(); - var valuesClause = insertMatch.Groups[3].Value.Trim(); - result = new InsertBreakdown(tableName, columnsClause, valuesClause) { SetupClauses = setupClauses, diff --git a/src/Strata.SqlTools.SqlServer/Statements/ParsePreparation.cs b/src/Strata.SqlTools.SqlServer/Statements/ParsePreparation.cs index 489a0e7..e3eadce 100644 --- a/src/Strata.SqlTools.SqlServer/Statements/ParsePreparation.cs +++ b/src/Strata.SqlTools.SqlServer/Statements/ParsePreparation.cs @@ -66,4 +66,37 @@ public static class ParsePreparation return true; } + + /// + /// Runs the shared INSERT-statement match used by SqlServer / Snowflake (and any future + /// dialect that accepts the same INSERT INTO table (cols) VALUES (vals) grammar). + /// + /// The SQL passed through . + /// On success, the matched table name (trimmed). + /// On success, the matched column list (trimmed). + /// On success, the matched values list (trimmed). + /// On failure, a human-readable parse-error message. + /// true if the regex matched and the three groups are populated; false otherwise. + public static bool TryMatchInsertSql(string sql, out string tableName, out string columnsClause, out string valuesClause, out string errorMessage) + { + tableName = null!; + columnsClause = null!; + valuesClause = null!; + errorMessage = null!; + + var insertMatch = Regex.Match(sql, + @"INSERT\s+INTO\s+([^\(\s]+)\s*\(([^\)]*)\)\s*VALUES\s*\(([^\)]*)\)", + RegexOptions.IgnoreCase | RegexOptions.Singleline, RegexDefaults.MatchTimeout); + + if (!insertMatch.Success) + { + errorMessage = "Could not parse INSERT statement. Expected format: INSERT INTO table (columns) VALUES (values)"; + return false; + } + + tableName = insertMatch.Groups[1].Value.Trim(); + columnsClause = insertMatch.Groups[2].Value.Trim(); + valuesClause = insertMatch.Groups[3].Value.Trim(); + return true; + } }