Skip to content

Commit

Permalink
feat(bigquery): remote function routine api
Browse files Browse the repository at this point in the history
  • Loading branch information
alvarowolfx committed Sep 20, 2022
1 parent 6bc9b69 commit c412574
Show file tree
Hide file tree
Showing 5 changed files with 254 additions and 11 deletions.
9 changes: 5 additions & 4 deletions bigquery/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@ require (
cloud.google.com/go v0.102.1
cloud.google.com/go/datacatalog v1.3.0
cloud.google.com/go/iam v0.3.0
cloud.google.com/go/run v0.1.2
cloud.google.com/go/storage v1.23.0
github.com/google/go-cmp v0.5.8
github.com/googleapis/gax-go/v2 v2.5.1
go.opencensus.io v0.23.0
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f
golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f
google.golang.org/api v0.95.0
google.golang.org/genproto v0.0.0-20220914142337-ca0e39ece12f
google.golang.org/api v0.96.0
google.golang.org/genproto v0.0.0-20220915135415-7fd63a7952de
google.golang.org/grpc v1.48.0
google.golang.org/protobuf v1.28.1
)
Expand All @@ -26,9 +27,9 @@ require (
github.com/google/uuid v1.3.0 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.1.0 // indirect
github.com/googleapis/go-type-adapters v1.0.0 // indirect
golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e // indirect
golang.org/x/net v0.0.0-20220909164309-bea034e7d591 // indirect
golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1 // indirect
golang.org/x/sys v0.0.0-20220624220833-87e55d714810 // indirect
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 // indirect
golang.org/x/text v0.3.7 // indirect
google.golang.org/appengine v1.6.7 // indirect
)
16 changes: 10 additions & 6 deletions bigquery/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2k
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
cloud.google.com/go/run v0.1.2 h1:Fah1y/Q1U8YclV6p2rte/b5JNBUbhBnQifO7k4eznRg=
cloud.google.com/go/run v0.1.2/go.mod h1:BWliZqXKsaBc+qFx5G13Mk4uQ02bX6ye8PDkiW4qyYo=
cloud.google.com/go/security v1.5.0/go.mod h1:lgxGdyOKKjHL4YG3/YwIL2zLqMFCKs0UbQwgyZmfJl4=
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
Expand Down Expand Up @@ -305,8 +307,9 @@ golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e h1:TsQ7F31D3bUCLeqPT0u+yjp1guoArKaNKmCr22PYgTQ=
golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.0.0-20220909164309-bea034e7d591 h1:D0B/7al0LLrVC8aWF4+oxpv/m8bc7ViFfVS8/gXGdqI=
golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
Expand Down Expand Up @@ -403,8 +406,9 @@ golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220624220833-87e55d714810 h1:rHZQSjJdAI4Xf5Qzeh2bBc5YJIkPFVM6oDtMFYmgws0=
golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 h1:WIoqL4EROvwiPdUtaip4VcDdpZ4kha7wBWZrbVKCIZg=
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
Expand Down Expand Up @@ -521,8 +525,8 @@ google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3p
google.golang.org/api v0.85.0/go.mod h1:AqZf8Ep9uZ2pyTvgL+x0D3Zt0eoT9b5E8fmzfu6FO2g=
google.golang.org/api v0.90.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw=
google.golang.org/api v0.93.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw=
google.golang.org/api v0.95.0 h1:d1c24AAS01DYqXreBeuVV7ewY/U8Mnhh47pwtsgVtYg=
google.golang.org/api v0.95.0/go.mod h1:eADj+UBuxkh5zlrSntJghuNeg8HwQ1w5lTKkuqaETEI=
google.golang.org/api v0.96.0 h1:F60cuQPJq7K7FzsxMYHAUJSiXh2oKctHxBMbDygxhfM=
google.golang.org/api v0.96.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
Expand Down Expand Up @@ -613,8 +617,8 @@ google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljW
google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
google.golang.org/genproto v0.0.0-20220722212130-b98a9ff5e252/go.mod h1:GkXuJDJ6aQ7lnJcRF+SJVgFdQhypqgl3LB1C9vabdRE=
google.golang.org/genproto v0.0.0-20220815135757-37a418bb8959/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk=
google.golang.org/genproto v0.0.0-20220914142337-ca0e39ece12f h1:wwbo0UziciPT4Dsca+bmplW53QNAl7tiUOw7FfAcsf8=
google.golang.org/genproto v0.0.0-20220914142337-ca0e39ece12f/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo=
google.golang.org/genproto v0.0.0-20220915135415-7fd63a7952de h1:5ANeKFmGdtiputJJYeUVg8nTGA/1bEirx4CgzcnPSx8=
google.golang.org/genproto v0.0.0-20220915135415-7fd63a7952de/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
Expand Down
22 changes: 22 additions & 0 deletions bigquery/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,15 @@ import (
"testing"
"time"

connection "cloud.google.com/go/bigquery/connection/apiv1"
"cloud.google.com/go/civil"
datacatalog "cloud.google.com/go/datacatalog/apiv1"
"cloud.google.com/go/httpreplay"
"cloud.google.com/go/internal"
"cloud.google.com/go/internal/pretty"
"cloud.google.com/go/internal/testutil"
"cloud.google.com/go/internal/uid"
run "cloud.google.com/go/run/apiv2"
"cloud.google.com/go/storage"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
Expand All @@ -54,6 +56,8 @@ var record = flag.Bool("record", false, "record RPCs")
var (
client *Client
storageClient *storage.Client
functionsClient *run.ServicesClient
connectionsClient *connection.Client
policyTagManagerClient *datacatalog.PolicyTagManagerClient
dataset *Dataset
otherDataset *Dataset
Expand Down Expand Up @@ -123,6 +127,14 @@ func initIntegrationTest() func() {
if err != nil {
log.Fatal(err)
}
functionsClient, err = run.NewServicesClient(ctx, option.WithHTTPClient(hc))
if err != nil {
log.Fatal(err)
}
connectionsClient, err = connection.NewClient(ctx, option.WithHTTPClient(hc))
if err != nil {
log.Fatal(err)
}
policyTagManagerClient, err = datacatalog.NewPolicyTagManagerClient(ctx)
if err != nil {
log.Fatal(err)
Expand All @@ -140,6 +152,8 @@ func initIntegrationTest() func() {
}
client = nil
storageClient = nil
functionsClient = nil
connectionsClient = nil
return func() {}

default: // Run integration tests against a real backend.
Expand Down Expand Up @@ -203,6 +217,14 @@ func initIntegrationTest() func() {
if err != nil {
log.Fatalf("datacatalog.NewPolicyTagManagerClient: %v", err)
}
functionsClient, err = run.NewServicesClient(ctx, sOpts...)
if err != nil {
log.Fatalf("run.NewService: %v", err)
}
connectionsClient, err = connection.NewClient(ctx, sOpts...)
if err != nil {
log.Fatalf("connection.NewService: %v", err)
}
c := initTestState(client, now)
return func() { c(); cleanup() }
}
Expand Down
87 changes: 86 additions & 1 deletion bigquery/routine.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,15 @@ const (
NotDeterministic RoutineDeterminism = "NOT_DETERMINISTIC"
)

const (
// ScalarFunctionRoutine scalar function routine type
ScalarFunctionRoutine = "SCALAR_FUNCTION"
// ProcedureRoutine procedure routine type
ProcedureRoutine = "PROCEDURE"
// TableValuedFunctionRoutine routine type for table valued functions
TableValuedFunctionRoutine = "TABLE_VALUED_FUNCTION"
)

// RoutineMetadata represents details of a given BigQuery Routine.
type RoutineMetadata struct {
ETag string
Expand All @@ -177,7 +186,11 @@ type RoutineMetadata struct {
// Language of the routine, such as SQL or JAVASCRIPT.
Language string
// The list of arguments for the the routine.
Arguments []*RoutineArgument
Arguments []*RoutineArgument

// Information to for a remote user-defined function.
RemoteFunctionOptions *RemoteFunctionOptions

ReturnType *StandardSQLDataType

// Set only if the routine type is TABLE_VALUED_FUNCTION.
Expand All @@ -195,6 +208,66 @@ type RoutineMetadata struct {
Body string
}

// RemoteFunctionOptions contains information for a remote user-defined function.
type RemoteFunctionOptions struct {

// Fully qualified name of the user-provided connection object which holds
// the authentication information to send requests to the remote service.
// Format:
// projects/{projectId}/locations/{locationId}/connections/{connectionId}
Connection string

// Endpoint of the user-provided remote service (e.g. a function url in
// Google Cloud Function or Cloud Run )
Endpoint string

// Max number of rows in each batch sent to the remote service.
// If absent or if 0, it means no limit.
MaxBatchingRows int64

// User-defined context as a set of key/value pairs,
// which will be sent as function invocation context together with
// batched arguments in the requests to the remote service. The total
// number of bytes of keys and values must be less than 8KB.
UserDefinedContext map[string]string
}

func bqToRemoteFunctionOptions(in *bq.RemoteFunctionOptions) (*RemoteFunctionOptions, error) {
if in == nil {
return nil, nil
}
rfo := &RemoteFunctionOptions{
Connection: in.Connection,
Endpoint: in.Endpoint,
MaxBatchingRows: in.MaxBatchingRows,
}
if in.UserDefinedContext != nil {
rfo.UserDefinedContext = make(map[string]string)
for k, v := range in.UserDefinedContext {
rfo.UserDefinedContext[k] = v
}
}
return rfo, nil
}

func (rfo *RemoteFunctionOptions) toBQ() (*bq.RemoteFunctionOptions, error) {
if rfo == nil {
return nil, nil
}
r := &bq.RemoteFunctionOptions{
Connection: rfo.Connection,
Endpoint: rfo.Endpoint,
MaxBatchingRows: rfo.MaxBatchingRows,
}
if rfo.UserDefinedContext != nil {
r.UserDefinedContext = make(map[string]string)
for k, v := range rfo.UserDefinedContext {
r.UserDefinedContext[k] = v
}
}
return r, nil
}

func (rm *RoutineMetadata) toBQ() (*bq.Routine, error) {
r := &bq.Routine{}
if rm == nil {
Expand Down Expand Up @@ -227,6 +300,13 @@ func (rm *RoutineMetadata) toBQ() (*bq.Routine, error) {
}
r.Arguments = args
r.ImportedLibraries = rm.ImportedLibraries
if rm.RemoteFunctionOptions != nil {
rfo, err := rm.RemoteFunctionOptions.toBQ()
if err != nil {
return nil, err
}
r.RemoteFunctionOptions = rfo
}
if !rm.CreationTime.IsZero() {
return nil, errors.New("cannot set CreationTime on create")
}
Expand Down Expand Up @@ -436,6 +516,11 @@ func bqToRoutineMetadata(r *bq.Routine) (*RoutineMetadata, error) {
return nil, err
}
meta.ReturnType = ret
rfo, err := bqToRemoteFunctionOptions(r.RemoteFunctionOptions)
if err != nil {
return nil, err
}
meta.RemoteFunctionOptions = rfo
tt, err := bqToStandardSQLTableType(r.ReturnTableType)
if err != nil {
return nil, err
Expand Down

0 comments on commit c412574

Please sign in to comment.