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 @@ -103,9 +103,10 @@ public static ColDataType fromTypeParameters(String dataType, String precision,
private void setNumericTypeParameters(String parameter, Integer scale) {
if (parameter != null) {
maxPrecision = "MAX".equalsIgnoreCase(parameter);
precision = maxPrecision ? null : new BigInteger(parameter);
// Oracle's NUMBER(*, s) has no precision of its own.
precision = maxPrecision || "*".equals(parameter) ? null : new BigInteger(parameter);
this.scale = scale;
dataType += " (" + (maxPrecision ? "MAX" : precision)
dataType += " (" + (maxPrecision ? "MAX" : precision != null ? precision : parameter)
+ (scale != null ? ", " + scale : "") + ")";
}
}
Expand Down Expand Up @@ -330,9 +331,10 @@ public ColDataType withXmlTypeModifier(XmlTypeModifier xmlTypeModifier) {
* The first numeric type parameter, e.g. {@code 255} for {@code VARCHAR(255)} or {@code 10} for
* {@code DECIMAL(10, 2)}. {@code MAX} is reported as {@link Integer#MAX_VALUE}. Returns
* {@code null} when the type carries no numeric parameters, e.g. {@code INT} or
* {@code ENUM('a', 'b')}, or when a numeric length exceeds the integer range. Use
* {@link #getNumericPrecision()} for the full range and {@link #isMaxPrecision()} to
* distinguish MAX from the numeric value 2147483647.
* {@code ENUM('a', 'b')}, when the precision is Oracle's {@code *} as in {@code NUMBER(*, 0)},
* or when a numeric length exceeds the integer range. Use {@link #getNumericPrecision()} for
* the full range and {@link #isMaxPrecision()} to distinguish MAX from the numeric value
* 2147483647.
*/
public Integer getPrecision() {
return maxPrecision ? Integer.valueOf(Integer.MAX_VALUE)
Expand Down
7 changes: 6 additions & 1 deletion src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt
Original file line number Diff line number Diff line change
Expand Up @@ -18902,7 +18902,10 @@ ColDataType DataType():
| tk=<K_CHAR> | tk=<K_JSON> | tk=<K_STRING> ) { type += " " + tk.image; }
)*
[
LOOKAHEAD(2) "(" ( tk=<S_LONG> { precision = tk.image; } | tk=<K_MAX> { precision = "MAX"; } )
LOOKAHEAD(2) "(" ( tk=<S_LONG> { precision = tk.image; } | tk=<K_MAX> { precision = "MAX"; }
// Oracle's NUMBER(*, s) and NUMBER(*)
| "*" { precision = "*"; requireDdlSyntax("NUMBER".equalsIgnoreCase(type),
"Wildcard precision is only supported for NUMBER"); } )
[ <K_BYTE> | <K_CHAR> ]
[ "," scaleText=SignedIntegerTypeArgument() { scale = Integer.valueOf(scaleText); } ]
")"
Expand Down Expand Up @@ -19045,6 +19048,8 @@ ColDataType ColDataType():
| tk=<K_NAME>
// PostgreSQL's geometric type
| tk=<K_PATH>
// Oracle's RAW(n)
| tk=<K_RAW>
)
{
schema = tk.image;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@

import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.expression.IntervalQualifier;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.test.TestUtils;
import org.junit.jupiter.api.Test;

import static net.sf.jsqlparser.test.TestUtils.assertSqlCanBeParsedAndDeparsed;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;

class ColDataTypeTest {
@Test
Expand Down Expand Up @@ -147,6 +149,31 @@ void testStructuredPrecisionForZonedTypes() throws JSQLParserException {
assertNull(unparameterized.getPrecision());
}

@Test
void testOracleNumberWithWildcardPrecision() throws JSQLParserException {
ColDataType number =
parseColumnType("CREATE TABLE t (a NUMBER(*, 0), b NUMBER(*), c NUMBER(*, 2))");
assertEquals("NUMBER (*, 0)", number.getDataType());
assertEquals("NUMBER", number.getBaseTypeName());
assertNull(number.getPrecision());
assertEquals(0, number.getScale());

assertSqlCanBeParsedAndDeparsed("SELECT CAST(1.5 AS NUMBER(*, 0)) FROM dual", true);

assertThrows(JSQLParserException.class,
() -> CCJSqlParserUtil.parseColDataType("NUMBER(*, *)"));
}

@Test
void testOracleRawType() throws JSQLParserException {
ColDataType raw = parseColumnType("CREATE TABLE t (id RAW(16), payload raw(2000))");
assertEquals("RAW", raw.getDataType());
assertEquals(16, raw.getPrecision());

assertSqlCanBeParsedAndDeparsed("ALTER TABLE t ADD payload RAW(2000)", true);
assertSqlCanBeParsedAndDeparsed("SELECT CAST(HEXTORAW('AB') AS RAW(16)) FROM dual", true);
}

private ColDataType parseColumnType(String sqlStr) throws JSQLParserException {
CreateTable create = (CreateTable) assertSqlCanBeParsedAndDeparsed(sqlStr, true);
return create.getColumnDefinitions().get(0).getColDataType();
Expand Down
Loading