refactor(dedup): redundant Snowflake override + shared Insert regex helper

Two follow-ups to the prior dedup pass:

- **Delete `Snowflake.UpdateBreakdown.GetSqlBreakdown`**: it was a
  byte-for-byte copy of the SqlServer base's `GetSqlBreakdown` (modulo
  one explanatory comment). Snowflake's UPDATE syntax — including the
  FROM clause — is identical at the formatter level, so the override
  was pure inheritance noise. Now inherits.

- **Extract `ParsePreparation.TryMatchInsertSql`**: the regex match +
  group extraction + failure message at the end of
  `SqlServer.InsertBreakdown.TryParse` and
  `Snowflake.InsertBreakdown.TryParse` was duplicated. Hoist the
  shared piece next to `TryRunPrelude` on `ParsePreparation`. Both
  callers continue to construct their own `InsertBreakdown` instance
  (the constructor signatures differ slightly between dialects).

All 1180 tests stay green.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Thom Lamb
2026-05-27 17:05:00 -05:00
co-authored by Claude Opus 4.7
parent 99e15725e7
commit 507620cc04
4 changed files with 39 additions and 52 deletions
@@ -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,
@@ -44,35 +44,8 @@ public class UpdateBreakdown : SqlServerUpdateBreakdown
WhereClause.Comment = whereComments.Count > 0 ? string.Join(" ", whereComments) : null;
}
/// <summary>
/// Gets the SQL breakdown as a string for Snowflake.
/// </summary>
/// <returns>The UPDATE SQL statement.</returns>
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
@@ -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,
@@ -66,4 +66,37 @@ public static class ParsePreparation
return true;
}
/// <summary>
/// Runs the shared INSERT-statement match used by SqlServer / Snowflake (and any future
/// dialect that accepts the same <c>INSERT INTO table (cols) VALUES (vals)</c> grammar).
/// </summary>
/// <param name="sql">The SQL passed through <see cref="TryRunPrelude"/>.</param>
/// <param name="tableName">On success, the matched table name (trimmed).</param>
/// <param name="columnsClause">On success, the matched column list (trimmed).</param>
/// <param name="valuesClause">On success, the matched values list (trimmed).</param>
/// <param name="errorMessage">On failure, a human-readable parse-error message.</param>
/// <returns><c>true</c> if the regex matched and the three groups are populated; <c>false</c> otherwise.</returns>
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;
}
}