You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hi, I am trying to dynamically add condition statements to SQL using JSqlparser. However, it seems there is an issue when the SQL contains a natural join:
publicstaticvoidmain(String[] args) throwsJSQLParserException {
Stringsql = "SELECT * FROM A a, B b where a.id = b.id";
Statementstatement = CCJSqlParserUtil.parse(sql, null);
PlainSelectplainSelect = (PlainSelect) ((Select) statement).getSelectBody();
Joinjoin = CollUtil.getFirst(plainSelect.getJoins());
// append a condition "a.id = '100'"join.setOnExpression(newEqualsTo(newColumn("a.id"), newStringValue("100")));
// = "SELECT * FROM A a, B b WHERE a.id = b.id"System.out.println(statement.toString());
}
I am not sure how JSqlparser handles this situation, but SELECT * FROM A a, B b WHERE a.id = b.id is clearly not the expected result.
Analysis
I tried debugging to find the root cause of this issue. I noticed that in the above code, the query of table B is parsed into a net.sf.jsqlparser.statement.select.Join object, and at this point, Join.simple is true.
After setting the ON condition with join.setOnExpression(new EqualsTo(new Column("a.id"), new StringValue("100"))); and attempting to convert it back to SQL, the ON condition is not correctly parsed into SQL because Join.simple is true:
@OverridepublicStringtoString() {
if (isSimple() && isOuter()) {
return"OUTER " + rightItem;
} elseif (isSimple()) {
return"" + rightItem;
} else {
// isSimple() returns true, so this branch is ignoredStringtype = "";
if (isRight()) {
type += "RIGHT ";
} elseif (isNatural()) {
type += "NATURAL ";
} elseif (isFull()) {
type += "FULL ";
} elseif (isLeft()) {
type += "LEFT ";
} elseif (isCross()) {
type += "CROSS ";
}
if (isOuter()) {
type += "OUTER ";
} elseif (isInner()) {
type += "INNER ";
} elseif (isSemi()) {
type += "SEMI ";
}
if (isStraight()) {
type = "STRAIGHT_JOIN ";
} elseif (isApply()) {
type += "APPLY ";
} else {
type += "JOIN ";
}
returntype + rightItem + ((joinWindow != null) ? " WITHIN " + joinWindow : "")
+ ((onExpression != null) ? " ON " + onExpression + "" : "")
+ PlainSelect.getFormatedList(usingColumns, "USING", true, true);
}
}
Fix
Calling join.setSimple(false) after setOnExpression fixes the issue:
publicstaticvoidmain(String[] args) throwsJSQLParserException {
Stringsql = "SELECT * FROM A a, B b where a.id = b.id";
Statementstatement = CCJSqlParserUtil.parse(sql, null);
PlainSelectplainSelect = (PlainSelect) ((Select) statement).getSelectBody();
Joinjoin = CollUtil.getFirst(plainSelect.getJoins());
join.setOnExpression(newEqualsTo(newColumn("a.id"), newStringValue("100")));
join.setSimple(false); // set Join.simple to false// SELECT * FROM A a JOIN B b ON a.id = '100' WHERE a.id = b.idSystem.out.println(statement.toString());
}
In fact, if the ON condition is not null, isSimple should return false. Should we make the following changes to fix this issue?
When calling the setOnExpression method, if the parameter is not null, set simple to false.
When calling the isSimple method, check if onExpression is null.
The text was updated successfully, but these errors were encountered:
Description
Hi, I am trying to dynamically add condition statements to SQL using JSqlparser. However, it seems there is an issue when the SQL contains a natural join:
I am not sure how JSqlparser handles this situation, but
SELECT * FROM A a, B b WHERE a.id = b.id
is clearly not the expected result.Analysis
I tried debugging to find the root cause of this issue. I noticed that in the above code, the query of table B is parsed into a
net.sf.jsqlparser.statement.select.Join
object, and at this point,Join.simple
istrue
.After setting the ON condition with
join.setOnExpression(new EqualsTo(new Column("a.id"), new StringValue("100")));
and attempting to convert it back to SQL, the ON condition is not correctly parsed into SQL becauseJoin.simple
istrue
:Fix
Calling
join.setSimple(false)
aftersetOnExpression
fixes the issue:In fact, if the ON condition is not null,
isSimple
should returnfalse
. Should we make the following changes to fix this issue?setOnExpression
method, if the parameter is not null, setsimple
tofalse
.isSimple
method, check ifonExpression
is null.The text was updated successfully, but these errors were encountered: