Skip to content

Commit 9eaad94

Browse files
authored
Merge branch 'main' into add-oracle-store
2 parents 113ae52 + e87089e commit 9eaad94

12 files changed

Lines changed: 636 additions & 41 deletions

File tree

data/semantickernel-data-jdbc/pom.xml

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<parent>
55
<groupId>com.microsoft.semantic-kernel</groupId>
66
<artifactId>semantickernel-parent</artifactId>
7-
<version>1.4.4-RC2-SNAPSHOT</version>
7+
<version>1.4.4-SNAPSHOT</version>
88
<relativePath>../../pom.xml</relativePath>
99
</parent>
1010

@@ -14,12 +14,13 @@
1414

1515
<dependencies>
1616
<dependency>
17-
<groupId>org.slf4j</groupId>
18-
<artifactId>slf4j-api</artifactId>
17+
<groupId>com.microsoft.semantic-kernel</groupId>
18+
<artifactId>semantickernel-api</artifactId>
1919
</dependency>
20+
2021
<dependency>
21-
<groupId>com.microsoft.semantic-kernel</groupId>
22-
<artifactId>semantickernel-api-data</artifactId>
22+
<groupId>org.slf4j</groupId>
23+
<artifactId>slf4j-api</artifactId>
2324
</dependency>
2425
<dependency>
2526
<groupId>com.fasterxml.jackson.core</groupId>
@@ -31,9 +32,41 @@
3132
<artifactId>jackson-core</artifactId>
3233
<scope>compile</scope>
3334
</dependency>
35+
<dependency>
36+
<groupId>com.github.jknack</groupId>
37+
<artifactId>handlebars</artifactId>
38+
</dependency>
39+
<dependency>
40+
<groupId>com.google.code.findbugs</groupId>
41+
<artifactId>jsr305</artifactId>
42+
</dependency>
43+
<dependency>
44+
<groupId>com.fasterxml.jackson.dataformat</groupId>
45+
<artifactId>jackson-dataformat-yaml</artifactId>
46+
<scope>compile</scope>
47+
</dependency>
3448
<dependency>
3549
<groupId>com.github.spotbugs</groupId>
3650
<artifactId>spotbugs-annotations</artifactId>
3751
</dependency>
52+
<dependency>
53+
<groupId>org.apache.commons</groupId>
54+
<artifactId>commons-text</artifactId>
55+
</dependency>
56+
<dependency>
57+
<groupId>org.postgresql</groupId>
58+
<artifactId>postgresql</artifactId>
59+
<version>42.7.4</version>
60+
</dependency>
61+
<dependency>
62+
<groupId>org.xerial</groupId>
63+
<artifactId>sqlite-jdbc</artifactId>
64+
<version>3.47.0.0</version>
65+
</dependency>
66+
<dependency>
67+
<groupId>com.oracle.database.jdbc</groupId>
68+
<artifactId>ojdbc11</artifactId>
69+
<version>23.7.0.25.01</version>
70+
</dependency>
3871
</dependencies>
3972
</project>

data/semantickernel-data-oracle/src/main/java/com/microsoft/semantickernel/data/jdbc/oracle/OracleDataTypesMapping.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
<<<<<<< add-oracle-store
12
/*
23
** Semantic Kernel Oracle connector version 1.0.
34
**
@@ -70,5 +71,27 @@ public class OracleDataTypesMapping {
7071
/**
7172
* Oracle database type used to map vectors (the parameter is the dimension of the vector)
7273
*/
74+
=======
75+
package com.microsoft.semantickernel.data.jdbc.oracle;
76+
77+
/**
78+
* Defines oracle database type constants for supported field types.
79+
*/
80+
public class OracleDataTypesMapping {
81+
public static final String STRING_VARCHAR = "NVARCHAR2(%s)";
82+
public static final String STRING_CLOB = "CLOB";
83+
public static final String BOOLEAN = "BOOLEAN";
84+
public static final String BYTE = "NUMBER(3)";
85+
public static final String BYTE_ARRAY = "RAW(2000)";
86+
public static final String SHORT = "NUMBER(5)";
87+
public static final String INTEGER = "NUMBER(10)";
88+
public static final String LONG = "NUMBER(19)";
89+
public static final String FLOAT = "BINARY_FLOAT";
90+
public static final String DOUBLE = "BINARY_DOUBLE";
91+
public static final String DECIMAL = "NUMBER";
92+
public static final String OFFSET_DATE_TIME = "TIMESTAMP(7) WITH TIME ZONE";
93+
public static final String UUID = "RAW(16)";
94+
public static final String JSON = "JSON";
95+
>>>>>>> main
7396
public static final String VECTOR_FLOAT = "VECTOR(%s, FLOAT32)";
7497
}

