Skip to content

Commit 52df32d

Browse files
feat: add a method checking balanced brackets
Signed-off-by: Andreas Reichel <[email protected]>
1 parent c3ffb86 commit 52df32d

File tree

3 files changed

+51
-3
lines changed

3 files changed

+51
-3
lines changed

src/main/java/net/sf/jsqlparser/parser/CCJSqlParserUtil.java

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import java.io.IOException;
1313
import java.io.InputStream;
1414
import java.io.Reader;
15+
import java.util.Stack;
1516
import java.util.concurrent.Callable;
1617
import java.util.concurrent.ExecutorService;
1718
import java.util.concurrent.Executors;
@@ -439,4 +440,43 @@ public static int getNestingDepth(String sql) {
439440
}
440441
return maxlevel;
441442
}
443+
444+
public static int getUnbalancedPosition(String text) {
445+
Stack<Character> stack = new Stack<>();
446+
boolean insideQuote = false;
447+
448+
for (int i = 0; i < text.length(); i++) {
449+
char c = text.charAt(i);
450+
if (c == '"' || c == '\'') {
451+
if (!insideQuote) {
452+
stack.push(c); // Add quote to stack
453+
} else if (stack.peek() == c) {
454+
stack.pop(); // Matching quote found, remove from stack
455+
}
456+
insideQuote = !insideQuote; // Toggle insideQuote flag
457+
} else if (!insideQuote && (c == '(' || c == '[' || c == '{')) {
458+
stack.push(c); // Add opening bracket to stack
459+
} else if (!insideQuote && (c == ')' || c == ']' || c == '}')) {
460+
if (stack.isEmpty()) {
461+
return i; // Return position of unbalanced closing bracket
462+
}
463+
char top = stack.pop();
464+
if ((c == ')' && top != '(') || (c == ']' && top != '[') || (c == '}' && top != '{')) {
465+
return i; // Return position of unbalanced closing bracket
466+
}
467+
}
468+
}
469+
470+
if (!stack.isEmpty()) {
471+
char unbalanced = stack.peek();
472+
for (int i = 0; i < text.length(); i++) {
473+
if (text.charAt(i) == unbalanced) {
474+
return i; // Return position of unbalanced opening bracket or quote
475+
}
476+
}
477+
}
478+
479+
return -1; // Return -1 if all brackets and quotes are balanced
480+
}
481+
442482
}

src/test/java/net/sf/jsqlparser/parser/CCJSqlParserUtilTest.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,4 +491,13 @@ public void execute() throws Throwable {
491491
executorService.shutdownNow();
492492
CCJSqlParserUtil.LOGGER.setLevel(Level.OFF);
493493
}
494+
495+
@Test
496+
void testUnbalancedPosition() {
497+
String sqlStr = "SELECT * from ( test ";
498+
sqlStr = "select\n" +
499+
" concat('{','\"dffs\":\"',if(dffs is null,'',cast(dffs as string),'\",\"djr\":\"',if(djr is null,'',cast(djr as string),'\",\"djrq\":\"',if(djrq is null,'',cast(djrq as string),'\",\"thjssj\":\"',if(thjssj is null,'',cast(thjssj as string),'\",\"thkssj\":\"',if(thkssj is null,'',cast(thkssj as string),'\",\"sjc\":\"',if(sjc is null,'',cast(sjc as string),'\",\"ldhm\":\"',if(ldhm is null,'',cast(ldhm as string),'\",\"lxdh\":\"',if(lxdh is null,'',cast(lxdh as string),'\",\"md\":\"',if(md is null,'',cast(md as string),'\",\"nr\":\"',if(nr is null,'',cast(nr as string),'\",\"nrfl\":\"',if(nrfl is null,'',cast(nrfl as string),'\",\"nrwjid\":\"',if(nrwjid is null,'',cast(nrwjid as string),'\",\"sfbm\":\"',if(sfbm is null,'',cast(sfbm as string),'\",\"sjly\":\"',if(sjly is null,'',cast(sjly as string),'\",\"wtsd\":\"',if(wtsd is null,'',cast(wtsd as string),'\",\"xb\":\"',if(xb is null,'',cast(xb as string),'\",\"xfjbh\":\"',if(xfjbh is null,'',cast(xfjbh as string),'\",\"xfjid\":\"',if(xfjid is null,'',cast(xfjid as string),'\",\"xm\":\"',if(xm is null,'',cast(xm as string),'\",\"zhut\":\"',if(zhut is null,'',cast(zhut as string),'\",\"zt\":\"',if(zt is null,'',cast(zt as string),'\"}')\n" +
500+
" from tab";
501+
assertEquals(-1 , CCJSqlParserUtil.getUnbalancedPosition(sqlStr));
502+
}
494503
}

src/test/java/net/sf/jsqlparser/statement/select/SelectTest.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5672,11 +5672,10 @@ void testParameterMultiPartName() throws JSQLParserException {
56725672
String sqlStr = "SELECT 1 FROM dual WHERE a = :paramMap.aValue";
56735673
PlainSelect select = (PlainSelect) assertSqlCanBeParsedAndDeparsed(sqlStr, true);
56745674

5675-
assertTrue(select
5675+
assertEquals("paramMap.aValue", select
56765676
.getWhere(EqualsTo.class)
56775677
.getRightExpression(JdbcNamedParameter.class)
5678-
.getName()
5679-
.equals("paramMap.aValue"));
5678+
.getName());
56805679
}
56815680

56825681
@Test

0 commit comments

Comments
 (0)