Skip to content

Commit 57638bc

Browse files
updating to 241016
1 parent 8816079 commit 57638bc

16 files changed

+1660
-672
lines changed

orajsoda/pom.xml

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
<dependency>
4343
<groupId>com.oracle.database.jdbc</groupId>
4444
<artifactId>ojdbc8</artifactId>
45-
<version>23.3.0.23.09</version>
45+
<version>23.5.0.24.07</version>
4646
</dependency>
4747
</dependencies>
4848

@@ -86,7 +86,7 @@
8686
</excludes>
8787
</configuration>
8888
</plugin>
89-
<plugin>
89+
<plugin>
9090
<groupId>org.apache.maven.plugins</groupId>
9191
<artifactId>maven-javadoc-plugin</artifactId>
9292
<version>3.6.3</version>
@@ -96,8 +96,10 @@
9696
<phase>prepare-package</phase>
9797
<goals>
9898
<goal>javadoc</goal>
99+
<goal>jar</goal>
99100
</goals>
100101
<configuration>
102+
<doctitle>Version 1.1.27</doctitle>
101103
<doclint>none</doclint>
102104
<sourcepath>src/main/java</sourcepath>
103105
<overview>src/main/java/oracle/soda/overview.html</overview>
@@ -106,9 +108,18 @@
106108
<version>false</version>
107109
<author>false</author>
108110
<failOnError>false</failOnError>
111+
<overview>src/main/java/oracle/soda/overview.html</overview>
112+
109113
<sourceFileExcludes>
110114
<sourceFileExclude>${excludes}</sourceFileExclude>
111115
</sourceFileExcludes>
116+
117+
<sourceFileIncludes>
118+
<sourceFileInclude>**/oracle/soda/*.java</sourceFileInclude>
119+
<sourceFileInclude>**/oracle/soda/rdbms/OracleRDBMSMetadataBuilder.java</sourceFileInclude>
120+
<sourceFileInclude>**/oracle/soda/rdbms/OracleRDBMSClient.java</sourceFileInclude>
121+
</sourceFileIncludes>
122+
112123
</configuration>
113124
</execution>
114125
</executions>

orajsoda/src/main/java/oracle/json/parser/AndORTree.java

Lines changed: 149 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
*/
1919
package oracle.json.parser;
2020

21+
import java.io.ByteArrayOutputStream;
2122
import java.io.InputStream;
2223
import java.math.BigDecimal;
2324
import java.sql.PreparedStatement;
@@ -47,6 +48,8 @@
4748
import oracle.json.common.JsonFactoryProvider;
4849
import oracle.json.parser.Evaluator.EvaluatorCode;
4950
import oracle.sql.json.OracleJsonValue;
51+
import oracle.sql.json.OracleJsonFactory;
52+
import oracle.sql.json.OracleJsonGenerator;
5053
import oracle.sql.json.OracleJsonString;
5154
import oracle.sql.json.OracleJsonTimestampTZ;
5255

@@ -867,12 +870,22 @@ public void appendJsonExists(StringBuilder output, boolean isTreatAsAvailable)
867870
appendJsonExists(output, null, 0, isTreatAsAvailable);
868871
}
869872