data/semantickernel-data-oracle/src/main/java/com/microsoft/semantickernel/data/jdbc/oracle/OracleVectorStoreFieldHelper.java

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,20 @@
1+
<<<<<<< add-oracle-store
12
/*
23
** Semantic Kernel Oracle connector version 1.0.
34
**
45
** Copyright (c) 2025 Oracle and/or its affiliates.
56
** Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
67
*/
8+
=======
9+
>>>>>>> main
710
package com.microsoft.semantickernel.data.jdbc.oracle;
811

912
import com.microsoft.semantickernel.data.jdbc.oracle.OracleVectorStoreQueryProvider.StringTypeMapping;
1013
import com.microsoft.semantickernel.data.vectorstorage.definition.VectorStoreRecordDataField;
14+
<<<<<<< add-oracle-store
1115
import com.microsoft.semantickernel.data.vectorstorage.definition.VectorStoreRecordField;
16+
=======
17+
>>>>>>> main
1218
import com.microsoft.semantickernel.data.vectorstorage.definition.VectorStoreRecordKeyField;
1319
import com.microsoft.semantickernel.data.vectorstorage.definition.VectorStoreRecordVectorField;
1420
import oracle.jdbc.OracleTypes;
@@ -23,6 +29,7 @@
2329
import java.util.stream.Collectors;
2430

2531
/**
32+
<<<<<<< add-oracle-store
2633
* Helper class for field operations. Handles mapping between field java types to DB types and
2734
* generating SQL statement to create field indexes.
2835
*/
@@ -32,13 +39,29 @@ class OracleVectorStoreFieldHelper {
3239
* The logger
3340
*/
3441
private static final Logger LOGGER = Logger.getLogger(OracleVectorStoreFieldHelper.class.getName());
42+
=======
43+
* Helper class for field operations.
44+
*/
45+
public class OracleVectorStoreFieldHelper {
46+
private static final Logger LOGGER = Logger.getLogger(OracleVectorStoreQueryProvider.class.getName());
47+
>>>>>>> main
3548

3649
/**
3750
* Maps supported key java classes to Oracle database types
3851
*/
3952
private static final HashMap<Class<?>, String> supportedKeyTypes = new HashMap() {
4053
{
4154
put(String.class, String.format(OracleDataTypesMapping.STRING_VARCHAR, 255));
55+
<<<<<<< add-oracle-store
56+
=======
57+
put(short.class, OracleDataTypesMapping.SHORT);
58+
put(Short.class, OracleDataTypesMapping.SHORT);
59+
put(int.class, OracleDataTypesMapping.INTEGER);
60+
put(Integer.class, OracleDataTypesMapping.INTEGER);
61+
put(long.class, OracleDataTypesMapping.LONG);
62+
put(Long.class, OracleDataTypesMapping.LONG);
63+
put(UUID .class, OracleDataTypesMapping.UUID);
64+
>>>>>>> main
4265
}
4366
};
4467

@@ -52,6 +75,17 @@ class OracleVectorStoreFieldHelper {
5275
put(Collection.class, OracleDataTypesMapping.VECTOR_FLOAT);
5376
put(float[].class, OracleDataTypesMapping.VECTOR_FLOAT);
5477
put(Float[].class, OracleDataTypesMapping.VECTOR_FLOAT);
78+
<<<<<<< add-oracle-store
79+
=======
80+
/*
81+
put(byte[].class,"VECTOR(%s, INT8)");
82+
put(Byte[].class,"VECTOR(%s, INT8)");
83+
put(double[].class,"VECTOR(%s, FLOAT64)");
84+
put(Double[].class,"VECTOR(%s, FLOAT64)");
85+
put(boolean[].class,"VECTOR(%s, BINARY)");
86+
put(Boolean[].class,"VECTOR(%s, BINARY)");
87+
*/
88+
>>>>>>> main
5589
}
5690
};
5791

@@ -80,12 +114,35 @@ class OracleVectorStoreFieldHelper {
80114
put(byte[].class, OracleDataTypesMapping.BYTE_ARRAY);
81115
put(List.class, OracleDataTypesMapping.JSON);
82116
}
117+
<<<<<<< add-oracle-store
83118
};
84119

