diff --git a/google-cloud-bigquery/clirr-ignored-differences.xml b/google-cloud-bigquery/clirr-ignored-differences.xml
index bfd3ee754..6c1fd8cd6 100644
--- a/google-cloud-bigquery/clirr-ignored-differences.xml
+++ b/google-cloud-bigquery/clirr-ignored-differences.xml
@@ -1,15 +1,10 @@
-
+
7013
- com/google/cloud/bigquery/ExternalTableDefinition
- java.lang.String getConnectionId()
-
-
- 7013
- com/google/cloud/bigquery/ExternalTableDefinition$Builder
- com.google.cloud.bigquery.ExternalTableDefinition$Builder setConnectionId(java.lang.String)
+ com/google/cloud/bigquery/RoutineInfo$Builder
+ com.google.cloud.bigquery.RoutineInfo$Builder setDeterminismLevel(java.lang.String)
\ No newline at end of file
diff --git a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/Routine.java b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/Routine.java
index f324f9d50..2fbf1d67d 100644
--- a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/Routine.java
+++ b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/Routine.java
@@ -87,6 +87,12 @@ Builder setLastModifiedTime(Long lastModifiedMillis) {
return this;
}
+ @Override
+ public Builder setDeterminismLevel(String determinismLevel) {
+ infoBuilder.setDeterminismLevel(determinismLevel);
+ return this;
+ }
+
@Override
public Builder setLanguage(String language) {
infoBuilder.setLanguage(language);
diff --git a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/RoutineInfo.java b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/RoutineInfo.java
index ba93b3d83..1f9c252d2 100644
--- a/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/RoutineInfo.java
+++ b/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/RoutineInfo.java
@@ -62,6 +62,7 @@ public Routine apply(RoutineInfo routineInfo) {
private final String routineType;
private final Long creationTime;
private final String description;
+ private final String determinismLevel;
private final Long lastModifiedTime;
private final String language;
private final List argumentList;
@@ -89,6 +90,12 @@ public abstract static class Builder {
abstract Builder setLastModifiedTime(Long lastModifiedMillis);
+ /**
+ * Sets the JavaScript UDF determinism levels (e.g. DETERMINISM_LEVEL_UNSPECIFIED,
+ * DETERMINISTIC, NOT_DETERMINISTIC) only applicable to Javascript UDFs.
+ */
+ public abstract Builder setDeterminismLevel(String determinismLevel);
+
/** Sets the language for the routine (e.g. SQL or JAVASCRIPT) */
public abstract Builder setLanguage(String language);
@@ -147,6 +154,7 @@ static class BuilderImpl extends Builder {
private String routineType;
private Long creationTime;
private String description;
+ private String determinismLevel;
private Long lastModifiedTime;
private String language;
private List argumentList;
@@ -162,6 +170,7 @@ static class BuilderImpl extends Builder {
this.routineType = routineInfo.routineType;
this.creationTime = routineInfo.creationTime;
this.description = routineInfo.description;
+ this.determinismLevel = routineInfo.determinismLevel;
this.lastModifiedTime = routineInfo.lastModifiedTime;
this.language = routineInfo.language;
this.argumentList = routineInfo.argumentList;
@@ -176,6 +185,7 @@ static class BuilderImpl extends Builder {
this.routineType = routinePb.getRoutineType();
this.creationTime = routinePb.getCreationTime();
this.description = routinePb.getDescription();
+ this.determinismLevel = routinePb.getDeterminismLevel();
this.lastModifiedTime = routinePb.getLastModifiedTime();
this.language = routinePb.getLanguage();
if (routinePb.getArguments() != null) {
@@ -223,6 +233,12 @@ public Builder setDescription(String description) {
return this;
}
+ @Override
+ public Builder setDeterminismLevel(String determinismLevel) {
+ this.determinismLevel = determinismLevel;
+ return this;
+ }
+
@Override
Builder setLastModifiedTime(Long lastModifiedMillis) {
this.lastModifiedTime = lastModifiedMillis;
@@ -271,6 +287,7 @@ public RoutineInfo build() {
this.routineType = builder.routineType;
this.creationTime = builder.creationTime;
this.description = builder.description;
+ this.determinismLevel = builder.determinismLevel;
this.lastModifiedTime = builder.lastModifiedTime;
this.language = builder.language;
this.argumentList = builder.argumentList;
@@ -304,6 +321,11 @@ public String getDescription() {
return description;
}
+ /** Returns the determinism level of the JavaScript UDF if defined. */
+ public String getDeterminismLevel() {
+ return determinismLevel;
+ }
+
/**
* Returns the last modification time of the routine, represented as milliseconds since the epoch.
*/
@@ -354,6 +376,7 @@ public String toString() {
.add("routineType", routineType)
.add("creationTime", creationTime)
.add("description", description)
+ .add("determinismLevel", determinismLevel)
.add("lastModifiedTime", lastModifiedTime)
.add("language", language)
.add("arguments", argumentList)
@@ -371,6 +394,7 @@ public int hashCode() {
routineType,
creationTime,
description,
+ determinismLevel,
lastModifiedTime,
language,
argumentList,
@@ -412,6 +436,7 @@ Routine toPb() {
.setDefinitionBody(getBody())
.setCreationTime(getCreationTime())
.setDescription(getDescription())
+ .setDeterminismLevel(getDeterminismLevel())
.setLastModifiedTime(getLastModifiedTime())
.setLanguage(getLanguage());
if (getRoutineId() != null) {
@@ -420,6 +445,9 @@ Routine toPb() {
if (getArguments() != null) {
routinePb.setArguments(Lists.transform(getArguments(), RoutineArgument.TO_PB_FUNCTION));
}
+ if (getReturnType() != null) {
+ routinePb.setReturnType(getReturnType().toPb());
+ }
return routinePb;
}
diff --git a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/RoutineInfoTest.java b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/RoutineInfoTest.java
index ce613193c..1f1181433 100644
--- a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/RoutineInfoTest.java
+++ b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/RoutineInfoTest.java
@@ -29,6 +29,7 @@ public class RoutineInfoTest {
private static final String ROUTINE_TYPE = "SCALAR_FUNCTION";
private static final Long CREATION_TIME = 10L;
private static final String DESCRIPTION = "description";
+ private static final String DETERMINISM = "DETERMINISTIC";
private static final Long LAST_MODIFIED_TIME = 20L;
private static final String LANGUAGE = "SQL";
@@ -55,6 +56,7 @@ public class RoutineInfoTest {
.setRoutineType(ROUTINE_TYPE)
.setCreationTime(CREATION_TIME)
.setDescription(DESCRIPTION)
+ .setDeterminismLevel(DETERMINISM)
.setLastModifiedTime(LAST_MODIFIED_TIME)
.setLanguage(LANGUAGE)
.setArguments(ARGUMENT_LIST)
@@ -81,6 +83,7 @@ public void testBuilder() {
assertEquals(ROUTINE_TYPE, ROUTINE_INFO.getRoutineType());
assertEquals(CREATION_TIME, ROUTINE_INFO.getCreationTime());
assertEquals(DESCRIPTION, ROUTINE_INFO.getDescription());
+ assertEquals(DETERMINISM, ROUTINE_INFO.getDeterminismLevel());
assertEquals(LAST_MODIFIED_TIME, ROUTINE_INFO.getLastModifiedTime());
assertEquals(LANGUAGE, ROUTINE_INFO.getLanguage());
assertEquals(ARGUMENT_LIST, ROUTINE_INFO.getArguments());
@@ -97,6 +100,7 @@ public void testOf() {
assertNull(routineInfo.getRoutineType());
assertNull(routineInfo.getCreationTime());
assertNull(routineInfo.getDescription());
+ assertNull(routineInfo.getDeterminismLevel());
assertNull(routineInfo.getLastModifiedTime());
assertNull(routineInfo.getLanguage());
assertNull(routineInfo.getArguments());
@@ -121,6 +125,7 @@ public void compareRoutineInfo(RoutineInfo expected, RoutineInfo value) {
assertEquals(expected.getRoutineType(), value.getRoutineType());
assertEquals(expected.getCreationTime(), value.getCreationTime());
assertEquals(expected.getDescription(), value.getDescription());
+ assertEquals(expected.getDeterminismLevel(), value.getDeterminismLevel());
assertEquals(expected.getLastModifiedTime(), value.getLastModifiedTime());
assertEquals(expected.getLanguage(), value.getLanguage());
assertEquals(expected.getArguments(), value.getArguments());
diff --git a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/RoutineTest.java b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/RoutineTest.java
index c51c77193..f0e29410d 100644
--- a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/RoutineTest.java
+++ b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/RoutineTest.java
@@ -38,6 +38,7 @@
public class RoutineTest {
private static final RoutineId ROUTINE_ID = RoutineId.of("dataset", "routine");
+ private static final String DETERMINISM_LEVEL = "DETERMINISTIC";
private static final String ETAG = "etag";
private static final String ROUTINE_TYPE = "SCALAR_FUNCTION";
private static final Long CREATION_TIME = 10L;
@@ -65,6 +66,7 @@ public class RoutineTest {
.setEtag(ETAG)
.setRoutineType(ROUTINE_TYPE)
.setCreationTime(CREATION_TIME)
+ .setDeterminismLevel(DETERMINISM_LEVEL)
.setLastModifiedTime(LAST_MODIFIED_TIME)
.setLanguage(LANGUAGE)
.setArguments(ARGUMENT_LIST)
@@ -96,6 +98,7 @@ public void testBuilder() {
.setEtag(ETAG)
.setRoutineType(ROUTINE_TYPE)
.setCreationTime(CREATION_TIME)
+ .setDeterminismLevel(DETERMINISM_LEVEL)
.setLastModifiedTime(LAST_MODIFIED_TIME)
.setLanguage(LANGUAGE)
.setArguments(ARGUMENT_LIST)
@@ -104,6 +107,7 @@ public void testBuilder() {
.setBody(BODY)
.build();
assertEquals(ETAG, builtRoutine.getEtag());
+ assertEquals(DETERMINISM_LEVEL, builtRoutine.getDeterminismLevel());
assertSame(bigquery, builtRoutine.getBigQuery());
}
@@ -191,6 +195,7 @@ public void compareRoutineInfo(RoutineInfo expected, RoutineInfo value) {
assertEquals(expected.getEtag(), value.getEtag());
assertEquals(expected.getRoutineType(), value.getRoutineType());
assertEquals(expected.getCreationTime(), value.getCreationTime());
+ assertEquals(expected.getDeterminismLevel(), value.getDeterminismLevel());
assertEquals(expected.getLastModifiedTime(), value.getLastModifiedTime());
assertEquals(expected.getLanguage(), value.getLanguage());
assertEquals(expected.getArguments(), value.getArguments());
diff --git a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java
index b15e59f5e..dc8b3c355 100644
--- a/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java
+++ b/google-cloud-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java
@@ -1522,7 +1522,6 @@ public void testEmptyListRoutines() {
@Test
public void testRoutineLifecycle() throws InterruptedException {
-
String routineName = RemoteBigQueryHelper.generateRoutineName();
// Create a routine using SQL.
String sql =
@@ -1587,6 +1586,34 @@ public void testRoutineAPICreation() {
assertEquals(routine.getRoutineType(), "SCALAR_FUNCTION");
}
+ @Test
+ public void testRoutineAPICreationJavascriptUDF() {
+ String routineName = RemoteBigQueryHelper.generateRoutineName();
+ RoutineId routineId = RoutineId.of(ROUTINE_DATASET, routineName);
+ RoutineInfo routineInfo =
+ RoutineInfo.newBuilder(routineId)
+ .setLanguage("JAVASCRIPT")
+ .setRoutineType("SCALAR_FUNCTION")
+ .setDeterminismLevel("DETERMINISTIC")
+ .setArguments(
+ ImmutableList.of(
+ RoutineArgument.newBuilder()
+ .setName("instr")
+ .setKind("FIXED_TYPE")
+ .setDataType(StandardSQLDataType.newBuilder("STRING").build())
+ .build()))
+ .setReturnType(StandardSQLDataType.newBuilder("STRING").build())
+ .setBody("return instr.toUpperCase();")
+ .build();
+
+ Routine routine = bigquery.create(routineInfo);
+ assertNotNull(routine);
+ assertEquals(routine.getLanguage(), "JAVASCRIPT");
+ assertEquals(routine.getDeterminismLevel(), "DETERMINISTIC");
+ assertEquals(routine.getRoutineType(), "SCALAR_FUNCTION");
+ assertEquals(routine.getReturnType(), StandardSQLDataType.newBuilder("STRING").build());
+ }
+
@Test
public void testAuthorizeRoutine() {
String routineName = RemoteBigQueryHelper.generateRoutineName();