@@ -166,6 +166,46 @@ PARSER_END(CCJSqlParser)
166
166
TOKEN_MGR_DECLS : {
167
167
public FeatureConfiguration configuration = new FeatureConfiguration();
168
168
169
+ // Identify the index of the quoting/escaping tokens
170
+ public int charLiteralIndex = -1;
171
+ public int squaredBracketOpenIndex = -1;
172
+ {
173
+ for (int i=0;i<CCJSqlParserConstants.tokenImage.length;i++) {
174
+ if ( CCJSqlParserConstants.tokenImage[i].equals("<S_CHAR_LITERAL>") ) {
175
+ charLiteralIndex = i;
176
+ break;
177
+ }
178
+ }
179
+ for (int i=0;i<CCJSqlParserConstants.tokenImage.length;i++) {
180
+ if (CCJSqlParserConstants.tokenImage[i].equals("\"[\"")) {
181
+ squaredBracketOpenIndex = i;
182
+ break;
183
+ }
184
+ }
185
+ }
186
+
187
+ // Finds first occurrence of "\\'"
188
+ public static int indexOfSequence(String s, String target) {
189
+ int len = s.length();
190
+ for (int i = 0; i < len - 1; i++) {
191
+ if (s.charAt(i) == '\\' && s.charAt(i + 1) == '\'') {
192
+ return i;
193
+ }
194
+ }
195
+ return -1;
196
+ }
197
+
198
+ // Finds last occurrence of "\\''"
199
+ public static int lastIndexOfSequence(String s, String target) {
200
+ int len = s.length();
201
+ for (int i = len - 3; i >= 0; i--) {
202
+ if (s.charAt(i) == '\\' && s.charAt(i + 1) == '\'' && s.charAt(i + 2) == '\'') {
203
+ return i;
204
+ }
205
+ }
206
+ return -1;
207
+ }
208
+
169
209
public void CommonTokenAction(Token t)
170
210
{
171
211
t.absoluteBegin = getCurrentTokenAbsolutePosition();
@@ -614,6 +654,7 @@ TOKEN : /* Statement Separators */
614
654
TOKEN : /* Operators */
615
655
{
616
656
<OP_GREATERTHANEQUALS: ">" (<WHITESPACE>)* "=">
657
+ | <OP_COSINESIMILARITY: "<=>">
617
658
| <OP_MINORTHANEQUALS: "<" (<WHITESPACE>)* "=">
618
659
| <OP_NOTEQUALSSTANDARD: "<" (<WHITESPACE>)* ">">
619
660
| <OP_NOTEQUALSBANG: "!" (<WHITESPACE>)* "=">
@@ -738,33 +779,33 @@ TOKEN:
738
779
// which contains the <SPECIAL_ESC>, then we will need to
739
780
// 1) break the <S_CHAR_LITERAL> at <SPECIAL_ESC> close it with a "'"
740
781
// 2) continue tokenizing after that <SPECIAL_ESC> with a new <S_CHAR_LITERAL> or any other Token
741
- if ( !configuration.getAsBoolean(Feature.allowBackslashEscapeCharacter) && matchedToken.image.contains("\\'") ) {
742
- matchedToken.image = image.substring( 0, image.indexOf("\\'") + 1 ) + "'";
743
- for (int i=0;i<CCJSqlParserConstants.tokenImage.length;i++) {
744
- if ( CCJSqlParserConstants.tokenImage[i].equals("<S_CHAR_LITERAL>") ) {
745
- matchedToken.kind = i;
746
- }
782
+ boolean allowEscape = configuration.getAsBoolean(Feature.allowBackslashEscapeCharacter);
783
+ String img = matchedToken.image;
784
+ int pos;
785
+ if (!allowEscape) {
786
+ pos = indexOfSequence(img, "\\'");
787
+ if (pos > 0) {
788
+ matchedToken.image = image.substring(0, pos + 1) + "'";
789
+ matchedToken.kind = charLiteralIndex;
790
+ input_stream.backup(image.length() - matchedToken.image.length());
747
791
}
748
- input_stream.backup(image.length() - matchedToken.image.length() );
749
- } else if ( configuration.getAsBoolean(Feature.allowBackslashEscapeCharacter) && matchedToken.image.contains("\\''") ) {
750
- matchedToken.image = image.substring( 0, image.lastIndexOf("\\'") + 3);
751
- for (int i=0;i<CCJSqlParserConstants.tokenImage.length;i++) {
752
- if ( CCJSqlParserConstants.tokenImage[i].equals("<S_CHAR_LITERAL>") ) {
753
- matchedToken.kind = i;
754
- }
792
+ } else {
793
+ pos = lastIndexOfSequence(img, "\\''");
794
+ if (pos > 0) {
795
+ matchedToken.image = image.substring(0, pos + 3);
796
+ matchedToken.kind = charLiteralIndex;
797
+ input_stream.backup(image.length() - matchedToken.image.length());
755
798
}
756
- input_stream.backup(image.length() - matchedToken.image.length() );
757
- }
799
+ }
758
800
}
759
801
| < S_QUOTED_IDENTIFIER: "\"" ( "\"\"" | ~["\n","\r","\""])* "\"" | "$$" (~["$"])* "$$" | ("`" (~["\n","\r","`"])+ "`") | ( "[" (~["\n","\r","]"])* "]" ) >
760
802
{
761
- if ( !configuration.getAsBoolean(Feature.allowSquareBracketQuotation) && matchedToken.image.charAt(0) == '[' ) {
803
+ if ( !configuration.getAsBoolean(Feature.allowSquareBracketQuotation)
804
+ && matchedToken.image.charAt(0) == '[' ) {
805
+
762
806
matchedToken.image = "[";
763
- for (int i=0;i<CCJSqlParserConstants.tokenImage.length;i++) {
764
- if (CCJSqlParserConstants.tokenImage[i].equals("\"[\"")) {
765
- matchedToken.kind = i;
766
- }
767
- }
807
+ // `squaredBracketOpenIndex` defined in TokenManagerDeclaration above
808
+ matchedToken.kind = squaredBracketOpenIndex;
768
809
input_stream.backup(image.length() - 1);
769
810
}
770
811
}
@@ -4614,7 +4655,7 @@ Expression RegularCondition() #RegularCondition:
4614
4655
| "-#" { result = new JsonOperator("-#"); }
4615
4656
| "<->" { result = new GeometryDistance("<->"); }
4616
4657
| "<#>" { result = new GeometryDistance("<#>"); }
4617
- | "<=>" { result = new CosineSimilarity(); }
4658
+ | <OP_COSINESIMILARITY> { result = new CosineSimilarity(); }
4618
4659
)
4619
4660
4620
4661
( LOOKAHEAD(2) <K_PRIOR> rightExpression=ComparisonItem() { oraclePrior = EqualsTo.ORACLE_PRIOR_END; }
0 commit comments