-
Notifications
You must be signed in to change notification settings - Fork 132
refactor: move skip methods to abstract parser #2948
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,7 +26,6 @@ | |
import java.util.HashSet; | ||
import java.util.Set; | ||
import java.util.regex.Pattern; | ||
import javax.annotation.Nullable; | ||
|
||
@InternalApi | ||
public class PostgreSQLStatementParser extends AbstractStatementParser { | ||
|
@@ -136,23 +135,6 @@ String removeCommentsAndTrimInternal(String sql) { | |
return res.toString().trim(); | ||
} | ||
|
||
String parseDollarQuotedString(String sql, int index) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This and the other methods here that appear to be deleted, are just moved to |
||
// Look ahead to the next dollar sign (if any). Everything in between is the quote tag. | ||
StringBuilder tag = new StringBuilder(); | ||
while (index < sql.length()) { | ||
char c = sql.charAt(index); | ||
if (c == DOLLAR) { | ||
return tag.toString(); | ||
} | ||
if (!isValidIdentifierChar(c)) { | ||
break; | ||
} | ||
tag.append(c); | ||
index++; | ||
} | ||
return null; | ||
} | ||
|
||
/** PostgreSQL does not support statement hints. */ | ||
@Override | ||
String removeStatementHint(String sql) { | ||
|
@@ -220,135 +202,6 @@ public Set<String> getQueryParameters(String sql) { | |
return parameters; | ||
} | ||
|
||
private int skip(String sql, int currentIndex, @Nullable StringBuilder result) { | ||
char currentChar = sql.charAt(currentIndex); | ||
if (currentChar == SINGLE_QUOTE || currentChar == DOUBLE_QUOTE) { | ||
appendIfNotNull(result, currentChar); | ||
return skipQuoted(sql, currentIndex, currentChar, result); | ||
} else if (currentChar == DOLLAR) { | ||
String dollarTag = parseDollarQuotedString(sql, currentIndex + 1); | ||
if (dollarTag != null) { | ||
appendIfNotNull(result, currentChar, dollarTag, currentChar); | ||
return skipQuoted( | ||
sql, currentIndex + dollarTag.length() + 1, currentChar, dollarTag, result); | ||
} | ||
} else if (currentChar == HYPHEN | ||
&& sql.length() > (currentIndex + 1) | ||
&& sql.charAt(currentIndex + 1) == HYPHEN) { | ||
return skipSingleLineComment(sql, currentIndex, result); | ||
} else if (currentChar == SLASH | ||
&& sql.length() > (currentIndex + 1) | ||
&& sql.charAt(currentIndex + 1) == ASTERISK) { | ||
return skipMultiLineComment(sql, currentIndex, result); | ||
} | ||
|
||
appendIfNotNull(result, currentChar); | ||
return currentIndex + 1; | ||
} | ||
|
||
static int skipSingleLineComment(String sql, int currentIndex, @Nullable StringBuilder result) { | ||
int endIndex = sql.indexOf('\n', currentIndex + 2); | ||
if (endIndex == -1) { | ||
endIndex = sql.length(); | ||
} else { | ||
// Include the newline character. | ||
endIndex++; | ||
} | ||
appendIfNotNull(result, sql.substring(currentIndex, endIndex)); | ||
return endIndex; | ||
} | ||
|
||
static int skipMultiLineComment(String sql, int startIndex, @Nullable StringBuilder result) { | ||
// Current position is start + '/*'.length(). | ||
int pos = startIndex + 2; | ||
// PostgreSQL allows comments to be nested. That is, the following is allowed: | ||
// '/* test /* inner comment */ still a comment */' | ||
int level = 1; | ||
while (pos < sql.length()) { | ||
if (sql.charAt(pos) == SLASH && sql.length() > (pos + 1) && sql.charAt(pos + 1) == ASTERISK) { | ||
level++; | ||
} | ||
if (sql.charAt(pos) == ASTERISK && sql.length() > (pos + 1) && sql.charAt(pos + 1) == SLASH) { | ||
level--; | ||
if (level == 0) { | ||
pos += 2; | ||
appendIfNotNull(result, sql.substring(startIndex, pos)); | ||
return pos; | ||
} | ||
} | ||
pos++; | ||
} | ||
appendIfNotNull(result, sql.substring(startIndex)); | ||
return sql.length(); | ||
} | ||
|
||
private int skipQuoted( | ||
String sql, int startIndex, char startQuote, @Nullable StringBuilder result) { | ||
return skipQuoted(sql, startIndex, startQuote, null, result); | ||
} | ||
|
||
private int skipQuoted( | ||
String sql, | ||
int startIndex, | ||
char startQuote, | ||
String dollarTag, | ||
@Nullable StringBuilder result) { | ||
int currentIndex = startIndex + 1; | ||
while (currentIndex < sql.length()) { | ||
char currentChar = sql.charAt(currentIndex); | ||
if (currentChar == startQuote) { | ||
if (currentChar == DOLLAR) { | ||
// Check if this is the end of the current dollar quoted string. | ||
String tag = parseDollarQuotedString(sql, currentIndex + 1); | ||
if (tag != null && tag.equals(dollarTag)) { | ||
appendIfNotNull(result, currentChar, dollarTag, currentChar); | ||
return currentIndex + tag.length() + 2; | ||
} | ||
} else if (sql.length() > currentIndex + 1 && sql.charAt(currentIndex + 1) == startQuote) { | ||
// This is an escaped quote (e.g. 'foo''bar') | ||
appendIfNotNull(result, currentChar); | ||
appendIfNotNull(result, currentChar); | ||
currentIndex += 2; | ||
continue; | ||
} else { | ||
appendIfNotNull(result, currentChar); | ||
return currentIndex + 1; | ||
} | ||
} | ||
currentIndex++; | ||
appendIfNotNull(result, currentChar); | ||
} | ||
throw SpannerExceptionFactory.newSpannerException( | ||
ErrorCode.INVALID_ARGUMENT, "SQL statement contains an unclosed literal: " + sql); | ||
} | ||
|
||
private void appendIfNotNull(@Nullable StringBuilder result, char currentChar) { | ||
if (result != null) { | ||
result.append(currentChar); | ||
} | ||
} | ||
|
||
private static void appendIfNotNull(@Nullable StringBuilder result, String suffix) { | ||
if (result != null) { | ||
result.append(suffix); | ||
} | ||
} | ||
|
||
private void appendIfNotNull( | ||
@Nullable StringBuilder result, char prefix, String tag, char suffix) { | ||
if (result != null) { | ||
result.append(prefix).append(tag).append(suffix); | ||
} | ||
} | ||
|
||
private boolean isValidIdentifierFirstChar(char c) { | ||
return Character.isLetter(c) || c == UNDERSCORE; | ||
} | ||
|
||
private boolean isValidIdentifierChar(char c) { | ||
return isValidIdentifierFirstChar(c) || Character.isDigit(c) || c == DOLLAR; | ||
} | ||
|
||
private boolean checkCharPrecedingReturning(char ch) { | ||
return (ch == SPACE) | ||
|| (ch == SINGLE_QUOTE) | ||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All the methods that are added here, are only copy-pasted from
PostgreSQLStatementParser
. We do this as step 1 for a larger refactoring, so the next steps are easier to follow and review.