Skip to content
Open
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
56 changes: 56 additions & 0 deletions src/main/java/net/sf/jsqlparser/parser/CCJSqlParserUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import net.sf.jsqlparser.parser.feature.Feature;
import net.sf.jsqlparser.statement.Statement;
import net.sf.jsqlparser.statement.Statements;
import net.sf.jsqlparser.statement.create.table.ColDataType;

/**
* Toolfunctions to start and use JSqlParser.
Expand Down Expand Up @@ -199,6 +200,61 @@ public static Expression parseExpression(String expression, boolean allowPartial
});
}

/**
* Parses a column data type fragment. The complete input must represent the data type; trailing
* tokens are rejected.
*
* @param columnDataType the column data type fragment to parse
* @return the parsed column data type, or {@code null} for a null or empty input
* @throws JSQLParserException when the input cannot be parsed completely
* @see #parseColDataType(String, Consumer)
*/
public static ColDataType parseColDataType(String columnDataType) throws JSQLParserException {
return parseColDataType(columnDataType, null);
}

/**
* Parses a column data type fragment while allowing the parser to be configured. The complete
* input must represent the data type; trailing tokens are rejected.
*
* @param columnDataType the column data type fragment to parse
* @param consumer parser configuration callback, or {@code null}
* @return the parsed column data type, or {@code null} for a null or empty input
* @throws JSQLParserException when the input cannot be parsed completely
*/
public static ColDataType parseColDataType(String columnDataType,
Consumer<CCJSqlParser> consumer) throws JSQLParserException {
if (columnDataType == null || columnDataType.isEmpty()) {
return null;
}

try {
return parseColDataType(columnDataType, false, consumer);
} catch (JSQLParserException ex) {
return parseColDataType(columnDataType, true, consumer);
}
}

private static ColDataType parseColDataType(String columnDataType, boolean allowComplexParsing,
Consumer<CCJSqlParser> consumer) throws JSQLParserException {
CCJSqlParser parser = newParser(columnDataType)
.withAllowComplexParsing(allowComplexParsing);
if (consumer != null) {
consumer.accept(parser);
}

try {
ColDataType result = parser.ColDataType();
if (parser.getNextToken().kind != CCJSqlParserTokenManager.EOF) {
throw new JSQLParserException(
"could only parse partial column data type " + result);
}
return result;
} catch (ParseException ex) {
throw new JSQLParserException(columnDataType, ex);
}
}

@SuppressWarnings("PMD.CyclomaticComplexity")
public static Expression parseExpression(String expressionStr, boolean allowPartialParse,
Consumer<CCJSqlParser> consumer) throws JSQLParserException {
Expand Down
30 changes: 30 additions & 0 deletions src/test/java/net/sf/jsqlparser/parser/CCJSqlParserUtilTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import net.sf.jsqlparser.statement.Statement;
import net.sf.jsqlparser.statement.Statements;
import net.sf.jsqlparser.statement.UnsupportedStatement;
import net.sf.jsqlparser.statement.create.table.ColDataType;
import net.sf.jsqlparser.statement.select.PlainSelect;
import net.sf.jsqlparser.statement.select.Select;
import net.sf.jsqlparser.statement.select.TableStatement;
Expand All @@ -39,6 +40,7 @@
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicBoolean;

import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
Expand Down Expand Up @@ -107,6 +109,34 @@ public void testParseExpression2() throws Exception {
assertInstanceOf(ParenthesedExpressionList.class, mult.getRightExpression());
}

@Test
public void testParseColDataType() throws Exception {
assertNull(CCJSqlParserUtil.parseColDataType(null));
assertNull(CCJSqlParserUtil.parseColDataType(""));

ColDataType arrayType = CCJSqlParserUtil.parseColDataType("integer[][]");
assertEquals("integer", arrayType.getDataType());
assertEquals(2, arrayType.getArrayData().size());
assertNull(arrayType.getArrayData().get(0));
assertNull(arrayType.getArrayData().get(1));

AtomicBoolean configured = new AtomicBoolean();
ColDataType enumType =
CCJSqlParserUtil.parseColDataType("enum('small','medium')", parser -> {
configured.set(true);
parser.withDialect(AbstractJSqlParser.Dialect.MYSQL);
});
assertTrue(configured.get());
assertEquals("enum", enumType.getDataType());
assertEquals(List.of("'small'", "'medium'"), enumType.getArgumentsStringList());
}

@Test
public void testParseColDataTypeRejectsTrailingTokens() {
assertThrows(JSQLParserException.class,
() -> CCJSqlParserUtil.parseColDataType("varchar(255) NOT NULL"));
}

@Test
public void testParseExpressionNonPartial() throws Exception {
assertThrows(JSQLParserException.class,
Expand Down
Loading