chore: refactor for sonarqube issues
SonarQube Analysis / sonarqube (pull_request) Successful in 6m3s
SonarQube Analysis / sonarqube (pull_request) Successful in 6m3s
This commit is contained in:
@@ -689,44 +689,74 @@ public class StatementParser
|
||||
// Only process keywords at top level (outside parentheses)
|
||||
if (parenthesisDepth == 0 && type == TokenType.String)
|
||||
{
|
||||
// Check for multi-word keywords (GROUP BY, ORDER BY)
|
||||
if (string.Equals(value, "GROUP", StringComparison.OrdinalIgnoreCase) &&
|
||||
tokenIndex + 1 < tokens.Count &&
|
||||
tokens[tokenIndex + 1].type == TokenType.String &&
|
||||
string.Equals(tokens[tokenIndex + 1].value, "BY", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (!clausePositions.ContainsKey(KeywordGroupBy))
|
||||
{
|
||||
clausePositions[KeywordGroupBy] = position;
|
||||
}
|
||||
|
||||
skipNextToken = true; // Skip BY in next iteration
|
||||
}
|
||||
else if (string.Equals(value, "ORDER", StringComparison.OrdinalIgnoreCase) &&
|
||||
tokenIndex + 1 < tokens.Count &&
|
||||
tokens[tokenIndex + 1].type == TokenType.String &&
|
||||
string.Equals(tokens[tokenIndex + 1].value, "BY", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (!clausePositions.ContainsKey(KeywordOrderBy))
|
||||
{
|
||||
clausePositions[KeywordOrderBy] = position;
|
||||
}
|
||||
|
||||
skipNextToken = true; // Skip BY in next iteration
|
||||
}
|
||||
else if (keywordSet.Contains(value))
|
||||
{
|
||||
var matchedKeyword = keywords.FirstOrDefault(k =>
|
||||
string.Equals(k, value, StringComparison.OrdinalIgnoreCase));
|
||||
if (matchedKeyword != null && !clausePositions.ContainsKey(matchedKeyword))
|
||||
{
|
||||
clausePositions[matchedKeyword] = position;
|
||||
}
|
||||
}
|
||||
skipNextToken = TryRecordKeywordAtToken(tokens, tokenIndex, value, position, keywords, keywordSet, clausePositions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Records the keyword at the given token (single-word or multi-word) into <paramref name="clausePositions"/>.
|
||||
/// </summary>
|
||||
/// <returns>True if a multi-word keyword (GROUP BY / ORDER BY) was matched and the following token should be skipped.</returns>
|
||||
private static bool TryRecordKeywordAtToken(
|
||||
List<(TokenType type, string value, int position)> tokens,
|
||||
int tokenIndex,
|
||||
string value,
|
||||
int position,
|
||||
string[] keywords,
|
||||
HashSet<string> keywordSet,
|
||||
Dictionary<string, int> clausePositions)
|
||||
{
|
||||
// Check for multi-word keywords (GROUP BY, ORDER BY); they consume the following BY token.
|
||||
if (TryRecordMultiWordKeyword(tokens, tokenIndex, "GROUP", KeywordGroupBy, clausePositions) ||
|
||||
TryRecordMultiWordKeyword(tokens, tokenIndex, "ORDER", KeywordOrderBy, clausePositions))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (keywordSet.Contains(value))
|
||||
{
|
||||
var matchedKeyword = keywords.FirstOrDefault(k =>
|
||||
string.Equals(k, value, StringComparison.OrdinalIgnoreCase));
|
||||
if (matchedKeyword != null && !clausePositions.ContainsKey(matchedKeyword))
|
||||
{
|
||||
clausePositions[matchedKeyword] = position;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Records a two-word keyword (e.g., "GROUP BY") when the token at <paramref name="tokenIndex"/> matches
|
||||
/// <paramref name="firstWord"/> and is immediately followed by "BY".
|
||||
/// </summary>
|
||||
/// <returns>True if the multi-word keyword pattern matched.</returns>
|
||||
private static bool TryRecordMultiWordKeyword(
|
||||
List<(TokenType type, string value, int position)> tokens,
|
||||
int tokenIndex,
|
||||
string firstWord,
|
||||
string canonicalKeyword,
|
||||
Dictionary<string, int> clausePositions)
|
||||
{
|
||||
var (_, value, position) = tokens[tokenIndex];
|
||||
|
||||
if (!string.Equals(value, firstWord, StringComparison.OrdinalIgnoreCase) ||
|
||||
tokenIndex + 1 >= tokens.Count ||
|
||||
tokens[tokenIndex + 1].type != TokenType.String ||
|
||||
!string.Equals(tokens[tokenIndex + 1].value, "BY", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!clausePositions.ContainsKey(canonicalKeyword))
|
||||
{
|
||||
clausePositions[canonicalKeyword] = position;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual SqlClauses ExtractAllClauses(string sql, Dictionary<string, int> clausePositions)
|
||||
{
|
||||
var clauses = new SqlClauses
|
||||
|
||||
Reference in New Issue
Block a user