870-
public int appendJsonExists(StringBuilder output, String tokenFormat, int startingTokenIndex, boolean isTreatAsAvailable)
873+
public int appendJsonExists(StringBuilder output, String tokenFormat, int startingTokenIndex,
874+
boolean isTreatAsAvailable)
875+
{
876+
return appendJsonExists(output, tokenFormat, startingTokenIndex, isTreatAsAvailable, true, null);
877+
}
878+
879+
public int appendJsonExists(StringBuilder output, String tokenFormat, int startingTokenIndex,
880+
boolean isTreatAsAvailable, boolean allowBinds, OracleJsonFactory factory)
871881
{
872882
// Assumes that this method is invoked only if hasJsonExists()
873883
// returns true. So jsonExists cannot be null here.
874884
if (jsonExists == null)
875885
throw new IllegalStateException();
886+
887+
if ((tokenFormat != null || startingTokenIndex != 0) && (!allowBinds))
888+
throw new IllegalStateException();
876889

877890
int tokenCount = 0;
878891

@@ -883,64 +896,139 @@ public int appendJsonExists(StringBuilder output, String tokenFormat, int starti
883896
output.append("'");
884897

885898
int numBinds = getNumVals();
886-
if (numBinds > 0)
887-
{
899+
if (numBinds > 0) {
888900
output.append(" passing ");
889901

890-
for (int varNum = 0; varNum < numBinds; ++varNum)
891-
{
902+
for (int varNum = 0; varNum < numBinds; ++varNum) {
892903
if (tokenFormat != null)
893904
token = String.format(tokenFormat, startingTokenIndex);
894905
ValueTypePair vpair = valueArray.get(varNum);
895906

896907
if (varNum > 0)
897908
output.append(", ");
898909

899-
if (vpair.isTimestamp())
900-
{
901-
// This format can consume trailing timezones including a "Z"
902-
// but only if it's used with TO_TIMESTAMP_TZ.
903-
output.append("TO_TIMESTAMP_TZ(");
904-
output.append(token);
905-
output.append(",'SYYYY-MM-DD\"T\"HH24:MI:SS.FFTZH:TZM')");
910+
if (allowBinds) {
911+
appendBindValue(vpair, output, token, isTreatAsAvailable);
912+
tokenCount++;
913+
} else {
914+
appendInlineBindValueExpression(vpair.value, output, factory);
906915
}
907-
else if (vpair.isDate())
908-
{
909-
// This format includes the time component to reliably consume
910-
// Oracle date+time values, but should also work if the time is
911-
// not present in the bind variable.
912-
output.append("TO_DATE(");
913-
output.append(token);
914-
output.append("?,'SYYYY-MM-DD\"T\"HH24:MI:SS')");
915-
}
916-
else if (isTreatAsAvailable && vpair.isObject())
917-
{
918-
output.append("treat(");
919-
output.append(token);
920-
output.append(" as json(object))");
921-
}
922-
else if (isTreatAsAvailable && vpair.isArray())
923-
{
924-
output.append("treat(");
925-
output.append(token);
926-
output.append(" as json(array))");
927-
}
928-
else
929-
output.append(token);
930-
931-
tokenCount++;
932916

933917
output.append(" as \"B");
934918
output.append(Integer.toString(varNum));
935919
output.append("\"");
936-
937-
startingTokenIndex++;
920+
921+
if (allowBinds)
922+
startingTokenIndex++;
938923
}
939924
}
940925

941926
return tokenCount;
942927
}
943928

929+
private String getOsonHex(OracleJsonValue bind, OracleJsonFactory factory) {
930+
ByteArrayOutputStream baos = new ByteArrayOutputStream();
931+
OracleJsonGenerator gen = factory.createJsonBinaryGenerator(baos);
932+
gen.write(bind);
933+
gen.close();
934+
byte[] oson = baos.toByteArray();
935+
String hex = ByteArray.rawToHex(oson);
936+
return hex;
937+
}
938+
939+
private void appendValueAsSQLType(String returnType, StringBuilder sql, String hex) {
940+
if (returnType != null)
941+
sql.append("json_value(json(hextoraw('").append(hex).append("')), '$' returning ").append(returnType).append(")");
942+
else
943+
sql.append("json(hextoraw('").append(hex).append("'))");
944+
}
945+
946+
private void appendInlineBindValueExpression(JsonValue value, StringBuilder sql, OracleJsonFactory factory) {
947+
OracleJsonValue ovalue = null;
948+
try {
949+
Wrapper wrapper;
950+
if (!(value instanceof Wrapper) || !((wrapper = (Wrapper) value)).isWrapperFor(OracleJsonValue.class)) {
951+
// infeasible as allowBinds is only false when input filter is oson
952+
throw new UnsupportedOperationException();
953+
}
954+
ovalue = wrapper.unwrap(OracleJsonValue.class);
955+
} catch (SQLException e) {
956+
// infeasible
957+
throw new IllegalStateException(e);
958+
}
959+
String hex = getOsonHex(ovalue, factory);
960+
switch (ovalue.getOracleJsonType()) {
961+
case ARRAY:
962+
case NULL:
963+
case OBJECT:
964+
case TRUE:
965+
case FALSE:
966+
appendValueAsSQLType(null, sql, hex);
967+
break;
968+
case BINARY:
969+
if (ovalue.asJsonBinary().isId())
970+
appendValueAsSQLType(null, sql, hex);
971+
else
972+
appendValueAsSQLType("raw", sql, hex);
973+
break;
974+
case DATE:
975+
appendValueAsSQLType("date", sql, hex);
976+
break;
977+
case DECIMAL:
978+
appendValueAsSQLType("number", sql, hex);
979+
break;
980+
case DOUBLE:
981+
appendValueAsSQLType("double precision", sql, hex);
982+
break;
983+
case FLOAT:
984+
appendValueAsSQLType("float", sql, hex);
985+
break;
986+
case INTERVALDS:
987+
appendValueAsSQLType("interval day to second", sql, hex);
988+
break;
989+
case INTERVALYM:
990+
appendValueAsSQLType("interval year to month", sql, hex);
991+
break;
992+
case STRING:
993+
appendValueAsSQLType("varchar2", sql, hex);
994+
break;
995+
case TIMESTAMP:
996+
appendValueAsSQLType("timestamp", sql, hex);
997+
break;
998+
case TIMESTAMPTZ:
999+
appendValueAsSQLType("timestamp with time zone", sql, hex);
1000+
break;
1001+
default:
1002+
throw new IllegalStateException();
1003+
}
1004+
}
1005+
1006+
private void appendBindValue(ValueTypePair vpair, StringBuilder output, String token, boolean isTreatAsAvailable) {
1007+
if (vpair.isTimestamp()) {
1008+
// This format can consume trailing timezones including a "Z"
1009+
// but only if it's used with TO_TIMESTAMP_TZ.
1010+
output.append("TO_TIMESTAMP_TZ(");
1011+
output.append(token);
1012+
output.append(",'SYYYY-MM-DD\"T\"HH24:MI:SS.FFTZH:TZM')");
1013+
} else if (vpair.isDate()) {
1014+
// This format includes the time component to reliably consume
1015+
// Oracle date+time values, but should also work if the time is
1016+
// not present in the bind variable.
1017+
output.append("TO_DATE(");
1018+
output.append(token);
1019+
output.append("?,'SYYYY-MM-DD\"T\"HH24:MI:SS')");
1020+
} else if (isTreatAsAvailable && vpair.isObject()) {
1021+
output.append("treat(");
1022+
output.append(token);
1023+
output.append(" as json(object))");
1024+
} else if (isTreatAsAvailable && vpair.isArray()) {
1025+
output.append("treat(");
1026+
output.append(token);
1027+
output.append(" as json(array))");
1028+
} else
1029+
output.append(token);
1030+
}
1031+
9441032
/*
9451033
* Append a bind variable for a SQL JSON operator,
9461034
* with an optional format wrapper
@@ -1082,13 +1170,15 @@ public boolean hasFilterSpec()
10821170
hasSqlJsonClause();
10831171
}
10841172

1085-
public boolean appendFilterSpec(StringBuilder sb, boolean append,
1086-
String columnName, String inputFormatClause,
1087-
boolean isTreatAsAvailable)
1088-
throws QueryException
1089-
{
1173+
public boolean appendFilterSpec(StringBuilder sb, boolean append, String columnName, String inputFormatClause,
1174+
boolean isTreatAsAvailable) throws QueryException {
1175+
return appendFilterSpec(sb, append, columnName, inputFormatClause, isTreatAsAvailable, true, null);
1176+
}
1177+
1178+
public boolean appendFilterSpec(StringBuilder sb, boolean append, String columnName, String inputFormatClause,
1179+
boolean isTreatAsAvailable, boolean allowBinds, OracleJsonFactory factory) throws QueryException {
10901180
int length = sb.length();
1091-
appendFilterSpec(sb, append, columnName, inputFormatClause, null, 0, isTreatAsAvailable);
1181+
appendFilterSpec(sb, append, columnName, inputFormatClause, null, 0, isTreatAsAvailable, allowBinds, factory);
10921182

10931183
if (sb.length() == length) {
10941184
if (append == true)
@@ -1098,12 +1188,20 @@ public boolean appendFilterSpec(StringBuilder sb, boolean append,
10981188
}
10991189
return true;
11001190
}
1191+
1192+
1193+
//Not part of a public API. Needs to be public for use from REST layer.
1194+
public int appendFilterSpec(StringBuilder sb, boolean append, String columnName, String inputFormatClause,
1195+
String format, int startingIndex, boolean isTreatAsAvailable) throws QueryException {
1196+
return appendFilterSpec(sb, append, columnName, inputFormatClause, format, startingIndex, isTreatAsAvailable, true, null);
1197+
}
11011198

1102-
// Not part of a public API. Needs to be public for use from REST layer.
1199+
//Not part of a public API
11031200
public int appendFilterSpec(StringBuilder sb, boolean append,
11041201
String columnName, String inputFormatClause,
11051202
String format, int startingIndex,
1106-
boolean isTreatAsAvailable) throws QueryException
1203+
boolean isTreatAsAvailable, boolean allowBinds,
1204+
OracleJsonFactory factory) throws QueryException
11071205
{
11081206
int tokenCount = 0;
11091207

@@ -1116,7 +1214,7 @@ public int appendFilterSpec(StringBuilder sb, boolean append,
11161214
if (hasJsonExists())
11171215
{
11181216
appendAnd(sb, append);
1119-
tokenCount = appendFilterSpecJsonExists(sb, columnName, inputFormatClause, format, startingIndex, isTreatAsAvailable);
1217+
tokenCount = appendFilterSpecJsonExists(sb, columnName, inputFormatClause, format, startingIndex, isTreatAsAvailable, allowBinds, factory);
11201218
append = true;
11211219
}
11221220

@@ -1159,7 +1257,8 @@ public int appendFilterSpec(StringBuilder sb, boolean append,
11591257

11601258
private int appendFilterSpecJsonExists(StringBuilder sb, String columnName,
11611259
String inputFormatClause, String tokenFormat,
1162-
int startingTokenIndex, boolean isTreatAsAvailable)
1260+
int startingTokenIndex, boolean isTreatAsAvailable,
1261+
boolean allowBinds, OracleJsonFactory factory)
11631262
{
11641263
int tokenCount = 0;
11651264
sb.append("JSON_EXISTS(");
@@ -1169,7 +1268,7 @@ private int appendFilterSpecJsonExists(StringBuilder sb, String columnName,
11691268
}
11701269

11711270
sb.append(",");
1172-
tokenCount = appendJsonExists(sb, tokenFormat, startingTokenIndex, isTreatAsAvailable);
1271+
tokenCount = appendJsonExists(sb, tokenFormat, startingTokenIndex, isTreatAsAvailable, allowBinds, factory);
11731272
if (this.strictTypeMode) {
11741273
sb.append(" type(strict)");
11751274
}

0 commit comments

Comments
 (0)