85120
/**
86121
* Suffix added to the effective column name to generate the index name for a vector column.
87122
*/
88123
public static final String VECTOR_INDEX_SUFFIX = "_VECTOR_INDEX";
124+
=======
125+
126+
};
127+
128+
/**
129+
* Maps vector type to OracleTypes. Only needed if types other than FLOAT_32 are supported.
130+
*/
131+
private static final Map<Class<?>, Integer> mapOracleTypeToVector = new HashMap() {
132+
{
133+
put(float[].class, OracleTypes.VECTOR_FLOAT32);
134+
put(Float[].class, OracleTypes.VECTOR_FLOAT32);
135+
/*
136+
put(byte[].class, OracleTypes.VECTOR_INT8);
137+
put(Byte[].class, OracleTypes.VECTOR_INT8);
138+
put(Double[].class, OracleTypes.VECTOR_FLOAT64);
139+
put(double[].class, OracleTypes.VECTOR_FLOAT64);
140+
put(Boolean[].class, OracleTypes.VECTOR_BINARY);
141+
put(boolean[].class, OracleTypes.VECTOR_BINARY);
142+
*/
143+
}
144+
};
145+
>>>>>>> main
89146

90147
/**
91148
* Gets the mapping between the supported Java key types and the Oracle database type.
@@ -103,11 +160,20 @@ public static HashMap<Class<?>, String> getSupportedKeyTypes() {
103160
*/
104161
public static Map<Class<?>, String> getSupportedDataTypes(
105162
StringTypeMapping stringTypeMapping, int defaultVarCharLength) {
163+
<<<<<<< add-oracle-store
106164
String stringType = stringTypeMapping.equals(StringTypeMapping.USE_VARCHAR)
107165
? String.format(OracleDataTypesMapping.STRING_VARCHAR, defaultVarCharLength)
108166
: OracleDataTypesMapping.STRING_CLOB;
109167
supportedDataTypes.put(String.class, stringType);
110168
LOGGER.finest("Mapping String columns to " + stringType);
169+
=======
170+
171+
if (stringTypeMapping.equals(StringTypeMapping.USE_VARCHAR)) {
172+
supportedDataTypes.put(String.class, String.format(OracleDataTypesMapping.STRING_VARCHAR, defaultVarCharLength));
173+
} else {
174+
supportedDataTypes.put(String.class, OracleDataTypesMapping.STRING_CLOB);
175+
}
176+
>>>>>>> main
111177
return supportedDataTypes;
112178
}
113179

