diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index db24e06080..16029c1647 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -106,6 +106,7 @@ jobs: - materialize-azure-blob-parquet - materialize-azure-fabric-warehouse - materialize-bigquery + - materialize-bigtable - materialize-clickhouse - materialize-databricks - materialize-dynamodb @@ -322,6 +323,7 @@ jobs: contains(fromJson('[ "materialize-azure-fabric-warehouse", "materialize-bigquery", + "materialize-bigtable", "materialize-clickhouse", "materialize-databricks", "materialize-dynamodb", diff --git a/go.mod b/go.mod index 115a3b818e..9ca006d334 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,8 @@ go 1.25.0 require ( cloud.google.com/go v0.123.0 - cloud.google.com/go/bigquery v1.73.1 + cloud.google.com/go/bigquery v1.74.0 + cloud.google.com/go/bigtable v1.46.0 cloud.google.com/go/firestore v1.21.0 cloud.google.com/go/pubsub v1.50.1 cloud.google.com/go/spanner v1.88.0 @@ -42,7 +43,6 @@ require ( github.com/estuary/flow v0.6.4 github.com/estuary/vitess v0.15.10 github.com/evanphx/json-patch/v5 v5.9.11 - github.com/firebolt-db/firebolt-go-sdk v1.2.0 github.com/go-mysql-org/go-mysql v0.0.0-20250907131429-558ed11751bc github.com/go-sql-driver/mysql v1.9.3 github.com/gogo/protobuf v1.3.2 @@ -88,9 +88,9 @@ require ( golang.org/x/sync v0.20.0 golang.org/x/text v0.35.0 golang.org/x/time v0.15.0 - google.golang.org/api v0.271.0 - google.golang.org/genproto v0.0.0-20260217215200-42d3e9bedb6d - google.golang.org/grpc v1.79.2 + google.golang.org/api v0.274.0 + google.golang.org/genproto v0.0.0-20260319201613-d00831a3d3e7 + google.golang.org/grpc v1.80.0 google.golang.org/protobuf v1.36.11 gopkg.in/yaml.v3 v3.0.1 resty.dev/v3 v3.0.0-beta.2 @@ -102,7 +102,7 @@ require ( cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect filippo.io/edwards25519 v1.1.0 // indirect github.com/andybalholm/brotli v1.2.0 // indirect - github.com/go-jose/go-jose/v4 v4.1.3 // indirect + github.com/go-jose/go-jose/v4 v4.1.4 // indirect github.com/jackc/pgproto3/v2 v2.3.3 // indirect github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8 // indirect github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3 // indirect @@ -117,9 +117,9 @@ require ( atomicgo.dev/schedule v0.1.0 // indirect cel.dev/expr v0.25.1 // indirect cloud.google.com/go/compute/metadata v0.9.0 // indirect - cloud.google.com/go/iam v1.5.3 // indirect - cloud.google.com/go/longrunning v0.8.0 // indirect - cloud.google.com/go/monitoring v1.24.3 // indirect + cloud.google.com/go/iam v1.7.0 // indirect + cloud.google.com/go/longrunning v0.9.0 // indirect + cloud.google.com/go/monitoring v1.25.0 // indirect cloud.google.com/go/pubsub/v2 v2.2.1 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.2 // indirect @@ -128,7 +128,7 @@ require ( github.com/BurntSushi/toml v1.4.0 // indirect github.com/DataDog/zstd v1.5.7 // indirect github.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp v1.6.0 // indirect - github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0 // indirect + github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.31.0 // indirect github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.55.0 // indirect github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.55.0 // indirect github.com/antlr4-go/antlr/v4 v4.13.1 // indirect @@ -137,7 +137,6 @@ require ( github.com/apache/arrow/go/v15 v15.0.2 // indirect github.com/apache/thrift v0.22.0 // indirect github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect - github.com/astaxie/beego v1.12.3 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.4 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.17 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.17 // indirect @@ -175,7 +174,7 @@ require ( github.com/duckdb/duckdb-go-bindings/lib/windows-amd64 v0.10502.0 // indirect github.com/dvsekhvalnov/jose2go v1.7.0 // indirect github.com/elastic/elastic-transport-go/v8 v8.6.0 // indirect - github.com/envoyproxy/go-control-plane/envoy v1.36.0 // indirect + github.com/envoyproxy/go-control-plane/envoy v1.37.0 // indirect github.com/envoyproxy/protoc-gen-validate v1.3.0 // indirect github.com/fatih/color v1.18.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect @@ -200,7 +199,7 @@ require ( github.com/google/s2a-go v0.1.9 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.14 // indirect - github.com/googleapis/gax-go/v2 v2.18.0 // indirect + github.com/googleapis/gax-go/v2 v2.21.0 // indirect github.com/gookit/color v1.6.0 // indirect github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect @@ -224,7 +223,6 @@ require ( github.com/kylelemons/godebug v1.1.0 // indirect github.com/lithammer/fuzzysearch v1.1.8 // indirect github.com/mailru/easyjson v0.7.7 // indirect - github.com/matishsiao/goInfo v0.0.0-20210923090445-da2e3fa8d45f // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.20 // indirect @@ -271,7 +269,6 @@ require ( github.com/xdg-go/scram v1.1.2 // indirect github.com/xdg-go/stringprep v1.0.4 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect - github.com/xwb1989/sqlparser v0.0.0-20180606152119-120387863bf2 // indirect github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect github.com/zeebo/xxh3 v1.1.0 // indirect go.opencensus.io v0.24.0 // indirect @@ -279,11 +276,11 @@ require ( go.opentelemetry.io/contrib/detectors/gcp v1.39.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 // indirect - go.opentelemetry.io/otel v1.42.0 // indirect - go.opentelemetry.io/otel/metric v1.42.0 // indirect - go.opentelemetry.io/otel/sdk v1.42.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.42.0 // indirect - go.opentelemetry.io/otel/trace v1.42.0 // indirect + go.opentelemetry.io/otel v1.43.0 // indirect + go.opentelemetry.io/otel/metric v1.43.0 // indirect + go.opentelemetry.io/otel/sdk v1.43.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.43.0 // indirect + go.opentelemetry.io/otel/trace v1.43.0 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.1 // indirect @@ -296,8 +293,8 @@ require ( golang.org/x/term v0.41.0 // indirect golang.org/x/tools v0.43.0 // indirect golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20260217215200-42d3e9bedb6d // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260311181403-84a4fc48630c // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260401024825-9d38bb4040a9 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260401024825-9d38bb4040a9 // indirect gopkg.in/ini.v1 v1.67.1 // indirect gopkg.in/jcmturner/aescts.v1 v1.0.1 // indirect gopkg.in/jcmturner/dnsutils.v1 v1.0.1 // indirect diff --git a/go.sum b/go.sum index f84168b892..045661a993 100644 --- a/go.sum +++ b/go.sum @@ -48,8 +48,10 @@ cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvf cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/bigquery v1.73.1 h1:v//GZwdhtmCbZ87rOnxz7pectOGFS1GNRvrGTvLzka4= -cloud.google.com/go/bigquery v1.73.1/go.mod h1:KSLx1mKP/yGiA8U+ohSrqZM1WknUnjZAxHAQZ51/b1k= +cloud.google.com/go/bigquery v1.74.0 h1:Q6bAMv+eyvufOpIrfrYxhM46qq1D3ZQTdgUDQqKS+n8= +cloud.google.com/go/bigquery v1.74.0/go.mod h1:iViO7Cx3A/cRKcHNRsHB3yqGAMInFBswrE9Pxazsc90= +cloud.google.com/go/bigtable v1.46.0 h1:Bd6vITx01s6gsdEPvjIGJL/oMMdKvraGI34UiixR2gk= +cloud.google.com/go/bigtable v1.46.0/go.mod h1:GUM6PdkG3rrDse9kugqvX5+ktwo3ldfLtLi1VFn5Wj4= cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs= cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10= cloud.google.com/go/datacatalog v1.26.1 h1:bCRKA8uSQN8wGW3Tw0gwko4E9a64GRmbW1nCblhgC2k= @@ -58,16 +60,16 @@ cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7 cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/firestore v1.21.0 h1:BhopUsx7kh6NFx77ccRsHhrtkbJUmDAxNY3uapWdjcM= cloud.google.com/go/firestore v1.21.0/go.mod h1:1xH6HNcnkf/gGyR8udd6pFO4Z7GWJSwLKQMx/u6UrP4= -cloud.google.com/go/iam v1.5.3 h1:+vMINPiDF2ognBJ97ABAYYwRgsaqxPbQDlMnbHMjolc= -cloud.google.com/go/iam v1.5.3/go.mod h1:MR3v9oLkZCTlaqljW6Eb2d3HGDGK5/bDv93jhfISFvU= -cloud.google.com/go/kms v1.25.0 h1:gVqvGGUmz0nYCmtoxWmdc1wli2L1apgP8U4fghPGSbQ= -cloud.google.com/go/kms v1.25.0/go.mod h1:XIdHkzfj0bUO3E+LvwPg+oc7s58/Ns8Nd8Sdtljihbk= +cloud.google.com/go/iam v1.7.0 h1:JD3zh0C6LHl16aCn5Akff0+GELdp1+4hmh6ndoFLl8U= +cloud.google.com/go/iam v1.7.0/go.mod h1:tetWZW1PD/m6vcuY2Zj/aU0eCHNPuxedbnbRTyKXvdY= +cloud.google.com/go/kms v1.26.0 h1:cK9mN2cf+9V63D3H1f6koxTatWy39aTI/hCjz1I+adU= +cloud.google.com/go/kms v1.26.0/go.mod h1:pHKOdFJm63hxBsiPkYtowZPltu9dW0MWvBa6IA4HM58= cloud.google.com/go/logging v1.13.2 h1:qqlHCBvieJT9Cdq4QqYx1KPadCQ2noD4FK02eNqHAjA= cloud.google.com/go/logging v1.13.2/go.mod h1:zaybliM3yun1J8mU2dVQ1/qDzjbOqEijZCn6hSBtKak= -cloud.google.com/go/longrunning v0.8.0 h1:LiKK77J3bx5gDLi4SMViHixjD2ohlkwBi+mKA7EhfW8= -cloud.google.com/go/longrunning v0.8.0/go.mod h1:UmErU2Onzi+fKDg2gR7dusz11Pe26aknR4kHmJJqIfk= -cloud.google.com/go/monitoring v1.24.3 h1:dde+gMNc0UhPZD1Azu6at2e79bfdztVDS5lvhOdsgaE= -cloud.google.com/go/monitoring v1.24.3/go.mod h1:nYP6W0tm3N9H/bOw8am7t62YTzZY+zUeQ+Bi6+2eonI= +cloud.google.com/go/longrunning v0.9.0 h1:0EzbDEGsAvOZNbqXopgniY0w0a1phvu5IdUFq8grmqY= +cloud.google.com/go/longrunning v0.9.0/go.mod h1:pkTz846W7bF4o2SzdWJ40Hu0Re+UoNT6Q5t+igIcb8E= +cloud.google.com/go/monitoring v1.25.0 h1:HnsTIOxTN6BCSkt1P/Im23r1m7MHTTpmSYCzPkW7NK4= +cloud.google.com/go/monitoring v1.25.0/go.mod h1:wlj6rX+JGyusw/8+2duW4cJ6kmDHGmde3zMTJuG3Jpc= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= 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= @@ -144,8 +146,8 @@ github.com/DefangLabs/secret-detector v0.0.0-20250403165618-22662109213e h1:rd4b github.com/DefangLabs/secret-detector v0.0.0-20250403165618-22662109213e/go.mod h1:blbwPQh4DTlCZEfk1BLU4oMIhLda2U+A840Uag9DsZw= github.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp v1.6.0 h1:BzsL0qE7LvtTEtXG7Dt5NS1EP0CQwI21HZfj9aGghhw= github.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp v1.6.0/go.mod h1:I7kE2kM3qCr9QPT4cU4cCFYkEpVyVr16YOGUHzy+nR0= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0 h1:sBEjpZlNHzK1voKq9695PJSX2o5NEXl7/OL3coiIY0c= -github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0/go.mod h1:P4WPRUkOhJC13W//jWpyfJNDAIpvRbAUIYLX/4jtlE0= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.31.0 h1:DHa2U07rk8syqvCge0QIGMCE1WxGj9njT44GH7zNJLQ= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.31.0/go.mod h1:P4WPRUkOhJC13W//jWpyfJNDAIpvRbAUIYLX/4jtlE0= github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.55.0 h1:UnDZ/zFfG1JhH/DqxIZYU/1CUAlTUScoXD/LcM2Ykk8= github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.55.0/go.mod h1:IA1C1U7jO/ENqm/vhi7V9YYpBsp+IMyqNrEN94N7tVc= github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.55.0 h1:7t/qx5Ost0s0wbA/VDrByOooURhp+ikYwv20i9Y07TQ= @@ -154,7 +156,6 @@ github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapp github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.55.0/go.mod h1:Mf6O40IAyB9zR/1J8nGDDPirZQQPbYJni8Yisy7NTMc= github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c h1:RGWPOewvKIROun94nF7v2cua9qP+thov/7M50KEoeSU= github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk= -github.com/Knetic/govaluate v3.0.0+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/MarvinJWendt/testza v0.1.0/go.mod h1:7AxNvlfeHP7Z/hDQ5JtE3OKYT3XFUeLCDE2DQninSqs= github.com/MarvinJWendt/testza v0.2.1/go.mod h1:God7bhG8n6uQxwdScay+gjm9/LnO4D3kkcZX4hv9Rp8= github.com/MarvinJWendt/testza v0.2.8/go.mod h1:nwIcjmr0Zz+Rcwfh3/4UhBp7ePKVhuBExvZqnKYWlII= @@ -176,12 +177,6 @@ github.com/RobinUS2/golang-moving-average v1.0.0/go.mod h1:MdzhY+KoEvi+OBygTPH0O github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8= github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo= github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alicebob/gopher-json v0.0.0-20180125190556-5a6b3ba71ee6/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= -github.com/alicebob/miniredis v2.5.0+incompatible/go.mod h1:8HZjEj4yU0dwhYHky+DxYx+6BMjkBbe5ONFIF1MXffk= github.com/alpacahq/alpaca-trade-api-go/v2 v2.8.0 h1:9rsXPiOSewm+zGoupFzCjxiOcYjJcCMunuCrXiEsrSc= github.com/alpacahq/alpaca-trade-api-go/v2 v2.8.0/go.mod h1:Y5TZayiNItMSkAZ64uN0diRc8/77Xw3wqh7CFAXhl0o= github.com/andybalholm/brotli v1.2.0 h1:ukwgCxwYrmACq68yiUqwIWnGY0cTPox/M94sVwToPjQ= @@ -189,10 +184,6 @@ github.com/andybalholm/brotli v1.2.0/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUS github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYWrPrQ= github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw= -github.com/apache/arrow-go/v18 v18.5.2-0.20260220015023-a886a5722b87 h1:r/gg2gzUXiXoy72VU3jnODh8l/5rL0aslnTAbtmai/U= -github.com/apache/arrow-go/v18 v18.5.2-0.20260220015023-a886a5722b87/go.mod h1:IJTMBTlHe7cDOhRh0ioGuEKBl5iTR6xPfl5BN4AgirU= -github.com/apache/arrow-go/v18 v18.5.2 h1:3uoHjoaEie5eVsxx/Bt64hKwZx4STb+beAkqKOlq/lY= -github.com/apache/arrow-go/v18 v18.5.2/go.mod h1:yNoizNTT4peTciJ7V01d2EgOkE1d0fQ1vZcFOsVtFsw= github.com/apache/arrow-go/v18 v18.5.3-0.20260309043541-3ad38d03dbc8 h1:dFDGxCA5sThUzmh01Zh4mYmQYtaOadSLvgVnMfVHyG8= github.com/apache/arrow-go/v18 v18.5.3-0.20260309043541-3ad38d03dbc8/go.mod h1:ppvmBRu3OjdD9hx7OX3TRJs0DsWjDBj2HBYVku+LIbM= github.com/apache/arrow/go/arrow v0.0.0-20200730104253-651201b0f516/go.mod h1:QNYViu/X0HXDHw7m3KXzWSVXIbfUvJqBFe6Gj8/pYA0= @@ -212,8 +203,6 @@ github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7D github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk= github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY= github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= -github.com/astaxie/beego v1.12.3 h1:SAQkdD2ePye+v8Gn1r4X6IKZM1wd28EyUOVQ3PDSOOQ= -github.com/astaxie/beego v1.12.3/go.mod h1:p3qIm0Ryx7zeBHLljmd7omloyca1s4yu1a8kM1FkpIA= github.com/atomicgo/cursor v0.0.1/go.mod h1:cBON2QmmrysudxNBFthvMtN32r3jxVRIvzkUiF/RuIk= github.com/aws/aws-sdk-go v1.30.19/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= github.com/aws/aws-sdk-go v1.55.8 h1:JRmEUbU52aJQZ2AjX4q4Wu7t4uZjOu71uyNmaWlUkJQ= @@ -291,18 +280,13 @@ github.com/aws/smithy-go v1.24.1 h1:VbyeNfmYkWoxMVpGUAbQumkODcYmfMRfZ8yQiH30SK0= github.com/aws/smithy-go v1.24.1/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0= github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= -github.com/beego/goyaml2 v0.0.0-20130207012346-5545475820dd/go.mod h1:1b+Y/CofkYwXMUU0OhQqGvsY2Bvgr4j6jfT699wyZKQ= -github.com/beego/x2j v0.0.0-20131220205130-a0352aadc542/go.mod h1:kSeGC/p1AbBiEp5kat81+DSQrZenVBZXklMLaELspWU= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bitfield/gotestdox v0.2.2 h1:x6RcPAbBbErKLnapz1QeAlf3ospg8efBsedU93CDsnE= github.com/bitfield/gotestdox v0.2.2/go.mod h1:D+gwtS0urjBrzguAkTM2wodsTQYFHdpx8eqRJ3N+9pY= github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w= github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= -github.com/bradfitz/gomemcache v0.0.0-20180710155616-bc664df96737/go.mod h1:PmM6Mmwb0LSuEubjR8N7PtNe1KxZLtOUHtbeikc5h60= github.com/bradleyjkemp/cupaloy v2.3.0+incompatible h1:UafIjBvWQmS9i/xRg+CamMrnLTKNzo+bdmT/oH34c2Y= github.com/bradleyjkemp/cupaloy v2.3.0+incompatible/go.mod h1:Au1Xw1sgaJ5iSFktEhYsS0dbQiS1B0/XMXl+42y9Ilk= github.com/buger/goterm v1.0.4 h1:Z9YvGmOih81P0FbVtEYTFF6YsSgxSUKEhf/f9bTMXbY= @@ -313,14 +297,12 @@ github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1 github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM= github.com/bytedance/sonic v1.10.0 h1:qtNZduETEIWJVIyDl01BeNxur2rW9OwTQ/yBqFRkKEk= github.com/bytedance/sonic v1.10.0/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4= -github.com/casbin/casbin v1.7.0/go.mod h1:c67qKN6Oum3UF5Q1+BByfFxkwKvhwW57ITjqwtzR1KE= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= @@ -333,11 +315,8 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/clipperhouse/uax29/v2 v2.2.0 h1:ChwIKnQN3kcZteTXMgb1wztSgaU+ZemkgWdohwgs8tY= -github.com/clipperhouse/uax29/v2 v2.2.0/go.mod h1:EFJ2TJMRUaplDxHKj1qAEhCtQPW2tJSwu5BF98AuoVM= github.com/clipperhouse/uax29/v2 v2.7.0 h1:+gs4oBZ2gPfVrKPthwbMzWZDaAFPGYK72F0NJv2v7Vk= github.com/clipperhouse/uax29/v2 v2.7.0/go.mod h1:EFJ2TJMRUaplDxHKj1qAEhCtQPW2tJSwu5BF98AuoVM= -github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58/go.mod h1:EOBUe0h4xcZ5GoxqC5SDxFQ8gwyZPKQoEzownBlhI80= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -377,14 +356,10 @@ github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03V github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/go-systemd/v22 v22.6.0 h1:aGVa/v8B7hpb0TKl0MWoAavPDmHvobFe5R5zn0bCJWo= github.com/coreos/go-systemd/v22 v22.6.0/go.mod h1:iG+pp635Fo7ZmV/j14KUcmEyWF+0X7Lua8rrTWzYgWU= -github.com/couchbase/go-couchbase v0.0.0-20200519150804-63f3cdb75e0d/go.mod h1:TWI8EKQMs5u5jLKW/tsb9VwauIrMIxQG1r5fMsswK5U= -github.com/couchbase/gomemcached v0.0.0-20200526233749-ec430f949808/go.mod h1:srVSlQLB8iXBVXHgnqemxUXqN6FCvClgCMPCsjBDR7c= -github.com/couchbase/goutils v0.0.0-20180530154633-e865a1461c8a/go.mod h1:BQwMFlJzDjFDG3DJUdU0KORxn88UlsOULuxLExMh3Hs= github.com/cpuguy83/dockercfg v0.3.2 h1:DlJTyZGBDlXqUZ2Dk2Q3xHs/FtnooJJVaad2S9GKorA= github.com/cpuguy83/dockercfg v0.3.2/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc= github.com/creasty/defaults v1.8.0 h1:z27FJxCAa0JKt3utc0sCImAEb+spPucmKoOdLHvHYKk= github.com/creasty/defaults v1.8.0/go.mod h1:iGzKe6pbEHnpMPtfDXZEr0NVxWnPTjb1bbDy08fPzYM= -github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76/go.mod h1:vYwsqCOLxGiisLwp9rITslkFNpZD5rz43tf41QFkTWY= github.com/danieljoos/wincred v1.2.2 h1:774zMFJrqaeYCK2W57BgAem/MLi6mtSE47MB6BOJ0i0= github.com/danieljoos/wincred v1.2.2/go.mod h1:w7w4Utbrz8lqeMbDAK0lkNJUv5sAOkFi7nd/ogr0Uh8= github.com/databricks/databricks-sdk-go v0.121.0 h1:5bGlH1/X0hkb7vHM3riQd61HNloH0vKI0bjINvmNXnM= @@ -443,16 +418,13 @@ github.com/dvsekhvalnov/jose2go v1.7.0 h1:bnQc8+GMnidJZA8zc6lLEAb4xNrIqHwO+9Tzqv github.com/dvsekhvalnov/jose2go v1.7.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= github.com/ebitengine/purego v0.8.4 h1:CF7LEKg5FFOsASUj0+QwaXf8Ht6TlFxg09+S9wz0omw= github.com/ebitengine/purego v0.8.4/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= -github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/eiannone/keyboard v0.0.0-20220611211555-0d226195f203 h1:XBBHcIb256gUJtLmY22n99HaZTz+r2Z51xUPi01m3wg= github.com/eiannone/keyboard v0.0.0-20220611211555-0d226195f203/go.mod h1:E1jcSv8FaEny+OP/5k9UxZVw9YFWGj7eI4KR/iOBqCg= github.com/elastic/elastic-transport-go/v8 v8.0.0-20230329154755-1a3c63de0db6/go.mod h1:87Tcz8IVNe6rVSLdBux1o/PEItLtyabHU3naC7IoqKI= github.com/elastic/elastic-transport-go/v8 v8.6.0 h1:Y2S/FBjx1LlCv5m6pWAF2kDJAHoSjSRSJCApolgfthA= github.com/elastic/elastic-transport-go/v8 v8.6.0/go.mod h1:YLHer5cj0csTzNFXoNQ8qhtGY1GTvSqPnKWKaqQE3Hk= -github.com/elastic/go-elasticsearch/v6 v6.8.5/go.mod h1:UwaDJsD3rWLM5rKNFzv9hgox93HoX8utj1kxD9aFUcI= github.com/elastic/go-elasticsearch/v8 v8.9.0 h1:8xtmYjUkqtahl50E0Bg/wjKI7K63krJrrLipbNj/fCU= github.com/elastic/go-elasticsearch/v8 v8.9.0/go.mod h1:NGmpvohKiRHXI0Sw4fuUGn6hYOmAXlyCphKpzVBiqDE= -github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4= github.com/emicklei/go-restful/v3 v3.13.0 h1:C4Bl2xDndpU6nJ4bc1jXd+uTmYPVUwkD6bFY/oTyCes= github.com/emicklei/go-restful/v3 v3.13.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -464,8 +436,8 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.m github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/go-control-plane v0.14.0 h1:hbG2kr4RuFj222B6+7T83thSPqLjwBIfQawTkC++2HA= github.com/envoyproxy/go-control-plane v0.14.0/go.mod h1:NcS5X47pLl/hfqxU70yPwL9ZMkUlwlKxtAohpi2wBEU= -github.com/envoyproxy/go-control-plane/envoy v1.36.0 h1:yg/JjO5E7ubRyKX3m07GF3reDNEnfOboJ0QySbH736g= -github.com/envoyproxy/go-control-plane/envoy v1.36.0/go.mod h1:ty89S1YCCVruQAm9OtKeEkQLTb+Lkz0k8v9W0Oxsv98= +github.com/envoyproxy/go-control-plane/envoy v1.37.0 h1:u3riX6BoYRfF4Dr7dwSOroNfdSbEPe9Yyl09/B6wBrQ= +github.com/envoyproxy/go-control-plane/envoy v1.37.0/go.mod h1:DReE9MMrmecPy+YvQOAOHNYMALuowAnbjjEMkkWOi6A= github.com/envoyproxy/go-control-plane/ratelimit v0.1.0 h1:/G9QYbddjL25KvtKTv3an9lx6VBE2cnb8wp1vEGNYGI= github.com/envoyproxy/go-control-plane/ratelimit v0.1.0/go.mod h1:Wk+tMFAFbCXaJPzVVHnPgRKdUdwW/KdbRt94AzgRee4= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= @@ -483,14 +455,11 @@ github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/firebolt-db/firebolt-go-sdk v1.2.0 h1:YSdaHPyiUIRcxdrYPedVIf+Oj6oP8odofNOBWRgWnC4= -github.com/firebolt-db/firebolt-go-sdk v1.2.0/go.mod h1:E1uO4yVy3JR9oS8bBx38/7lNwwx4MwVyB89zTSfQ8+c= github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/fsnotify/fsevents v0.2.0 h1:BRlvlqjvNTfogHfeBOFvSC9N0Ddy+wzQCQukyoD7o/c= github.com/fsnotify/fsevents v0.2.0/go.mod h1:B3eEk39i4hz8y1zaWS/wPrAP4O6wkIl7HQwKBr1qH/w= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/fvbommel/sortorder v1.1.0 h1:fUmoe+HLsBTctBDoaBwpQo5N+nrCp8g/BjKb/6ZQmYw= @@ -505,7 +474,6 @@ github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= -github.com/glendc/gopher-json v0.0.0-20170414221815-dc4743023d0c/go.mod h1:Gja1A+xZ9BoviGJNA2E9vFkPjjsl+CoJxSXiQM1UXtw= github.com/go-faster/city v1.0.1 h1:4WAxSZ3V2Ws4QRDrscLEDcibJY8uf41H6AhXDrNDcGw= github.com/go-faster/city v1.0.1/go.mod h1:jKcUJId49qdW3L1qKHH/3wPeUstCVpVSXTM6vO3VcTw= github.com/go-faster/errors v0.7.1 h1:MkJTnDoEdi9pDabt1dpWf7AA8/BaSYZqibYyhZ20AYg= @@ -517,13 +485,9 @@ github.com/go-fonts/stix v0.1.0/go.mod h1:w/c1f0ldAUlJmLBvlbkvVXLAD+tAMqobIIQpmn github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-jose/go-jose/v4 v4.1.3 h1:CVLmWDhDVRa6Mi/IgCgaopNosCaHz7zrMeF9MlZRkrs= -github.com/go-jose/go-jose/v4 v4.1.3/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-jose/go-jose/v4 v4.1.4 h1:moDMcTHmvE6Groj34emNPLs/qtYXRVcd6S7NHbHz3kA= +github.com/go-jose/go-jose/v4 v4.1.4/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08= github.com/go-latex/latex v0.0.0-20210118124228-b3d85cf34e07/go.mod h1:CO1AlKB2CSIqUrmQPqA0gdRIlnLEY0gK5JGjh37zN5U= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -569,12 +533,10 @@ github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91 github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= github.com/go-playground/validator/v10 v10.15.1 h1:BSe8uhN+xQ4r5guV/ywQI4gO59C2raYcGffYWZEjZzM= github.com/go-playground/validator/v10 v10.15.1/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= -github.com/go-redis/redis v6.14.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= github.com/go-sql-driver/mysql v1.9.3 h1:U/N249h2WzJ3Ukj8SowVFjdtZKfu9vlLZxjPXV1aweo= github.com/go-sql-driver/mysql v1.9.3/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-test/deep v1.0.4 h1:u2CU3YKy9I2pmu9pX0eq50wCgjfGIt539SqR7FbHiho= github.com/go-test/deep v1.0.4/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= @@ -595,7 +557,6 @@ github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6 github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/flock v0.12.1 h1:MTLVXXHf8ekldpJk3AKicLij9MdwOWkZ+a/jHHZby9E= github.com/gofrs/flock v0.12.1/go.mod h1:9zxTsyu5xtJ9DK+1tFZyibEV7y3uwDxPPfbxeeHCoD0= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-jwt/jwt/v5 v5.3.1 h1:kYf81DTWFe7t+1VvL7eS+jKFVWaUnK9cB1qbwn63YCY= @@ -644,15 +605,15 @@ github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs= github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= +github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= github.com/google/flatbuffers v1.11.0/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/flatbuffers v2.0.0+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/flatbuffers v25.12.19+incompatible h1:haMV2JRRJCe1998HeW/p0X9UaMTK6SDo0ffLn2+DbLs= @@ -716,12 +677,12 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= -github.com/googleapis/gax-go/v2 v2.18.0 h1:jxP5Uuo3bxm3M6gGtV94P4lliVetoCB4Wk2x8QA86LI= -github.com/googleapis/gax-go/v2 v2.18.0/go.mod h1:uSzZN4a356eRG985CzJ3WfbFSpqkLTjsnhWGJR6EwrE= +github.com/googleapis/gax-go/v2 v2.21.0 h1:h45NjjzEO3faG9Lg/cFrBh2PgegVVgzqKzuZl/wMbiI= +github.com/googleapis/gax-go/v2 v2.21.0/go.mod h1:But/NJU6TnZsrLai/xBAQLLz+Hc7fHZJt/hsCz3Fih4= +github.com/gookit/assert v0.1.1 h1:lh3GcawXe/p+cU7ESTZ5Ui3Sm/x8JWpIis4/1aF0mY0= +github.com/gookit/assert v0.1.1/go.mod h1:jS5bmIVQZTIwk42uXl4lyj4iaaxx32tqH16CFj0VX2E= github.com/gookit/color v1.4.2/go.mod h1:fqRyamkC1W8uxl+lxCQxOT09l/vYfZ+QeiX3rKQHCoQ= github.com/gookit/color v1.5.0/go.mod h1:43aQb+Zerm/BWh2GnrgOQm7ffz7tvQXEKV6BFMl7wAo= -github.com/gookit/color v1.5.4 h1:FZmqs7XOyGgCAxmWyPslpiok1k05wmY3SJTytgvYFs0= -github.com/gookit/color v1.5.4/go.mod h1:pZJOeOS8DM43rXbp4AZo1n9zCU2qjpcRko0b6/QJi9w= github.com/gookit/color v1.6.0 h1:JjJXBTk1ETNyqyilJhkTXJYYigHG24TM9Xa2M1xAhRA= github.com/gookit/color v1.6.0/go.mod h1:9ACFc7/1IpHGBW8RwuDm/0YEnhg3dwwXpoMsmtyHfjs= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= @@ -759,10 +720,8 @@ github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bP github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c= github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ibmdb/go_ibm_db v0.5.4 h1:cveEOt1J2PoQivQdxIQB0f8ugDJYKaSmh7RUKAaJyAE= @@ -813,7 +772,6 @@ github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT github.com/jonboulle/clockwork v0.5.0 h1:Hyh9A8u51kptdkR+cqRpT1EebBwTn1oK9YfGYbdFz6I= github.com/jonboulle/clockwork v0.5.0/go.mod h1:3mZlmanh0g2NDKO5TWZVJAfofYk64M7XN3SzBPjZF60= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= @@ -821,7 +779,6 @@ github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHm github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= github.com/keybase/go-keychain v0.0.1 h1:way+bWYa6lDppZoZcgMbYsvC7GxljxrskdNInRtuthU= @@ -845,10 +802,8 @@ github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU= github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -859,11 +814,9 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/ledisdb/ledisdb v0.0.0-20200510135210-d35789ec47e6/go.mod h1:n931TsDuKuq+uX4v1fulaMbA/7ZLLhjc85h7chZGBCQ= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= -github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lithammer/fuzzysearch v1.1.8 h1:/HIuJnjHuXS8bKaiTMeeDlW2/AyIWk2brx1V8LFgLN4= @@ -874,8 +827,6 @@ github.com/magiconair/properties v1.8.10 h1:s31yESBquKXCV9a/ScB3ESkOjUYYv+X0rg8S github.com/magiconair/properties v1.8.10/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/matishsiao/goInfo v0.0.0-20210923090445-da2e3fa8d45f h1:B0OD7nYl2FPQEVrw8g2uyc1lGEzNbvrKh7fspGZcbvY= -github.com/matishsiao/goInfo v0.0.0-20210923090445-da2e3fa8d45f/go.mod h1:aEt7p9Rvh67BYApmZwNDPpgircTO2kgdmDUoF/1QmwA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= @@ -886,8 +837,6 @@ github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/mattn/go-runewidth v0.0.19 h1:v++JhqYnZuu5jSKrk9RbgF5v4CGUjqRfBm05byFGLdw= -github.com/mattn/go-runewidth v0.0.19/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs= github.com/mattn/go-runewidth v0.0.20 h1:WcT52H91ZUAwy8+HUkdM3THM6gXqXuLJi9O3rjcQQaQ= github.com/mattn/go-runewidth v0.0.20/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs= github.com/mattn/go-shellwords v1.0.12 h1:M2zGm7EW6UQJvDeQxo4T51eKPurbeFbe8WtebGE2xrk= @@ -895,7 +844,6 @@ github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lL github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U= github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/microsoft/go-mssqldb v1.8.2 h1:236sewazvC8FvG6Dr3bszrVhMkAl4KYImryLkRMCd0I= github.com/microsoft/go-mssqldb v1.8.2/go.mod h1:vp38dT33FGfVotRiTmDo3bFyaHq+p3LektQrjTULowo= github.com/microsoft/kiota-abstractions-go v1.9.3 h1:cqhbqro+VynJ7kObmo7850h3WN2SbvoyhypPn8uJ1SE= @@ -975,7 +923,6 @@ github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/ncruces/go-strftime v1.0.0 h1:HMFp8mLCTPp341M/ZnA4qaf7ZlsbTc+miZjCLOFAw7w= @@ -984,9 +931,6 @@ github.com/ncw/swift v1.0.52/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/oapi-codegen/runtime v1.1.1 h1:EXLHh0DXIJnWhdRPN2w4MXAzFyE4CskzhNLUmtpMYro= github.com/oapi-codegen/runtime v1.1.1/go.mod h1:SK9X900oXmPWilYR5/WKPzt3Kqxn/uS/+lbpREv+eCg= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= @@ -999,13 +943,10 @@ github.com/paulmach/orb v0.12.0 h1:z+zOwjmG3MyEEqzv92UN49Lg1JFYx0L9GpGKNVDKk1s= github.com/paulmach/orb v0.12.0/go.mod h1:5mULz1xQfs3bmQm63QEJA6lNGujuRafwA5S/EnuLaLU= github.com/paulmach/protoscan v0.2.1/go.mod h1:SpcSwydNLrxUGSDvXvO0P7g7AuhJ7lcKfDlhJCDw2gY= github.com/pborman/getopt v0.0.0-20180729010549-6fdd0a2c7117/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o= -github.com/pelletier/go-toml v1.0.1/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M= github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc= -github.com/peterh/liner v1.0.1-0.20171122030339-3681c2a91233/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc= github.com/phpdave11/gofpdf v1.4.2/go.mod h1:zpO6xFn9yxo3YLyMvW8HcKWVdbNqgIfOOp2dXMnm1mY= github.com/phpdave11/gofpdi v1.0.12/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= github.com/pierrec/lz4/v4 v4.1.8/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= @@ -1022,7 +963,6 @@ github.com/pingcap/tidb/pkg/parser v0.0.0-20250421232622-526b2c79173d h1:3Ej6eTu github.com/pingcap/tidb/pkg/parser v0.0.0-20250421232622-526b2c79173d/go.mod h1:+8feuexTKcXHZF/dkDfvCwEyBAmgb4paFc3/WeYV2eE= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -1035,24 +975,13 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.7.0/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o= github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= -github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.67.1 h1:OTSON1P4DNxzTg4hmKCc37o4ZAZDv0cfXLkOt0oEowI= github.com/prometheus/common v0.67.1/go.mod h1:RpmT9v35q2Y+lsieQsdOh5sXZ6ajUGC8NjZAmr8vb0Q= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.17.0 h1:FuLQ+05u4ZI+SS/w9+BWEM2TXiHKsUQ9TADiRH7DuK0= github.com/prometheus/procfs v0.17.0/go.mod h1:oPQLaDAMRbA+u8H5Pbfq+dl3VDAvHxMUOVhe0wYB2zw= github.com/pterm/pterm v0.12.27/go.mod h1:PhQ89w4i95rhgE+xedAoqous6K9X+r6aSOI2eFF7DZI= @@ -1062,8 +991,6 @@ github.com/pterm/pterm v0.12.31/go.mod h1:32ZAWZVXD7ZfG0s8qqHXePte42kdz8ECtRyEej github.com/pterm/pterm v0.12.33/go.mod h1:x+h2uL+n7CP/rel9+bImHD5lF3nM9vJj80k9ybiiTTE= github.com/pterm/pterm v0.12.36/go.mod h1:NjiL09hFhT/vWjQHSj1athJpx6H8cjpHXNAK5bUw8T8= github.com/pterm/pterm v0.12.40/go.mod h1:ffwPLwlbXxP+rxT0GsgDTzS3y3rmpAO1NMjUkGTYf8s= -github.com/pterm/pterm v0.12.82 h1:+D9wYhCaeaK0FIQoZtqbNQuNpe2lB2tajKKsTd5paVQ= -github.com/pterm/pterm v0.12.82/go.mod h1:TyuyrPjnxfwP+ccJdBTeWHtd/e0ybQHkOS/TakajZCw= github.com/pterm/pterm v0.12.83 h1:ie+YmGmA727VuhxBlyGr74Ks+7McV6kT99IB8EU80aA= github.com/pterm/pterm v0.12.83/go.mod h1:xlgc6bFWyJIMtmLJvGim+L7jhSReilOlOnodeIYe4Tk= github.com/puzpuzpuz/xsync/v3 v3.5.1 h1:GJYJZwO6IdxN/IKbneznS6yPkVC+c3zyY/j19c++5Fg= @@ -1095,20 +1022,14 @@ github.com/serialx/hashring v0.0.0-20200727003509-22c0c7ab6b1b h1:h+3JX2VoWTFuyQ github.com/serialx/hashring v0.0.0-20200727003509-22c0c7ab6b1b/go.mod h1:/yeG0My1xr/u+HZrFQ1tOQQQQrOawfyMUH13ai5brBc= github.com/shibumi/go-pathspec v1.3.0 h1:QUyMZhFo0Md5B8zV8x2tesohbb5kfbpTi9rBnKh5dkI= github.com/shibumi/go-pathspec v1.3.0/go.mod h1:Xutfslp817l2I1cZvgcfeMQJG5QnU2lh5tVaaMCl3jE= -github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644/go.mod h1:nkxAfR/5quYxwPZhyDxgasBMnRtBZd0FCEpawpjMUFg= github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= github.com/shirou/gopsutil/v4 v4.25.6 h1:kLysI2JsKorfaFPcYmcJqbzROzsBWEOAtw6A7dIfqXs= github.com/shirou/gopsutil/v4 v4.25.6/go.mod h1:PfybzyydfZcN+JMMjkF6Zb8Mq1A/VcogFFg7hj50W9c= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= -github.com/siddontang/go v0.0.0-20170517070808-cb568a3e5cc0/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw= -github.com/siddontang/goredis v0.0.0-20150324035039-760763f78400/go.mod h1:DDcKzU3qCuvj/tPnimWSsZZzvk9qvkvrIL5naVBPh5s= -github.com/siddontang/rdb v0.0.0-20150307021120-fc89ed2e418d/go.mod h1:AMEsy7v5z92TR1JKMkLLoaOQk++LVnOKL3ScbJ8GNGA= github.com/sijms/go-ora/v2 v2.9.0 h1:+iQbUeTeCOFMb5BsOMgUhV8KWyrv9yjKpcK4x7+MFrg= github.com/sijms/go-ora/v2 v2.9.0/go.mod h1:QgFInVi3ZWyqAiJwzBQA+nbKYKH77tdp1PYoCqhR2dU= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 h1:JIAuq3EEf9cgbU6AtGPK4CTG3Zf6CKMNqf0MHTggAUA= @@ -1130,11 +1051,9 @@ github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3A github.com/spiffe/go-spiffe/v2 v2.6.0 h1:l+DolpxNWYgruGQVV0xsfeya3CsC7m8iBzDnMpsbLuo= github.com/spiffe/go-spiffe/v2 v2.6.0/go.mod h1:gm2SeUoMZEtpnzPNs2Csc0D/gX33k1xIx7lEzqblHEs= github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0= -github.com/ssdb/gossdb v0.0.0-20180723034631-88f6b59b84ec/go.mod h1:QBvMkMya+gXctz3kmljlUCu/yB3GZ6oee+dUozsezQE= github.com/std-uritemplate/std-uritemplate/go/v2 v2.0.3 h1:7hth9376EoQEd1hH4lAp3vnaLP2UMyxuMMghLKzDHyU= github.com/std-uritemplate/std-uritemplate/go/v2 v2.0.3/go.mod h1:Z5KcoM0YLC7INlNhEezeIZ0TZNYf7WSNO0Lvah4DSeQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= @@ -1155,14 +1074,10 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/substrait-io/substrait v0.81.0 h1:0E+0cCOAlCupfKRH85KVf7R4zrODLMP29NoVY3zSYiU= github.com/substrait-io/substrait v0.81.0/go.mod h1:MPFNw6sToJgpD5Z2rj0rQrdP/Oq8HG7Z2t3CAEHtkHw= -github.com/substrait-io/substrait-go/v7 v7.4.0 h1:I8VRblvZeDCMQV13eAzVTyyzoRACSwsK4Bh4p+qCjNc= -github.com/substrait-io/substrait-go/v7 v7.4.0/go.mod h1:hWZ349MkCNRPMY0WZ9Mo+a+VGeda/x5bGMOl+rIZI1M= github.com/substrait-io/substrait-go/v7 v7.5.0 h1:85G60D/TBZ9yTqgnYHxky75WJZG4eBDQzLlX/Grva4U= github.com/substrait-io/substrait-go/v7 v7.5.0/go.mod h1:hWZ349MkCNRPMY0WZ9Mo+a+VGeda/x5bGMOl+rIZI1M= github.com/substrait-io/substrait-protobuf/go v0.81.0 h1:/qC1XYKuO4oPdTwLYySuVZ6rq7xVS4E7U07Dcgm4+6U= github.com/substrait-io/substrait-protobuf/go v0.81.0/go.mod h1:hn+Szm1NmZZc91FwWK9EXD/lmuGBSRTJ5IvHhlG1YnQ= -github.com/syndtr/goleveldb v0.0.0-20160425020131-cfa635847112/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0= -github.com/syndtr/goleveldb v0.0.0-20181127023241-353a9fca669c/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0= github.com/testcontainers/testcontainers-go v0.40.0 h1:pSdJYLOVgLE8YdUY2FHQ1Fxu+aMnb6JfVz1mxk7OeMU= github.com/testcontainers/testcontainers-go v0.40.0/go.mod h1:FSXV5KQtX2HAMlm7U3APNyLkkap35zNLxukw9oBi/MY= github.com/testcontainers/testcontainers-go/modules/compose v0.40.0 h1:Bj8W7GieY56sRbVJx1yLh0JVEtOQ8SQMhX+jRtzenLA= @@ -1204,7 +1119,6 @@ github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/twmb/murmur3 v1.1.8 h1:8Yt9taO/WN3l08xErzjeschgZU2QSrwm1kclYq+0aRg= github.com/twmb/murmur3 v1.1.8/go.mod h1:Qq/R7NUyOfr65zD+6Q5IHKsJLwP7exErjN6lyyq3OSQ= -github.com/ugorji/go v0.0.0-20171122102828-84cb69a8af83/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ= github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= @@ -1231,7 +1145,6 @@ github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IU github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= -github.com/wendal/errors v0.0.0-20130201093226-f66c77a7882b/go.mod h1:Q12BUT7DqIlHRmgv3RskH+UCM/4eqVMgI0EMmlSpAXc= github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc= github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= @@ -1262,8 +1175,6 @@ github.com/xitongsys/parquet-go-source v0.0.0-20220527110425-ba4adb87a31b/go.mod github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= -github.com/xwb1989/sqlparser v0.0.0-20180606152119-120387863bf2 h1:zzrxE1FKn5ryBNl9eKOeqQ58Y/Qpo3Q9QNxKHX5uzzQ= -github.com/xwb1989/sqlparser v0.0.0-20180606152119-120387863bf2/go.mod h1:hzfGeIUDq/j97IG+FhNqkowIyEcD88LrW6fyU3K3WqY= github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU= github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= @@ -1275,7 +1186,6 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/yuin/gopher-lua v0.0.0-20171031051903-609c9cd26973/go.mod h1:aEV29XrmTYFr3CiRxZeGHpkvbwq+prZduBqMaascyCU= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/zclconf/go-cty v1.17.0 h1:seZvECve6XX4tmnvRzWtJNHdscMtYEx5R7bnnVyd/d0= @@ -1316,8 +1226,8 @@ go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0. go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.60.0/go.mod h1:CosX/aS4eHnG9D7nESYpV753l4j9q5j3SL/PUYd2lR8= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 h1:OyrsyzuttWTSur2qN/Lm0m2a8yqyIjUVBZcxFPuXq2o= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0/go.mod h1:C2NGBr+kAB4bk3xtMXfZ94gqFDtg/GkI7e9zqGh5Beg= -go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= -go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel v1.43.0 h1:mYIM03dnh5zfN7HautFE4ieIig9amkNANT+xcVxAj9I= +go.opentelemetry.io/otel v1.43.0/go.mod h1:JuG+u74mvjvcm8vj8pI5XiHy1zDeoCS2LB1spIq7Ay0= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.37.0 h1:zG8GlgXCJQd5BU98C0hZnBbElszTmUgCNCfYneaDL0A= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.37.0/go.mod h1:hOfBCz8kv/wuq73Mx2H2QnWokh/kHZxkh6SNF2bdKtw= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.35.0 h1:0NIXxOCFx+SKbhCVxwl3ETG8ClLPAa0KuKV6p3yhxP8= @@ -1330,17 +1240,17 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 h1:aTL7F go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0/go.mod h1:kldtb7jDTeol0l3ewcmd8SDvx3EmIE7lyvqbasU3QC4= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.39.0 h1:5gn2urDL/FBnK8OkCfD1j3/ER79rUuTYmCvlXBKeYL8= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.39.0/go.mod h1:0fBG6ZJxhqByfFZDwSwpZGzJU671HkwpWaNe2t4VUPI= -go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= -go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= -go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo= -go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts= -go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA= -go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc= -go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= -go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/otel/metric v1.43.0 h1:d7638QeInOnuwOONPp4JAOGfbCEpYb+K6DVWvdxGzgM= +go.opentelemetry.io/otel/metric v1.43.0/go.mod h1:RDnPtIxvqlgO8GRW18W6Z/4P462ldprJtfxHxyKd2PY= +go.opentelemetry.io/otel/sdk v1.43.0 h1:pi5mE86i5rTeLXqoF/hhiBtUNcrAGHLKQdhg4h4V9Dg= +go.opentelemetry.io/otel/sdk v1.43.0/go.mod h1:P+IkVU3iWukmiit/Yf9AWvpyRDlUeBaRg6Y+C58QHzg= +go.opentelemetry.io/otel/sdk/metric v1.43.0 h1:S88dyqXjJkuBNLeMcVPRFXpRw2fuwdvfCGLEo89fDkw= +go.opentelemetry.io/otel/sdk/metric v1.43.0/go.mod h1:C/RJtwSEJ5hzTiUz5pXF1kILHStzb9zFlIEe85bhj6A= +go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09nk+3A= +go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLhe+8WVFxiFff0= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4= -go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE= +go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A= +go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= @@ -1366,7 +1276,6 @@ golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUu golang.org/x/arch v0.4.0 h1:A8WCeEWhLwPBKNbFi5Wv5UTCBx5zzubnXDlMOFAzFMc= golang.org/x/arch v0.4.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/crypto v0.0.0-20180723164146-c126467f60eb/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -1433,8 +1342,6 @@ golang.org/x/mod v0.34.0 h1:xIHgNUUnW6sYkcM5Jleh05DvLOtwc6RitGHbDk4akRI= golang.org/x/mod v0.34.0/go.mod h1:ykgH52iCZe79kzLLMhyCUzhMci+nQj+0XkbXpNYtVjY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -1442,7 +1349,6 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -1511,13 +1417,9 @@ golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1525,10 +1427,8 @@ golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191112214154-59a1497f0cea/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1542,7 +1442,6 @@ golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200828194041-157a740278f4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1718,8 +1617,8 @@ google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqiv google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= -google.golang.org/api v0.271.0 h1:cIPN4qcUc61jlh7oXu6pwOQqbJW2GqYh5PS6rB2C/JY= -google.golang.org/api v0.271.0/go.mod h1:CGT29bhwkbF+i11qkRUJb2KMKqcJ1hdFceEIRd9u64Q= +google.golang.org/api v0.274.0 h1:aYhycS5QQCwxHLwfEHRRLf9yNsfvp1JadKKWBE54RFA= +google.golang.org/api v0.274.0/go.mod h1:JbAt7mF+XVmWu6xNP8/+CTiGH30ofmCmk9nM8d8fHew= 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= @@ -1786,12 +1685,12 @@ google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEc google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20260217215200-42d3e9bedb6d h1:vsOm753cOAMkt76efriTCDKjpCbK18XGHMJHo0JUKhc= -google.golang.org/genproto v0.0.0-20260217215200-42d3e9bedb6d/go.mod h1:0oz9d7g9QLSdv9/lgbIjowW1JoxMbxmBVNe8i6tORJI= -google.golang.org/genproto/googleapis/api v0.0.0-20260217215200-42d3e9bedb6d h1:EocjzKLywydp5uZ5tJ79iP6Q0UjDnyiHkGRWxuPBP8s= -google.golang.org/genproto/googleapis/api v0.0.0-20260217215200-42d3e9bedb6d/go.mod h1:48U2I+QQUYhsFrg2SY6r+nJzeOtjey7j//WBESw+qyQ= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260311181403-84a4fc48630c h1:xgCzyF2LFIO/0X2UAoVRiXKU5Xg6VjToG4i2/ecSswk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260311181403-84a4fc48630c/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/genproto v0.0.0-20260319201613-d00831a3d3e7 h1:XzmzkmB14QhVhgnawEVsOn6OFsnpyxNPRY9QV01dNB0= +google.golang.org/genproto v0.0.0-20260319201613-d00831a3d3e7/go.mod h1:L43LFes82YgSonw6iTXTxXUX1OlULt4AQtkik4ULL/I= +google.golang.org/genproto/googleapis/api v0.0.0-20260401024825-9d38bb4040a9 h1:VPWxll4HlMw1Vs/qXtN7BvhZqsS9cdAittCNvVENElA= +google.golang.org/genproto/googleapis/api v0.0.0-20260401024825-9d38bb4040a9/go.mod h1:7QBABkRtR8z+TEnmXTqIqwJLlzrZKVfAUm7tY3yGv0M= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260401024825-9d38bb4040a9 h1:m8qni9SQFH0tJc1X0vmnpw/0t+AImlSvp30sEupozUg= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260401024825-9d38bb4040a9/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= 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= @@ -1817,8 +1716,8 @@ google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQ google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.79.2 h1:fRMD94s2tITpyJGtBBn7MkMseNpOZU8ZxgC3MMBaXRU= -google.golang.org/grpc v1.79.2/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/grpc v1.80.0 h1:Xr6m2WmWZLETvUNvIUmeD5OAagMw3FiKmMlTdViWsHM= +google.golang.org/grpc v1.80.0/go.mod h1:ho/dLnxwi3EDJA4Zghp7k2Ec1+c2jqup0bFkw07bwF4= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -1835,18 +1734,15 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo= gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.67.1 h1:tVBILHy0R6e4wkYOn3XmiITt/hEVH4TFMYvAX2Ytz6k= @@ -1862,15 +1758,11 @@ gopkg.in/jcmturner/gokrb5.v6 v6.1.1/go.mod h1:NFjHNLrHQiruory+EmqDXCGv6CrjkeYeA+ gopkg.in/jcmturner/gokrb5.v7 v7.3.0/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM= gopkg.in/jcmturner/rpc.v1 v1.1.0 h1:QHIUxTX1ISuAv9dD2wJ9HWQVuWDX/Zc0PfeC2tjc4rU= gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLvuNnlv8= -gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= @@ -1916,6 +1808,7 @@ nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0 nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= resty.dev/v3 v3.0.0-beta.2 h1:xu4mGAdbCLuc3kbk7eddWfWm4JfhwDtdapwss5nCjnQ= resty.dev/v3 v3.0.0-beta.2/go.mod h1:OgkqiPvTDtOuV4MGZuUDhwOpkY8enjOsjjMzeOHefy4= +rsc.io/binaryregexp v0.2.0 h1:HfqmD5MEmC0zvwBuF187nq9mdnXjXsSivRiXN7SmRkE= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= diff --git a/materialize-bigtable/.snapshots/TestIntegration-apply b/materialize-bigtable/.snapshots/TestIntegration-apply new file mode 100644 index 0000000000..127465e7e5 --- /dev/null +++ b/materialize-bigtable/.snapshots/TestIntegration-apply @@ -0,0 +1,174 @@ +Task: acmeCo/tests/materialize-bigtable + +Big Schema Initial Constraints: +{"Field":"_meta/flow_truncated","Type":4,"TypeString":"FIELD_OPTIONAL","Reason":"Metadata fields are able to be materialized"} +{"Field":"arrayField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"boolField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"flow_document","Type":2,"TypeString":"LOCATION_REQUIRED","Reason":"The root document is required for a standard updates materialization"} +{"Field":"flow_published_at","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"intField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"key","Type":2,"TypeString":"LOCATION_REQUIRED","Reason":"Primary key locations are required"} +{"Field":"multipleField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"nullField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"numField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"objField","Type":4,"TypeString":"FIELD_OPTIONAL","Reason":"Object fields may be materialized"} +{"Field":"stringDateField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringDateTimeField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringDurationField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringEmailField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringHostnameField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringIdnEmailField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringIdnHostnameField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringIntegerField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringIpv4Field","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringIpv6Field","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringIriField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringIriReferenceField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringJsonPointerField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringMacAddr8Field","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringMacAddrField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringNumberField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringRegexField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringRelativeJsonPointerField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringTimeField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringUint32Field","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringUint64Field","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringUriField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringUriReferenceField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringUriTemplateField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringUuidField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} + +Big Schema Re-validated Constraints: +{"Field":"_meta/flow_truncated","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This location is part of the current materialization"} +{"Field":"arrayField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"boolField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"flow_document","Type":1,"TypeString":"FIELD_REQUIRED","Reason":"This field is the document in the current materialization"} +{"Field":"flow_published_at","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"intField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"key","Type":2,"TypeString":"LOCATION_REQUIRED","Reason":"Primary key locations are required"} +{"Field":"multipleField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"nullField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"numField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"objField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This location is part of the current materialization"} +{"Field":"stringDateField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringDateTimeField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringDurationField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringEmailField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringHostnameField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringIdnEmailField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringIdnHostnameField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringIntegerField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringIpv4Field","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringIpv6Field","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringIriField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringIriReferenceField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringJsonPointerField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringMacAddr8Field","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringMacAddrField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringNumberField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringRegexField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringRelativeJsonPointerField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringTimeField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringUint32Field","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringUint64Field","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringUriField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringUriReferenceField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringUriTemplateField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringUuidField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} + +Big Schema Changed Types Constraints: +{"Field":"_meta/flow_truncated","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This location is part of the current materialization"} +{"Field":"arrayField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This location is part of the current materialization"} +{"Field":"boolField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"flow_document","Type":1,"TypeString":"FIELD_REQUIRED","Reason":"This field is the document in the current materialization"} +{"Field":"flow_published_at","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"intField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"key","Type":2,"TypeString":"LOCATION_REQUIRED","Reason":"Primary key locations are required"} +{"Field":"multipleField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"nullField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This location is part of the current materialization"} +{"Field":"numField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"objField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringDateField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringDateTimeField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringDurationField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringEmailField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringHostnameField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringIdnEmailField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringIdnHostnameField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringIntegerField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringIpv4Field","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringIpv6Field","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringIriField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringIriReferenceField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringJsonPointerField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringMacAddr8Field","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringMacAddrField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringNumberField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringRegexField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringRelativeJsonPointerField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringTimeField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringUint32Field","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringUint64Field","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringUriField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringUriReferenceField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringUriTemplateField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringUuidField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} + +Big Schema Materialized Resource Schema With All Fields Required: + +Big Schema Materialized Resource Schema With No Fields Required: + +Big Schema Changed Types With Backfill Constraints: +{"Field":"_meta/flow_truncated","Type":4,"TypeString":"FIELD_OPTIONAL","Reason":"Metadata fields are able to be materialized"} +{"Field":"arrayField","Type":4,"TypeString":"FIELD_OPTIONAL","Reason":"Object fields may be materialized"} +{"Field":"boolField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"flow_document","Type":2,"TypeString":"LOCATION_REQUIRED","Reason":"The root document is required for a standard updates materialization"} +{"Field":"flow_published_at","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"intField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"key","Type":2,"TypeString":"LOCATION_REQUIRED","Reason":"Primary key locations are required"} +{"Field":"multipleField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"nullField","Type":4,"TypeString":"FIELD_OPTIONAL","Reason":"Object fields may be materialized"} +{"Field":"numField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"objField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringDateField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringDateTimeField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringDurationField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringEmailField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringHostnameField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringIdnEmailField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringIdnHostnameField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringIntegerField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringIpv4Field","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringIpv6Field","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringIriField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringIriReferenceField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringJsonPointerField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringMacAddr8Field","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringMacAddrField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringNumberField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringRegexField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringRelativeJsonPointerField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringTimeField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringUint32Field","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringUint64Field","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringUriField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringUriReferenceField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringUriTemplateField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} +{"Field":"stringUuidField","Type":3,"TypeString":"LOCATION_RECOMMENDED","Reason":"This field is able to be materialized"} + +Big Schema Materialized Resource Schema Changed Types With Backfill: + +add a single field: + +remove a single optional field: + +remove a single required field: + +add and remove many fields: + +Challenging Field Names Materialized Columns: + diff --git a/materialize-bigtable/.snapshots/TestIntegration-materialize b/materialize-bigtable/.snapshots/TestIntegration-materialize new file mode 100644 index 0000000000..e7bb79a0d3 --- /dev/null +++ b/materialize-bigtable/.snapshots/TestIntegration-materialize @@ -0,0 +1,106 @@ +Task: acmeCo/tests/materialize-bigtable + +Resource: simple_standard +["applied.actionDescription", "create table \"simple_standard\"\ncreate table \"not_simple\"\ncreate table \"data_types\""] +["connectorState",{"updated":{"committed_timestamp":1}}] +["connectorState",{"updated":{"committed_timestamp":2}}] +["connectorState",{"updated":{"committed_timestamp":3}}] +["connectorState",{"updated":{"committed_timestamp":4}}] +["connectorState",{"updated":{"committed_timestamp":4}}] + + +Table Data: +{"_meta/op":"c","_row_key":"0x1504","canary":"strengthen","flow_document":{"_meta":{"op":"c","uuid":"770f6b80-1dda-11b2-8000-071353030311"},"canary":"strengthen","id":4,"val":4},"flow_published_at":"1970-01-01T01:00:03.000000000Z","id":"0x0000000000000004","val":"0x0000000000000004"} +{"_meta/op":"c","_row_key":"0x1505","canary":"Kringle's","flow_document":{"_meta":{"op":"c","uuid":"77a80200-1dda-11b2-8000-071353030311"},"canary":"Kringle's","id":5,"val":5},"flow_published_at":"1970-01-01T01:00:04.000000000Z","id":"0x0000000000000005","val":"0x0000000000000005"} +{"_meta/op":"c","_row_key":"0x1506","canary":"grosbeak's","flow_document":{"_meta":{"op":"c","uuid":"78409880-1dda-11b2-8000-071353030311"},"canary":"grosbeak's","id":6,"val":6},"flow_published_at":"1970-01-01T01:00:05.000000000Z","id":"0x0000000000000006","val":"0x0000000000000006"} +{"_meta/op":"c","_row_key":"0x1507","canary":"pieced","flow_document":{"_meta":{"op":"c","uuid":"38ce7800-1deb-11b2-8000-071353030311"},"canary":"pieced","id":7,"val":7},"flow_published_at":"1970-01-01T03:00:00.000000000Z","id":"0x0000000000000007","val":"0x0000000000000007"} +{"_meta/op":"c","_row_key":"0x1508","canary":"roaches","flow_document":{"_meta":{"op":"c","uuid":"39670e80-1deb-11b2-8000-071353030311"},"canary":"roaches","id":8,"val":8},"flow_published_at":"1970-01-01T03:00:01.000000000Z","id":"0x0000000000000008","val":"0x0000000000000008"} +{"_meta/op":"c","_row_key":"0x1509","canary":"devilish","flow_document":{"_meta":{"op":"c","uuid":"39ffa500-1deb-11b2-8000-071353030311"},"canary":"devilish","id":9,"val":9},"flow_published_at":"1970-01-01T03:00:02.000000000Z","id":"0x0000000000000009","val":"0x0000000000000009"} +{"_meta/op":"c","_row_key":"0x150a","canary":"glucose's","flow_document":{"_meta":{"op":"c","uuid":"3a983b80-1deb-11b2-8000-071353030311"},"canary":"glucose's","id":10,"val":10},"flow_published_at":"1970-01-01T03:00:03.000000000Z","id":"0x000000000000000a","val":"0x000000000000000a"} +{"_meta/op":"d","_row_key":"0x1501","canary":"amputation's","flow_document":{"_meta":{"op":"d","uuid":"3cfa9580-1deb-11b2-8000-071353030311"},"canary":"amputation's","id":1,"val":1},"flow_published_at":"1970-01-01T03:00:07.000000000Z","id":"0x0000000000000001","val":"0x0000000000000001"} +{"_meta/op":"d","_row_key":"0x1502","canary":"armament's","flow_document":{"_meta":{"op":"d","uuid":"3d932c00-1deb-11b2-8000-071353030311"},"canary":"armament's","id":2,"val":2},"flow_published_at":"1970-01-01T03:00:08.000000000Z","id":"0x0000000000000002","val":"0x0000000000000002"} +{"_meta/op":"d","_row_key":"0x150b","canary":"asteroid","flow_document":{"_meta":{"op":"d","uuid":"3b30d200-1deb-11b2-8000-071353030311"},"canary":"asteroid","id":11,"val":11},"flow_published_at":"1970-01-01T03:00:04.000000000Z","id":"0x000000000000000b","val":"0x000000000000000b"} +{"_meta/op":"d","_row_key":"0x150c","canary":"penguin","flow_document":{"_meta":{"op":"d","uuid":"3c61ff00-1deb-11b2-8000-071353030311"},"canary":"penguin","id":12,"val":12},"flow_published_at":"1970-01-01T03:00:06.000000000Z","id":"0x000000000000000c","val":"0x000000000000000c"} +{"_meta/op":"u","_row_key":"0x1503","canary":"splatters","flow_document":{"_meta":{"op":"u","uuid":"3e2bc280-1deb-11b2-8000-071353030311"},"canary":"splatters","id":3,"val":3},"flow_published_at":"1970-01-01T03:00:09.000000000Z","id":"0x0000000000000003","val":"0x0000000000000003"} + +Resource: not_simple +["applied.actionDescription", "create table \"simple_standard\"\ncreate table \"not_simple\"\ncreate table \"data_types\""] +["connectorState",{"updated":{"committed_timestamp":1}}] +["connectorState",{"updated":{"committed_timestamp":2}}] +["connectorState",{"updated":{"committed_timestamp":3}}] +["connectorState",{"updated":{"committed_timestamp":4}}] +["connectorState",{"updated":{"committed_timestamp":4}}] + + +Table Data: +{" ,;{}().- problematicField � 𐀀 嶲 ":null," ,;{}().- problematicKey � 𐀀 嶲 ":"test-key-2","$dollar$signs":null,"123":null,"123startsWithDigits":null,"FIELDWITHDIFFERENTCAPS":null,"_id":"doc_002","_row_key":"0x02746573742d6b65792d320002646f635f30303200025647567a644552686447453d00","a\"string`with`quote'characters":null,"binaryKey":"TestData","field with separated words":null,"field-with-separated-words":null,"field.with-separated_words":null,"field.with.separated.words":null,"fieldWithDifferentCaps":null,"field_with_separated_words":null,"fieldwithdifferentcaps":null,"flow_document":{" ,;{}().- problematicField � 𐀀 嶲 ":""," ,;{}().- problematicKey � 𐀀 嶲 ":"test-key-2","$dollar$signs":"","123":"","123startsWithDigits":"","FIELDWITHDIFFERENTCAPS":"","_id":"doc_002","_meta":{"uuid":"7971c580-1dda-11b2-8000-071353030311"},"a\"string`with`quote''characters":"","binaryKey":"VGVzdERhdGE=","field with separated words":"","field-with-separated-words":"","field.with-separated_words":"","field.with.separated.words":"","fieldWithDifferentCaps":"","field_with_separated_words":"","fieldwithdifferentcaps":"","longString":"","testing (%s)":"","unsignedBigint":0},"flow_published_at":"1970-01-01T01:00:07.000000000Z","longString":null,"testing (%s)":null,"unsignedBigint":"0"} +{" ,;{}().- problematicField � 𐀀 嶲 ":"symbols: !@#$%^\u0026*()_+-=[]{}|;':\",./\u003c\u003e?"," ,;{}().- problematicKey � 𐀀 嶲 ":"very long string that exceeds 256 characters to test if dynamic sizing of varchar fields works. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostru.","$dollar$signs":"$100.50$","123":"999","123startsWithDigits":"field starting with 123","FIELDWITHDIFFERENTCAPS":"ALL UPPERCASE VALUE","_id":"doc_003","_row_key":"0x0276657279206c6f6e6720737472696e672074686174206578636565647320323536206368617261637465727320746f20746573742069662064796e616d69632073697a696e67206f662076617263686172206669656c647320776f726b732e204c6f72656d20697073756d20646f6c6f722073697420616d65742c20636f6e73656374657475722061646970697363696e6720656c69742c2073656420646f20656975736d6f642074656d706f7220696e6369646964756e74207574206c61626f726520657420646f6c6f7265206d61676e6120616c697175612e20557420656e696d206164206d696e696d2076656e69616d2c2071756973206e6f737472752e0002646f635f3030330002516d6c7559584a355647567a644552686447453d00","a\"string`with`quote'characters":null,"binaryKey":"BinaryTestData","field with separated words":"edge case testing","field-with-separated-words":"hyphen-separated-values","field.with-separated_words":"mixed.separator-test_data","field.with.separated.words":"system.test.data","fieldWithDifferentCaps":"CamelCaseValue","field_with_separated_words":"underscore_separated_values","fieldwithdifferentcaps":"all lowercase value","flow_document":{" ,;{}().- problematicField � 𐀀 嶲 ":"symbols: !@#$%^\u0026*()_+-=[]{}|;':\",./\u003c\u003e?"," ,;{}().- problematicKey � 𐀀 嶲 ":"very long string that exceeds 256 characters to test if dynamic sizing of varchar fields works. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostru.","$dollar$signs":"$100.50$","123":"999","123startsWithDigits":"field starting with 123","FIELDWITHDIFFERENTCAPS":"ALL UPPERCASE VALUE","_id":"doc_003","_meta":{"uuid":"7a0a5c00-1dda-11b2-8000-071353030311"},"a\"string`with`quote''characters":"testing \"quotes\" and `backticks` and 'apostrophes'","binaryKey":"QmluYXJ5VGVzdERhdGE=","field with separated words":"edge case testing","field-with-separated-words":"hyphen-separated-values","field.with-separated_words":"mixed.separator-test_data","field.with.separated.words":"system.test.data","fieldWithDifferentCaps":"CamelCaseValue","field_with_separated_words":"underscore_separated_values","fieldwithdifferentcaps":"all lowercase value","longString":"very long string that exceeds 256 characters to test if dynamic sizing of varchar fields works. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostru.","testing (%s)":"printf style format string test","unsignedBigint":18446744073709551615},"flow_published_at":"1970-01-01T01:00:08.000000000Z","longString":"very long string that exceeds 256 characters to test if dynamic sizing of varchar fields works. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostru.","testing (%s)":"printf style format string test","unsignedBigint":"18446744073709551615"} +{" ,;{}().- problematicField � 𐀀 嶲 ":"updated special chars"," ,;{}().- problematicKey � 𐀀 嶲 ":"\\he \\ ' \" `llo`","$dollar$signs":"updated dollars","123":"updated 123","123startsWithDigits":"updated numbers","FIELDWITHDIFFERENTCAPS":"UPDATED UPPERCASE","_id":"doc_001","_row_key":"0x025c6865205c2027202220606c6c6f600002646f635f30303100025347567362473867563239796247513d00","a\"string`with`quote'characters":null,"binaryKey":"Hello World","field with separated words":"updated spaces","field-with-separated-words":"updated dashes","field.with-separated_words":"updated mixed","field.with.separated.words":"updated dots","fieldWithDifferentCaps":"updatedCamelCase","field_with_separated_words":"updated underscores","fieldwithdifferentcaps":"updated lowercase","flow_document":{" ,;{}().- problematicField � 𐀀 嶲 ":"updated special chars"," ,;{}().- problematicKey � 𐀀 嶲 ":"\\he \\ ' \" `llo`","$dollar$signs":"updated dollars","123":"updated 123","123startsWithDigits":"updated numbers","FIELDWITHDIFFERENTCAPS":"UPDATED UPPERCASE","_id":"doc_001","_meta":{"uuid":"3ec45900-1deb-11b2-8000-071353030311"},"a\"string`with`quote''characters":"updated quotes","binaryKey":"SGVsbG8gV29ybGQ=","field with separated words":"updated spaces","field-with-separated-words":"updated dashes","field.with-separated_words":"updated mixed","field.with.separated.words":"updated dots","fieldWithDifferentCaps":"updatedCamelCase","field_with_separated_words":"updated underscores","fieldwithdifferentcaps":"updated lowercase","longString":"Updated long string with more Unicode: 🎭🎨🎪🎯 αβγδε ñáéíóú 中文更新测试 العربية עברית русский 한국어 日本語","testing (%s)":"updated printf","unsignedBigint":18446744073709551615},"flow_published_at":"1970-01-01T03:00:10.000000000Z","longString":"Updated long string with more Unicode: 🎭🎨🎪🎯 αβγδε ñáéíóú 中文更新测试 العربية עברית русский 한국어 日本語","testing (%s)":"updated printf","unsignedBigint":"18446744073709551615"} + +Resource: data_types +["applied.actionDescription", "create table \"simple_standard\"\ncreate table \"not_simple\"\ncreate table \"data_types\""] +["connectorState",{"updated":{"committed_timestamp":1}}] +["connectorState",{"updated":{"committed_timestamp":2}}] +["connectorState",{"updated":{"committed_timestamp":3}}] +["connectorState",{"updated":{"committed_timestamp":4}}] +["connectorState",{"updated":{"committed_timestamp":4}}] + + +Table Data: +{"_row_key":"0x1501","arrayField":[1,"two",3.0,true,null],"boolField":"0x01","flow_document":{"_meta":{"uuid":"3ff58600-1deb-11b2-8000-071353030311"},"arrayField":[1,"two",3.0,true,null],"boolField":true,"id":1,"intField":42.0,"multipleField":"string value","nullField":null,"numField":3.14159,"objField":{"count":123,"nested":"value"},"stringAndIntegerField":"1.0","stringAndNumberField":"123.456","stringDateField":"2023-01-15","stringDateTimeField":"2023-01-15T10:30:45z","stringDurationField":"P1Y2M3DT4H5M6S","stringEmailField":"test@example.com","stringField":"hello world","stringHostnameField":"example.com","stringIntegerField":"1.0","stringIpv4Field":"192.168.1.1","stringIpv6Field":"2001:db8::1","stringIriField":"https://例え.テスト","stringIriReferenceField":"/例え/テスト","stringJsonPointerField":"/path/to/field","stringMacAddr8Field":"00:14:22:ff:fe:01:23:45","stringMacAddrField":"00:14:22:01:23:45","stringNumberField":"123.456","stringRegexField":"^[a-zA-Z0-9]+$","stringRelativeJsonPointerField":"1/name","stringTimeField":"14:30:00+02:30","stringUint32Field":"4294967295","stringUint64Field":"18446744073709551615","stringUriField":"https://example.com/path","stringUriReferenceField":"/relative/path","stringUriTemplateField":"https://api.example.com/{id}","stringUuidField":"550e8400-e29b-41d4-a716-446655440000"},"flow_published_at":"1970-01-01T03:00:12.000000000Z","id":"0x0000000000000001","intField":"0x000000000000002a","multipleField":"\"string value\"","nullField":null,"numField":"0x400921f9f01b866e","stringAndIntegerField":"0x0000000000000001","stringAndNumberField":"0x405edd2f1a9fbe77","stringDateField":"2023-01-15","stringDateTimeField":"2023-01-15T10:30:45z","stringDurationField":"P1Y2M3DT4H5M6S","stringEmailField":"test@example.com","stringField":"hello world","stringHostnameField":"example.com","stringIntegerField":"0x0000000000000001","stringIpv4Field":"192.168.1.1","stringIpv6Field":"2001:db8::1","stringIriField":"https://例え.テスト","stringIriReferenceField":"/例え/テスト","stringJsonPointerField":"/path/to/field","stringMacAddr8Field":"00:14:22:ff:fe:01:23:45","stringMacAddrField":"00:14:22:01:23:45","stringNumberField":"0x405edd2f1a9fbe77","stringRegexField":"^[a-zA-Z0-9]+$","stringRelativeJsonPointerField":"1/name","stringTimeField":"14:30:00+02:30","stringUint32Field":"0x00000000ffffffff","stringUint64Field":"18446744073709551615","stringUriField":"https://example.com/path","stringUriReferenceField":"/relative/path","stringUriTemplateField":"https://api.example.com/{id}","stringUuidField":"550e8400-e29b-41d4-a716-446655440000"} +{"_row_key":"0x1502","arrayField":[],"boolField":"0x00","flow_document":{"_meta":{"uuid":"408e1c80-1deb-11b2-8000-071353030311"},"arrayField":[],"boolField":false,"id":2,"intField":-999,"multipleField":42,"nullField":null,"numField":-2.718281828,"objField":{},"stringAndIntegerField":-123,"stringAndNumberField":-456.789,"stringDateField":"1999-12-31","stringDateTimeField":"1999-12-31T23:59:59.123456789Z","stringDurationField":"PT30M","stringEmailField":"admin@localhost","stringField":"","stringHostnameField":"localhost","stringIntegerField":"-123","stringIpv4Field":"127.0.0.1","stringIpv6Field":"::1","stringIriField":"http://localhost","stringIriReferenceField":"/","stringJsonPointerField":"/0","stringMacAddr8Field":"ff:ff:ff:ff:ff:ff:ff:ff","stringMacAddrField":"ff:ff:ff:ff:ff:ff","stringNumberField":"-456.789","stringRegexField":".*","stringRelativeJsonPointerField":"0","stringTimeField":"03:55:23.123456789Z","stringUint32Field":"0","stringUint64Field":"0","stringUriField":"http://localhost:8080","stringUriReferenceField":"#fragment","stringUriTemplateField":"http://example.com/~{username}/","stringUuidField":"00000000-0000-0000-0000-000000000000"},"flow_published_at":"1970-01-01T03:00:13.000000000Z","id":"0x0000000000000002","intField":"0xfffffffffffffc19","multipleField":"42","nullField":null,"numField":"0xc005bf0a8b04919b","stringAndIntegerField":"0xffffffffffffff85","stringAndNumberField":"0xc07c8c9fbe76c8b4","stringDateField":"1999-12-31","stringDateTimeField":"1999-12-31T23:59:59.123456789Z","stringDurationField":"PT30M","stringEmailField":"admin@localhost","stringField":null,"stringHostnameField":"localhost","stringIntegerField":"0xffffffffffffff85","stringIpv4Field":"127.0.0.1","stringIpv6Field":"::1","stringIriField":"http://localhost","stringIriReferenceField":"/","stringJsonPointerField":"/0","stringMacAddr8Field":"ff:ff:ff:ff:ff:ff:ff:ff","stringMacAddrField":"ff:ff:ff:ff:ff:ff","stringNumberField":"0xc07c8c9fbe76c8b4","stringRegexField":".*","stringRelativeJsonPointerField":"0","stringTimeField":"03:55:23.123456789Z","stringUint32Field":"0x0000000000000000","stringUint64Field":"0","stringUriField":"http://localhost:8080","stringUriReferenceField":"#fragment","stringUriTemplateField":"http://example.com/~{username}/","stringUuidField":"00000000-0000-0000-0000-000000000000"} +{"_row_key":"0x1503","arrayField":[{"obj":"in array"},[1,[2,[3]]],"mixed types"],"boolField":"0x01","flow_document":{"_meta":{"uuid":"7bd41f80-1dda-11b2-8000-071353030311"},"arrayField":[{"obj":"in array"},[1,[2,[3]]],"mixed types"],"boolField":true,"id":3,"intField":0,"multipleField":{"object":"value"},"nullField":null,"numField":0.0,"objField":{"array":[1,2,3],"nested":{"deep":"value"}},"stringAndIntegerField":"2147483647","stringAndNumberField":"0","stringDateField":"2024-02-29","stringDateTimeField":"2024-02-29T12:00:00.000000000z","stringDurationField":"P0D","stringEmailField":"user+tag@sub.domain.com","stringField":"special chars: !@#$%^\u0026*()[]{}|\\:;\"'\u003c\u003e?/.,","stringHostnameField":"sub.domain.example.org","stringIntegerField":"2147483647","stringIpv4Field":"10.0.0.1","stringIpv6Field":"2001:0db8:0000:0000:0000:ff00:0042:8329","stringIriField":"https://москва.рф/path","stringIriReferenceField":"/москва/путь","stringJsonPointerField":"/nested/array/0/field","stringMacAddr8Field":"01:23:45:67:89:ab:cd:ef","stringMacAddrField":"01:23:45:67:89:ab","stringNumberField":"0","stringRegexField":"[0-9]{3}-[0-9]{2}-[0-9]{4}","stringRelativeJsonPointerField":"2/nested/field","stringTimeField":"23:59:59.999-01:15","stringUint32Field":"2147483648","stringUint64Field":"9223372036854775808","stringUriField":"ftp://user:pass@host.com:21/path?query=value","stringUriReferenceField":"?query=value\u0026other=param","stringUriTemplateField":"https://{host}{/path*}{?query*}","stringUuidField":"f47ac10b-58cc-4372-a567-0e02b2c3d479"},"flow_published_at":"1970-01-01T01:00:11.000000000Z","id":"0x0000000000000003","intField":"0x0000000000000000","multipleField":{"object":"value"},"nullField":null,"numField":"0x0000000000000000","stringAndIntegerField":"0x000000007fffffff","stringAndNumberField":"0x0000000000000000","stringDateField":"2024-02-29","stringDateTimeField":"2024-02-29T12:00:00.000000000z","stringDurationField":"P0D","stringEmailField":"user+tag@sub.domain.com","stringField":"special chars: !@#$%^\u0026*()[]{}|\\:;\"'\u003c\u003e?/.,","stringHostnameField":"sub.domain.example.org","stringIntegerField":"0x000000007fffffff","stringIpv4Field":"10.0.0.1","stringIpv6Field":"2001:0db8:0000:0000:0000:ff00:0042:8329","stringIriField":"https://москва.рф/path","stringIriReferenceField":"/москва/путь","stringJsonPointerField":"/nested/array/0/field","stringMacAddr8Field":"01:23:45:67:89:ab:cd:ef","stringMacAddrField":"01:23:45:67:89:ab","stringNumberField":"0x0000000000000000","stringRegexField":"[0-9]{3}-[0-9]{2}-[0-9]{4}","stringRelativeJsonPointerField":"2/nested/field","stringTimeField":"23:59:59.999-01:15","stringUint32Field":"0x0000000080000000","stringUint64Field":"9223372036854775808","stringUriField":"ftp://user:pass@host.com:21/path?query=value","stringUriReferenceField":"?query=value\u0026other=param","stringUriTemplateField":"https://{host}{/path*}{?query*}","stringUuidField":"f47ac10b-58cc-4372-a567-0e02b2c3d479"} +{"_row_key":"0x1504","arrayField":["updated","array","values"],"boolField":"0x00","flow_document":{"_meta":{"uuid":"3f5cef80-1deb-11b2-8000-071353030311"},"arrayField":["updated","array","values"],"boolField":false,"id":4,"intField":2147483647,"multipleField":999,"nullField":null,"numField":12345678900.0,"objField":{"timestamp":"2024-01-01","updated":true},"stringAndIntegerField":999,"stringAndNumberField":999.999,"stringDateField":"2024-12-25","stringDateTimeField":"2024-12-25T00:00:00Z","stringDurationField":"P1D","stringEmailField":"updated@test.org","stringField":"updated value","stringHostnameField":"api.example.org","stringIntegerField":"999","stringIpv4Field":"8.8.8.8","stringIpv6Field":"2001:4860:4860::8888","stringIriField":"https://テスト.例","stringIriReferenceField":"/テスト/例","stringJsonPointerField":"/data/items/0/name","stringMacAddr8Field":"aa:bb:cc:dd:ee:ff:00:11","stringMacAddrField":"aa:bb:cc:dd:ee:ff","stringNumberField":"999.999","stringRegexField":"^\\d{4}-\\d{2}-\\d{2}$","stringRelativeJsonPointerField":"3/updated","stringTimeField":"12:00:00z","stringUint32Field":"1000000000","stringUint64Field":"1000000000000000000","stringUriField":"https://api.example.org/v1/resource","stringUriReferenceField":"../parent/resource","stringUriTemplateField":"/api/v{version}/users/{id}","stringUuidField":"123e4567-e89b-12d3-a456-426614174000"},"flow_published_at":"1970-01-01T03:00:11.000000000Z","id":"0x0000000000000004","intField":"0x000000007fffffff","multipleField":"999","nullField":null,"numField":"0x4206fee0e1a00000","stringAndIntegerField":"0x00000000000003e7","stringAndNumberField":"0x408f3ffdf3b645a2","stringDateField":"2024-12-25","stringDateTimeField":"2024-12-25T00:00:00Z","stringDurationField":"P1D","stringEmailField":"updated@test.org","stringField":"updated value","stringHostnameField":"api.example.org","stringIntegerField":"0x00000000000003e7","stringIpv4Field":"8.8.8.8","stringIpv6Field":"2001:4860:4860::8888","stringIriField":"https://テスト.例","stringIriReferenceField":"/テスト/例","stringJsonPointerField":"/data/items/0/name","stringMacAddr8Field":"aa:bb:cc:dd:ee:ff:00:11","stringMacAddrField":"aa:bb:cc:dd:ee:ff","stringNumberField":"0x408f3ffdf3b645a2","stringRegexField":"^\\d{4}-\\d{2}-\\d{2}$","stringRelativeJsonPointerField":"3/updated","stringTimeField":"12:00:00z","stringUint32Field":"0x000000003b9aca00","stringUint64Field":"1000000000000000000","stringUriField":"https://api.example.org/v1/resource","stringUriReferenceField":"../parent/resource","stringUriTemplateField":"/api/v{version}/users/{id}","stringUuidField":"123e4567-e89b-12d3-a456-426614174000"} + +Task: acmeCo/tests/materialize-bigtable-hard-delete + +Resource: simple_standard +["applied.actionDescription", "create table \"simple_standard\"\ncreate table \"not_simple\"\ncreate table \"data_types\""] +["connectorState",{"updated":{"committed_timestamp":1}}] +["connectorState",{"updated":{"committed_timestamp":2}}] +["connectorState",{"updated":{"committed_timestamp":3}}] +["connectorState",{"updated":{"committed_timestamp":4}}] +["connectorState",{"updated":{"committed_timestamp":4}}] + + +Table Data: +{"_meta/op":"c","_row_key":"0x1504","canary":"strengthen","flow_document":{"_meta":{"op":"c","uuid":"770f6b80-1dda-11b2-8000-071353030311"},"canary":"strengthen","id":4,"val":4},"flow_published_at":"1970-01-01T01:00:03.000000000Z","id":"0x0000000000000004","val":"0x0000000000000004"} +{"_meta/op":"c","_row_key":"0x1505","canary":"Kringle's","flow_document":{"_meta":{"op":"c","uuid":"77a80200-1dda-11b2-8000-071353030311"},"canary":"Kringle's","id":5,"val":5},"flow_published_at":"1970-01-01T01:00:04.000000000Z","id":"0x0000000000000005","val":"0x0000000000000005"} +{"_meta/op":"c","_row_key":"0x1506","canary":"grosbeak's","flow_document":{"_meta":{"op":"c","uuid":"78409880-1dda-11b2-8000-071353030311"},"canary":"grosbeak's","id":6,"val":6},"flow_published_at":"1970-01-01T01:00:05.000000000Z","id":"0x0000000000000006","val":"0x0000000000000006"} +{"_meta/op":"c","_row_key":"0x1507","canary":"pieced","flow_document":{"_meta":{"op":"c","uuid":"38ce7800-1deb-11b2-8000-071353030311"},"canary":"pieced","id":7,"val":7},"flow_published_at":"1970-01-01T03:00:00.000000000Z","id":"0x0000000000000007","val":"0x0000000000000007"} +{"_meta/op":"c","_row_key":"0x1508","canary":"roaches","flow_document":{"_meta":{"op":"c","uuid":"39670e80-1deb-11b2-8000-071353030311"},"canary":"roaches","id":8,"val":8},"flow_published_at":"1970-01-01T03:00:01.000000000Z","id":"0x0000000000000008","val":"0x0000000000000008"} +{"_meta/op":"c","_row_key":"0x1509","canary":"devilish","flow_document":{"_meta":{"op":"c","uuid":"39ffa500-1deb-11b2-8000-071353030311"},"canary":"devilish","id":9,"val":9},"flow_published_at":"1970-01-01T03:00:02.000000000Z","id":"0x0000000000000009","val":"0x0000000000000009"} +{"_meta/op":"c","_row_key":"0x150a","canary":"glucose's","flow_document":{"_meta":{"op":"c","uuid":"3a983b80-1deb-11b2-8000-071353030311"},"canary":"glucose's","id":10,"val":10},"flow_published_at":"1970-01-01T03:00:03.000000000Z","id":"0x000000000000000a","val":"0x000000000000000a"} +{"_meta/op":"d","_row_key":"0x150b","canary":"asteroid","flow_document":{"_meta":{"op":"d","uuid":"3b30d200-1deb-11b2-8000-071353030311"},"canary":"asteroid","id":11,"val":11},"flow_published_at":"1970-01-01T03:00:04.000000000Z","id":"0x000000000000000b","val":"0x000000000000000b"} +{"_meta/op":"u","_row_key":"0x1503","canary":"splatters","flow_document":{"_meta":{"op":"u","uuid":"3e2bc280-1deb-11b2-8000-071353030311"},"canary":"splatters","id":3,"val":3},"flow_published_at":"1970-01-01T03:00:09.000000000Z","id":"0x0000000000000003","val":"0x0000000000000003"} + +Resource: not_simple +["applied.actionDescription", "create table \"simple_standard\"\ncreate table \"not_simple\"\ncreate table \"data_types\""] +["connectorState",{"updated":{"committed_timestamp":1}}] +["connectorState",{"updated":{"committed_timestamp":2}}] +["connectorState",{"updated":{"committed_timestamp":3}}] +["connectorState",{"updated":{"committed_timestamp":4}}] +["connectorState",{"updated":{"committed_timestamp":4}}] + + +Table Data: +{" ,;{}().- problematicField � 𐀀 嶲 ":null," ,;{}().- problematicKey � 𐀀 嶲 ":"test-key-2","$dollar$signs":null,"123":null,"123startsWithDigits":null,"FIELDWITHDIFFERENTCAPS":null,"_id":"doc_002","_row_key":"0x02746573742d6b65792d320002646f635f30303200025647567a644552686447453d00","a\"string`with`quote'characters":null,"binaryKey":"TestData","field with separated words":null,"field-with-separated-words":null,"field.with-separated_words":null,"field.with.separated.words":null,"fieldWithDifferentCaps":null,"field_with_separated_words":null,"fieldwithdifferentcaps":null,"flow_document":{" ,;{}().- problematicField � 𐀀 嶲 ":""," ,;{}().- problematicKey � 𐀀 嶲 ":"test-key-2","$dollar$signs":"","123":"","123startsWithDigits":"","FIELDWITHDIFFERENTCAPS":"","_id":"doc_002","_meta":{"uuid":"7971c580-1dda-11b2-8000-071353030311"},"a\"string`with`quote''characters":"","binaryKey":"VGVzdERhdGE=","field with separated words":"","field-with-separated-words":"","field.with-separated_words":"","field.with.separated.words":"","fieldWithDifferentCaps":"","field_with_separated_words":"","fieldwithdifferentcaps":"","longString":"","testing (%s)":"","unsignedBigint":0},"flow_published_at":"1970-01-01T01:00:07.000000000Z","longString":null,"testing (%s)":null,"unsignedBigint":"0"} +{" ,;{}().- problematicField � 𐀀 嶲 ":"symbols: !@#$%^\u0026*()_+-=[]{}|;':\",./\u003c\u003e?"," ,;{}().- problematicKey � 𐀀 嶲 ":"very long string that exceeds 256 characters to test if dynamic sizing of varchar fields works. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostru.","$dollar$signs":"$100.50$","123":"999","123startsWithDigits":"field starting with 123","FIELDWITHDIFFERENTCAPS":"ALL UPPERCASE VALUE","_id":"doc_003","_row_key":"0x0276657279206c6f6e6720737472696e672074686174206578636565647320323536206368617261637465727320746f20746573742069662064796e616d69632073697a696e67206f662076617263686172206669656c647320776f726b732e204c6f72656d20697073756d20646f6c6f722073697420616d65742c20636f6e73656374657475722061646970697363696e6720656c69742c2073656420646f20656975736d6f642074656d706f7220696e6369646964756e74207574206c61626f726520657420646f6c6f7265206d61676e6120616c697175612e20557420656e696d206164206d696e696d2076656e69616d2c2071756973206e6f737472752e0002646f635f3030330002516d6c7559584a355647567a644552686447453d00","a\"string`with`quote'characters":null,"binaryKey":"BinaryTestData","field with separated words":"edge case testing","field-with-separated-words":"hyphen-separated-values","field.with-separated_words":"mixed.separator-test_data","field.with.separated.words":"system.test.data","fieldWithDifferentCaps":"CamelCaseValue","field_with_separated_words":"underscore_separated_values","fieldwithdifferentcaps":"all lowercase value","flow_document":{" ,;{}().- problematicField � 𐀀 嶲 ":"symbols: !@#$%^\u0026*()_+-=[]{}|;':\",./\u003c\u003e?"," ,;{}().- problematicKey � 𐀀 嶲 ":"very long string that exceeds 256 characters to test if dynamic sizing of varchar fields works. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostru.","$dollar$signs":"$100.50$","123":"999","123startsWithDigits":"field starting with 123","FIELDWITHDIFFERENTCAPS":"ALL UPPERCASE VALUE","_id":"doc_003","_meta":{"uuid":"7a0a5c00-1dda-11b2-8000-071353030311"},"a\"string`with`quote''characters":"testing \"quotes\" and `backticks` and 'apostrophes'","binaryKey":"QmluYXJ5VGVzdERhdGE=","field with separated words":"edge case testing","field-with-separated-words":"hyphen-separated-values","field.with-separated_words":"mixed.separator-test_data","field.with.separated.words":"system.test.data","fieldWithDifferentCaps":"CamelCaseValue","field_with_separated_words":"underscore_separated_values","fieldwithdifferentcaps":"all lowercase value","longString":"very long string that exceeds 256 characters to test if dynamic sizing of varchar fields works. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostru.","testing (%s)":"printf style format string test","unsignedBigint":18446744073709551615},"flow_published_at":"1970-01-01T01:00:08.000000000Z","longString":"very long string that exceeds 256 characters to test if dynamic sizing of varchar fields works. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostru.","testing (%s)":"printf style format string test","unsignedBigint":"18446744073709551615"} +{" ,;{}().- problematicField � 𐀀 嶲 ":"updated special chars"," ,;{}().- problematicKey � 𐀀 嶲 ":"\\he \\ ' \" `llo`","$dollar$signs":"updated dollars","123":"updated 123","123startsWithDigits":"updated numbers","FIELDWITHDIFFERENTCAPS":"UPDATED UPPERCASE","_id":"doc_001","_row_key":"0x025c6865205c2027202220606c6c6f600002646f635f30303100025347567362473867563239796247513d00","a\"string`with`quote'characters":null,"binaryKey":"Hello World","field with separated words":"updated spaces","field-with-separated-words":"updated dashes","field.with-separated_words":"updated mixed","field.with.separated.words":"updated dots","fieldWithDifferentCaps":"updatedCamelCase","field_with_separated_words":"updated underscores","fieldwithdifferentcaps":"updated lowercase","flow_document":{" ,;{}().- problematicField � 𐀀 嶲 ":"updated special chars"," ,;{}().- problematicKey � 𐀀 嶲 ":"\\he \\ ' \" `llo`","$dollar$signs":"updated dollars","123":"updated 123","123startsWithDigits":"updated numbers","FIELDWITHDIFFERENTCAPS":"UPDATED UPPERCASE","_id":"doc_001","_meta":{"uuid":"3ec45900-1deb-11b2-8000-071353030311"},"a\"string`with`quote''characters":"updated quotes","binaryKey":"SGVsbG8gV29ybGQ=","field with separated words":"updated spaces","field-with-separated-words":"updated dashes","field.with-separated_words":"updated mixed","field.with.separated.words":"updated dots","fieldWithDifferentCaps":"updatedCamelCase","field_with_separated_words":"updated underscores","fieldwithdifferentcaps":"updated lowercase","longString":"Updated long string with more Unicode: 🎭🎨🎪🎯 αβγδε ñáéíóú 中文更新测试 العربية עברית русский 한국어 日本語","testing (%s)":"updated printf","unsignedBigint":18446744073709551615},"flow_published_at":"1970-01-01T03:00:10.000000000Z","longString":"Updated long string with more Unicode: 🎭🎨🎪🎯 αβγδε ñáéíóú 中文更新测试 العربية עברית русский 한국어 日本語","testing (%s)":"updated printf","unsignedBigint":"18446744073709551615"} + +Resource: data_types +["applied.actionDescription", "create table \"simple_standard\"\ncreate table \"not_simple\"\ncreate table \"data_types\""] +["connectorState",{"updated":{"committed_timestamp":1}}] +["connectorState",{"updated":{"committed_timestamp":2}}] +["connectorState",{"updated":{"committed_timestamp":3}}] +["connectorState",{"updated":{"committed_timestamp":4}}] +["connectorState",{"updated":{"committed_timestamp":4}}] + + +Table Data: +{"_row_key":"0x1501","arrayField":[1,"two",3.0,true,null],"boolField":"0x01","flow_document":{"_meta":{"uuid":"3ff58600-1deb-11b2-8000-071353030311"},"arrayField":[1,"two",3.0,true,null],"boolField":true,"id":1,"intField":42.0,"multipleField":"string value","nullField":null,"numField":3.14159,"objField":{"count":123,"nested":"value"},"stringAndIntegerField":"1.0","stringAndNumberField":"123.456","stringDateField":"2023-01-15","stringDateTimeField":"2023-01-15T10:30:45z","stringDurationField":"P1Y2M3DT4H5M6S","stringEmailField":"test@example.com","stringField":"hello world","stringHostnameField":"example.com","stringIntegerField":"1.0","stringIpv4Field":"192.168.1.1","stringIpv6Field":"2001:db8::1","stringIriField":"https://例え.テスト","stringIriReferenceField":"/例え/テスト","stringJsonPointerField":"/path/to/field","stringMacAddr8Field":"00:14:22:ff:fe:01:23:45","stringMacAddrField":"00:14:22:01:23:45","stringNumberField":"123.456","stringRegexField":"^[a-zA-Z0-9]+$","stringRelativeJsonPointerField":"1/name","stringTimeField":"14:30:00+02:30","stringUint32Field":"4294967295","stringUint64Field":"18446744073709551615","stringUriField":"https://example.com/path","stringUriReferenceField":"/relative/path","stringUriTemplateField":"https://api.example.com/{id}","stringUuidField":"550e8400-e29b-41d4-a716-446655440000"},"flow_published_at":"1970-01-01T03:00:12.000000000Z","id":"0x0000000000000001","intField":"0x000000000000002a","multipleField":"\"string value\"","nullField":null,"numField":"0x400921f9f01b866e","stringAndIntegerField":"0x0000000000000001","stringAndNumberField":"0x405edd2f1a9fbe77","stringDateField":"2023-01-15","stringDateTimeField":"2023-01-15T10:30:45z","stringDurationField":"P1Y2M3DT4H5M6S","stringEmailField":"test@example.com","stringField":"hello world","stringHostnameField":"example.com","stringIntegerField":"0x0000000000000001","stringIpv4Field":"192.168.1.1","stringIpv6Field":"2001:db8::1","stringIriField":"https://例え.テスト","stringIriReferenceField":"/例え/テスト","stringJsonPointerField":"/path/to/field","stringMacAddr8Field":"00:14:22:ff:fe:01:23:45","stringMacAddrField":"00:14:22:01:23:45","stringNumberField":"0x405edd2f1a9fbe77","stringRegexField":"^[a-zA-Z0-9]+$","stringRelativeJsonPointerField":"1/name","stringTimeField":"14:30:00+02:30","stringUint32Field":"0x00000000ffffffff","stringUint64Field":"18446744073709551615","stringUriField":"https://example.com/path","stringUriReferenceField":"/relative/path","stringUriTemplateField":"https://api.example.com/{id}","stringUuidField":"550e8400-e29b-41d4-a716-446655440000"} +{"_row_key":"0x1502","arrayField":[],"boolField":"0x00","flow_document":{"_meta":{"uuid":"408e1c80-1deb-11b2-8000-071353030311"},"arrayField":[],"boolField":false,"id":2,"intField":-999,"multipleField":42,"nullField":null,"numField":-2.718281828,"objField":{},"stringAndIntegerField":-123,"stringAndNumberField":-456.789,"stringDateField":"1999-12-31","stringDateTimeField":"1999-12-31T23:59:59.123456789Z","stringDurationField":"PT30M","stringEmailField":"admin@localhost","stringField":"","stringHostnameField":"localhost","stringIntegerField":"-123","stringIpv4Field":"127.0.0.1","stringIpv6Field":"::1","stringIriField":"http://localhost","stringIriReferenceField":"/","stringJsonPointerField":"/0","stringMacAddr8Field":"ff:ff:ff:ff:ff:ff:ff:ff","stringMacAddrField":"ff:ff:ff:ff:ff:ff","stringNumberField":"-456.789","stringRegexField":".*","stringRelativeJsonPointerField":"0","stringTimeField":"03:55:23.123456789Z","stringUint32Field":"0","stringUint64Field":"0","stringUriField":"http://localhost:8080","stringUriReferenceField":"#fragment","stringUriTemplateField":"http://example.com/~{username}/","stringUuidField":"00000000-0000-0000-0000-000000000000"},"flow_published_at":"1970-01-01T03:00:13.000000000Z","id":"0x0000000000000002","intField":"0xfffffffffffffc19","multipleField":"42","nullField":null,"numField":"0xc005bf0a8b04919b","stringAndIntegerField":"0xffffffffffffff85","stringAndNumberField":"0xc07c8c9fbe76c8b4","stringDateField":"1999-12-31","stringDateTimeField":"1999-12-31T23:59:59.123456789Z","stringDurationField":"PT30M","stringEmailField":"admin@localhost","stringField":null,"stringHostnameField":"localhost","stringIntegerField":"0xffffffffffffff85","stringIpv4Field":"127.0.0.1","stringIpv6Field":"::1","stringIriField":"http://localhost","stringIriReferenceField":"/","stringJsonPointerField":"/0","stringMacAddr8Field":"ff:ff:ff:ff:ff:ff:ff:ff","stringMacAddrField":"ff:ff:ff:ff:ff:ff","stringNumberField":"0xc07c8c9fbe76c8b4","stringRegexField":".*","stringRelativeJsonPointerField":"0","stringTimeField":"03:55:23.123456789Z","stringUint32Field":"0x0000000000000000","stringUint64Field":"0","stringUriField":"http://localhost:8080","stringUriReferenceField":"#fragment","stringUriTemplateField":"http://example.com/~{username}/","stringUuidField":"00000000-0000-0000-0000-000000000000"} +{"_row_key":"0x1503","arrayField":[{"obj":"in array"},[1,[2,[3]]],"mixed types"],"boolField":"0x01","flow_document":{"_meta":{"uuid":"7bd41f80-1dda-11b2-8000-071353030311"},"arrayField":[{"obj":"in array"},[1,[2,[3]]],"mixed types"],"boolField":true,"id":3,"intField":0,"multipleField":{"object":"value"},"nullField":null,"numField":0.0,"objField":{"array":[1,2,3],"nested":{"deep":"value"}},"stringAndIntegerField":"2147483647","stringAndNumberField":"0","stringDateField":"2024-02-29","stringDateTimeField":"2024-02-29T12:00:00.000000000z","stringDurationField":"P0D","stringEmailField":"user+tag@sub.domain.com","stringField":"special chars: !@#$%^\u0026*()[]{}|\\:;\"'\u003c\u003e?/.,","stringHostnameField":"sub.domain.example.org","stringIntegerField":"2147483647","stringIpv4Field":"10.0.0.1","stringIpv6Field":"2001:0db8:0000:0000:0000:ff00:0042:8329","stringIriField":"https://москва.рф/path","stringIriReferenceField":"/москва/путь","stringJsonPointerField":"/nested/array/0/field","stringMacAddr8Field":"01:23:45:67:89:ab:cd:ef","stringMacAddrField":"01:23:45:67:89:ab","stringNumberField":"0","stringRegexField":"[0-9]{3}-[0-9]{2}-[0-9]{4}","stringRelativeJsonPointerField":"2/nested/field","stringTimeField":"23:59:59.999-01:15","stringUint32Field":"2147483648","stringUint64Field":"9223372036854775808","stringUriField":"ftp://user:pass@host.com:21/path?query=value","stringUriReferenceField":"?query=value\u0026other=param","stringUriTemplateField":"https://{host}{/path*}{?query*}","stringUuidField":"f47ac10b-58cc-4372-a567-0e02b2c3d479"},"flow_published_at":"1970-01-01T01:00:11.000000000Z","id":"0x0000000000000003","intField":"0x0000000000000000","multipleField":{"object":"value"},"nullField":null,"numField":"0x0000000000000000","stringAndIntegerField":"0x000000007fffffff","stringAndNumberField":"0x0000000000000000","stringDateField":"2024-02-29","stringDateTimeField":"2024-02-29T12:00:00.000000000z","stringDurationField":"P0D","stringEmailField":"user+tag@sub.domain.com","stringField":"special chars: !@#$%^\u0026*()[]{}|\\:;\"'\u003c\u003e?/.,","stringHostnameField":"sub.domain.example.org","stringIntegerField":"0x000000007fffffff","stringIpv4Field":"10.0.0.1","stringIpv6Field":"2001:0db8:0000:0000:0000:ff00:0042:8329","stringIriField":"https://москва.рф/path","stringIriReferenceField":"/москва/путь","stringJsonPointerField":"/nested/array/0/field","stringMacAddr8Field":"01:23:45:67:89:ab:cd:ef","stringMacAddrField":"01:23:45:67:89:ab","stringNumberField":"0x0000000000000000","stringRegexField":"[0-9]{3}-[0-9]{2}-[0-9]{4}","stringRelativeJsonPointerField":"2/nested/field","stringTimeField":"23:59:59.999-01:15","stringUint32Field":"0x0000000080000000","stringUint64Field":"9223372036854775808","stringUriField":"ftp://user:pass@host.com:21/path?query=value","stringUriReferenceField":"?query=value\u0026other=param","stringUriTemplateField":"https://{host}{/path*}{?query*}","stringUuidField":"f47ac10b-58cc-4372-a567-0e02b2c3d479"} +{"_row_key":"0x1504","arrayField":["updated","array","values"],"boolField":"0x00","flow_document":{"_meta":{"uuid":"3f5cef80-1deb-11b2-8000-071353030311"},"arrayField":["updated","array","values"],"boolField":false,"id":4,"intField":2147483647,"multipleField":999,"nullField":null,"numField":12345678900.0,"objField":{"timestamp":"2024-01-01","updated":true},"stringAndIntegerField":999,"stringAndNumberField":999.999,"stringDateField":"2024-12-25","stringDateTimeField":"2024-12-25T00:00:00Z","stringDurationField":"P1D","stringEmailField":"updated@test.org","stringField":"updated value","stringHostnameField":"api.example.org","stringIntegerField":"999","stringIpv4Field":"8.8.8.8","stringIpv6Field":"2001:4860:4860::8888","stringIriField":"https://テスト.例","stringIriReferenceField":"/テスト/例","stringJsonPointerField":"/data/items/0/name","stringMacAddr8Field":"aa:bb:cc:dd:ee:ff:00:11","stringMacAddrField":"aa:bb:cc:dd:ee:ff","stringNumberField":"999.999","stringRegexField":"^\\d{4}-\\d{2}-\\d{2}$","stringRelativeJsonPointerField":"3/updated","stringTimeField":"12:00:00z","stringUint32Field":"1000000000","stringUint64Field":"1000000000000000000","stringUriField":"https://api.example.org/v1/resource","stringUriReferenceField":"../parent/resource","stringUriTemplateField":"/api/v{version}/users/{id}","stringUuidField":"123e4567-e89b-12d3-a456-426614174000"},"flow_published_at":"1970-01-01T03:00:11.000000000Z","id":"0x0000000000000004","intField":"0x000000007fffffff","multipleField":"999","nullField":null,"numField":"0x4206fee0e1a00000","stringAndIntegerField":"0x00000000000003e7","stringAndNumberField":"0x408f3ffdf3b645a2","stringDateField":"2024-12-25","stringDateTimeField":"2024-12-25T00:00:00Z","stringDurationField":"P1D","stringEmailField":"updated@test.org","stringField":"updated value","stringHostnameField":"api.example.org","stringIntegerField":"0x00000000000003e7","stringIpv4Field":"8.8.8.8","stringIpv6Field":"2001:4860:4860::8888","stringIriField":"https://テスト.例","stringIriReferenceField":"/テスト/例","stringJsonPointerField":"/data/items/0/name","stringMacAddr8Field":"aa:bb:cc:dd:ee:ff:00:11","stringMacAddrField":"aa:bb:cc:dd:ee:ff","stringNumberField":"0x408f3ffdf3b645a2","stringRegexField":"^\\d{4}-\\d{2}-\\d{2}$","stringRelativeJsonPointerField":"3/updated","stringTimeField":"12:00:00z","stringUint32Field":"0x000000003b9aca00","stringUint64Field":"1000000000000000000","stringUriField":"https://api.example.org/v1/resource","stringUriReferenceField":"../parent/resource","stringUriTemplateField":"/api/v{version}/users/{id}","stringUuidField":"123e4567-e89b-12d3-a456-426614174000"} + + diff --git a/materialize-bigtable/.snapshots/TestSpec b/materialize-bigtable/.snapshots/TestSpec new file mode 100644 index 0000000000..e762ce6355 --- /dev/null +++ b/materialize-bigtable/.snapshots/TestSpec @@ -0,0 +1,138 @@ +{ + "config_schema_json": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://github.com/estuary/connectors/materialize-bigtable/config", + "properties": { + "project_id": { + "type": "string", + "title": "Project ID", + "description": "Google Cloud Project ID that owns the Bigtable instance.", + "order": 0 + }, + "instance_id": { + "type": "string", + "title": "Instance ID", + "description": "Bigtable instance ID for the materialized tables.", + "order": 1 + }, + "credentials": { + "oneOf": [ + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://github.com/estuary/connectors/materialize-bigtable/credentials-json-config", + "properties": { + "auth_type": { + "type": "string", + "const": "CredentialsJSON", + "default": "CredentialsJSON", + "order": 0 + }, + "credentials_json": { + "type": "string", + "title": "Service Account JSON", + "description": "The JSON credentials of the service account to use for authorization.", + "multiline": true, + "order": 0, + "secret": true + } + }, + "type": "object", + "required": [ + "credentials_json" + ], + "title": "Credentials JSON" + }, + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://github.com/estuary/connectors/go/auth/iam/gcp-config", + "properties": { + "auth_type": { + "type": "string", + "const": "GCPIAM", + "default": "GCPIAM", + "order": 0 + }, + "gcp_service_account_to_impersonate": { + "type": "string", + "title": "Service Account", + "description": "GCP Service Account email for Cloud SQL IAM authentication" + }, + "gcp_workload_identity_pool_audience": { + "type": "string", + "title": "Workload Identity Pool Audience", + "description": "GCP Workload Identity Pool Audience in the format //iam.googleapis.com/projects/123/locations/global/workloadIdentityPools/test-pool/providers/test-provider" + } + }, + "type": "object", + "required": [ + "gcp_service_account_to_impersonate", + "gcp_workload_identity_pool_audience" + ], + "title": "GCP IAM" + } + ], + "type": "object", + "title": "Authentication", + "default": { + "auth_type": "CredentialsJSON" + }, + "discriminator": { + "propertyName": "auth_type" + }, + "order": 2, + "x-iam-auth": true + }, + "hardDelete": { + "type": "boolean", + "title": "Hard Delete", + "description": "If this option is enabled items deleted in the source will also be deleted from the destination. By default is disabled and _meta/op in the destination will signify whether rows have been deleted (soft-delete).", + "default": false, + "order": 3 + }, + "advanced": { + "properties": { + "endpoint": { + "type": "string", + "title": "Bigtable Endpoint", + "description": "The Bigtable endpoint URI to connect to. Use if you're materializing to a compatible API that isn't provided by Google." + }, + "feature_flags": { + "type": "string", + "title": "Feature Flags", + "description": "This property is intended for Estuary internal use. You should only modify this field as directed by Estuary support." + } + }, + "additionalProperties": false, + "type": "object", + "title": "Advanced Options", + "description": "Options for advanced users. You should not typically need to modify these.", + "advanced": true + } + }, + "type": "object", + "required": [ + "project_id", + "instance_id", + "credentials" + ], + "title": "Materialize Bigtable Spec" + }, + "resource_config_schema_json": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://github.com/estuary/connectors/materialize-bigtable/resource", + "properties": { + "table": { + "type": "string", + "title": "Table Name", + "description": "The name of the Bigtable table to materialize to.", + "x-collection-name": true + } + }, + "type": "object", + "required": [ + "table" + ], + "title": "Bigtable Table" + }, + "documentation_url": "https://go.estuary.dev/materialize-bigtable" +} diff --git a/materialize-bigtable/Dockerfile b/materialize-bigtable/Dockerfile new file mode 100644 index 0000000000..e081af8ca1 --- /dev/null +++ b/materialize-bigtable/Dockerfile @@ -0,0 +1,39 @@ +ARG BASE_IMAGE=ghcr.io/estuary/base-image:v1 + +# Build Stage +################################################################################ +FROM --platform=linux/amd64 golang:1.25-bookworm AS builder + +WORKDIR /builder + +# Download & compile dependencies early. Doing this separately allows for layer +# caching opportunities when no dependencies are updated. +COPY go.* ./ +RUN go mod download + +COPY go ./go +COPY materialize-boilerplate ./materialize-boilerplate +COPY materialize-bigtable ./materialize-bigtable + +RUN go test -tags nozstd -v ./materialize-boilerplate/... +RUN go test -tags nozstd -short -v ./materialize-bigtable/... + +# Build the connector. +RUN go build -tags nozstd -v -o ./connector ./materialize-bigtable + +# Runtime Stage +################################################################################ +FROM ${BASE_IMAGE} + +WORKDIR /connector +ENV PATH="/connector:$PATH" + +# Bring in the compiled connector artifact from the builder. +COPY --from=builder /builder/connector /connector/materialize-bigtable + +# Avoid running the connector as root. +USER nonroot:nonroot + +LABEL FLOW_RUNTIME_PROTOCOL=materialize + +ENTRYPOINT ["/connector/materialize-bigtable"] diff --git a/materialize-bigtable/VERSION b/materialize-bigtable/VERSION new file mode 100644 index 0000000000..626799f0f8 --- /dev/null +++ b/materialize-bigtable/VERSION @@ -0,0 +1 @@ +v1 diff --git a/materialize-bigtable/docker-compose.yaml b/materialize-bigtable/docker-compose.yaml new file mode 100644 index 0000000000..a37243b4f0 --- /dev/null +++ b/materialize-bigtable/docker-compose.yaml @@ -0,0 +1,20 @@ +services: + bigtable: + image: "google/cloud-sdk:latest" + command: > + gcloud beta emulators bigtable start + --host-port=0.0.0.0:8086 + ports: + - "8086:8086" + networks: + - flow-test + healthcheck: + test: ["CMD", "bash", "-c", "echo > /dev/tcp/localhost/8086"] + interval: 2s + timeout: 2s + retries: 30 + +networks: + flow-test: + name: flow-test + external: true diff --git a/materialize-bigtable/driver.go b/materialize-bigtable/driver.go new file mode 100644 index 0000000000..eeed8e6ad9 --- /dev/null +++ b/materialize-bigtable/driver.go @@ -0,0 +1,535 @@ +package main + +import ( + "context" + "encoding/hex" + "encoding/json" + "errors" + "fmt" + "regexp" + "slices" + "sort" + "strings" + "unicode" + "unicode/utf8" + + "cloud.google.com/go/bigtable" + "github.com/estuary/connectors/go/auth/iam" + cerrors "github.com/estuary/connectors/go/connector-errors" + m "github.com/estuary/connectors/go/materialize" + schemagen "github.com/estuary/connectors/go/schema-gen" + boilerplate "github.com/estuary/connectors/materialize-boilerplate" + pf "github.com/estuary/flow/go/protocols/flow" + pm "github.com/estuary/flow/go/protocols/materialize" + "github.com/invopop/jsonschema" + "golang.org/x/oauth2" + "google.golang.org/api/option" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/credentials/insecure" + "google.golang.org/grpc/status" +) + +var featureFlagDefaults = map[string]bool{} + +type AuthType string + +const ( + CredentialsJSON AuthType = "CredentialsJSON" + GCPIAM AuthType = "GCPIAM" +) + +type CredentialsJSONConfig struct { + CredentialsJSON string `json:"credentials_json" jsonschema:"title=Service Account JSON,description=The JSON credentials of the service account to use for authorization." jsonschema_extras:"secret=true,multiline=true,order=0"` +} + +type CredentialsConfig struct { + AuthType AuthType `json:"auth_type"` + + CredentialsJSONConfig + iam.IAMConfig +} + +func (CredentialsConfig) JSONSchema() *jsonschema.Schema { + subSchemas := []schemagen.OneOfSubSchemaT{ + schemagen.OneOfSubSchema("Credentials JSON", CredentialsJSONConfig{}, string(CredentialsJSON)), + schemagen.OneOfSubSchema("GCP IAM", iam.GCPConfig{}, string(GCPIAM)), + } + + return schemagen.OneOfSchema("Authentication", "", "auth_type", string(CredentialsJSON), subSchemas...) +} + +func (c *CredentialsConfig) Validate() error { + switch c.AuthType { + case CredentialsJSON: + if c.CredentialsJSON == "" { + return errors.New("missing 'credentials_json'") + } + if !json.Valid([]byte(c.CredentialsJSON)) { + return fmt.Errorf("service account credentials must be valid JSON, and the provided credentials were not") + } + return nil + case GCPIAM: + return c.ValidateIAM() + default: + return fmt.Errorf("unknown 'auth_type'") + } +} + +type config struct { + ProjectID string `json:"project_id" jsonschema:"title=Project ID,description=Google Cloud Project ID that owns the Bigtable instance." jsonschema_extras:"order=0"` + InstanceID string `json:"instance_id" jsonschema:"title=Instance ID,description=Bigtable instance ID for the materialized tables." jsonschema_extras:"order=1"` + Credentials *CredentialsConfig `json:"credentials" jsonschema:"title=Authentication" jsonschema_extras:"x-iam-auth=true,order=2"` + HardDelete bool `json:"hardDelete,omitempty" jsonschema:"title=Hard Delete,description=If this option is enabled items deleted in the source will also be deleted from the destination. By default is disabled and _meta/op in the destination will signify whether rows have been deleted (soft-delete).,default=false" jsonschema_extras:"order=3"` + + Advanced advancedConfig `json:"advanced,omitempty" jsonschema:"title=Advanced Options,description=Options for advanced users. You should not typically need to modify these." jsonschema_extras:"advanced=true"` +} + +type advancedConfig struct { + Endpoint string `json:"endpoint,omitempty" jsonschema:"title=Bigtable Endpoint,description=The Bigtable endpoint URI to connect to. Use if you're materializing to a compatible API that isn't provided by Google."` + FeatureFlags string `json:"feature_flags,omitempty" jsonschema:"title=Feature Flags,description=This property is intended for Estuary internal use. You should only modify this field as directed by Estuary support."` +} + +func (c config) Validate() error { + var requiredProperties = [][]string{ + {"project_id", c.ProjectID}, + {"instance_id", c.InstanceID}, + } + for _, req := range requiredProperties { + if req[1] == "" { + return fmt.Errorf("missing '%s'", req[0]) + } + } + + if c.Credentials == nil { + return errors.New("missing 'credentials'") + } + + return c.Credentials.Validate() +} + +func (c config) DefaultNamespace() string { return "" } + +func (c config) FeatureFlags() (string, map[string]bool) { + return c.Advanced.FeatureFlags, featureFlagDefaults +} + +func (c config) CredentialsClientOption() (option.ClientOption, error) { + switch c.Credentials.AuthType { + case CredentialsJSON: + return option.WithAuthCredentialsJSON(option.ServiceAccount, []byte(c.Credentials.CredentialsJSON)), nil + case GCPIAM: + return option.WithTokenSource(oauth2.StaticTokenSource( + &oauth2.Token{AccessToken: c.Credentials.GoogleToken()}, + )), nil + default: + return nil, fmt.Errorf("unknown 'auth_type'") + } +} + +func (c config) buildClientOptions() ([]option.ClientOption, error) { + var clientOpts []option.ClientOption + + if c.Advanced.Endpoint != "" { + clientOpts = append(clientOpts, + option.WithEndpoint(c.Advanced.Endpoint), + option.WithoutAuthentication(), + option.WithGRPCDialOption(grpc.WithTransportCredentials(insecure.NewCredentials())), + ) + } else { + credOption, err := c.CredentialsClientOption() + if err != nil { + return nil, err + } + clientOpts = append(clientOpts, credOption) + } + + return clientOpts, nil +} + +func (c config) dataClient(ctx context.Context) (*bigtable.Client, error) { + opts, err := c.buildClientOptions() + if err != nil { + return nil, err + } + + cfg := bigtable.ClientConfig{MetricsProvider: bigtable.NoopMetricsProvider{}} + client, err := bigtable.NewClientWithConfig(ctx, c.ProjectID, c.InstanceID, cfg, opts...) + if err != nil { + return nil, fmt.Errorf("creating bigtable data client: %w", err) + } + + return client, nil +} + +func (c config) adminClient(ctx context.Context) (*bigtable.AdminClient, error) { + opts, err := c.buildClientOptions() + if err != nil { + return nil, err + } + + client, err := bigtable.NewAdminClient(ctx, c.ProjectID, c.InstanceID, opts...) + if err != nil { + return nil, fmt.Errorf("creating bigtable admin client: %w", err) + } + + return client, nil +} + +type resource struct { + Table string `json:"table" jsonschema:"title=Table Name,description=The name of the Bigtable table to materialize to." jsonschema_extras:"x-collection-name=true"` +} + +func (r resource) Validate() error { + if r.Table == "" { + return fmt.Errorf("missing 'table'") + } + + return nil +} + +func (r resource) WithDefaults(cfg config) resource { return r } + +func (r resource) Parameters() ([]string, bool, error) { + return []string{normalizeTableName(r.Table)}, false, nil +} + +// Bigtable table IDs match the pattern `[_a-zA-Z0-9][-_.a-zA-Z0-9]*` and are +// capped at 50 bytes. The first character cannot be `-` or `.`, so we strip +// any such leading runs after the body sanitization. +// Ref: https://cloud.google.com/bigtable/docs/reference/admin/rest/v2/projects.instances.tables/create +const maxTableNameLength = 50 + +var tableNameSanitizer = regexp.MustCompile(`[^a-zA-Z0-9_\-\.]`) + +func normalizeTableName(t string) string { + cleaned := tableNameSanitizer.ReplaceAllString(t, "_") + cleaned = strings.TrimLeft(cleaned, "-.") + if len(cleaned) > maxTableNameLength { + cleaned = cleaned[:maxTableNameLength] + } + return cleaned +} + +type driver struct{} + +var _ boilerplate.Connector = &driver{} + +func (d driver) Spec(ctx context.Context, req *pm.Request_Spec) (*pm.Response_Spec, error) { + endpointSchema, err := schemagen.GenerateSchema("Materialize Bigtable Spec", &config{}).MarshalJSON() + if err != nil { + return nil, fmt.Errorf("generating endpoint schema: %w", err) + } + + resourceSchema, err := schemagen.GenerateSchema("Bigtable Table", &resource{}).MarshalJSON() + if err != nil { + return nil, fmt.Errorf("generating resource schema: %w", err) + } + + return boilerplate.RunSpec(ctx, req, "https://go.estuary.dev/materialize-bigtable", endpointSchema, resourceSchema) +} + +func (d driver) Validate(ctx context.Context, req *pm.Request_Validate) (*pm.Response_Validated, error) { + return boilerplate.RunValidate(ctx, req, newMaterialization) +} + +func (d driver) Apply(ctx context.Context, req *pm.Request_Apply) (*pm.Response_Applied, error) { + return boilerplate.RunApply(ctx, req, newMaterialization) +} + +func (d driver) NewTransactor(ctx context.Context, req pm.Request_Open, be *m.BindingEvents) (m.Transactor, *pm.Response_Opened, *m.MaterializeOptions, error) { + return boilerplate.RunNewTransactor(ctx, req, be, newMaterialization) +} + +type materialization struct { + cfg config + adminClient *bigtable.AdminClient + dataClient *bigtable.Client +} + +var _ boilerplate.Materializer[config, fieldConfig, resource, mappedType] = &materialization{} + +func newMaterialization(ctx context.Context, materializationName string, cfg config, featureFlags map[string]bool) (boilerplate.Materializer[config, fieldConfig, resource, mappedType], error) { + admin, err := cfg.adminClient(ctx) + if err != nil { + return nil, err + } + + data, err := cfg.dataClient(ctx) + if err != nil { + admin.Close() + return nil, err + } + + return &materialization{ + cfg: cfg, + adminClient: admin, + dataClient: data, + }, nil +} + +func (d *materialization) Config() boilerplate.MaterializeCfg { + return boilerplate.MaterializeCfg{ + TranslateField: func(f string) string { return f }, + ConcurrentApply: true, + NoCreateNamespaces: true, + NoTruncateResources: true, + } +} + +func (d *materialization) PopulateInfoSchema(ctx context.Context, is *boilerplate.InfoSchema, resourcePaths [][]string) error { + for _, p := range resourcePaths { + tableName := p[0] + if _, err := d.adminClient.TableInfo(ctx, tableName); err != nil { + if status.Code(err) == codes.NotFound { + continue + } + return fmt.Errorf("describing table %q: %w", tableName, err) + } + is.PushResource(tableName) + } + + return nil +} + +func (d *materialization) CheckPrerequisites(ctx context.Context) *cerrors.PrereqErr { + prereq := &cerrors.PrereqErr{} + + // Tables() proves three things: the instance/project IDs resolve, the + // credentials authenticate, and the role has at least bigtable.tables.list + // on the instance. Most user-facing misconfigurations surface here. + if _, err := d.adminClient.Tables(ctx); err != nil { + switch status.Code(err) { + case codes.NotFound: + prereq.Err(fmt.Errorf("Bigtable instance %q not found in project %q: double-check the project_id and instance_id", d.cfg.InstanceID, d.cfg.ProjectID)) + case codes.PermissionDenied, codes.Unauthenticated: + prereq.Err(fmt.Errorf("permission denied accessing instance %q: the configured credentials need at minimum the Bigtable User role on this instance", d.cfg.InstanceID)) + default: + prereq.Err(fmt.Errorf("listing tables in instance %q: %w", d.cfg.InstanceID, err)) + } + } + + return prereq +} + +func (d *materialization) NewConstraint(p pf.Projection, _ bool, fc fieldConfig) pm.Response_Validated_Constraint { + var c pm.Response_Validated_Constraint + switch { + case p.IsPrimaryKey: + c.Type = pm.Response_Validated_Constraint_LOCATION_REQUIRED + c.Reason = "Primary key locations are required" + case p.IsRootDocumentProjection(): + c.Type = pm.Response_Validated_Constraint_LOCATION_REQUIRED + c.Reason = "The root document is required for a standard updates materialization" + case p.Field == "_meta/op": + c.Type = pm.Response_Validated_Constraint_LOCATION_RECOMMENDED + c.Reason = "The operation type should usually be materialized" + case strings.HasPrefix(p.Field, "_meta/"): + c.Type = pm.Response_Validated_Constraint_FIELD_OPTIONAL + c.Reason = "Metadata fields are able to be materialized" + case p.Inference.IsSingleType() && slices.Contains(p.Inference.Types, "object"): + c.Type = pm.Response_Validated_Constraint_FIELD_OPTIONAL + c.Reason = "Object fields may be materialized" + default: + c.Type = pm.Response_Validated_Constraint_LOCATION_RECOMMENDED + c.Reason = "This field is able to be materialized" + } + return c +} + +func (d *materialization) MapType(p boilerplate.Projection, fc fieldConfig) (mappedType, boilerplate.ElementConverter) { + return mapType(p), nil +} + +func (d *materialization) Setup(ctx context.Context, is *boilerplate.InfoSchema) (string, error) { + return "", nil +} + +func (d *materialization) CreateNamespace(ctx context.Context, ns string) (string, error) { + return "", nil +} + +func (d *materialization) CreateResource(ctx context.Context, res boilerplate.MappedBinding[config, resource, mappedType]) (string, boilerplate.ActionApplyFn, error) { + tableName := res.ResourcePath[0] + return fmt.Sprintf("create table %q", tableName), func(ctx context.Context) error { + // MaxVersions(2) keeps the last committed cell plus an in-flight cell + // from a crashed attempt, so the dirty-read detection in Load can fall + // back to the safe version. + conf := &bigtable.TableConf{ + TableID: tableName, + ColumnFamilies: map[string]bigtable.Family{ + columnFamily: {GCPolicy: bigtable.MaxVersionsGCPolicy(2)}, + }, + } + if err := d.adminClient.CreateTableFromConf(ctx, conf); err != nil { + return fmt.Errorf("create table %s: %w", tableName, err) + } + + return nil + }, nil +} + +func (d *materialization) DeleteResource(ctx context.Context, resourcePath []string) (string, boilerplate.ActionApplyFn, error) { + tableName := resourcePath[0] + return fmt.Sprintf("delete table %q", tableName), func(ctx context.Context) error { + if err := d.adminClient.DeleteTable(ctx, tableName); err != nil { + return fmt.Errorf("delete table %s: %w", tableName, err) + } + + return nil + }, nil +} + +func (d *materialization) TruncateResource(ctx context.Context, path []string) (string, boilerplate.ActionApplyFn, error) { + panic("not supported — NoTruncateResources is set") +} + +func (d *materialization) MustRecreateResource(req *pm.Request_Apply, lastBinding, newBinding *pf.MaterializationSpec_Binding) (bool, error) { + return false, nil +} + +func (d *materialization) UpdateResource( + ctx context.Context, + resourcePath []string, + existing boilerplate.ExistingResource, + update boilerplate.BindingUpdate[config, resource, mappedType], +) (string, boilerplate.ActionApplyFn, error) { + return "", nil, nil +} + +func (d *materialization) NewTransactor( + ctx context.Context, + req pm.Request_Open, + is boilerplate.InfoSchema, + mappedBindings []boilerplate.MappedBinding[config, resource, mappedType], + be *m.BindingEvents, +) (m.Transactor, error) { + bindings := make([]binding, 0, len(mappedBindings)) + for _, mb := range mappedBindings { + b := binding{ + tableName: mb.ResourcePath[0], + table: d.dataClient.Open(mb.ResourcePath[0]), + docField: mb.FieldSelection.Document, // Usually "flow_document", but can be projected to a different field name + } + for _, p := range mb.SelectedProjections() { + if !p.IsRootDocumentProjection() { + b.fields = append(b.fields, p.Mapped) + } + } + bindings = append(bindings, b) + } + + return &transactor{bindings: bindings, hardDelete: d.cfg.HardDelete}, nil +} + +func (d *materialization) ListTestTasks(ctx context.Context) ([]string, error) { return nil, nil } +func (d *materialization) CleanupTestTask(ctx context.Context, taskName string) error { return nil } + +func (d *materialization) SnapshotTestResource(ctx context.Context, path []string) ([]string, [][]any, error) { + tableName := path[0] + tbl := d.dataClient.Open(tableName) + + // Read latest 1 version of every cell — snapshots reflect committed state. + var rows []bigtable.Row + if err := tbl.ReadRows(ctx, bigtable.InfiniteRange(""), func(r bigtable.Row) bool { + rows = append(rows, r) + return true + }, bigtable.RowFilter(bigtable.LatestNFilter(1))); err != nil { + return nil, nil, fmt.Errorf("scanning table %q: %w", tableName, err) + } + + // columnQualifier strips the column-family prefix from a "family:qualifier" + // string returned by Bigtable. + columnQualifier := func(c string) string { + if i := strings.IndexByte(c, ':'); i >= 0 { + return c[i+1:] + } + + return c + } + + // renderBytes converts a raw cell value into a snapshot-friendly form to + // keep test snapshots legible — without it, Go's JSON encoder would render + // every []byte as base64. + // + // - empty cells become null (a 0-byte cell is how we encode null). + // - JSON objects/arrays surface as json.RawMessage so they inline. This + // covers the document column (which may be projected under any name) and + // JSON-typed fields. + // - cells that are valid printable UTF-8 render as a string. + // - everything else (8-byte BE ints, packed FDB tuples, etc.) renders as + // `0x...` hex — deterministic and easier to eyeball than base64. + renderBytes := func(value []byte) any { + if len(value) == 0 { + return nil + } + if (value[0] == '{' || value[0] == '[') && json.Valid(value) { + return json.RawMessage(value) + } + if utf8.Valid(value) { + printable := true + for _, r := range string(value) { + if !unicode.IsPrint(r) && !unicode.IsSpace(r) { + printable = false + break + } + } + if printable { + return string(value) + } + } + + return "0x" + hex.EncodeToString(value) + } + + colSet := map[string]struct{}{"_row_key": {}} + for _, r := range rows { + for _, items := range r { + for _, it := range items { + colSet[columnQualifier(it.Column)] = struct{}{} + } + } + } + columns := make([]string, 0, len(colSet)) + for c := range colSet { + columns = append(columns, c) + } + sort.Strings(columns) + + out := make([][]any, 0, len(rows)) + for _, r := range rows { + row := make([]any, len(columns)) + for i, c := range columns { + if c == "_row_key" { + row[i] = renderBytes([]byte(r.Key())) + continue + } + for _, items := range r { + for _, it := range items { + if columnQualifier(it.Column) == c { + row[i] = renderBytes(it.Value) + } + } + } + } + out = append(out, row) + } + + sort.Slice(out, func(i, j int) bool { + for c := range columns { + vi := fmt.Sprint(out[i][c]) + vj := fmt.Sprint(out[j][c]) + if vi != vj { + return vi < vj + } + } + return false + }) + + return columns, out, nil +} + +func (d *materialization) Close(ctx context.Context) { + d.dataClient.Close() + d.adminClient.Close() +} diff --git a/materialize-bigtable/driver_test.go b/materialize-bigtable/driver_test.go new file mode 100644 index 0000000000..379ec35a43 --- /dev/null +++ b/materialize-bigtable/driver_test.go @@ -0,0 +1,62 @@ +package main + +import ( + "flag" + "os" + "os/exec" + "testing" + + boilerplate "github.com/estuary/connectors/materialize-boilerplate/testutil" + "github.com/stretchr/testify/require" +) + +// testAll controls whether integration tests run against a real Cloud +// Bigtable instance in addition to the local emulator. The real-instance +// path requires the encrypted `config.gcp.yaml` to decrypt and a live +// instance pre-provisioned per `testdata/README.md`, so by default we +// only exercise the emulator. Opt in to the full matrix by setting the +// `BIGTABLE_TEST_ALL` environment variable or passing +// `-bigtable.test-all` to `go test`. +var testAll = flag.Bool("bigtable.test-all", false, "run integration tests against a real Cloud Bigtable instance in addition to the local emulator") + +func testConfig() *config { + return &config{ + ProjectID: "test-project", + InstanceID: "test-instance", + Advanced: advancedConfig{ + Endpoint: "localhost:8086", + }, + } +} + +func TestIntegration(t *testing.T) { + if testing.Short() { + t.Skip() + } + + makeResourceFn := func(table string, delta bool) resource { + return resource{Table: table} + } + + require.NoError(t, exec.Command("docker", "compose", "-f", "docker-compose.yaml", "up", "--wait").Run()) + t.Cleanup(func() { + exec.Command("docker", "compose", "-f", "docker-compose.yaml", "down", "-v").Run() + }) + + all := *testAll || os.Getenv("BIGTABLE_TEST_ALL") != "" + + materializeSpec := "testdata/materialize-local.flow.yaml" + applySpec := "testdata/apply-local.flow.yaml" + if all { + materializeSpec = "testdata/materialize.flow.yaml" + applySpec = "testdata/apply.flow.yaml" + } + + t.Run("materialize", func(t *testing.T) { + boilerplate.RunMaterializationTest(t, newMaterialization, materializeSpec, makeResourceFn, nil) + }) + + t.Run("apply", func(t *testing.T) { + boilerplate.RunApplyTest(t, &driver{}, newMaterialization, applySpec, makeResourceFn) + }) +} diff --git a/materialize-bigtable/driver_unit_test.go b/materialize-bigtable/driver_unit_test.go new file mode 100644 index 0000000000..a0540ce0a5 --- /dev/null +++ b/materialize-bigtable/driver_unit_test.go @@ -0,0 +1,55 @@ +package main + +import ( + "context" + "encoding/json" + "strings" + "testing" + + "github.com/bradleyjkemp/cupaloy" + pm "github.com/estuary/flow/go/protocols/materialize" + "github.com/stretchr/testify/require" +) + +func TestSpec(t *testing.T) { + driver := driver{} + response, err := driver.Spec(context.Background(), &pm.Request_Spec{}) + require.NoError(t, err) + + formatted, err := json.MarshalIndent(response, "", " ") + require.NoError(t, err) + cupaloy.SnapshotT(t, string(formatted)) +} + +func TestNormalizeTableName(t *testing.T) { + for _, tt := range []struct { + name string + input string + want string + }{ + { + name: "not normalized", + input: "Some.collection-Name_v1", + want: "Some.collection-Name_v1", + }, + { + name: "non-ascii sanitized", + input: "café_table", + want: "caf__table", + }, + { + name: "leading dashes and dots stripped", + input: "-.-foo.bar", + want: "foo.bar", + }, + { + name: "truncated", + input: strings.Repeat("a", maxTableNameLength+5), + want: strings.Repeat("a", maxTableNameLength), + }, + } { + t.Run(tt.name, func(t *testing.T) { + require.Equal(t, tt.want, normalizeTableName(tt.input)) + }) + } +} diff --git a/materialize-bigtable/main.go b/materialize-bigtable/main.go new file mode 100644 index 0000000000..d950b07208 --- /dev/null +++ b/materialize-bigtable/main.go @@ -0,0 +1,9 @@ +package main + +import ( + boilerplate "github.com/estuary/connectors/materialize-boilerplate" +) + +func main() { + boilerplate.RunMain(driver{}) +} diff --git a/materialize-bigtable/testdata/README.md b/materialize-bigtable/testdata/README.md new file mode 100644 index 0000000000..722a088cb8 --- /dev/null +++ b/materialize-bigtable/testdata/README.md @@ -0,0 +1,83 @@ +# Test fixtures + +By default, integration tests run against the local Bigtable emulator (brought +up by the connector's `docker-compose.yaml`) using `config.local.yaml`. CI runs +this path so the test suite is fast and free. The default specs are +`materialize-local.flow.yaml` and `apply-local.flow.yaml`. + +A second materialization task (`acmeCo/tests/materialize-bigtable-gcp`) is +defined in `materialize.flow.yaml` and `apply.flow.yaml` for testing against a +real Cloud Bigtable instance using the encrypted `config.gcp.yaml`. Run it +manually when you need to verify behavior the emulator doesn't cover (auth, +PingAndWarm, real network errors, etc.) by opting in via the +`BIGTABLE_TEST_ALL` environment variable or the `-bigtable.test-all` flag. + +## Running against real Cloud Bigtable + +### 1. Create the Bigtable instance + +`config.gcp.yaml` is configured to talk to an instance named `estuary-test` in +the `estuary-theatre` project, single SSD node in `us-east1-d`. Create it: + +```bash +gcloud bigtable instances create estuary-test \ + --display-name=estuary-test \ + --cluster-config=id=estuary-test-c1,zone=us-east1-d,nodes=1 \ + --project=estuary-theatre +``` + +### 2. Add a placeholder table + +The Bigtable Go client primes its connection pool by calling `PingAndWarm` at +startup. The server returns `NotFound: No tables found for instance` when the +instance is empty, which the client treats as a fatal startup error. Creating +any single table makes priming succeed: + +```bash +cbt -project=estuary-theatre -instance=estuary-test createtable __keepalive +``` + +(`cbt` is part of the gcloud SDK: `gcloud components install cbt`.) + +### 3. Grant the test SA Bigtable roles on the instance + +The service account whose key is embedded in `config.gcp.yaml` needs Bigtable +permissions on the new instance. The connector creates tables and column +families during Apply, so it needs admin in addition to user: + +```bash +SA="" # decrypt config.gcp.yaml to find it + +gcloud bigtable instances add-iam-policy-binding estuary-test \ + --member="serviceAccount:${SA}" \ + --role='roles/bigtable.user' \ + --project=estuary-theatre + +gcloud bigtable instances add-iam-policy-binding estuary-test \ + --member="serviceAccount:${SA}" \ + --role='roles/bigtable.admin' \ + --project=estuary-theatre +``` + +IAM bindings can take 30-120 seconds to propagate. If the first test attempt +fails with `PermissionDenied: bigtable.instances.ping`, wait a minute and retry. + +### 4. Run the tests + +From the repo root, set `BIGTABLE_TEST_ALL` (or pass `-bigtable.test-all`) to +include the GCP-backed task: + +```bash +BIGTABLE_TEST_ALL=1 go test -v -run TestIntegration -timeout 20m ./materialize-bigtable/... +``` + +Both the emulator-backed and GCP-backed materialization tasks will run. + +### 5. Tear down the instance + +To stop being billed, delete the instance when you're done. Tables, +column families, and IAM bindings on the instance go with it. + +```bash +gcloud bigtable instances delete estuary-test --project=estuary-theatre +``` diff --git a/materialize-bigtable/testdata/apply-local.flow.yaml b/materialize-bigtable/testdata/apply-local.flow.yaml new file mode 100644 index 0000000000..e4dd5fd1b8 --- /dev/null +++ b/materialize-bigtable/testdata/apply-local.flow.yaml @@ -0,0 +1,8 @@ +materializations: + acmeCo/tests/materialize-bigtable: + endpoint: + local: + command: ["go", "run", "."] + protobuf: true + config: config.local.yaml + bindings: [] diff --git a/materialize-bigtable/testdata/apply.flow.yaml b/materialize-bigtable/testdata/apply.flow.yaml new file mode 100644 index 0000000000..c06681603a --- /dev/null +++ b/materialize-bigtable/testdata/apply.flow.yaml @@ -0,0 +1,16 @@ +materializations: + acmeCo/tests/materialize-bigtable: + endpoint: + local: + command: ["go", "run", "."] + protobuf: true + config: config.local.yaml + bindings: [] + + acmeCo/tests/materialize-bigtable-gcp: + endpoint: + local: + command: ["go", "run", "."] + protobuf: true + config: config.gcp.yaml + bindings: [] diff --git a/materialize-bigtable/testdata/config.gcp.yaml b/materialize-bigtable/testdata/config.gcp.yaml new file mode 100644 index 0000000000..76dd8eb028 --- /dev/null +++ b/materialize-bigtable/testdata/config.gcp.yaml @@ -0,0 +1,16 @@ +project_id: estuary-theatre +instance_id: estuary-test +credentials: + auth_type: CredentialsJSON + credentials_json_sops: ENC[AES256_GCM,data:8DnWgIspn+PP5fzZk8mIafV3n/4hqI94/du/G3PYS/iCKPEtRq3tr91tHaQVEKI1CYL0aEMULUmtLge0bX8rjXOBv4uHH5O26f6McYUHBUntkSt9l3DNzffKSGVlHRshc/ONRzwklZXlFjaoAcP04W7puy3j+nq41ENLDuKN/cs1EM1ySsOS7rcI+OLh9cx0SJYjmh40j9B4bD5D0t+eGJ9MeX0mwlf4qFxZtyxKqtGLZ8mN30tjcUyJa7IPI70IGEVNVqbNZ4ic1aOSFn38r2T+NXm3c783Us/Dku8viOZ7eaah0d39PYXYVvQCgd60fOdcYIvb0aIQ3SAM0l+qeMFQcM4KUoXk1/4G5cVwc5RbtD9Jgv/hV1UJOA6Tzeb2qghK/7gIlcllxEbQQsMueoB+kcdbDkB6yz6ZHlMN4z75rI8QLTS+Ezs6n8LzXGwp4WohNrHvaTveHH7ZxCBJHksk/dO07qstUcdHUmKQ7TZrCp5ouCpVtXGCBgtAbJTCmJ1vwj4gHxJeNZeY9EgCsQ4RWxj3W85KIxPZGcPvQj6a0BauTummgSxBojdkVwq7BJTtzGLt1NPQYiaZDEe2zBSY9aWj8dm2VuUZqLSX53KtlF/M7Y2HJMGVci9VXpaw4thkBoPMJ8NxId6sQSJpPkweCExdi+xFsL662Iqj0wtUWVRXyHeoPwP6i+5ok9o3h53PevtgTgJqtay96adq2lJQdQmDx+2xtc8mUYouf9YfC8HbIJ+nc1YY99nxZ8dgZBFPbgMKMdp4wY0F4xl9yaDKJd+uCYIY70ImxSED8V4Vt4g7cmePlW8Sdf0mA4BYzSH4PWozseHQasImFczD9NjZKas9pIISh3iB23TGoHQFzX231UxcMTIslwcb5j9uNbjtz374/oNxltrcEh8ETTevG8XvTweO6aSxH5fmoQB+cb+IRsAfFzDvYwBp9B2iCMV4D9wNrM0EY1TAsXfa10MqzeiYuCpfH95q0y4aEd1hlrEMT0f/aOenOB37f3BP3C7x5ACsjSf/evlMGKqf4Pl4OeOwsjIivkQS3FDzOoN4ehjKrugsgq+29F7eqs/9sr0W3Wf5X1PvOVzYm+4XpDJI7iiisC21igiDq0/Tn9YlrO5NAee11HJ9itRug+QXkad4ZQxycbW2iVXWjxKKV3E2qQoI+JiwqlgR0ANdW0i15XwqQzACBqO5JT8yLmb3fqO7WKiTcZIlAJfHRHqaK6aJmSqx3vKxpvKoYHrnjGTblJbXCHxoWC1SOQg0ddFzagDxX/XbNzlJhmy7yWMKI4fRunSL7sillrlybeK/opYsjflqYD1CetDe0p/DfXDjc4Q4re7An9Dmc/UY0Q6V3B2IGXcDyIYrUrNetHVnC/Wo0qcuAAPTroipdrvBp9Nt29E6N5Wfjj7QLSBwxKNbpIhQhNFwLmzY/nw1iuACJN9LNQrXE/swu3KOaWHtaBgNY+9LPlTgzU6eL6uqc1n2tDYPTPYPZX6270g/+ngh38oNzoHU4EnJrHM38V5no082Ni4rjLU/4bvciPOqDVOqKT6+LVuzvgTkWc5VLWrFBcYOMvunXYIiZ4KpWYJ/ri0cq498M+Ex6FahohZqznmJ/IwQVoEIFLLbKTqbP4d/bRjjNgoosHxgG5WZeTHJoXH+9sj7fGRHTBjSD9pBIV+UT2huZVOZZhW67SoyezcKu5r4Mu2HsEXJag5XgrfwNLTVnZsh2B7XzstLDln8EJlfH44GXGtFlaIjRVkK8nURVWkMp6QWGanrEXoSAZYAV+uLhixsIv6RkHMm/rW+bkjoS56vPusfrb57ahH6edjuxlEIMWLOuZWtcw1KFPUd9n8ZSfCOsS27oFMJIalcQZfjlpTj1CdCqYahvTF0thfufBkiIZxaH8CdVzuSvUzo60tc2W/z2Mw8TY7BAzdq2HYkFbMKjX12YhQGX3wm4sQKSEepwFUyBdI9uIiH73Knli1H/oCAi3geXFxh8jIPCNFWfXC/EpyMVfcnHCtG8T1LXZRphe6FoubpRi/puO+4Xk27vMgG2daX37mIOgu/h1wpQQKsr0jtvR+hd1zcG7dHVZDKmZT9WOgOTUrpNlSl4OIMScDNhDJ3q/ErRxrawlvuZddPXU4xdhX1LfnysOvv/VbqdTNObLqIVP4rZytKylO5/imZP34FLdSbrzjWO28+s9bFm3b9WpJtZIuCNhMv4UDRsFeurbDak4rH0j/uF/ZiUfdei40GB310qY+XkN/9bt2L8wpJ7jFk4VzwLm5xdt53xXN7Z8r7KiSfL6CkK1KLG1A5eMoVdlA65q22W+LFLZnHoad5MJpYnCMAgEG07jliO17BKWmrB2v3Ij8Wph73T7a3HF9GjIdWRgt9ct2nCFBTfcCZDeoBSwaCl+5AmVmyxbuDA+aB+OyNVsWrTZcwkrABCpdE9DMieXiHKWDLtms/qJVsFHgSAqKCp/J0ft3UoOMaMgBS5q6xnsUkU6G2jlS8lbqpDl77vSQ1kfNJQ+5tcaUgi53bsFTLzvg6iUu6ZsoCljbh9ad+3DCngWWLMsVULjpkmAallF1rLtXGnaiGV06V5jADLfATgxwdSjHOS2rIV6gOhb1EyV17Kj5GqcvrK7T5ldLQPKTQUM5Zeo56W9JzhMjHKgdDv/3+Z0YlXJtaZ1pK1abJxrR9+aIy2FTnNQb9TBDLxzDZp8qzlK4U02b5av5apiYSJUNdLNjWLcLE9zmJ7DUm9YNrFEEHD7rr7+aJ4j0ZBqTpyT9JKKBx+mgmdp7cLmVrAWs2Z0DysydHvLDokr0lHS325kQWvp9mv0xolmdqYFjr6P6aauf4TI3mOQ6uTH0WuclI6bN7S4ZTzR+c5jriPhoUl32mna+ofFjUJLffSwTJ/nk56HLjKnu1NN51AQxok6rdEm7sB2F3cF93CgL1WfDMOpomMeS9x4RydzkiOw0r/7Cb5LtN50SCi55T5HYmrSLh3nD1tYS3U8bzYIy/TKXRnAkSrmzOT+T3Rxz26NhEEwuIH+kzfFT9xNryrOV0SNQkNYz8wTfROAmRTupbaVoK4fxO/rTTOOL9mDIJRfkMGVkH3H99etnnumD69awOqB1cDIK4QutR675SUwpUlIxi1dSoVVa9qBnHhU178booDMlRj+z2dQ==,iv:aWT6Y9A6JohHpWG0pjFE9Er28sJYIHzMQo3M0Lyj5dY=,tag:FXmAtpCzJkpCpn1PC6R8bA==,type:str] +advanced: + feature_flags: allow_existing_tables_for_new_bindings +sops: + gcp_kms: + - resource_id: projects/estuary-theatre/locations/us-central1/keyRings/connector-keyring/cryptoKeys/connector-repository + created_at: "2026-05-05T15:48:58Z" + enc: CiUAdmEdwnP4QYwg/DNbTlkkneyZKuI4scZrNWZnBWLTGiVHyvrCEkkAJFAC3cYgQv74qQTNbu8wHHBWETUAdrMHU4nYbK5SEfc5NcVWNPLyTKyekTxwYDpk7I2Dm5j+mPrP59Og61xoGb8WM0vhe7wD + lastmodified: "2026-05-05T16:28:05Z" + mac: ENC[AES256_GCM,data:BWLorisR+ZAxmAV/VZFr5qOiHWf+cNZhnCZgLhrVVsVMd6zBzqzMJxxyie77xkAJ/yni3yHnbwRRKlbiifm9Ido+wr9Cw0Gfzwfmv+oWQjSzNgSm37YVKy5SVcoJgkIgs1gO0IgYpYYxQX+y1ps+djLBMKA5RK2LlKES+WoIvRc=,iv:yeykDtMSjP8u10m3ipy98yTihX+Y5OTA9ct6nezahro=,tag:FSrxr3Hr8SvAV+TgEXA5jQ==,type:str] + encrypted_suffix: _sops + version: 3.12.1 diff --git a/materialize-bigtable/testdata/config.local.hard-delete.yaml b/materialize-bigtable/testdata/config.local.hard-delete.yaml new file mode 100644 index 0000000000..adc6f09579 --- /dev/null +++ b/materialize-bigtable/testdata/config.local.hard-delete.yaml @@ -0,0 +1,9 @@ +project_id: test-project +instance_id: test-instance +credentials: + auth_type: CredentialsJSON + credentials_json: "{}" +hardDelete: true +advanced: + endpoint: localhost:8086 + feature_flags: allow_existing_tables_for_new_bindings diff --git a/materialize-bigtable/testdata/config.local.yaml b/materialize-bigtable/testdata/config.local.yaml new file mode 100644 index 0000000000..fa1f902f1f --- /dev/null +++ b/materialize-bigtable/testdata/config.local.yaml @@ -0,0 +1,8 @@ +project_id: test-project +instance_id: test-instance +credentials: + auth_type: CredentialsJSON + credentials_json: "{}" +advanced: + endpoint: localhost:8086 + feature_flags: allow_existing_tables_for_new_bindings diff --git a/materialize-bigtable/testdata/materialize-local.flow.yaml b/materialize-bigtable/testdata/materialize-local.flow.yaml new file mode 100644 index 0000000000..d654545848 --- /dev/null +++ b/materialize-bigtable/testdata/materialize-local.flow.yaml @@ -0,0 +1,34 @@ +import: + - ../../materialize-boilerplate/testdata/integration/collections.materialize.flow.yaml + +materializations: + acmeCo/tests/materialize-bigtable: + endpoint: + local: + command: ["go", "run", "."] + protobuf: true + config: config.local.yaml + bindings: &bindings + - resource: + table: simple_standard + source: tests/simple + fields: + recommended: true + - resource: + table: not_simple + source: tests/not-simple + fields: + recommended: true + - resource: + table: data_types + source: tests/data-types + fields: + recommended: true + + acmeCo/tests/materialize-bigtable-hard-delete: + endpoint: + local: + command: ["go", "run", "."] + protobuf: true + config: config.local.hard-delete.yaml + bindings: *bindings diff --git a/materialize-bigtable/testdata/materialize.flow.yaml b/materialize-bigtable/testdata/materialize.flow.yaml new file mode 100644 index 0000000000..986ffed6df --- /dev/null +++ b/materialize-bigtable/testdata/materialize.flow.yaml @@ -0,0 +1,42 @@ +import: + - ../../materialize-boilerplate/testdata/integration/collections.materialize.flow.yaml + +materializations: + acmeCo/tests/materialize-bigtable: + endpoint: + local: + command: ["go", "run", "."] + protobuf: true + config: config.local.yaml + bindings: &bindings + - resource: + table: simple_standard + source: tests/simple + fields: + recommended: true + - resource: + table: not_simple + source: tests/not-simple + fields: + recommended: true + - resource: + table: data_types + source: tests/data-types + fields: + recommended: true + + acmeCo/tests/materialize-bigtable-hard-delete: + endpoint: + local: + command: ["go", "run", "."] + protobuf: true + config: config.local.hard-delete.yaml + bindings: *bindings + + acmeCo/tests/materialize-bigtable-gcp: + endpoint: + local: + command: ["go", "run", "."] + protobuf: true + config: config.gcp.yaml + bindings: *bindings diff --git a/materialize-bigtable/transactor.go b/materialize-bigtable/transactor.go new file mode 100644 index 0000000000..30126686ad --- /dev/null +++ b/materialize-bigtable/transactor.go @@ -0,0 +1,327 @@ +package main + +import ( + "context" + "encoding/json" + "fmt" + "regexp" + "sync" + + "cloud.google.com/go/bigtable" + m "github.com/estuary/connectors/go/materialize" + pf "github.com/estuary/flow/go/protocols/flow" + pc "go.gazette.dev/core/consumer/protocol" + "golang.org/x/sync/errgroup" +) + +const ( + // Per-batch caps. Bytes limit bounds typical memory; size limit guards + // against pathologically small elements where Go's per-element overhead + // dominates. + batchBytesLimit = 10 * 1024 * 1024 + batchSizeLimit = 1000 + + // Concurrent in-flight ReadRows / ApplyBulk calls. Pipelining keeps the + // iterator advancing while previous batches are still streaming. + concurrentWorkers = 5 +) + +type binding struct { + tableName string + table *bigtable.Table + + // fields are the non-document selected projections, ordered to match the + // stream of (key | values) that a Store iterator produces. + fields []mappedType + + // docField is the column qualifier holding the materialized root document. + // Usually the default `flow_document` but a user may project the root + // document under an alternate name. + docField string +} + +type state struct { + // CommittedTimestamp is the last successfully committed cell timestamp; + // the timestamp stamped on writes for the in-progress transaction is + // always `CommittedTimestamp + 1`. + CommittedTimestamp int64 `json:"committed_timestamp"` +} + +type transactor struct { + bindings []binding + state state + hardDelete bool +} + +func (t *transactor) RecoverCheckpoint(ctx context.Context, spec pf.MaterializationSpec, rangeSpec pf.RangeSpec) (m.RuntimeCheckpoint, error) { + return nil, nil +} + +func (t *transactor) UnmarshalState(raw json.RawMessage) error { + if err := json.Unmarshal(raw, &t.state); err != nil { + return fmt.Errorf("unmarshalling connector state: %w", err) + } + + return nil +} + +func (t *transactor) Acknowledge(ctx context.Context) (*pf.ConnectorState, error) { + return nil, nil +} + +type loadBatch struct { + binding int + keys bigtable.RowList +} + +func (t *transactor) Load(it *m.LoadIterator, loaded func(int, json.RawMessage) error) error { + ctx := it.Context() + it.WaitForAcknowledged() + + var mu sync.Mutex + lockedAndLoaded := func(binding int, doc json.RawMessage) error { + mu.Lock() + defer mu.Unlock() + return loaded(binding, doc) + } + + batches := make(chan loadBatch) + group, groupCtx := errgroup.WithContext(ctx) + txTS := bigtable.Timestamp(t.state.CommittedTimestamp + 1) + + for range concurrentWorkers { + group.Go(func() error { + return t.loadWorker(groupCtx, txTS, lockedAndLoaded, batches) + }) + } + + // Load keys are not strictly in binding order, but they tend to arrive in + // runs for the same binding. Accumulate one batch at a time and send it + // whenever the binding changes or the batch hits a limit. + var ( + currentBatch bigtable.RowList + currentBytes int + lastBinding int + ) + + sendBatch := func() error { + select { + case <-groupCtx.Done(): + return group.Wait() + case batches <- loadBatch{binding: lastBinding, keys: currentBatch}: + currentBatch = nil + currentBytes = 0 + return nil + } + } + + for it.Next() { + if len(currentBatch) > 0 && lastBinding != it.Binding { + if err := sendBatch(); err != nil { + return fmt.Errorf("sending load batch: %w", err) + } + } + + lastBinding = it.Binding + currentBatch = append(currentBatch, string(it.PackedKey)) + currentBytes += len(it.PackedKey) + + if len(currentBatch) >= batchSizeLimit || currentBytes >= batchBytesLimit { + if err := sendBatch(); err != nil { + return fmt.Errorf("sending load batch: %w", err) + } + } + } + if it.Err() != nil { + return fmt.Errorf("iterating loads: %w", it.Err()) + } + + if len(currentBatch) > 0 { + if err := sendBatch(); err != nil { + return fmt.Errorf("sending final load batch: %w", err) + } + } + + close(batches) + if err := group.Wait(); err != nil { + return fmt.Errorf("draining load workers: %w", err) + } + + return nil +} + +func (t *transactor) loadWorker( + ctx context.Context, + txTS bigtable.Timestamp, + loaded func(int, json.RawMessage) error, + batches <-chan loadBatch, +) error { + for { + select { + case <-ctx.Done(): + return ctx.Err() + case batch, ok := <-batches: + if !ok { + return nil + } + + b := &t.bindings[batch.binding] + + filter := bigtable.ChainFilters( + bigtable.FamilyFilter(columnFamily), + bigtable.ColumnFilter(regexp.QuoteMeta(b.docField)), + bigtable.LatestNFilter(2), + ) + + var loadErr error + err := b.table.ReadRows(ctx, batch.keys, func(r bigtable.Row) bool { + // The filter restricts items to document-cell versions, newest first. + // Walk forward to the first non-dirty cell and surface it as the + // committed value. + for _, cell := range r[columnFamily] { + if cell.Timestamp == txTS { + continue + } + if err := loaded(batch.binding, json.RawMessage(cell.Value)); err != nil { + loadErr = err + return false + } + + return true + } + + return true + }, bigtable.RowFilter(filter)) + if err != nil { + return fmt.Errorf("ReadRows on table %q: %w", b.tableName, err) + } else if loadErr != nil { + return fmt.Errorf("loaded callback for table %q: %w", b.tableName, loadErr) + } + } + } +} + +type storeBatch struct { + binding int + rowKeys []string + mutations []*bigtable.Mutation +} + +func (t *transactor) Store(it *m.StoreIterator) (m.StartCommitFunc, error) { + ctx := it.Context() + + batches := make(chan storeBatch) + group, groupCtx := errgroup.WithContext(ctx) + + for range concurrentWorkers { + group.Go(func() error { + return t.storeWorker(groupCtx, batches) + }) + } + + var ( + currentBatch storeBatch + currentBytes int + ts = bigtable.Timestamp(t.state.CommittedTimestamp + 1) + ) + + sendBatch := func() error { + select { + case <-groupCtx.Done(): + return group.Wait() + case batches <- currentBatch: + currentBatch = storeBatch{} + currentBytes = 0 + return nil + } + } + + for it.Next(t.hardDelete) { + if len(currentBatch.rowKeys) > 0 && currentBatch.binding != it.Binding { + if err := sendBatch(); err != nil { + return nil, fmt.Errorf("sending store batch: %w", err) + } + } + + b := &t.bindings[it.Binding] + + mut := bigtable.NewMutation() + if it.Delete && t.hardDelete { + mut.DeleteRow() + } else { + allFields := append(it.Key, it.Values...) + for i, te := range allFields { + f := b.fields[i] + val, err := f.encode(te) + if err != nil { + return nil, fmt.Errorf("encoding field %q on table %q: %w", f.field, b.tableName, err) + } + mut.Set(columnFamily, f.field, ts, val) + } + mut.Set(columnFamily, b.docField, ts, it.RawJSON) + } + + currentBatch.binding = it.Binding + currentBatch.rowKeys = append(currentBatch.rowKeys, string(it.PackedKey)) + currentBatch.mutations = append(currentBatch.mutations, mut) + currentBytes += len(it.PackedKey) + len(it.RawJSON) + + if len(currentBatch.rowKeys) >= batchSizeLimit || currentBytes >= batchBytesLimit { + if err := sendBatch(); err != nil { + return nil, fmt.Errorf("sending store batch: %w", err) + } + } + } + if it.Err() != nil { + return nil, fmt.Errorf("iterating stores: %w", it.Err()) + } + + if len(currentBatch.rowKeys) > 0 { + if err := sendBatch(); err != nil { + return nil, fmt.Errorf("sending final store batch: %w", err) + } + } + close(batches) + + t.state.CommittedTimestamp = int64(ts) + newState, err := json.Marshal(t.state) + if err != nil { + return nil, fmt.Errorf("marshalling state: %w", err) + } + + return func(_ context.Context, _ *pc.Checkpoint) (*pf.ConnectorState, m.OpFuture) { + return &pf.ConnectorState{UpdatedJson: newState}, m.RunAsyncOperation(func() error { + if err := group.Wait(); err != nil { + return fmt.Errorf("draining store workers: %w", err) + } + + return nil + }) + }, nil +} + +func (t *transactor) storeWorker(ctx context.Context, batches <-chan storeBatch) error { + for { + select { + case <-ctx.Done(): + return ctx.Err() + case batch, ok := <-batches: + if !ok { + return nil + } + + b := &t.bindings[batch.binding] + errs, err := b.table.ApplyBulk(ctx, batch.rowKeys, batch.mutations) + if err != nil { + return fmt.Errorf("ApplyBulk on table %q: %w", b.tableName, err) + } + for i, e := range errs { + if e != nil { + return fmt.Errorf("ApplyBulk row %q on table %q: %w", batch.rowKeys[i], b.tableName, e) + } + } + } + } +} + +func (t *transactor) Destroy() {} diff --git a/materialize-bigtable/type_mapping.go b/materialize-bigtable/type_mapping.go new file mode 100644 index 0000000000..aa41360177 --- /dev/null +++ b/materialize-bigtable/type_mapping.go @@ -0,0 +1,300 @@ +package main + +import ( + "encoding/base64" + "encoding/binary" + "encoding/json" + "fmt" + "math" + "strconv" + "strings" + + boilerplate "github.com/estuary/connectors/materialize-boilerplate" + "github.com/estuary/flow/go/protocols/fdb/tuple" + pf "github.com/estuary/flow/go/protocols/flow" +) + +// columnFamily is the single column family used by the connector. The +// specific name used isn't important; it can be anything. But keeping it +// short minimizes per-cell overhead. +const columnFamily = "f" + +type mappedType struct { + field string + flatType boilerplate.FlatType + encodeFn func(tuple.TupleElement) ([]byte, error) +} + +func (m mappedType) String() string { + switch m.flatType.(type) { + case boilerplate.FlatTypeBoolean: + return "bool" + case boilerplate.FlatTypeInteger: + return "integer" + case boilerplate.FlatTypeNumber: + return "number" + case boilerplate.FlatTypeString: + return "string" + case boilerplate.FlatTypeBinary: + return "binary" + case boilerplate.FlatTypeStringFormatInteger: + return "string-format-integer" + case boilerplate.FlatTypeStringFormatNumber: + return "string-format-number" + case boilerplate.FlatTypeArray, boilerplate.FlatTypeObject, boilerplate.FlatTypeMultiple, boilerplate.FlatTypeNever: + return "json" + default: + panic(fmt.Sprintf("unknown flat type: %T", m.flatType)) + } +} + +func (m mappedType) Compatible(existing boilerplate.ExistingField) bool { return true } +func (m mappedType) CanMigrate(existing boilerplate.ExistingField) bool { return false } + +type fieldConfig struct{} + +func (fieldConfig) Validate() error { return nil } +func (fieldConfig) CastToString() bool { return false } + +func mapType(p boilerplate.Projection) mappedType { + out := mappedType{field: p.Field, flatType: p.FlatType} + + numericExceedsInt64 := func(n pf.Inference_Numeric) bool { + return n.Maximum > math.MaxInt64 || n.Minimum < math.MinInt64 + } + + switch ft := p.FlatType.(type) { + case boilerplate.FlatTypeBoolean: + out.encodeFn = encodeBool + case boilerplate.FlatTypeInteger: + if numericExceedsInt64(ft.InferenceNumeric) { + out.encodeFn = encodeIntegerAsString + } else { + out.encodeFn = encodeInteger + } + case boilerplate.FlatTypeNumber: + out.encodeFn = encodeNumber + case boilerplate.FlatTypeString: + out.encodeFn = encodeString + case boilerplate.FlatTypeBinary: + out.encodeFn = encodeBinary + case boilerplate.FlatTypeStringFormatInteger: + // 18 digits always fit in int64; a 19-digit value can exceed MaxInt64. + if numericExceedsInt64(ft.InferenceNumeric) || ft.InferenceString.MaxLength > 18 { + out.encodeFn = encodeIntegerAsString + } else { + out.encodeFn = encodeStringFormatInt + } + case boilerplate.FlatTypeStringFormatNumber: + // float64 reliably preserves ~17 significant decimal digits; + // strings longer than that may carry more precision than the + // 8-byte IEEE 754 encoding can hold. + if ft.InferenceString.MaxLength > 17 { + out.encodeFn = encodeNumberAsString + } else { + out.encodeFn = encodeStringFormatNum + } + case boilerplate.FlatTypeArray, boilerplate.FlatTypeObject, boilerplate.FlatTypeMultiple, boilerplate.FlatTypeNever: + out.encodeFn = encodeJSON + default: + panic(fmt.Sprintf("unhandled flat type %T for field %q", p.FlatType, p.Field)) + } + + return out +} + +func (m mappedType) encode(te tuple.TupleElement) ([]byte, error) { + if te == nil { + return []byte{}, nil + } + + return m.encodeFn(te) +} + +func encodeBool(te tuple.TupleElement) ([]byte, error) { + if b, ok := te.(bool); !ok { + return nil, fmt.Errorf("bool field expected bool for field, got %T", te) + } else if b { + return []byte{0x01}, nil + } else { + return []byte{0x00}, nil + } +} + +func encodeInteger(te tuple.TupleElement) ([]byte, error) { + out := make([]byte, 8) + switch v := te.(type) { + case int: + binary.BigEndian.PutUint64(out, uint64(int64(v))) + case int64: + binary.BigEndian.PutUint64(out, uint64(v)) + case uint64: + binary.BigEndian.PutUint64(out, v) + case float64: + binary.BigEndian.PutUint64(out, uint64(int64(v))) // Truncate trailing zero fraction + default: + return nil, fmt.Errorf("integer field expected numeric, got %T", te) + } + + return out, nil +} + +func encodeIntegerAsString(te tuple.TupleElement) ([]byte, error) { + switch v := te.(type) { + case string: + if idx := strings.Index(v, "."); idx != -1 { + v = v[:idx] + } + return []byte(v), nil + case int: + return strconv.AppendInt(nil, int64(v), 10), nil + case int64: + return strconv.AppendInt(nil, v, 10), nil + case uint64: + return strconv.AppendUint(nil, v, 10), nil + case float64: + return strconv.AppendInt(nil, int64(v), 10), nil + default: + return nil, fmt.Errorf("integer field expected string or numeric, got %T", te) + } +} + +func encodeNumber(te tuple.TupleElement) ([]byte, error) { + var f float64 + switch v := te.(type) { + case float64: + f = v + case int: + f = float64(v) + case int64: + f = float64(v) + case uint64: + f = float64(v) + case string: + switch v { + case "NaN": + f = math.NaN() + case "Infinity": + f = math.Inf(1) + case "-Infinity": + f = math.Inf(-1) + default: + return nil, fmt.Errorf("number field got unexpected string %q", v) + } + default: + return nil, fmt.Errorf("number field expected numeric, got %T", te) + } + + out := make([]byte, 8) + binary.BigEndian.PutUint64(out, math.Float64bits(f)) + + return out, nil +} + +func encodeNumberAsString(te tuple.TupleElement) ([]byte, error) { + switch v := te.(type) { + case string: + return []byte(v), nil + case float64: + switch { + case math.IsNaN(v): + return []byte("NaN"), nil + case math.IsInf(v, 1): + return []byte("Infinity"), nil + case math.IsInf(v, -1): + return []byte("-Infinity"), nil + default: + return strconv.AppendFloat(nil, v, 'g', -1, 64), nil + } + case int: + return strconv.AppendInt(nil, int64(v), 10), nil + case int64: + return strconv.AppendInt(nil, v, 10), nil + case uint64: + return strconv.AppendUint(nil, v, 10), nil + default: + return nil, fmt.Errorf("number field expected string or numeric, got %T", te) + } +} + +func encodeString(te tuple.TupleElement) ([]byte, error) { + if s, ok := te.(string); ok { + return []byte(s), nil + } else { + return nil, fmt.Errorf("string field expected string, got %T", te) + } +} + +func encodeBinary(te tuple.TupleElement) ([]byte, error) { + if s, ok := te.(string); ok { + return base64.StdEncoding.DecodeString(s) + } else { + return nil, fmt.Errorf("binary field expected string, got %T", te) + } +} + +func encodeStringFormatInt(te tuple.TupleElement) ([]byte, error) { + s, ok := te.(string) + if !ok { + return encodeInteger(te) + } + + if idx := strings.Index(s, "."); idx != -1 { + s = s[:idx] + } + + if n, err := strconv.ParseInt(s, 10, 64); err == nil { + return encodeInteger(n) + } else if u, err := strconv.ParseUint(s, 10, 64); err == nil { + // Fall back to unsigned for values that overflow int64 but fit uint64. + return encodeInteger(u) + } + + return nil, fmt.Errorf("parsing integer-formatted string %q", s) +} + +func encodeStringFormatNum(te tuple.TupleElement) ([]byte, error) { + var f float64 + switch v := te.(type) { + case string: + switch v { + case "NaN": + f = math.NaN() + case "Infinity": + f = math.Inf(1) + case "-Infinity": + f = math.Inf(-1) + default: + parsed, err := strconv.ParseFloat(v, 64) + if err != nil { + return nil, fmt.Errorf("parsing number-formatted string %q: %w", v, err) + } + f = parsed + } + case float64: + f = v + case int: + f = float64(v) + case int64: + f = float64(v) + case uint64: + f = float64(v) + default: + return nil, fmt.Errorf("string-format-number field expected string, got %T", te) + } + + out := make([]byte, 8) + binary.BigEndian.PutUint64(out, math.Float64bits(f)) + + return out, nil +} + +func encodeJSON(te tuple.TupleElement) ([]byte, error) { + if b, ok := te.([]byte); ok { + // Pre-serialized JSON; don't re-encode. + return b, nil + } + + // Everything else gets JSON-marshaled to its textual JSON form. + return json.Marshal(te) +} diff --git a/materialize-bigtable/type_mapping_test.go b/materialize-bigtable/type_mapping_test.go new file mode 100644 index 0000000000..adca0c1837 --- /dev/null +++ b/materialize-bigtable/type_mapping_test.go @@ -0,0 +1,242 @@ +package main + +import ( + "encoding/binary" + "math" + "testing" + + boilerplate "github.com/estuary/connectors/materialize-boilerplate" + pf "github.com/estuary/flow/go/protocols/flow" + "github.com/stretchr/testify/require" +) + +func TestMapType(t *testing.T) { + type encodeCase struct { + name string + in any + want []byte + wantErr bool + } + + float64BE := func(f float64) []byte { + out := make([]byte, 8) + binary.BigEndian.PutUint64(out, math.Float64bits(f)) + return out + } + + uint64BE := func(n uint64) []byte { + out := make([]byte, 8) + binary.BigEndian.PutUint64(out, n) + return out + } + + nan := float64BE(math.NaN()) + posInf := float64BE(math.Inf(1)) + negInf := float64BE(math.Inf(-1)) + + for _, tc := range []struct { + name string + flatType boilerplate.FlatType + encodes []encodeCase + }{ + { + name: "bool", + flatType: boilerplate.FlatTypeBoolean{}, + encodes: []encodeCase{ + {name: "nil", in: nil, want: []byte{}}, + {name: "true", in: true, want: []byte{0x01}}, + {name: "false", in: false, want: []byte{0x00}}, + {name: "wrong type", in: "yes", wantErr: true}, + }, + }, + { + name: "integer", + flatType: boilerplate.FlatTypeInteger{}, + encodes: []encodeCase{ + {name: "nil", in: nil, want: []byte{}}, + {name: "int64 positive", in: int64(0x0102030405060708), want: uint64BE(0x0102030405060708)}, + {name: "int64 negative", in: int64(-1), want: uint64BE(math.MaxUint64)}, + {name: "int", in: int(42), want: uint64BE(42)}, + {name: "uint64 max", in: uint64(math.MaxUint64), want: uint64BE(math.MaxUint64)}, + {name: "float64", in: float64(3.0), want: uint64BE(3)}, + {name: "wrong type", in: "abc", wantErr: true}, + }, + }, + { + name: "number", + flatType: boilerplate.FlatTypeNumber{}, + encodes: []encodeCase{ + {name: "nil", in: nil, want: []byte{}}, + {name: "float64", in: 1.5, want: float64BE(1.5)}, + {name: "int", in: 7, want: float64BE(7)}, + {name: "int64", in: int64(7), want: float64BE(7)}, + {name: "uint64", in: uint64(7), want: float64BE(7)}, + {name: "NaN string", in: "NaN", want: nan}, + {name: "+Inf string", in: "Infinity", want: posInf}, + {name: "-Inf string", in: "-Infinity", want: negInf}, + {name: "float64 NaN", in: math.NaN(), want: nan}, + {name: "float64 +Inf", in: math.Inf(1), want: posInf}, + {name: "float64 -Inf", in: math.Inf(-1), want: negInf}, + {name: "unknown string", in: "abc", wantErr: true}, + {name: "wrong type", in: true, wantErr: true}, + }, + }, + { + name: "string", + flatType: boilerplate.FlatTypeString{}, + encodes: []encodeCase{ + {name: "nil", in: nil, want: []byte{}}, + {name: "string", in: "hello", want: []byte("hello")}, + {name: "wrong type", in: 42, wantErr: true}, + }, + }, + { + name: "binary", + flatType: boilerplate.FlatTypeBinary{}, + encodes: []encodeCase{ + {name: "nil", in: nil, want: []byte{}}, + {name: "base64 string decoded", in: "aGVsbG8=", want: []byte("hello")}, + {name: "invalid base64", in: "@@@", wantErr: true}, + {name: "wrong type", in: 42, wantErr: true}, + }, + }, + { + name: "string-format-integer", + flatType: boilerplate.FlatTypeStringFormatInteger{}, + encodes: []encodeCase{ + {name: "nil", in: nil, want: []byte{}}, + {name: "string positive", in: "42", want: uint64BE(42)}, + {name: "string negative", in: "-1", want: uint64BE(math.MaxUint64)}, + {name: "string at uint64 max", in: "18446744073709551615", want: uint64BE(math.MaxUint64)}, + {name: "string beyond uint64", in: "18446744073709551616", wantErr: true}, + {name: "string fractional zero", in: "1.0", want: uint64BE(1)}, + {name: "int64", in: int64(42), want: uint64BE(42)}, + {name: "uint64", in: uint64(42), want: uint64BE(42)}, + {name: "float64", in: float64(3.0), want: uint64BE(3)}, + {name: "unparseable", in: "abc", wantErr: true}, + {name: "wrong type", in: true, wantErr: true}, + }, + }, + { + name: "integer (wide via numeric inference)", + flatType: boilerplate.FlatTypeInteger{ + InferenceNumeric: pf.Inference_Numeric{Maximum: 1e20}, + }, + encodes: []encodeCase{ + {name: "nil", in: nil, want: []byte{}}, + {name: "int", in: int(42), want: []byte("42")}, + {name: "int64 negative", in: int64(-1), want: []byte("-1")}, + {name: "uint64", in: uint64(123), want: []byte("123")}, + {name: "float64", in: float64(7), want: []byte("7")}, + {name: "wrong type", in: true, wantErr: true}, + }, + }, + { + name: "string-format-integer (wide via string inference)", + flatType: boilerplate.FlatTypeStringFormatInteger{ + InferenceString: pf.Inference_String{MaxLength: 30}, + }, + encodes: []encodeCase{ + {name: "nil", in: nil, want: []byte{}}, + {name: "small string", in: "42", want: []byte("42")}, + {name: "negative string", in: "-1", want: []byte("-1")}, + {name: "beyond uint64", in: "99999999999999999999999", + want: []byte("99999999999999999999999")}, + {name: "fractional zero", in: "1.0", want: []byte("1")}, + {name: "wrong type", in: true, wantErr: true}, + }, + }, + { + name: "string-format-number (wide via string inference)", + flatType: boilerplate.FlatTypeStringFormatNumber{ + InferenceString: pf.Inference_String{MaxLength: 40}, + }, + encodes: []encodeCase{ + {name: "nil", in: nil, want: []byte{}}, + {name: "short string", in: "1.5", want: []byte("1.5")}, + {name: "high precision string", + in: "3.14159265358979323846264338327950288", + want: []byte("3.14159265358979323846264338327950288")}, + {name: "NaN string", in: "NaN", want: []byte("NaN")}, + {name: "+Inf string", in: "Infinity", want: []byte("Infinity")}, + {name: "-Inf string", in: "-Infinity", want: []byte("-Infinity")}, + {name: "float64", in: 1.5, want: []byte("1.5")}, + {name: "float64 NaN", in: math.NaN(), want: []byte("NaN")}, + {name: "float64 +Inf", in: math.Inf(1), want: []byte("Infinity")}, + {name: "float64 -Inf", in: math.Inf(-1), want: []byte("-Infinity")}, + {name: "int", in: 7, want: []byte("7")}, + {name: "int64", in: int64(7), want: []byte("7")}, + {name: "uint64", in: uint64(7), want: []byte("7")}, + {name: "wrong type", in: true, wantErr: true}, + }, + }, + { + name: "string-format-number", + flatType: boilerplate.FlatTypeStringFormatNumber{}, + encodes: []encodeCase{ + {name: "nil", in: nil, want: []byte{}}, + {name: "string", in: "1.5", want: float64BE(1.5)}, + {name: "NaN", in: "NaN", want: nan}, + {name: "+Inf", in: "Infinity", want: posInf}, + {name: "-Inf", in: "-Infinity", want: negInf}, + {name: "float64", in: 1.5, want: float64BE(1.5)}, + {name: "int", in: 7, want: float64BE(7)}, + {name: "unparseable", in: "abc", wantErr: true}, + {name: "wrong type", in: true, wantErr: true}, + }, + }, + { + name: "array", + flatType: boilerplate.FlatTypeArray{}, + encodes: []encodeCase{ + {name: "nil", in: nil, want: []byte{}}, + {name: "bytes pass-through", in: []byte(`[1,2]`), want: []byte(`[1,2]`)}, + }, + }, + { + name: "object", + flatType: boilerplate.FlatTypeObject{}, + encodes: []encodeCase{ + {name: "nil", in: nil, want: []byte{}}, + {name: "bytes pass-through", in: []byte(`{"a":1}`), want: []byte(`{"a":1}`)}, + }, + }, + { + name: "multiple", + flatType: boilerplate.FlatTypeMultiple{}, + encodes: []encodeCase{ + {name: "nil", in: nil, want: []byte{}}, + {name: "bytes pass-through", in: []byte(`{"a":1}`), want: []byte(`{"a":1}`)}, + {name: "string", in: "hi", want: []byte(`"hi"`)}, + {name: "int", in: 7, want: []byte("7")}, + {name: "int64", in: int64(7), want: []byte("7")}, + {name: "uint64", in: uint64(7), want: []byte("7")}, + {name: "float64", in: 1.5, want: []byte("1.5")}, + {name: "bool true", in: true, want: []byte("true")}, + {name: "bool false", in: false, want: []byte("false")}, + {name: "map", in: map[string]int{"a": 1}, want: []byte(`{"a":1}`)}, + }, + }, + {name: "never", flatType: boilerplate.FlatTypeNever{}}, + } { + t.Run(tc.name, func(t *testing.T) { + mt := mapType(boilerplate.Projection{ + Projection: pf.Projection{Field: "f"}, + FlatType: tc.flatType, + }) + require.Equal(t, "f", mt.field) + + for _, ec := range tc.encodes { + t.Run(ec.name, func(t *testing.T) { + got, err := mt.encode(ec.in) + if ec.wantErr { + require.Error(t, err) + return + } + require.NoError(t, err) + require.Equal(t, ec.want, got) + }) + } + }) + } +} diff --git a/tests/benchmark/materialize/runs/baselines/materialize-bigtable/large-docs.json b/tests/benchmark/materialize/runs/baselines/materialize-bigtable/large-docs.json new file mode 100644 index 0000000000..78f9b4286c --- /dev/null +++ b/tests/benchmark/materialize/runs/baselines/materialize-bigtable/large-docs.json @@ -0,0 +1,52 @@ +{ + "connector": "materialize-bigtable", + "scenario": "large-docs.yaml", + "seed": 0, + "preview_exit_code": 0, + "apply_seconds": 2.786668977, + "wall_seconds": 232.290173129, + "total_docs": 10000, + "total_bytes": 10485760000, + "docs_per_sec": 43.04960414509916, + "mb_per_sec": 43.04960414509916, + "transactions": [ + { + "index": 0, + "collection": "bench/big", + "doc_count": 5000, + "doc_size": 1048576, + "bytes": 5242880000, + "fresh": { + "start": 0, + "count": 5000, + "op": "c" + }, + "overlaps": [], + "wall_seconds": 112.981666368, + "mb_per_sec": 44.254967737103215, + "docs_per_sec": 44.254967737103215 + }, + { + "index": 1, + "collection": "bench/big", + "doc_count": 5000, + "doc_size": 1048576, + "bytes": 5242880000, + "fresh": { + "start": 5000, + "count": 3000, + "op": "c" + }, + "overlaps": [ + { + "op": "u", + "with": 0, + "count": 2000 + } + ], + "wall_seconds": 118.768350197, + "mb_per_sec": 42.098757722125, + "docs_per_sec": 42.098757722125 + } + ] +}