diff --git a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt index f6dc2e737..915a22992 100644 --- a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt +++ b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt @@ -10705,6 +10705,8 @@ ColDataType ColDataType(): Token prefix = null; Token tk = null; Token tk2 = null; + Token intervalUnit = null; + Token intervalTo = null; String schema; String type=""; List argumentsStringList = new ArrayList(); @@ -10753,6 +10755,9 @@ ColDataType ColDataType(): | tk= ) { schema = tk.image; } + // INTERVAL qualifier such as `interval hour to minute` or `interval year` (PG/Oracle column type) + [ LOOKAHEAD({ tk.kind == K_INTERVAL && getToken(1).kind == K_DATE_LITERAL }) intervalUnit= { schema += " " + intervalUnit.image; } + [ intervalTo= intervalUnit= { schema += " " + intervalTo.image + " " + intervalUnit.image; } ] ] [ LOOKAHEAD(2) "." arrayType = ColDataType() { schema += "." + arrayType.toString(); } ] { colDataType.setDataType(schema); } ) diff --git a/src/test/java/net/sf/jsqlparser/statement/create/table/ColDataTypeTest.java b/src/test/java/net/sf/jsqlparser/statement/create/table/ColDataTypeTest.java index 5fdae46c2..c46c6f5e4 100644 --- a/src/test/java/net/sf/jsqlparser/statement/create/table/ColDataTypeTest.java +++ b/src/test/java/net/sf/jsqlparser/statement/create/table/ColDataTypeTest.java @@ -14,6 +14,7 @@ import org.junit.jupiter.api.Test; import static net.sf.jsqlparser.test.TestUtils.assertSqlCanBeParsedAndDeparsed; +import static org.junit.jupiter.api.Assertions.assertEquals; class ColDataTypeTest { @Test @@ -57,4 +58,26 @@ void testStruct() throws JSQLParserException { " );\n"; assertSqlCanBeParsedAndDeparsed(sqlStr, true); } + + // PG/Oracle allow an INTERVAL column type carrying a time-unit qualifier, + // e.g. `interval hour to minute`. Previously the qualifier was not consumed + // as part of the data type, so parsing failed with "Encountered ... ". + @Test + void testIntervalQualifierIssue1728() throws JSQLParserException { + String sqlStr = "CREATE TABLE films (code char(5), len interval hour to minute)"; + CreateTable create = (CreateTable) assertSqlCanBeParsedAndDeparsed(sqlStr, true); + + // The qualifier must be attached to the column's data type, not parsed as an + // alias or left unconsumed. + ColumnDefinition len = create.getColumnDefinitions().stream() + .filter(c -> c.getColumnName().equalsIgnoreCase("len")) + .findFirst() + .orElseThrow(); + assertEquals("interval hour to minute", len.getColDataType().getDataType()); + } + + @Test + void testIntervalQualifierYearToMonthIssue1728() throws JSQLParserException { + assertSqlCanBeParsedAndDeparsed("CREATE TABLE t (a interval year to month)", true); + } }