Skip to content

Commit c02708a

Browse files
committed
feat: support wildcard arguments in Oracle VECTOR types
1 parent bfafeaa commit c02708a

3 files changed

Lines changed: 79 additions & 0 deletions

File tree

‎README.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ and missing syntax gets added on demand — [open an issue](https://github.com/J
143143
| **ClickHouse column selection** | `COLUMNS('regexp')` select items with chained `APPLY`, `EXCEPT`, and `REPLACE` transformers |
144144
| **DML** | `INSERT` · `UPDATE` · `UPSERT` · `MERGE` · `DELETE` · `TRUNCATE TABLE` |
145145
| **DDL** | `CREATE …` · `ALTER …` · `DROP …` |
146+
| **Oracle vector types** | `VECTOR(*, *)` · `VECTOR(*, FLOAT32)` · `VECTOR(3, *)`, including dense and sparse storage formats |
146147
| **PostgreSQL ownership** | `DROP OWNED` · `REASSIGN OWNED` |
147148
| **MySQL table maintenance** | `ANALYZE` · `CHECK` · `OPTIMIZE` · `REPAIR TABLE` |
148149
| **MySQL account management** | `CREATE`/`ALTER`/`RENAME USER` · `CREATE ROLE` · `SET ROLE` · `SET DEFAULT ROLE` · `SET PASSWORD` |

‎src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18745,6 +18745,9 @@ ColDataType ColDataType():
1874518745
tk=<DATA_TYPE>
1874618746
|
1874718747
tk=<K_CHAR>
18748+
|
18749+
tk="*" { requireDdlSyntax("VECTOR".equalsIgnoreCase(colDataType.getDataType()),
18750+
"Wildcard type arguments are only supported for VECTOR"); }
1874818751
)
1874918752
)
1875018753
{
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*-
2+
* #%L
3+
* JSQLParser library
4+
* %%
5+
* Copyright (C) 2004 - 2026 JSQLParser
6+
* %%
7+
* Dual licensed under GNU LGPL 2.1 or Apache License 2.0
8+
* #L%
9+
*/
10+
package net.sf.jsqlparser.parser;
11+
12+
import static org.junit.jupiter.api.Assertions.assertEquals;
13+
import static org.junit.jupiter.api.Assertions.assertThrows;
14+
import java.util.Arrays;
15+
import java.util.List;
16+
import net.sf.jsqlparser.JSQLParserException;
17+
import net.sf.jsqlparser.parser.AbstractJSqlParser.Dialect;
18+
import net.sf.jsqlparser.statement.Statement;
19+
import net.sf.jsqlparser.statement.create.table.ColDataType;
20+
import net.sf.jsqlparser.statement.create.table.CreateTable;
21+
import net.sf.jsqlparser.test.TestUtils;
22+
import net.sf.jsqlparser.util.deparser.StatementDeParser;
23+
import org.junit.jupiter.params.ParameterizedTest;
24+
import org.junit.jupiter.params.provider.ValueSource;
25+
26+
class OracleVectorTypeTest {
27+
@ParameterizedTest
28+
@ValueSource(strings = {"*, *", "*, FLOAT32", "3, *", "*, *, DENSE", "*, *, SPARSE",
29+
"*, FLOAT32, SPARSE", "3, *, SPARSE", "3, FLOAT32, *", "*, *, *", "3, FLOAT32",
30+
"3", "1024, FLOAT32, SPARSE"})
31+
void preservesVectorArguments(String arguments) throws JSQLParserException {
32+
List<String> expected = Arrays.asList(arguments.split(", "));
33+
for (String name : List.of("VECTOR", "vector")) {
34+
String typeSql = name + "(" + arguments + ")";
35+
for (ColDataType type : List.of(CCJSqlParserUtil.parseColDataType(typeSql),
36+
CCJSqlParserUtil.parseColDataType(typeSql,
37+
p -> p.withDialect(Dialect.ORACLE)))) {
38+
assertEquals(name, type.getDataType());
39+
assertEquals(expected, type.getArgumentsStringList());
40+
assertEquals(name + " (" + arguments + ")", type.toString());
41+
}
42+
}
43+
}
44+
45+
@ParameterizedTest
46+
@ValueSource(strings = {"VECTOR(*, *)", "VECTOR(*, FLOAT32)", "VECTOR(3, *)",
47+
"VECTOR(*, *, SPARSE)", "VECTOR(3, FLOAT32, *)"})
48+
void roundTripsVectorColumnsBeforeOtherColumns(String typeSql) throws JSQLParserException {
49+
String sql = "CREATE TABLE items (embedding " + typeSql + ", label VARCHAR2(20))";
50+
for (Statement statement : List.of(TestUtils.assertSqlCanBeParsedAndDeparsed(sql),
51+
CCJSqlParserUtil.parse(sql, p -> p.withDialect(Dialect.ORACLE)))) {
52+
CreateTable table = (CreateTable) statement;
53+
assertEquals(2, table.getColumnDefinitions().size());
54+
assertEquals("label", table.getColumnDefinitions().get(1).getColumnName());
55+
StringBuilder buffer = new StringBuilder();
56+
statement.accept(new StatementDeParser(buffer), null);
57+
assertEquals(statement.toString(), buffer.toString());
58+
CreateTable reparsed = (CreateTable) CCJSqlParserUtil.parse(buffer.toString());
59+
assertEquals(
60+
table.getColumnDefinitions().get(0).getColDataType().getArgumentsStringList(),
61+
reparsed.getColumnDefinitions().get(0).getColDataType()
62+
.getArgumentsStringList());
63+
}
64+
}
65+
66+
@ParameterizedTest
67+
@ValueSource(strings = {"VARCHAR(*)", "NUMERIC(3, *)", "custom_type(*)",
68+
"\"VECTOR\"(*, *)", "VECTOR(*,", "VECTOR(, *)", "VECTOR(*, *) NOT NULL"})
69+
void rejectsWildcardsOutsideVectorAndIncompleteTypes(String typeSql) {
70+
assertThrows(JSQLParserException.class, () -> CCJSqlParserUtil.parseColDataType(typeSql));
71+
assertThrows(JSQLParserException.class,
72+
() -> CCJSqlParserUtil.parseColDataType(typeSql,
73+
p -> p.withDialect(Dialect.ORACLE)));
74+
}
75+
}

0 commit comments

Comments
 (0)