@@ -158,14 +224,22 @@ public static String getCreateVectorIndexStatement(VectorStoreRecordVectorField
158224
*/
159225
public static String createIndexForDataField(String collectionTableName, VectorStoreRecordDataField dataField, Map<Class<?>, String> supportedDataTypes) {
160226
if (supportedDataTypes.get(dataField.getFieldType()) == "JSON") {
227+
<<<<<<< add-oracle-store
161228
String dataFieldIndex = "CREATE MULTIVALUE INDEX IF NOT EXISTS %s ON %s t (t.%s.%s)";
229+
=======
230+
String dataFieldIndex = "CREATE MULTIVALUE INDEX %s ON %s t (t.%s.%s)";
231+
>>>>>>> main
162232
return String.format(dataFieldIndex,
163233
collectionTableName + "_" + dataField.getEffectiveStorageName(),
164234
collectionTableName,
165235
dataField.getEffectiveStorageName(),
166236
getFunctionForType(supportedDataTypes.get(dataField.getFieldSubType())));
167237
} else {
238+
<<<<<<< add-oracle-store
168239
String dataFieldIndex = "CREATE INDEX IF NOT EXISTS %s ON %s (%s ASC)";
240+
=======
241+
String dataFieldIndex = "CREATE INDEX %s ON %s (%s ASC)";
242+
>>>>>>> main
169243
return String.format(dataFieldIndex,
170244
collectionTableName + "_" + dataField.getEffectiveStorageName(),
171245
collectionTableName,
@@ -175,6 +249,7 @@ public static String createIndexForDataField(String collectionTableName, VectorS
175249
}
176250

177251
/**
252+
<<<<<<< add-oracle-store
178253
* Returns vector columns names and types for CREATE TABLE statement
179254
* @param fields list of vector record fields.
180255
* @return comma separated list of columns and types for CREATE TABLE statement.
@@ -219,6 +294,8 @@ private static String getTypeForVectorField(VectorStoreRecordVectorField field)
219294
}
220295

221296
/**
297+
=======
298+
>>>>>>> main
222299
* Gets the function that allows to return the function that converts the JSON value to the
223300
* data type.
224301
* @param jdbcType The JDBC type.
@@ -244,4 +321,93 @@ private static String getFunctionForType(String jdbcType) {
244321
}
245322
}
246323

324+
<<<<<<< add-oracle-store
325+
=======
326+
/**
327+
* Gets the type of the vector given the field definition. This method is not needed if only
328+
*
329+
* @param field the vector field definition.
330+
* @return returns the type of vector for the given field type.
331+
*/
332+
public static String getTypeForVectorField(VectorStoreRecordVectorField field) {
333+
String dimension = field.getDimensions() > 0 ? String.valueOf(field.getDimensions()) : "*";
334+
return String.format(supportedVectorTypes.get(field.getFieldType()), dimension);
335+
/* Not needed since all types are FLOAT32
336+
if (field.getFieldSubType() != null) {
337+
String vectorType;
338+
switch (field.getFieldSubType().getName()) {
339+
case "java.lang.Double":
340+
vectorType = "FLOAT64";
341+
break;
342+
case "java.lang.Byte":
343+
vectorType = "INT8";
344+
break;
345+
case "java.lang.Boolean":
346+
vectorType = "BINARY";
347+
break;
348+
default:
349+
vectorType = "FLOAT32";
350+
}
351+
return String.format(supportedVectorTypes.get(field.getFieldType()), dimension, vectorType);
352+
} else {
353+
return String.format(supportedVectorTypes.get(field.getFieldType()), dimension);
354+
}
355+
*/
356+
}
357+
358+
/**
359+
* Gets the JDBC oracle of the vector field definition.
360+
* @param field the vector field definition.
361+
* @return the JDBC oracle type.
362+
*/
363+
public static int getOracleTypeForField(VectorStoreRecordVectorField field) {
364+
if (field.getFieldSubType() == null) {
365+
return mapOracleTypeToVector.get(field.getFieldType()).intValue();
366+
} else {
367+
switch (field.getFieldSubType().getName()) {
368+
case "java.lang.Double":
369+
return OracleTypes.VECTOR_FLOAT64;
370+
case "java.lang.Byte":
371+
return OracleTypes.VECTOR_INT8;
372+
case "java.lang.Boolean":
373+
return OracleTypes.VECTOR_BINARY;
374+
default:
375+
return OracleTypes.VECTOR_FLOAT32;
376+
}
377+
}
378+
}
379+
380+
/**
381+
* Generates the index name given the field name. by suffixing "_VECTOR_INDEX" to the field name.
382+
* @param effectiveStorageName the field name.
383+
* @return the index name.
384+
*/
385+
private static String getIndexName(String effectiveStorageName) {
386+
return effectiveStorageName + "_VECTOR_INDEX";
387+
}
388+
389+
/**
390+
* Returns vector columns names and types for CREATE TABLE statement
391+
* @param fields list of vector record fields.
392+
* @return comma separated list of columns and types for CREATE TABLE statement.
393+
*/
394+
public static String getVectorColumnNamesAndTypes(List<VectorStoreRecordVectorField> fields) {
395+
List<String> columns = fields.stream()
396+
.map(field -> field.getEffectiveStorageName() + " " +
397+
OracleVectorStoreFieldHelper.getTypeForVectorField(field)
398+
).collect(Collectors.toList());
399+
400+
return String.join(", ", columns);
401+
}
402+
403+
/**
404+
* Returns key column names and type for key column for CREATE TABLE statement
405+
* @param field the key field.
406+
* @return column name and type of the key field for CREATE TABLE statement.
407+
*/
408+
public static String getKeyColumnNameAndType(VectorStoreRecordKeyField field) {
409+
return field.getEffectiveStorageName() + " " + supportedKeyTypes.get(field.getFieldType());
410+
}
411+
412+
>>>>>>> main
247413
}

data/semantickernel-data-oracle/src/main/java/com/microsoft/semantickernel/data/jdbc/oracle/OracleVectorStoreQueryProvider.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -802,4 +802,5 @@ public OracleVectorStoreQueryProvider build() {
802802
prefixForCollectionTables, defaultVarcharSize, stringTypeMapping, objectMapper);
803803
}
804804
}
805-
}
805+
}
806+

0 commit comments

Comments
 (0)