Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
package net.sf.jsqlparser.expression.operators.relational;

import java.util.Locale;
import java.util.regex.Pattern;
import net.sf.jsqlparser.expression.BinaryExpression;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.ExpressionVisitor;
Expand Down Expand Up @@ -174,9 +175,11 @@ public LikeExpression withRightExpression(Expression arg0) {
public enum KeyWord {
LIKE, ILIKE, RLIKE, REGEXP_LIKE, REGEXP, GLOB, SIMILAR_TO, MATCH_ANY, MATCH_ALL, MATCH_PHRASE, MATCH_PHRASE_PREFIX, MATCH_REGEXP;

private static final Pattern WHITESPACE = Pattern.compile("\\s+");

public static KeyWord from(String keyword) {
return Enum.valueOf(KeyWord.class,
keyword.toUpperCase(Locale.ROOT).replaceAll("\\s+", "_"));
WHITESPACE.matcher(keyword.toUpperCase(Locale.ROOT)).replaceAll("_"));
}
}

Expand Down
51 changes: 36 additions & 15 deletions src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt
Original file line number Diff line number Diff line change
Expand Up @@ -1333,12 +1333,8 @@ public class CCJSqlParser extends AbstractJSqlParser<CCJSqlParser> {
* everywhere else, e.g. f(content).
*/
private void consumeXmlLeadingKeyword(Function function) {
String name = function.getName();
if (name == null) {
return;
}
name = name.toUpperCase(java.util.Locale.ROOT);
if (!"XMLPARSE".equals(name) && !"XMLELEMENT".equals(name) && !"XMLFOREST".equals(name)) {
if (!hasUnqualifiedName(function, "XMLPARSE") && !hasUnqualifiedName(function, "XMLELEMENT")
&& !hasUnqualifiedName(function, "XMLFOREST")) {
return;
}
Token token = getToken(1);
Expand All @@ -1358,6 +1354,12 @@ public class CCJSqlParser extends AbstractJSqlParser<CCJSqlParser> {
function.setExtraKeyword(getNextToken().image);
}

// Matches the single name part, since getName() joins the parts into a new string on each call.
private static boolean hasUnqualifiedName(Function function, String name) {
List<String> nameParts = function.getMultipartName();
return nameParts != null && nameParts.size() == 1 && name.equalsIgnoreCase(nameParts.get(0));
}

/**
* An unquoted YEAR, MONTH, DAY, HOUR, MINUTE or SECOND passed on its own as a function argument, as in
* DATEADD(day, 1, d), is a date unit. Anywhere else it is an ordinary identifier, so it is parsed as a
Expand Down Expand Up @@ -12181,14 +12183,20 @@ Expression Condition():
Expression result;
Expression left;
// Leading NOT / ! prefixes, leftmost token wraps outermost (issue #1170).
final Deque<Boolean> exclamationMarks = new ArrayDeque<Boolean>();
Deque<Boolean> exclamationMarks = null;
int oraclePrior = EqualsTo.NO_ORACLE_PRIOR;
int oracleJoin = EqualsTo.NO_ORACLE_JOIN;
}
{
(
LOOKAHEAD({ getToken(1).kind == K_NOT || "!".equals(getToken(1).image) })
( <K_NOT> { exclamationMarks.addFirst(Boolean.FALSE); } | "!" { exclamationMarks.addFirst(Boolean.TRUE); } )
( <K_NOT> | "!" )
{
if (exclamationMarks == null) {
exclamationMarks = new ArrayDeque<Boolean>();
}
exclamationMarks.addFirst("!".equals(getToken(0).image));
}
)*
(
LOOKAHEAD(<K_EXISTS> JdbcNamedParameter() ":", {
Expand Down Expand Up @@ -12258,7 +12266,7 @@ Expression Condition():
&& result instanceof SupportsOldOracleJoinSyntax) {
((SupportsOldOracleJoinSyntax) result).setOraclePriorPosition(oraclePrior);
}
while (!exclamationMarks.isEmpty()) {
while (exclamationMarks != null && !exclamationMarks.isEmpty()) {
result = new NotExpression(result, exclamationMarks.pollFirst());
}
return result;
Expand Down Expand Up @@ -13192,21 +13200,29 @@ Expression PrimaryExpression() #PrimaryExpression:
Token token = null;
Token sign = null;
Token innerSign;
List<Token> innerSigns = new ArrayList<Token>();
List<Token> innerSigns = null;
ColDataType type = null;
boolean not = false;
boolean exclamationMarkNot = false;
boolean dateExpressionAllowed = true;
ExpressionList list;

final List<Map.Entry<Expression, String>> jsonIdents = new ArrayList<Map.Entry<Expression, String>>();
List<Map.Entry<Expression, String>> jsonIdents = null;
}
{
[ <K_NOT> { not=true; } | "!" { not=true; exclamationMarkNot=true; } ]
[
( sign="+" | sign="-" | sign="~" )
// DuckDB's chained signs, e.g. - -1 or +-+1
( LOOKAHEAD(1) ( innerSign="+" | innerSign="-" | innerSign="~" ) { innerSigns.add(innerSign); } )*
(
LOOKAHEAD(1) ( innerSign="+" | innerSign="-" | innerSign="~" )
{
if (innerSigns == null) {
innerSigns = new ArrayList<Token>();
}
innerSigns.add(innerSign);
}
)*
]
(
<K_NULL> { retval = new NullValue(); }
Expand Down Expand Up @@ -13405,6 +13421,9 @@ Expression PrimaryExpression() #PrimaryExpression:
expression=SimpleExpression()
)
{
if (jsonIdents == null) {
jsonIdents = new ArrayList<Map.Entry<Expression, String>>();
}
jsonIdents.add(new AbstractMap.SimpleEntry<Expression, String>(expression, token.image ));
}
)+
Expand All @@ -13424,8 +13443,10 @@ Expression PrimaryExpression() #PrimaryExpression:
timezoneExpr.setLeftExpression(retval);
retval=timezoneExpr;
}
for (int i = innerSigns.size() - 1; i >= 0; i--) {
retval = new SignedExpression(innerSigns.get(i).image.charAt(0), retval);
if (innerSigns != null) {
for (int i = innerSigns.size() - 1; i >= 0; i--) {
retval = new SignedExpression(innerSigns.get(i).image.charAt(0), retval);
}
}
if (sign != null) {
retval = new SignedExpression(sign.image.charAt(0), retval);
Expand Down Expand Up @@ -15420,7 +15441,7 @@ ExpressionList FunctionArgumentList(Function retval):
Token extraKeywordToken;
}
{
{ if ("XMLFOREST".equalsIgnoreCase(retval.getName())) { return XmlForestArguments(); } }
{ if (hasUnqualifiedName(retval, "XMLFOREST")) { return XmlForestArguments(); } }
[ LOOKAHEAD(2) extraKeywordToken = <K_TABLE> { retval.setExtraKeyword(extraKeywordToken.image); } ]
expressionList=ExpressionList()
// explicit lookahead: InternalFunction accepts ORDER BY after IGNORE NULLS too
Expand Down
Loading