Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(bigquery): add support for allowing Javascript UDFs to indicate determinism #3534

Merged
3 changes: 2 additions & 1 deletion bigquery/integration_test.go
Expand Up @@ -2918,7 +2918,8 @@ func TestIntegration_RoutineJSUDF(t *testing.T) {
routine := dataset.Routine(routineID)
err := routine.Create(ctx, &RoutineMetadata{
Language: "JAVASCRIPT", Type: "SCALAR_FUNCTION",
Description: "capitalizes using javascript",
Description: "capitalizes using javascript",
DeterminismLevel: Deterministic,
Arguments: []*RoutineArgument{
{Name: "instr", Kind: "FIXED_TYPE", DataType: &StandardSQLDataType{TypeKind: "STRING"}},
},
Expand Down
26 changes: 23 additions & 3 deletions bigquery/routine.go
Expand Up @@ -129,13 +129,27 @@ func (r *Routine) Delete(ctx context.Context) (err error) {
return req.Do()
}

// RoutineDeterminism specifies the level of determinism that javascript User Defined Functions
// exhibit.
type RoutineDeterminism string

const (
// Deterministic indicates that two calls with the same input to a UDF yield the same output.
Deterministic RoutineDeterminism = "DETERMINISTIC"
// NonDeterministic indicates that the output of the UDF is not guaranteed to yield the same
// output each time for a given set of inputs.
NonDeterministic RoutineDeterminism = "NON_DETERMINSTIC"
)

// RoutineMetadata represents details of a given BigQuery Routine.
type RoutineMetadata struct {
ETag string
// Type indicates the type of routine, such as SCALAR_FUNCTION or PROCEDURE.
Type string
CreationTime time.Time
Description string
Type string
CreationTime time.Time
Description string
// DeterminismLevel is only applicable to Javascript UDFs.
DeterminismLevel RoutineDeterminism
LastModifiedTime time.Time
// Language of the routine, such as SQL or JAVASCRIPT.
Language string
Expand All @@ -161,6 +175,7 @@ func (rm *RoutineMetadata) toBQ() (*bq.Routine, error) {
return r, nil
}
r.Description = rm.Description
r.DeterminismLevel = string(rm.DeterminismLevel)
r.Language = rm.Language
r.RoutineType = rm.Type
r.DefinitionBody = rm.Body
Expand Down Expand Up @@ -280,6 +295,7 @@ func routineArgumentsToBQ(in []*RoutineArgument) ([]*bq.Argument, error) {
type RoutineMetadataToUpdate struct {
Arguments []*RoutineArgument
Description optional.String
DeterminismLevel optional.String
Type optional.String
Language optional.String
Body optional.String
Expand All @@ -299,6 +315,9 @@ func (rm *RoutineMetadataToUpdate) toBQ() (*bq.Routine, error) {
r.Description = optional.ToString(rm.Description)
forceSend("Description")
}
if rm.DeterminismLevel != nil {
r.DeterminismLevel = optional.ToString(rm.DeterminismLevel)
}
if rm.Arguments != nil {
if len(rm.Arguments) == 0 {
nullField("Arguments")
Expand Down Expand Up @@ -348,6 +367,7 @@ func bqToRoutineMetadata(r *bq.Routine) (*RoutineMetadata, error) {
Type: r.RoutineType,
CreationTime: unixMillisToTime(r.CreationTime),
Description: r.Description,
DeterminismLevel: RoutineDeterminism(r.DeterminismLevel),
LastModifiedTime: unixMillisToTime(r.LastModifiedTime),
Language: r.Language,
ImportedLibraries: r.ImportedLibraries,
Expand Down
2 changes: 2 additions & 0 deletions bigquery/routine_test.go
Expand Up @@ -80,6 +80,7 @@ func TestRoutineTypeConversions(t *testing.T) {
DefinitionBody: "body",
Description: "desc",
Etag: "etag",
DeterminismLevel: "DETERMINISTIC",
RoutineType: "type",
Language: "lang",
ReturnType: &bq.StandardSqlDataType{TypeKind: "INT64"},
Expand All @@ -88,6 +89,7 @@ func TestRoutineTypeConversions(t *testing.T) {
CreationTime: aTime,
LastModifiedTime: aTime,
Description: "desc",
DeterminismLevel: Deterministic,
Body: "body",
ETag: "etag",
Type: "type",
Expand Down