├── .codecov.yml ├── .gitignore ├── .travis.yml ├── ChangeLog.txt ├── Gopkg.lock ├── Gopkg.toml ├── LICENSE ├── Makefile ├── README.md ├── _config.yml ├── athenareader ├── README.md ├── athenareader.config ├── go.mod ├── go.sum ├── main.go └── query.sql ├── examples ├── README.md ├── auth.go ├── constants │ ├── doc.go │ └── secret.go ├── doc.go ├── lambda │ └── Go │ │ ├── README.md │ │ ├── athena_in_lambda.png │ │ ├── go.mod │ │ ├── go.sum │ │ └── main.go ├── logging.go ├── maskcolumn.go ├── metrics.go ├── pc_get_driver_version.go ├── pc_get_query_id.go ├── pc_get_query_id_status.go ├── pc_stop_query_id.go ├── perf │ ├── benchmark.go │ ├── concurrency.go │ ├── concurrency.output.2020-02-09-13-49-18.log │ └── doc.go ├── ping.go ├── qid.go ├── query │ ├── ddl_alter.go │ ├── ddl_create_database.go │ ├── ddl_create_table.go │ ├── ddl_ctas.go │ ├── ddl_ctas_with_partition.go │ ├── ddl_cvas.go │ ├── ddl_drop.go │ ├── ddl_msck.go │ ├── ddl_path.go │ ├── dml_insert_into_select.go │ ├── dml_insert_into_values.go │ ├── dml_select_array.go │ ├── dml_select_count.go │ ├── dml_select_db_exec.go │ ├── dml_select_fields.go │ ├── dml_select_geo.go │ ├── dml_select_information_schema.go │ ├── dml_select_join.go │ ├── dml_select_json.go │ ├── dml_select_map.go │ ├── dml_select_prepare.go │ ├── dml_select_row.go │ ├── dml_select_simple.go │ ├── dml_select_star.go │ ├── dml_select_time.go │ ├── dml_values.go │ ├── doc.go │ ├── unsupported.go │ ├── util_desc_table.go │ ├── util_desc_view.go │ └── util_show.go ├── querycancel.go ├── readonly.go ├── reconnect.go ├── trans.go ├── types.go └── workgroup_with_tag.go ├── go.mod ├── go.sum ├── go ├── cache.go ├── config.go ├── config_test.go ├── connection.go ├── connection_test.go ├── connector.go ├── connector_test.go ├── constants.go ├── cost.go ├── datetime.go ├── datetime_test.go ├── doc.go ├── driver.go ├── driver_test.go ├── errors.go ├── mockathenaclient_test.go ├── result.go ├── result_test.go ├── rows.go ├── rows_test.go ├── servicelimitoverride.go ├── servicelimitoverride_test.go ├── statement.go ├── statement_test.go ├── trace.go ├── trace_test.go ├── utils.go ├── utils_test.go ├── version.go ├── wg.go ├── wg_test.go ├── wgconfig.go └── wgtag.go ├── lib ├── configfx │ ├── module.go │ └── util.go └── queryfx │ └── module.go ├── resources ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── ColumnInfo.png ├── ResultSet_Uml.png ├── UndocumentedAthena.md ├── atg-infra.png ├── athenadriver.pdf ├── athenadriver.png ├── athenadriver_engblog.pdf ├── aws_keys.png ├── issue_1.png ├── issue_2.png ├── issue_3.png ├── issue_4.png ├── issue_5.png ├── issue_show_tblproperties.png ├── logo.png ├── pin.png ├── select_query_with_column_as_first_row.png ├── sql_Rows.png ├── style.png └── workgroup.png └── scripts ├── buildkite.sh └── checklic.sh /.codecov.yml: -------------------------------------------------------------------------------- 1 | coverage: 2 | status: 3 | patch: false 4 | 5 | range: 70..100 # First number represents red, and second represents green 6 | # (default is 70..100) 7 | round: down # up, down, or nearest 8 | precision: 2 # Number of decimal places, between 0 and 5 9 | 10 | # Ignoring Paths 11 | # -------------- 12 | # which folders/files to ignore 13 | ignore: 14 | - */img/.* 15 | - */examples/.* 16 | - */scripts/.* 17 | - setup.py 18 | - versioneer.py 19 | 20 | # Pull request comments: 21 | # ---------------------- 22 | # Diff is the Coverage Diff of the pull request. 23 | # Files are the files impacted by the pull request 24 | comment: 25 | layout: diff, files # accepted in any order: reach, diff, flags, and/or files 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, built with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | 14 | # Dependency directories (remove the comment below to include it) 15 | # vendor/ 16 | .Rproj.user 17 | 18 | # IDEs 19 | .idea/ 20 | .vscode/ 21 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: go 3 | go_import_path: github.com/uber/athenadriver 4 | 5 | env: 6 | global: 7 | - GO111MODULE=on 8 | 9 | matrix: 10 | include: 11 | - go: 1.12.x 12 | - go: 1.13.x 13 | - go: 1.14.x 14 | - go: 1.15.x 15 | - go: 1.16.x 16 | env: LINT=1 17 | 18 | install: 19 | - make install 20 | 21 | script: 22 | - test -z "$LINT" || make lint 23 | - make test 24 | 25 | after_success: 26 | - make cover 27 | - bash <(curl -s https://codecov.io/bash) 28 | -------------------------------------------------------------------------------- /ChangeLog.txt: -------------------------------------------------------------------------------- 1 | v1.1.15 - Merge community contribution (March 03, 2024) 2 | - Rename S3 bucket in test code (@jonathanbaker7 Jonathan Baker, @henrywoo) 3 | - Make poll interval configurable (@keshav-dataco Keshav Murthy) 4 | - Add microseconds and nanosecond time format parsing (@Sly1024 Szilveszter Safar) 5 | - Add option to return missing values as nil (@kevinwcyu Kevin Yu) 6 | 7 | v1.1.14 - Merge community contribution (August 19, 2022) 8 | - Adding default AWS SDK credential resolution to connector (dfreiman-hbo, Dan Freiman) 9 | - Bump go-pretty version to most recent version (nyergler, Nathan Yergler) 10 | - Expose DriverTracer factory functions (andresmgot, Andres Martinez Gotor) 11 | - Add support to go 1.17+ (henrywoo, Henry Fuheng Wu) 12 | - README cleanup (henrywoo, Henry Fuheng Wu) 13 | 14 | v1.1.13 - Merge community contribution (July 16, 2021) 15 | - Overriding Athena Service Limits for Query Timeout 16 | - README cleanup 17 | 18 | v1.1.12 - Minor bug fix and more documentation (October 29, 2020) 19 | - Use exact match for Query ID search 20 | 21 | v1.1.11 - Minor bug fix and more documentation (June 16, 2020) 22 | - Uber Engdoc documentation 23 | - Support $path in Athena query 24 | - Remove SQL Tidy function and working on replacing it with a Presto SQL parser in the future 25 | 26 | v1.1.10 - Minor bug fix and more documentation (June 5, 2020) 27 | - documentation and minor bug fix 28 | 29 | v1.1.8 - Athenareader output style and format added (May 31, 2020) 30 | 31 | - prettify athenareader output 32 | - One bug fix (https://github.com/uber/athenadriver/issues/12) 33 | 34 | v1.1.6 - Pseudo commands, bug fix and more document and sample code (May 25, 2020) 35 | 36 | - Introduce pseudo commands: get_query_id, get_query_id_status, stop_query_id, get_driver_version (doc: https://github.com/uber/athenadriver#pseudo-commands, Sample code: https://github.com/uber/athenadriver/tree/master/examples) 37 | - Enable AWS profile manual setup for authentication (Sample code: https://github.com/uber/athenadriver/blob/master/examples/auth.go) 38 | - Query Athena with athenadriver in AWS Lambda (https://github.com/uber/athenadriver/tree/master/examples/lambda/Go) 39 | - One bug fix (https://github.com/uber/athenadriver/commit/8618706818a8db7abc8f1bd344ac0eca50d38959) 40 | -------------------------------------------------------------------------------- /Gopkg.toml: -------------------------------------------------------------------------------- 1 | # Gopkg.toml example 2 | # 3 | # Refer to https://golang.github.io/dep/docs/Gopkg.toml.html 4 | # for detailed Gopkg.toml documentation. 5 | # 6 | # required = ["github.com/user/thing/cmd/thing"] 7 | # ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] 8 | # 9 | # [[constraint]] 10 | # name = "github.com/user/project" 11 | # version = "1.0.0" 12 | # 13 | # [[constraint]] 14 | # name = "github.com/user/project2" 15 | # branch = "dev" 16 | # source = "github.com/myfork/project2" 17 | # 18 | # [[override]] 19 | # name = "github.com/x/y" 20 | # version = "2.4.0" 21 | # 22 | # [prune] 23 | # non-go = false 24 | # go-tests = true 25 | # unused-packages = true 26 | 27 | 28 | [[constraint]] 29 | name = "github.com/aws/aws-sdk-go" 30 | version = "1.25.36" 31 | 32 | [prune] 33 | go-tests = true 34 | unused-packages = true -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2022 Uber Technologies, Inc. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | export GOBIN ?= $(shell pwd)/bin 2 | 3 | GOLINT = $(GOBIN)/golint 4 | 5 | GO_FILES := $(shell \ 6 | find . '(' -path './go/.*' -o -path './athenareader' ')' -prune \ 7 | -o -name '*.go' -print | cut -b3-) 8 | 9 | .PHONY: build 10 | build: 11 | go build github.com/uber/athenadriver/go 12 | 13 | .PHONY: install 14 | install: 15 | go mod download 16 | 17 | .PHONY: dependencies 18 | dependencies: 19 | go mod download 20 | 21 | .PHONY: checklic 22 | checklic: 23 | @echo "Checking for license headers..." 24 | @cd scripts && ./checklic.sh | tee -a ../lint.log 25 | 26 | .PHONY: test 27 | test: 28 | GOPRIVATE="github.com/uber" go test github.com/uber/athenadriver/go 29 | 30 | .PHONY: cover 31 | cover: 32 | GOPRIVATE="github.com/uber" go test -race -coverprofile=cover.out -coverpkg=github.com/uber/athenadriver/go/... github.com/uber/athenadriver/go/... 33 | GOPRIVATE="github.com/uber" go tool cover -html=cover.out -o cover.html 34 | 35 | $(GOLINT): 36 | go install golang.org/x/lint/golint 37 | 38 | .PHONY: lint 39 | lint: $(GOLINT) 40 | @rm -rf lint.log 41 | @echo "Checking formatting..." 42 | @gofmt -d -s $(GO_FILES) 2>&1 | tee lint.log 43 | @echo "Checking vet..." 44 | @go vet github.com/uber/athenadriver/go/... 2>&1 | tee -a lint.log 45 | @echo "Checking lint..." 46 | @$(GOLINT) github.com/uber/athenadriver/go/... | tee -a lint.log 47 | @$(GOLINT) github.com/uber/athenadriver/athenareader/... | tee -a lint.log 48 | @echo "Checking for unresolved FIXMEs..." 49 | @git grep -i fixme | grep -v -e vendor -e Makefile -e .md | tee -a lint.log 50 | @[ ! -s lint.log ] 51 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-cayman -------------------------------------------------------------------------------- /athenareader/athenareader.config: -------------------------------------------------------------------------------- 1 | athenareader: 2 | output: 3 | # options are table, markdown, csv, html 4 | render: csv 5 | # page size is the number of lines per page, default 1024 6 | pagesize: 1024 7 | # options are StyleDefault, StyleBold, StyleColoredBright, StyleColoredDark, 8 | # StyleColoredBlackOnBlueWhite, StyleColoredBlackOnCyanWhite, StyleColoredBlackOnGreenWhite 9 | # StyleColoredBlackOnMagentaWhite, StyleColoredBlackOnYellowWhite, StyleColoredBlackOnRedWhite 10 | # StyleColoredBlueWhiteOnBlack, StyleColoredCyanWhiteOnBlack, StyleColoredGreenWhiteOnBlack 11 | # StyleColoredMagentaWhiteOnBlack, StyleColoredRedWhiteOnBlack, StyleColoredYellowWhiteOnBlack 12 | # StyleDouble, StyleLight, StyleRounded 13 | style: StyleColoredYellowWhiteOnBlack 14 | rowonly: false 15 | moneywise: false 16 | 17 | input: 18 | bucket: "s3://athena-query-result-bucket/" 19 | region: "us-east-1" 20 | database: sampledb 21 | admin: false 22 | -------------------------------------------------------------------------------- /athenareader/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/uber/athenadriver/athenareader 2 | 3 | go 1.13 4 | 5 | require ( 6 | github.com/uber/athenadriver v1.1.15 7 | go.uber.org/fx v1.12.0 8 | ) 9 | -------------------------------------------------------------------------------- /athenareader/main.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package main 22 | 23 | import ( 24 | "context" 25 | "strings" 26 | 27 | drv "github.com/uber/athenadriver/go" 28 | "github.com/uber/athenadriver/lib/configfx" 29 | "github.com/uber/athenadriver/lib/queryfx" 30 | "go.uber.org/fx" 31 | ) 32 | 33 | func main() { 34 | app := fx.New(opts(), fx.Options(fx.NopLogger)) 35 | ctx := context.Background() 36 | app.Start(ctx) 37 | defer app.Stop(ctx) 38 | } 39 | 40 | func opts() fx.Option { 41 | return fx.Options( 42 | configfx.Module, 43 | queryfx.Module, 44 | fx.Invoke(queryAthena), 45 | ) 46 | } 47 | 48 | func queryAthena(qad queryfx.QueryAndDBConnection, mc configfx.AthenaDriverConfig) { 49 | for _, query := range qad.Query { 50 | query = strings.Trim(query, " \n\t") 51 | if query == "" { 52 | continue 53 | } 54 | rows, err := qad.DB.Query(query) 55 | if err != nil { 56 | println("ERROR: " + err.Error()) 57 | if mc.OutputConfig.Fastfail { 58 | return 59 | } 60 | continue 61 | } 62 | defer rows.Close() 63 | if mc.OutputConfig.Rowonly { 64 | drv.PrettyPrintSQLRows(rows, mc.OutputConfig.Style, mc.OutputConfig.Render, mc.OutputConfig.Page) 65 | } else { 66 | drv.PrettyPrintSQLColsRows(rows, mc.OutputConfig.Style, mc.OutputConfig.Render, mc.OutputConfig.Page) 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /athenareader/query.sql: -------------------------------------------------------------------------------- 1 | select request_timestamp,elb_name from elb_logs limit 1 2 | -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | This folder contains sample code, including integration/stress/crash/demo code, for `athenadriver`. 2 | 3 | For more details, please check [ :scroll: ](../resources/athenadriver.pdf). 4 | 5 | -------------------------------------------------------------------------------- /examples/constants/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | // The examples/constants folder contains all the const variables used by integration tests in examples folder, so please make sure all credentials are correct for you so that you can run the tests on your own machine. 22 | package constants 23 | -------------------------------------------------------------------------------- /examples/constants/secret.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package constants 22 | 23 | // To run integration test, please replace the below information to match your own AWS account. 24 | const ( 25 | OutputBucket = "s3://qr-athena-query-result-prod/Henry/" 26 | OutputBucketDev = "s3://query-results-bucket-henrywu/" 27 | OutputBucketProd = "s3://qr-athena-query-result-prod/Henry/" 28 | Region = "us-east-2" 29 | AccessID = "dummy" 30 | SecretAccessKey = "dummy" 31 | ) 32 | -------------------------------------------------------------------------------- /examples/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | // The examples folder contains all the integration tests, benchmark tests for package athenadriver. 22 | // 23 | // How to prepare integration end-to-end test? 24 | // 25 | // 1. Prerequisites - AWS Credentials & S3 Query Result Bucket. 26 | // 27 | // To be able to query AWS Athena, you need to have an AWS account at Amazon AWS's website. To give it a shot, 28 | // a free tier account is enough. You also need to have a pair of AWS access key ID and secret access key. 29 | // You can get it from AWS Security Credentials section of Identity and Access Management (IAM). 30 | // If you don't have one, please create it. 31 | // 32 | // In addition to AWS credentials, you also need an s3 bucket to store query result. 33 | // Just go to AWS S3 web console page to create one. In the examples below, 34 | // the s3 bucket I use is s3://henrywuqueryresults/. 35 | // 36 | // In most cases, you need the following 4 prerequisites : 37 | // 38 | // S3 Output bucket 39 | // access key ID 40 | // secret access key 41 | // AWS region 42 | // 43 | // For more details on athenadriver's support on AWS credentials & S3 query result bucket, 44 | // please refer to README section Support Multiple AWS Authorization Methods. 45 | // 46 | // 2. Installation athenadriver. 47 | // 48 | // Before Go 1.17, go get can be used to install athenadriver: 49 | // 50 | // go get -u github.com/uber/athenadriver 51 | // 52 | // Starting in Go 1.17, installing executables with go get is deprecated. go install may be used instead. 53 | // 54 | // go install github.com/uber/athenadriver@latest 55 | // 56 | // 3. Integration Test. 57 | // 58 | // To Build it: 59 | // 60 | // $cd $GOPATH/src/github.com/uber/athenadriver 61 | // $go build examples/maskcolumn.go 62 | // 63 | // Run it and you can see output like: 64 | // 65 | // $./maskcolumn 66 | // 2015-01-07T12:00:01.206255Z,xxx 67 | // 2015-01-07T12:00:01.612598Z,xxx 68 | // 2015-01-07T12:00:02.793335Z,xxx 69 | package main 70 | -------------------------------------------------------------------------------- /examples/lambda/Go/README.md: -------------------------------------------------------------------------------- 1 | # Query Athena with `athenadriver` in AWS Lambda 2 | 3 | ## Example 4 | 5 | First, install `aws-lambda-go`: 6 | 7 | ```go 8 | go get github.com/aws/aws-lambda-go/lambda 9 | ``` 10 | 11 | Build and package locally: 12 | ```go 13 | go mod init lambda-test 14 | go build main.go && zip function.zip main 15 | ``` 16 | 17 | Then upload `function.zip` to AWS by command line or web console, whichever you like. The handler name is `main` in this case. 18 | 19 | Create a test and run a test in AWS Lambda web console, then you can see: 20 | 21 | ![athena_in_lambda result](athena_in_lambda.png) -------------------------------------------------------------------------------- /examples/lambda/Go/athena_in_lambda.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uber/athenadriver/ed473510065ed1101f60270e27f6601eb1f41cea/examples/lambda/Go/athena_in_lambda.png -------------------------------------------------------------------------------- /examples/lambda/Go/go.mod: -------------------------------------------------------------------------------- 1 | module lambda-test 2 | 3 | go 1.13 4 | 5 | require ( 6 | github.com/aws/aws-lambda-go v1.17.0 7 | github.com/uber/athenadriver v1.1.6 8 | ) 9 | -------------------------------------------------------------------------------- /examples/lambda/Go/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "database/sql" 6 | "encoding/json" 7 | "github.com/aws/aws-lambda-go/events" 8 | "github.com/aws/aws-lambda-go/lambda" 9 | drv "github.com/uber/athenadriver/go" 10 | "os" 11 | ) 12 | 13 | type response struct { 14 | QueryResult string `json:"result"` 15 | } 16 | 17 | // Make sure to select a role which can query Athena! 18 | // https://epsagon.com/blog/getting-started-with-aws-lambda-and-go/ 19 | // https://docs.aws.amazon.com/lambda/latest/dg/golang-package.html 20 | func handleRequest(ctx context.Context, request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) { 21 | // 1. Set AWS Credential in Driver Config. 22 | os.Setenv("AWS_SDK_LOAD_CONFIG", "1") 23 | conf, err := drv.NewDefaultConfig("s3://athena-query-result/lambda/", 24 | drv.DummyRegion, drv.DummyAccessID, drv.DummySecretAccessKey) 25 | if err != nil { 26 | return events.APIGatewayProxyResponse{}, err 27 | } 28 | // 2. Open Connection. 29 | db, err := sql.Open(drv.DriverName, conf.Stringify()) 30 | if err != nil { 31 | return events.APIGatewayProxyResponse{Body: string(err.Error()), StatusCode: 500}, err 32 | } 33 | // 3. Query 34 | rows, err := db.QueryContext(ctx, "select 123") 35 | if err != nil { 36 | return events.APIGatewayProxyResponse{Body: string(err.Error()), StatusCode: 500}, err 37 | } 38 | defer rows.Close() 39 | resp := &response{ 40 | QueryResult: drv.ColsRowsToCSV(rows), 41 | } 42 | body, err := json.Marshal(resp) 43 | if err != nil { 44 | return events.APIGatewayProxyResponse{}, err 45 | } 46 | return events.APIGatewayProxyResponse{Body: string(body), StatusCode: 200}, nil 47 | } 48 | func main() { 49 | lambda.Start(handleRequest) 50 | } 51 | -------------------------------------------------------------------------------- /examples/logging.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package main 22 | 23 | import ( 24 | "context" 25 | "database/sql" 26 | "log" 27 | "time" 28 | 29 | "go.uber.org/zap" 30 | 31 | secret "github.com/uber/athenadriver/examples/constants" 32 | drv "github.com/uber/athenadriver/go" 33 | ) 34 | 35 | func main() { 36 | // 1. Set AWS Credential in Driver Config. 37 | conf, err := drv.NewDefaultConfig(secret.OutputBucket, secret.Region, 38 | secret.AccessID, secret.SecretAccessKey) 39 | conf.SetLogging(true) 40 | if err != nil { 41 | log.Fatal(err) 42 | return 43 | } 44 | 45 | // 2. Open Connection. 46 | dsn := conf.Stringify() 47 | db, _ := sql.Open(drv.DriverName, dsn) 48 | 49 | logger, _ := zap.NewProduction() 50 | defer logger.Sync() 51 | // 3. Query cancellation after 2 seconds 52 | ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) 53 | defer cancel() 54 | ctx = context.WithValue(ctx, drv.LoggerKey, logger) 55 | rows, err := db.QueryContext(ctx, "select count(*) from sampledb.elb_logs") 56 | if err != nil { 57 | log.Fatal(err) 58 | return 59 | } 60 | defer rows.Close() 61 | } 62 | 63 | /* 64 | Sample Output: 65 | {"level":"warn","ts":1579990455.5467792,"caller":"go/observability.go:73","msg":"query canceled","resp.QueryExecutionId":"34e08219-ca2e-4e10-94b3-0ebf6c4c22f6"} 66 | 2020/01/25 14:14:15 context deadline exceeded 67 | */ 68 | -------------------------------------------------------------------------------- /examples/maskcolumn.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package main 22 | 23 | import ( 24 | "database/sql" 25 | "log" 26 | 27 | secret "github.com/uber/athenadriver/examples/constants" 28 | drv "github.com/uber/athenadriver/go" 29 | ) 30 | 31 | func main() { 32 | // 1. Set AWS Credential in Driver Config. 33 | conf, err := drv.NewDefaultConfig(secret.OutputBucket, secret.Region, 34 | secret.AccessID, secret.SecretAccessKey) 35 | if err != nil { 36 | log.Fatal(err) 37 | return 38 | } 39 | conf.SetMaskedColumnValue("url", "xxx") 40 | // 2. Open Connection. 41 | dsn := conf.Stringify() 42 | db, _ := sql.Open(drv.DriverName, dsn) 43 | // 3. Query and print results 44 | rows, err := db.Query("select request_timestamp, url from sampledb.elb_logs limit 3") 45 | if err != nil { 46 | log.Fatal(err) 47 | return 48 | } 49 | defer rows.Close() 50 | 51 | var requestTimestamp string 52 | var url string 53 | for rows.Next() { 54 | if err := rows.Scan(&requestTimestamp, &url); err != nil { 55 | log.Fatal(err) 56 | } 57 | println(requestTimestamp + "," + url) 58 | } 59 | } 60 | 61 | /* 62 | Sample Output: 63 | 2015-01-03T12:00:00.516940Z,xxx 64 | 2015-01-03T12:00:00.902953Z,xxx 65 | 2015-01-03T12:00:01.206255Z,xxx 66 | */ 67 | -------------------------------------------------------------------------------- /examples/metrics.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package main 22 | 23 | import ( 24 | "context" 25 | "database/sql" 26 | "io" 27 | "log" 28 | "time" 29 | 30 | "github.com/cactus/go-statsd-client/statsd" 31 | tallystatsd "github.com/uber-go/tally/v4/statsd" 32 | 33 | "github.com/uber-go/tally/v4" 34 | secret "github.com/uber/athenadriver/examples/constants" 35 | drv "github.com/uber/athenadriver/go" 36 | ) 37 | 38 | func newScope() (tally.Scope, io.Closer) { 39 | statter, _ := statsd.NewBufferedClient("127.0.0.1:8125", 40 | "stats", 100*time.Millisecond, 1440) 41 | 42 | reporter := tallystatsd.NewReporter(statter, tallystatsd.Options{ 43 | SampleRate: 1.0, 44 | }) 45 | 46 | scope, closer := tally.NewRootScope(tally.ScopeOptions{ 47 | Prefix: "henrywu_test_metrics_service", 48 | Tags: map[string]string{}, 49 | Reporter: reporter, 50 | }, time.Second) 51 | 52 | return scope, closer 53 | } 54 | 55 | func main() { 56 | // 1. Set AWS Credential in Driver Config. 57 | conf, err := drv.NewDefaultConfig(secret.OutputBucket, secret.Region, 58 | secret.AccessID, secret.SecretAccessKey) 59 | if err != nil { 60 | log.Fatal(err) 61 | return 62 | } 63 | 64 | // 2. Open Connection. 65 | dsn := conf.Stringify() 66 | db, _ := sql.Open(drv.DriverName, dsn) 67 | 68 | // 3. Query cancellation after 2 seconds 69 | // Create tally scope 70 | scope, _ := newScope() 71 | // Create context and attach tally scope with context 72 | ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) 73 | defer cancel() 74 | ctx = context.WithValue(ctx, drv.MetricsKey, scope) 75 | rows, err := db.QueryContext(ctx, "select count(*) from sampledb.elb_logs") 76 | if err != nil { 77 | log.Fatal(err) 78 | return 79 | } 80 | defer rows.Close() 81 | } 82 | 83 | /* 84 | Sample Output: 85 | Run nc in another terminal, so you can use the metrics is reported like below: 86 | $nc 8125 -l -u 87 | stats.henrywu_test_metrics_service.awsathena.connector.connect:0.140147|ms 88 | stats.henrywu_test_metrics_service.awsathena.query.workgroup:0.000607|msstats.henrywu_test_metrics_service.awsathena.query.startqueryexecution:1191.644566|msstats.henrywu_test_metrics_service.awsathena.query.queryexecutionstatesucceeded:3320.820154|ms 89 | */ 90 | -------------------------------------------------------------------------------- /examples/pc_get_driver_version.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package main 22 | 23 | import ( 24 | "context" 25 | "database/sql" 26 | "os" 27 | 28 | secret "github.com/uber/athenadriver/examples/constants" 29 | drv "github.com/uber/athenadriver/go" 30 | ) 31 | 32 | func main() { 33 | // 1. Set AWS Credential in Driver Config. 34 | os.Setenv("AWS_SDK_LOAD_CONFIG", "1") 35 | conf, err := drv.NewDefaultConfig(secret.OutputBucket, secret.Region, secret.AccessID, secret.SecretAccessKey) 36 | conf.SetLogging(true) 37 | if err != nil { 38 | panic(err) 39 | return 40 | } 41 | 42 | // 2. Open Connection. 43 | dsn := conf.Stringify() 44 | db, _ := sql.Open(drv.DriverName, dsn) 45 | 46 | // 3. Query with pseudo command `pc:get_driver_version` 47 | rows, err := db.QueryContext(context.Background(), "pc:get_driver_version") 48 | if err != nil { 49 | panic(err) 50 | } 51 | defer rows.Close() 52 | println(drv.ColsRowsToCSV(rows)) 53 | } 54 | 55 | /* 56 | Sample Output: 57 | _col0 58 | 1.1.6 59 | */ 60 | -------------------------------------------------------------------------------- /examples/pc_get_query_id.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package main 22 | 23 | import ( 24 | "database/sql" 25 | "os" 26 | 27 | secret "github.com/uber/athenadriver/examples/constants" 28 | drv "github.com/uber/athenadriver/go" 29 | ) 30 | 31 | func main() { 32 | // 1. Set AWS Credential in Driver Config. 33 | os.Setenv("AWS_SDK_LOAD_CONFIG", "1") 34 | conf, err := drv.NewDefaultConfig(secret.OutputBucket, secret.Region, secret.AccessID, secret.SecretAccessKey) 35 | conf.SetLogging(true) 36 | if err != nil { 37 | panic(err) 38 | return 39 | } 40 | 41 | // 2. Open Connection. 42 | dsn := conf.Stringify() 43 | db, _ := sql.Open(drv.DriverName, dsn) 44 | 45 | // 3. Query with pseudo command `pc:get_query_id` 46 | var qid string 47 | _ = db.QueryRow("pc:get_query_id select url from sampledb.elb_logs limit 2").Scan(&qid) 48 | println("Query ID: ", qid) 49 | } 50 | 51 | /* 52 | Sample Output: 53 | Query ID: c89088ab-595d-4ee6-a9ce-73b55aeb8953 54 | */ 55 | -------------------------------------------------------------------------------- /examples/pc_get_query_id_status.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package main 22 | 23 | import ( 24 | "database/sql" 25 | "os" 26 | 27 | secret "github.com/uber/athenadriver/examples/constants" 28 | drv "github.com/uber/athenadriver/go" 29 | ) 30 | 31 | func main() { 32 | // 1. Set AWS Credential in Driver Config. 33 | os.Setenv("AWS_SDK_LOAD_CONFIG", "1") 34 | conf, err := drv.NewDefaultConfig(secret.OutputBucket, secret.Region, secret.AccessID, secret.SecretAccessKey) 35 | conf.SetLogging(true) 36 | if err != nil { 37 | panic(err) 38 | return 39 | } 40 | 41 | // 2. Open Connection. 42 | dsn := conf.Stringify() 43 | db, _ := sql.Open(drv.DriverName, dsn) 44 | 45 | // 3. Query with pseudo command 46 | var qidStatus string 47 | _ = db.QueryRow("pc:get_query_id_status c89088ab-595d-4ee6-a9ce-73b55aeb8953").Scan(&qidStatus) 48 | println("Query ID c89088ab-595d-4ee6-a9ce-73b55aeb8953's Status: ", qidStatus) 49 | } 50 | 51 | /* 52 | Sample Output: 53 | Query ID c89088ab-595d-4ee6-a9ce-73b55aeb8953's Status: SUCCEEDED 54 | */ 55 | -------------------------------------------------------------------------------- /examples/pc_stop_query_id.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package main 22 | 23 | import ( 24 | "database/sql" 25 | "os" 26 | 27 | secret "github.com/uber/athenadriver/examples/constants" 28 | drv "github.com/uber/athenadriver/go" 29 | ) 30 | 31 | func main() { 32 | // 1. Set AWS Credential in Driver Config. 33 | os.Setenv("AWS_SDK_LOAD_CONFIG", "1") 34 | conf, err := drv.NewDefaultConfig(secret.OutputBucket, secret.Region, secret.AccessID, secret.SecretAccessKey) 35 | conf.SetLogging(true) 36 | if err != nil { 37 | panic(err) 38 | return 39 | } 40 | 41 | // 2. Open Connection. 42 | dsn := conf.Stringify() 43 | db, _ := sql.Open(drv.DriverName, dsn) 44 | 45 | // 3. Query with pseudo command 46 | var s string 47 | _ = db.QueryRow("pc:stop_query_id c89088ab-595d-4ee6-a9ce-73b55aeb8953").Scan(&s) 48 | println("Stop Query ID c89088ab-595d-4ee6-a9ce-73b55aeb8953 returns:", s) 49 | } 50 | 51 | /* 52 | Sample Output: 53 | Stop Query ID c89088ab-595d-4ee6-a9ce-73b55aeb8953 returns: OK 54 | */ 55 | -------------------------------------------------------------------------------- /examples/perf/benchmark.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package main 22 | 23 | import ( 24 | "context" 25 | "database/sql" 26 | "fmt" 27 | "math/rand" 28 | "os" 29 | "sync" 30 | "time" 31 | 32 | secret "github.com/uber/athenadriver/examples/constants" 33 | drv "github.com/uber/athenadriver/go" 34 | "go.uber.org/zap" 35 | "go.uber.org/zap/zapcore" 36 | ) 37 | 38 | func main() { 39 | // 1. Set AWS Credential in Driver Config. 40 | os.Setenv("AWS_SDK_LOAD_CONFIG", "1") 41 | conf, err := drv.NewDefaultConfig( 42 | "s3://qr-athena-query-result/", 43 | secret.Region, 44 | secret.AccessID, 45 | secret.SecretAccessKey) 46 | os.Setenv("AWS_REGION", "us-east-1") 47 | if err != nil { 48 | panic(err) 49 | } 50 | var wg sync.WaitGroup 51 | numGoRoutine := 10000 52 | wg.Add(numGoRoutine) 53 | for i := 0; i < numGoRoutine; i++ { 54 | // 2. Open Connection. 55 | db, _ := sql.Open(drv.DriverName, conf.Stringify()) 56 | encoderCfg := zap.NewDevelopmentEncoderConfig() 57 | atom := zap.NewAtomicLevel() 58 | logger := zap.New(zapcore.NewCore( 59 | zapcore.NewJSONEncoder(encoderCfg), 60 | zapcore.Lock(os.Stdout), 61 | atom, 62 | )) 63 | atom.SetLevel(zapcore.DebugLevel) 64 | defer logger.Sync() 65 | go func(i int, conf *drv.Config) { 66 | defer wg.Done() 67 | // 3. Query cancellation after 2 seconds 68 | ctx := context.WithValue(context.Background(), drv.LoggerKey, logger) 69 | // 3. Query 70 | query := "SELECT \"" + randString(drv.MAXQueryStringLength-32) + "\"" 71 | r, e := db.QueryContext(ctx, query) 72 | if e != nil { 73 | fmt.Errorf("[%v]%s\n", i, e.Error()) 74 | return 75 | } else { 76 | print(i, ",") 77 | } 78 | defer r.Close() 79 | cnt := 0 80 | for r.Next() { 81 | cnt++ 82 | } 83 | }(i, conf) 84 | go func(i int, conf *drv.Config) { 85 | defer wg.Done() 86 | // 3. Query cancellation after 2 seconds 87 | ctx := context.WithValue(context.Background(), drv.LoggerKey, logger) 88 | // 3. Query 89 | r, e := db.QueryContext(ctx, "SHOW FUNCTIONS") 90 | if e != nil { 91 | fmt.Errorf("[%v]%s\n", i, e.Error()) 92 | return 93 | } else { 94 | print(i, ",") 95 | } 96 | defer r.Close() 97 | cnt := 0 98 | for r.Next() { 99 | cnt++ 100 | } 101 | }(i, conf) 102 | 103 | go func(db *sql.DB, logger *zap.Logger) { 104 | for range time.Tick(2 * time.Second) { 105 | stats := db.Stats() 106 | logDBStats2(stats, logger) 107 | } 108 | }(db, logger) 109 | } 110 | wg.Wait() 111 | } 112 | 113 | // logDBStats is to log DB statistics. 114 | func logDBStats2(stats sql.DBStats, logger *zap.Logger) { 115 | logger.Info("DBPoolStatus", 116 | zap.Int("MaxOpenConnections", stats.MaxOpenConnections), 117 | zap.Int("OpenConnections", stats.OpenConnections), 118 | zap.Int("Idle", stats.Idle), 119 | zap.Int("InUse", stats.InUse), 120 | zap.Int64("WaitCount", stats.WaitCount), 121 | zap.Duration("WaitDuration", stats.WaitDuration), 122 | zap.Int64("MaxIdleClosed", stats.MaxIdleClosed), 123 | zap.Int64("MaxLifetimeClosed", stats.MaxLifetimeClosed), 124 | ) 125 | } 126 | 127 | func randString(l int) string { 128 | const alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" 129 | s := make([]byte, l) 130 | for i := 0; i < l; i++ { 131 | s[i] = alphabet[rand.Intn(len(alphabet))] 132 | } 133 | return string(s) 134 | } 135 | -------------------------------------------------------------------------------- /examples/perf/concurrency.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package main 22 | 23 | import ( 24 | "context" 25 | "database/sql" 26 | "fmt" 27 | "os" 28 | "sync" 29 | "time" 30 | 31 | secret "github.com/uber/athenadriver/examples/constants" 32 | drv "github.com/uber/athenadriver/go" 33 | "go.uber.org/zap" 34 | "go.uber.org/zap/zapcore" 35 | ) 36 | 37 | func main() { 38 | // 1. Set AWS Credential in Driver Config. 39 | os.Setenv("AWS_SDK_LOAD_CONFIG", "1") 40 | conf, err := drv.NewDefaultConfig( 41 | "s3://qr-athena-query-result/", 42 | secret.Region, 43 | secret.AccessID, 44 | secret.SecretAccessKey) 45 | os.Setenv("AWS_REGION", "us-east-1") 46 | if err != nil { 47 | panic(err) 48 | } 49 | var wg sync.WaitGroup 50 | numGoRoutine := 100 51 | wg.Add(numGoRoutine) 52 | for i := 0; i < numGoRoutine; i++ { 53 | // 2. Open Connection. 54 | db, _ := sql.Open(drv.DriverName, conf.Stringify()) 55 | encoderCfg := zap.NewDevelopmentEncoderConfig() 56 | //encoderCfg.TimeKey = "" 57 | atom := zap.NewAtomicLevel() 58 | logger := zap.New(zapcore.NewCore( 59 | zapcore.NewJSONEncoder(encoderCfg), 60 | zapcore.Lock(os.Stdout), 61 | atom, 62 | )) 63 | atom.SetLevel(drv.DebugLevel) 64 | defer logger.Sync() 65 | go func(i int, conf *drv.Config) { 66 | defer wg.Done() 67 | // 3. Query cancellation after 2 seconds 68 | ctx := context.WithValue(context.Background(), drv.LoggerKey, logger) 69 | // 3. Query 70 | r, e := db.QueryContext(ctx, "SHOW FUNCTIONS") 71 | if e != nil { 72 | fmt.Errorf("[%v]%s\n", i, e.Error()) 73 | return 74 | } else { 75 | print(i, ",") 76 | } 77 | defer r.Close() 78 | cnt := 0 79 | for r.Next() { 80 | cnt++ 81 | } 82 | }(i, conf) 83 | 84 | go func(db *sql.DB, logger *zap.Logger) { 85 | for range time.Tick(2 * time.Second) { 86 | stats := db.Stats() 87 | logDBStats(stats, logger) 88 | } 89 | }(db, logger) 90 | } 91 | wg.Wait() 92 | } 93 | 94 | // logDBStats is to log DB statistics. 95 | func logDBStats(stats sql.DBStats, logger *zap.Logger) { 96 | logger.Info("DBPoolStatus", 97 | zap.Int("MaxOpenConnections", stats.MaxOpenConnections), 98 | zap.Int("OpenConnections", stats.OpenConnections), 99 | zap.Int("Idle", stats.Idle), 100 | zap.Int("InUse", stats.InUse), 101 | zap.Int64("WaitCount", stats.WaitCount), 102 | zap.Duration("WaitDuration", stats.WaitDuration), 103 | zap.Int64("MaxIdleClosed", stats.MaxIdleClosed), 104 | zap.Int64("MaxLifetimeClosed", stats.MaxLifetimeClosed), 105 | ) 106 | } 107 | -------------------------------------------------------------------------------- /examples/ping.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package main 22 | 23 | import ( 24 | "context" 25 | "database/sql" 26 | "time" 27 | 28 | "go.uber.org/zap" 29 | 30 | secret "github.com/uber/athenadriver/examples/constants" 31 | drv "github.com/uber/athenadriver/go" 32 | ) 33 | 34 | func main() { 35 | // 1. Set AWS Credential in Driver Config. 36 | conf, err := drv.NewDefaultConfig(secret.OutputBucket, secret.Region, 37 | secret.AccessID, secret.SecretAccessKey) 38 | conf.SetLogging(true) 39 | if err != nil { 40 | panic(err) 41 | return 42 | } 43 | 44 | // 2. Open Connection. 45 | dsn := conf.Stringify() 46 | db, _ := sql.Open(drv.DriverName, dsn) 47 | 48 | logger, _ := zap.NewProduction() 49 | defer logger.Sync() 50 | // 3. Query cancellation after 2 seconds 51 | ctx, cancel := context.WithTimeout(context.Background(), 2000*time.Second) 52 | defer cancel() 53 | ctx = context.WithValue(ctx, drv.LoggerKey, logger) 54 | e := db.PingContext(ctx) 55 | if e != nil { 56 | panic(e) 57 | } 58 | println("OK") 59 | } 60 | 61 | /* 62 | Sample output: 63 | (When setup is well done and connection is good) 64 | OK 65 | 66 | (otherwise) 67 | panic: driver: bad connection 68 | 69 | goroutine 1 [running]: 70 | main.main() 71 | /opt/share/go/path/src/github.com/uber/athenadriver/examples/ping.go:35 +0x320 72 | */ 73 | -------------------------------------------------------------------------------- /examples/qid.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package main 22 | 23 | import ( 24 | "context" 25 | "database/sql" 26 | "os" 27 | 28 | secret "github.com/uber/athenadriver/examples/constants" 29 | drv "github.com/uber/athenadriver/go" 30 | "go.uber.org/zap" 31 | ) 32 | 33 | // main will query Athena and print all columns and rows information in csv format 34 | func main() { 35 | // 1. Set AWS Credential in Driver Config. 36 | os.Setenv("AWS_SDK_LOAD_CONFIG", "1") 37 | conf, err := drv.NewDefaultConfig(secret.OutputBucket, secret.Region, 38 | secret.AccessID, secret.SecretAccessKey) 39 | if err != nil { 40 | return 41 | } 42 | // 2. Open Connection. 43 | conf.SetMoneyWise(true) 44 | dsn := conf.Stringify() 45 | db, _ := sql.Open(drv.DriverName, dsn) 46 | 47 | logger, _ := zap.NewProduction() 48 | defer logger.Sync() 49 | // 3. Query 50 | ctx := context.WithValue(context.Background(), drv.LoggerKey, logger) 51 | rows, err := db.QueryContext(ctx, `3e6d49a6-999c-46ef-8295-7a101c327f90`) 52 | if err != nil { 53 | println(err.Error()) 54 | return 55 | } 56 | defer rows.Close() 57 | println(drv.ColsRowsToCSV(rows)) 58 | } 59 | 60 | /* 61 | Sample output: 62 | query cost: 0.0 USD, scanned data: 0 B, qid: 3e6d49a6-999c-46ef-8295-7a101c327f90 63 | elb_name 64 | elb_demo_006 65 | */ 66 | -------------------------------------------------------------------------------- /examples/query/ddl_alter.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package main 22 | 23 | /* 24 | // The type of query statement that was run. DDL indicates DDL query statements. 25 | // DML indicates DML (Data Manipulation Language) query statements, such as 26 | // CREATE TABLE AS SELECT. UTILITY indicates query statements other than DDL 27 | // and DML, such as SHOW CREATE TABLE, or DESCRIBE . 28 | StatementType *string `type:"string" enum:"StatementType"` 29 | 30 | 31 | */ 32 | 33 | import ( 34 | "database/sql" 35 | "log" 36 | 37 | secret "github.com/uber/athenadriver/examples/constants" 38 | 39 | drv "github.com/uber/athenadriver/go" 40 | ) 41 | 42 | func main() { 43 | // 1. Set AWS Credential in Driver Config. 44 | conf, err := drv.NewDefaultConfig(secret.OutputBucket, secret.Region, 45 | secret.AccessID, secret.SecretAccessKey) 46 | if err != nil { 47 | log.Fatal(err) 48 | return 49 | } 50 | // 2. Open Connection. 51 | dsn := conf.Stringify() 52 | db, _ := sql.Open(drv.DriverName, dsn) 53 | // 3. Query and print results 54 | rows, err := db.Query("ALTER TABLE testme2 DROP PARTITION (ssl_protocol = 'TLSv1.2')") 55 | if err != nil { 56 | log.Fatal(err) 57 | return 58 | } 59 | defer rows.Close() 60 | println(drv.ColsRowsToCSV(rows)) 61 | } 62 | 63 | /* 64 | Sample Output: 65 | */ 66 | -------------------------------------------------------------------------------- /examples/query/ddl_create_database.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package main 22 | 23 | import ( 24 | "database/sql" 25 | "log" 26 | 27 | secret "github.com/uber/athenadriver/examples/constants" 28 | "go.uber.org/zap" 29 | 30 | drv "github.com/uber/athenadriver/go" 31 | ) 32 | 33 | func main() { 34 | // 1. Set AWS Credential in Driver Config. 35 | conf, err := drv.NewDefaultConfig(secret.OutputBucket, secret.Region, 36 | secret.AccessID, secret.SecretAccessKey) 37 | if err != nil { 38 | log.Fatal(err) 39 | return 40 | } 41 | // 2. Open Connection. 42 | dsn := conf.Stringify() 43 | db, _ := sql.Open(drv.DriverName, dsn) 44 | // 3. Query and print results 45 | logger, _ := zap.NewProduction() 46 | defer logger.Sync() 47 | 48 | var rows *sql.Rows 49 | rows, err = db.Query("CREATE DATABASE IF NOT EXISTS clickstreams" + 50 | " COMMENT 'Site Foo clickstream data aggregates'" + 51 | " LOCATION 's3://myS3location/clickstreams/'" + 52 | " WITH DBPROPERTIES ('creator'='Jane D.', 'Dept.'='Marketing analytics');") 53 | if err != nil { 54 | log.Fatal(err) 55 | return 56 | } 57 | println(drv.ColsRowsToCSV(rows)) 58 | } 59 | 60 | /* 61 | Sample Output: 62 | */ 63 | -------------------------------------------------------------------------------- /examples/query/ddl_create_table.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package main 22 | 23 | import ( 24 | "database/sql" 25 | "log" 26 | 27 | secret "github.com/uber/athenadriver/examples/constants" 28 | "go.uber.org/zap" 29 | 30 | drv "github.com/uber/athenadriver/go" 31 | ) 32 | 33 | func main() { 34 | // 1. Set AWS Credential in Driver Config. 35 | conf, err := drv.NewDefaultConfig(secret.OutputBucket, secret.Region, 36 | secret.AccessID, secret.SecretAccessKey) 37 | if err != nil { 38 | log.Fatal(err) 39 | return 40 | } 41 | // 2. Open Connection. 42 | dsn := conf.Stringify() 43 | db, _ := sql.Open(drv.DriverName, dsn) 44 | // 3. Query and print results 45 | logger, _ := zap.NewProduction() 46 | defer logger.Sync() 47 | 48 | var rows *sql.Rows 49 | rows, err = db.Query("CREATE EXTERNAL TABLE `elb_logs_henrywu`(" + 50 | " `request_timestamp` string COMMENT ''," + 51 | " `elb_name` string COMMENT ''," + 52 | " `request_ip` string COMMENT ''," + 53 | " `request_port` int COMMENT ''," + 54 | " `backend_ip` string COMMENT ''," + 55 | " `backend_port` int COMMENT ''," + 56 | " `request_processing_time` double COMMENT ''," + 57 | " `backend_processing_time` double COMMENT ''," + 58 | " `client_response_time` double COMMENT ''," + 59 | " `elb_response_code` string COMMENT ''," + 60 | " `backend_response_code` string COMMENT ''," + 61 | " `received_bytes` bigint COMMENT ''," + 62 | " `sent_bytes` bigint COMMENT ''," + 63 | " `request_verb` string COMMENT ''," + 64 | " `url` string COMMENT ''," + 65 | " `protocol` string COMMENT ''," + 66 | " `user_agent` string COMMENT ''," + 67 | " `ssl_cipher` string COMMENT ''," + 68 | " `ssl_protocol` string COMMENT '')" + 69 | " ROW FORMAT SERDE" + 70 | " 'org.apache.hadoop.hive.serde2.RegexSerDe'" + 71 | " WITH SERDEPROPERTIES (" + 72 | " 'input.regex'='([^ ]*) ([^ ]*) ([^ ]*):([0-9]*) ([^ ]*):([0-9]*) ([.0-9]*) " + 73 | "([.0-9]*) ([.0-9]*) (-|[0-9]*) (-|[0-9]*) ([-0-9]*) ([-0-9]*) \\\"([^ ]*) ([^ ]*) " + 74 | "(- |[^ ]*)\\\" (\"[^\"]*\") ([A-Z0-9-]+) ([A-Za-z0-9.-]*)$')" + 75 | " STORED AS INPUTFORMAT" + 76 | " 'org.apache.hadoop.mapred.TextInputFormat'" + 77 | " OUTPUTFORMAT" + 78 | " 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'" + 79 | " LOCATION" + 80 | " 's3://athena-examples-us-east-2/elb/plaintext'" + 81 | " TBLPROPERTIES (" + 82 | " 'transient_lastDdlTime'='1480278335')") 83 | if err != nil { 84 | log.Fatal(err) 85 | return 86 | } 87 | println(drv.ColsRowsToCSV(rows)) 88 | } 89 | 90 | /* 91 | Sample Output: 92 | */ 93 | -------------------------------------------------------------------------------- /examples/query/ddl_ctas.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package main 22 | 23 | import ( 24 | "database/sql" 25 | "log" 26 | 27 | secret "github.com/uber/athenadriver/examples/constants" 28 | "go.uber.org/zap" 29 | 30 | drv "github.com/uber/athenadriver/go" 31 | ) 32 | 33 | func main() { 34 | // 1. Set AWS Credential in Driver Config. 35 | conf, err := drv.NewDefaultConfig(secret.OutputBucket, secret.Region, 36 | secret.AccessID, secret.SecretAccessKey) 37 | if err != nil { 38 | log.Fatal(err) 39 | return 40 | } 41 | // 2. Open Connection. 42 | dsn := conf.Stringify() 43 | db, _ := sql.Open(drv.DriverName, dsn) 44 | // 3. Query and print results 45 | logger, _ := zap.NewProduction() 46 | defer logger.Sync() 47 | 48 | var rows *sql.Rows 49 | rows, err = db.Query("DROP TABLE IF EXISTS sampledb.elb_logs_new;") 50 | if err != nil { 51 | log.Fatal(err) 52 | return 53 | } 54 | rows, err = db.Query("CREATE TABLE sampledb.elb_logs_new AS " + 55 | "SELECT * FROM sampledb.elb_logs limit 10;") 56 | if err != nil { 57 | log.Println(err) 58 | } 59 | 60 | println(drv.ColsRowsToCSV(rows)) 61 | } 62 | 63 | /* 64 | Sample Output: 65 | rows 66 | 10 67 | */ 68 | -------------------------------------------------------------------------------- /examples/query/ddl_ctas_with_partition.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package main 22 | 23 | import ( 24 | "database/sql" 25 | "log" 26 | 27 | secret "github.com/uber/athenadriver/examples/constants" 28 | 29 | drv "github.com/uber/athenadriver/go" 30 | ) 31 | 32 | func main() { 33 | // 1. Set AWS Credential in Driver Config. 34 | conf, err := drv.NewDefaultConfig(secret.OutputBucket, secret.Region, 35 | secret.AccessID, secret.SecretAccessKey) 36 | if err != nil { 37 | log.Fatal(err) 38 | return 39 | } 40 | // 2. Open Connection. 41 | dsn := conf.Stringify() 42 | db, _ := sql.Open(drv.DriverName, dsn) 43 | // 3. Query and print results 44 | rows, err := db.Query("CREATE TABLE testme3 WITH (format = 'TEXTFILE', " + 45 | "external_location = 's3://external-location-henrywu/testme3_2', " + 46 | "partitioned_by = ARRAY['ssl_protocol']) AS SELECT * FROM sampledb.elb_logs") 47 | if err != nil { 48 | log.Fatal(err) 49 | return 50 | } 51 | defer rows.Close() 52 | println(drv.ColsRowsToCSV(rows)) 53 | } 54 | 55 | /* 56 | Sample Output: 57 | rows 58 | 1356206 59 | */ 60 | -------------------------------------------------------------------------------- /examples/query/ddl_cvas.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package main 22 | 23 | import ( 24 | "context" 25 | "database/sql" 26 | "log" 27 | 28 | secret "github.com/uber/athenadriver/examples/constants" 29 | "go.uber.org/zap" 30 | 31 | drv "github.com/uber/athenadriver/go" 32 | ) 33 | 34 | func main() { 35 | // 1. Set AWS Credential in Driver Config. 36 | conf, err := drv.NewDefaultConfig(secret.OutputBucket, secret.Region, 37 | secret.AccessID, secret.SecretAccessKey) 38 | if err != nil { 39 | log.Fatal(err) 40 | return 41 | } 42 | // 2. Open Connection. 43 | dsn := conf.Stringify() 44 | db, _ := sql.Open(drv.DriverName, dsn) 45 | // 3. Query and print results 46 | logger, _ := zap.NewProduction() 47 | defer logger.Sync() 48 | 49 | var rows *sql.Rows 50 | rows, err = db.Query("DROP VIEW IF EXISTS sampledb.elb_logs_view;") 51 | if err != nil { 52 | log.Fatal(err) 53 | return 54 | } 55 | rows, err = db.Query("CREATE VIEW sampledb.elb_logs_view AS SELECT * FROM sampledb.elb_logs limit 1;") 56 | if err != nil { 57 | log.Println(err) 58 | } 59 | 60 | ctx := context.WithValue(context.Background(), drv.LoggerKey, logger) 61 | rows, err = db.QueryContext(ctx, "describe sampledb.elb_logs_view") 62 | if err != nil { 63 | log.Fatal(err) 64 | return 65 | } 66 | println(drv.ColsRowsToCSV(rows)) 67 | } 68 | 69 | /* 70 | Sample Output: 71 | column,type 72 | request_timestamp,varchar 73 | elb_name,varchar 74 | request_ip,varchar 75 | request_port,integer 76 | backend_ip,varchar 77 | backend_port,integer 78 | request_processing_time,double 79 | backend_processing_time,double 80 | client_response_time,double 81 | elb_response_code,varchar 82 | backend_response_code,varchar 83 | received_bytes,bigint 84 | sent_bytes,bigint 85 | request_verb,varchar 86 | url,varchar 87 | protocol,varchar 88 | user_agent,varchar 89 | ssl_cipher,varchar 90 | ssl_protocol,varchar 91 | 92 | */ 93 | -------------------------------------------------------------------------------- /examples/query/ddl_drop.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package main 22 | 23 | import ( 24 | "context" 25 | "database/sql" 26 | "log" 27 | 28 | secret "github.com/uber/athenadriver/examples/constants" 29 | "go.uber.org/zap" 30 | 31 | drv "github.com/uber/athenadriver/go" 32 | ) 33 | 34 | func main() { 35 | // 1. Set AWS Credential in Driver Config. 36 | conf, err := drv.NewDefaultConfig(secret.OutputBucket, secret.Region, 37 | secret.AccessID, secret.SecretAccessKey) 38 | if err != nil { 39 | log.Fatal(err) 40 | return 41 | } 42 | // 2. Open Connection. 43 | dsn := conf.Stringify() 44 | db, _ := sql.Open(drv.DriverName, dsn) 45 | // 3. Query and print results 46 | logger, _ := zap.NewProduction() 47 | defer logger.Sync() 48 | 49 | var rows *sql.Rows 50 | ctx := context.WithValue(context.Background(), drv.LoggerKey, logger) 51 | rows, err = db.QueryContext(ctx, "drop table IF EXISTS testme3") 52 | if err != nil { 53 | log.Fatal(err) 54 | return 55 | } 56 | println(drv.ColsRowsToCSV(rows)) 57 | } 58 | 59 | /* 60 | Sample Output: 61 | */ 62 | -------------------------------------------------------------------------------- /examples/query/ddl_msck.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package main 22 | 23 | /* 24 | // The type of query statement that was run. DDL indicates DDL query statements. 25 | // DML indicates DML (Data Manipulation Language) query statements, such as 26 | // CREATE TABLE AS SELECT. UTILITY indicates query statements other than DDL 27 | // and DML, such as SHOW CREATE TABLE, or DESCRIBE
. 28 | StatementType *string `type:"string" enum:"StatementType"` 29 | 30 | 31 | */ 32 | 33 | import ( 34 | "database/sql" 35 | "log" 36 | 37 | secret "github.com/uber/athenadriver/examples/constants" 38 | 39 | drv "github.com/uber/athenadriver/go" 40 | ) 41 | 42 | func main() { 43 | // 1. Set AWS Credential in Driver Config. 44 | conf, err := drv.NewDefaultConfig(secret.OutputBucket, secret.Region, 45 | secret.AccessID, secret.SecretAccessKey) 46 | if err != nil { 47 | log.Fatal(err) 48 | return 49 | } 50 | // 2. Open Connection. 51 | dsn := conf.Stringify() 52 | db, _ := sql.Open(drv.DriverName, dsn) 53 | // 3. Query and print results 54 | rows, err := db.Query("MSCK REPAIR TABLE testme") 55 | if err != nil { 56 | log.Fatal(err) 57 | return 58 | } 59 | defer rows.Close() 60 | println(drv.ColsRowsToCSV(rows)) 61 | 62 | rows, err = db.Query("MSCK REPAIR TABLE sampledb.elb_logs") 63 | if err != nil { 64 | log.Fatal(err) 65 | return 66 | } 67 | println(drv.ColsRowsToCSV(rows)) 68 | } 69 | 70 | /* 71 | Sample Output: 72 | _col0 73 | Partitions not in metastore: elb_logs:2015/01/01 elb_logs:2015/01/02 elb_logs:2015/01/03 elb_logs:2015/01/04 elb_logs:2015/01/05 elb_logs:2015/01/06 elb_logs:2015/01/07 74 | */ 75 | -------------------------------------------------------------------------------- /examples/query/ddl_path.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package main 22 | 23 | import ( 24 | "context" 25 | "database/sql" 26 | "log" 27 | "os" 28 | 29 | secret "github.com/uber/athenadriver/examples/constants" 30 | drv "github.com/uber/athenadriver/go" 31 | "go.uber.org/zap" 32 | ) 33 | 34 | // Note: 35 | // Amazon Redshift Spectrum support $path and $size 36 | // https://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_EXTERNAL_TABLE.html#r_CREATE_EXTERNAL_TABLE_usage-pseudocolumns 37 | // But Athena supports only $path 38 | func main() { 39 | // 1. Set AWS Credential in Driver Config. 40 | os.Setenv("AWS_SDK_LOAD_CONFIG", "1") 41 | conf, err := drv.NewDefaultConfig(secret.OutputBucket, secret.Region, 42 | secret.AccessID, secret.SecretAccessKey) 43 | if err != nil { 44 | log.Fatal(err) 45 | return 46 | } 47 | // 2. Open Connection. 48 | dsn := conf.Stringify() 49 | db, _ := sql.Open(drv.DriverName, dsn) 50 | // 3. Query and print results 51 | logger, _ := zap.NewProduction() 52 | defer logger.Sync() 53 | 54 | var rows *sql.Rows 55 | ctx := context.WithValue(context.Background(), drv.LoggerKey, logger) 56 | rows, err = db.QueryContext(ctx, "SELECT \"$path\" as s3_filepath from sampledb.elb_logs limit 1") 57 | if err != nil { 58 | log.Fatal(err) 59 | return 60 | } 61 | println(drv.ColsRowsToCSV(rows)) 62 | // skip $size in TidySQL to ensure the raw string is passed in 63 | rows, err = db.QueryContext(ctx, "SELECT \"$path\", \"$size\" from sampledb.elb_logs limit 1") 64 | if err != nil { 65 | log.Fatal(err) 66 | return 67 | } 68 | println(drv.ColsRowsToCSV(rows)) 69 | } 70 | 71 | /* 72 | Sample Output: 73 | s3_filepath 74 | s3://athena-examples-us-east-1/elb/plaintext/2015/01/03/part-r-00014-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt 75 | 76 | {"level":"error","ts":1592019844.947993,"caller":"go/trace.go:129","msg":"QueryExecutionStateFailed","workgroup":"primary","queryID":"49c8ad1c-13c6-48e5-ba65-061934b3dde4","reason":"SYNTAX_ERROR: line 1:17: Column '$size' cannot be resolved","stacktrace":"github.com/uber/athenadriver/go.(*DriverTracer).Log\n\t/opt/share/go/path/src/github.com/uber/athenadriver/go/trace.go:129\ngithub.com/uber/athenadriver/go.(*Connection).QueryContext\n\t/opt/share/go/path/src/github.com/uber/athenadriver/go/connection.go:393\ndatabase/sql.ctxDriverQuery\n\t/opt/share/yuanma/go_src/src/database/sql/ctxutil.go:48\ndatabase/sql.(*DB).queryDC.func1\n\t/opt/share/yuanma/go_src/src/database/sql/sql.go:1592\ndatabase/sql.withLock\n\t/opt/share/yuanma/go_src/src/database/sql/sql.go:3184\ndatabase/sql.(*DB).queryDC\n\t/opt/share/yuanma/go_src/src/database/sql/sql.go:1587\ndatabase/sql.(*DB).query\n\t/opt/share/yuanma/go_src/src/database/sql/sql.go:1570\ndatabase/sql.(*DB).QueryContext\n\t/opt/share/yuanma/go_src/src/database/sql/sql.go:1547\nmain.main\n\t/opt/share/go/path/src/github.com/uber/athenadriver/examples/query/ddl_path.go:51\nruntime.main\n\t/opt/share/yuanma/go_src/src/runtime/proc.go:203"} 77 | 2020/06/12 20:44:04 SYNTAX_ERROR: line 1:17: Column '$size' cannot be resolved 78 | */ 79 | -------------------------------------------------------------------------------- /examples/query/dml_insert_into_select.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package main 22 | 23 | import ( 24 | "database/sql" 25 | "log" 26 | 27 | secret "github.com/uber/athenadriver/examples/constants" 28 | 29 | drv "github.com/uber/athenadriver/go" 30 | ) 31 | 32 | // https://aws.amazon.com/about-aws/whats-new/2019/09/amazon-athena-adds-support-inserting-data-into-table-results-of-select-query/ 33 | // 34 | // With this release, 35 | // you can insert new rows into a destination table based on a SELECT query 36 | // statement that runs on a source table, 37 | // or based on a set of values that are provided as part of the query 38 | // statement. Supported data formats include Avro, JSON, ORC, Parquet, 39 | // and Text files. 40 | // 41 | // INSERT INTO statements can also help you simplify your ETL process. 42 | // For example, you can use INSERT INTO to select data from a source table 43 | // that is in JSON format and write to a destination table in Parquet format 44 | // in a single query. INSERT INTO statements are charged based on bytes 45 | // scanned in the Select phase, 46 | // similar to how Athena charges for Select queries. 47 | func main() { 48 | // 1. Set AWS Credential in Driver Config. 49 | conf, err := drv.NewDefaultConfig(secret.OutputBucket, secret.Region, 50 | secret.AccessID, secret.SecretAccessKey) 51 | if err != nil { 52 | log.Fatal(err) 53 | return 54 | } 55 | // 2. Open Connection. 56 | dsn := conf.Stringify() 57 | db, _ := sql.Open(drv.DriverName, dsn) 58 | // 3. Query and print results 59 | rows, err := db.Query("INSERT INTO testme2 SELECT * FROM testme") 60 | if err != nil { 61 | log.Fatal(err) 62 | return 63 | } 64 | defer rows.Close() 65 | println(drv.ColsRowsToCSV(rows)) 66 | } 67 | 68 | /* 69 | Sample Output: 70 | rows 71 | 1 72 | */ 73 | -------------------------------------------------------------------------------- /examples/query/dml_insert_into_values.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package main 22 | 23 | import ( 24 | "context" 25 | "database/sql" 26 | 27 | secret "github.com/uber/athenadriver/examples/constants" 28 | drv "github.com/uber/athenadriver/go" 29 | ) 30 | 31 | func main() { 32 | // 1. Set AWS Credential in Driver Config. 33 | var conf *drv.Config 34 | var err error 35 | if conf, err = drv.NewDefaultConfig(secret.OutputBucket, secret.Region, 36 | secret.AccessID, secret.SecretAccessKey); err != nil { 37 | panic(err) 38 | } 39 | // 2. Open Connection. 40 | db, _ := sql.Open(drv.DriverName, conf.Stringify()) 41 | // 3. Execute and print results 42 | if _, err = db.ExecContext(context.Background(), 43 | "DROP TABLE IF EXISTS sampledb.urls"); err != nil { 44 | panic(err) 45 | } 46 | 47 | var result sql.Result 48 | if result, err = db.Exec("CREATE TABLE sampledb.urls AS "+ 49 | "SELECT url FROM sampledb.elb_logs where request_ip=? limit ?", 50 | "244.157.42.179", 1); err != nil { 51 | panic(err) 52 | } 53 | if rowsAffected, err := result.RowsAffected(); err == nil { 54 | println(rowsAffected) 55 | } 56 | 57 | if result, err = db.Exec("INSERT INTO sampledb.urls VALUES (?),(?),(?)", 58 | "abc", "efg", "xyz"); err != nil { 59 | panic(err) 60 | } 61 | if rowsAffected, err := result.RowsAffected(); err == nil { 62 | println(rowsAffected) 63 | } 64 | } 65 | 66 | /* 67 | Sample Output: 68 | 1 69 | 3 70 | */ 71 | -------------------------------------------------------------------------------- /examples/query/dml_select_array.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package main 22 | 23 | import ( 24 | "database/sql" 25 | "log" 26 | 27 | secret "github.com/uber/athenadriver/examples/constants" 28 | drv "github.com/uber/athenadriver/go" 29 | ) 30 | 31 | // main will query Athena and print all columns and rows information in csv format 32 | func main() { 33 | // 1. Set AWS Credential in Driver Config. 34 | conf, err := drv.NewDefaultConfig(secret.OutputBucket, secret.Region, 35 | secret.AccessID, secret.SecretAccessKey) 36 | if err != nil { 37 | log.Fatal(err) 38 | return 39 | } 40 | // 2. Open Connection. 41 | dsn := conf.Stringify() 42 | db, _ := sql.Open(drv.DriverName, dsn) 43 | // 3. Query and print results 44 | rows, err := db.Query("SELECT ARRAY [1,2,3,4] AS items") 45 | if err != nil { 46 | println(err.Error()) 47 | return 48 | } 49 | defer rows.Close() 50 | drv.ColsToCSV(rows) 51 | // array, map, binary, structure are returned as string type. 52 | var items string 53 | for rows.Next() { 54 | if err := rows.Scan(&items); err != nil { 55 | log.Fatal(err) 56 | } 57 | } 58 | println(items) 59 | } 60 | 61 | /* 62 | Sample output: 63 | items 64 | [1, 2, 3, 4] 65 | */ 66 | -------------------------------------------------------------------------------- /examples/query/dml_select_count.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package main 22 | 23 | import ( 24 | "database/sql" 25 | "log" 26 | 27 | secret "github.com/uber/athenadriver/examples/constants" 28 | 29 | drv "github.com/uber/athenadriver/go" 30 | ) 31 | 32 | // main will query Athena and print all columns and rows information in csv format 33 | func main() { 34 | // 1. Set AWS Credential in Driver Config. 35 | conf, err := drv.NewDefaultConfig(secret.OutputBucket, secret.Region, 36 | secret.AccessID, secret.SecretAccessKey) 37 | if err != nil { 38 | log.Fatal(err) 39 | return 40 | } 41 | // 2. Open Connection. 42 | dsn := conf.Stringify() 43 | db, _ := sql.Open(drv.DriverName, dsn) 44 | // 3. Query and print results 45 | rows, err := db.Query("select count(*) from sampledb.elb_logs") 46 | if err != nil { 47 | println(err.Error()) 48 | return 49 | } 50 | defer rows.Close() 51 | println(drv.ColsRowsToCSV(rows)) 52 | } 53 | 54 | /* 55 | Sample output: 56 | _col0 57 | 1356206 58 | */ 59 | -------------------------------------------------------------------------------- /examples/query/dml_select_db_exec.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package main 22 | 23 | import ( 24 | "database/sql" 25 | 26 | secret "github.com/uber/athenadriver/examples/constants" 27 | drv "github.com/uber/athenadriver/go" 28 | ) 29 | 30 | func main() { 31 | // 1. Set AWS Credential in Driver Config. 32 | conf, err := drv.NewDefaultConfig(secret.OutputBucket, secret.Region, 33 | secret.AccessID, secret.SecretAccessKey) 34 | if err != nil { 35 | return 36 | } 37 | // 2. Open Connection. 38 | db, _ := sql.Open(drv.DriverName, conf.Stringify()) 39 | // 3. Query and print results 40 | result, err := db.Exec("SELECT url from sampledb.elb_logs limit 10") 41 | i, _ := result.RowsAffected() 42 | println(i) 43 | i, _ = result.LastInsertId() 44 | println(i) 45 | } 46 | 47 | /* 48 | Sample Output: 49 | 0 50 | -1 51 | */ 52 | -------------------------------------------------------------------------------- /examples/query/dml_select_fields.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package main 22 | 23 | import ( 24 | "database/sql" 25 | "log" 26 | "strconv" 27 | 28 | secret "github.com/uber/athenadriver/examples/constants" 29 | drv "github.com/uber/athenadriver/go" 30 | ) 31 | 32 | func main() { 33 | // 1. Set AWS Credential in Driver Config. 34 | conf, err := drv.NewDefaultConfig(secret.OutputBucket, secret.Region, 35 | secret.AccessID, secret.SecretAccessKey) 36 | if err != nil { 37 | log.Fatal(err) 38 | return 39 | } 40 | // 2. Open Connection. 41 | dsn := conf.Stringify() 42 | db, _ := sql.Open(drv.DriverName, dsn) 43 | // 3. Query and print results 44 | rows, err := db.Query("select nan(), infinity(), url, " + 45 | "request_port from sampledb.elb_logs limit 3") 46 | if err != nil { 47 | log.Fatal(err) 48 | return 49 | } 50 | defer rows.Close() 51 | 52 | var real, inf float64 53 | var url string 54 | var request_port int 55 | for rows.Next() { 56 | if err := rows.Scan(&real, &inf, &url, 57 | &request_port); err != nil { 58 | log.Fatal(err) 59 | } 60 | println(strconv.FormatFloat(real, 'f', 6, 64) + "," + 61 | strconv.FormatFloat(inf, 'f', 6, 64) + "," + url + "," + 62 | strconv.Itoa(request_port)) 63 | } 64 | } 65 | 66 | /* 67 | Sample Output: 68 | NaN,+Inf,http://www.example.com/images/386,8096 69 | NaN,+Inf,https://www.example.com/jobs/132,24938 70 | NaN,+Inf,https://www.example.com/images/229,7963 71 | */ 72 | -------------------------------------------------------------------------------- /examples/query/dml_select_geo.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package main 22 | 23 | import ( 24 | "context" 25 | "database/sql" 26 | "log" 27 | 28 | secret "github.com/uber/athenadriver/examples/constants" 29 | drv "github.com/uber/athenadriver/go" 30 | "go.uber.org/zap" 31 | ) 32 | 33 | // main will query Athena and print all columns and rows information in csv format 34 | func main() { 35 | // 1. Set AWS Credential in Driver Config. 36 | conf, err := drv.NewDefaultConfig(secret.OutputBucket, secret.Region, 37 | secret.AccessID, secret.SecretAccessKey) 38 | if err != nil { 39 | log.Fatal(err) 40 | return 41 | } 42 | // 2. Open Connection. 43 | dsn := conf.Stringify() 44 | db, _ := sql.Open(drv.DriverName, dsn) 45 | // 3. Query and print results 46 | logger, _ := zap.NewDevelopment() 47 | defer logger.Sync() 48 | ctx := context.WithValue(context.Background(), drv.LoggerKey, logger) 49 | rows, err := db.QueryContext(ctx, "SELECT ST_POINT(-74.006801, 40.705220);") 50 | if err != nil { 51 | println(err.Error()) 52 | return 53 | } 54 | defer rows.Close() 55 | drv.ColsToCSV(rows) 56 | // array, map, binary, structure are returned as string type. 57 | var items string 58 | for rows.Next() { 59 | if err := rows.Scan(&items); err != nil { 60 | log.Fatal(err) 61 | } 62 | } 63 | println(items) 64 | } 65 | 66 | /* 67 | Sample output: 68 | _col0 69 | 00 00 00 00 01 01 00 00 00 20 25 76 6d 6f 80 52 c0 18 3e 22 a6 44 5a 44 40 70 | 71 | After adding logging: 72 | _col0 73 | 2020-02-02T10:51:37.355-0800 DEBUG go/observability.go:103 type: varbinary {"val": "00 00 00 00 01 01 00 00 00 20 25 76 6d 6f 80 52 c0 18 3e 22 a6 44 5a 44 40"} 74 | 00 00 00 00 01 01 00 00 00 20 25 76 6d 6f 80 52 c0 18 3e 22 a6 44 5a 44 40 75 | */ 76 | -------------------------------------------------------------------------------- /examples/query/dml_select_information_schema.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package main 22 | 23 | import ( 24 | "database/sql" 25 | "log" 26 | 27 | secret "github.com/uber/athenadriver/examples/constants" 28 | drv "github.com/uber/athenadriver/go" 29 | ) 30 | 31 | // main will query Athena and print all columns and rows information in csv format 32 | func main() { 33 | // 1. Set AWS Credential in Driver Config. 34 | conf, err := drv.NewDefaultConfig(secret.OutputBucket, secret.Region, 35 | secret.AccessID, secret.SecretAccessKey) 36 | if err != nil { 37 | log.Fatal(err) 38 | return 39 | } 40 | // 2. Open Connection. 41 | dsn := conf.Stringify() 42 | db, _ := sql.Open(drv.DriverName, dsn) 43 | // 3. Query and print results 44 | rows, err := db.Query("SELECT * FROM information_schema." + 45 | "columns where table_schema='sampledb' and table_name='elb_logs';") 46 | if err != nil { 47 | println(err.Error()) 48 | return 49 | } 50 | defer rows.Close() 51 | println(drv.ColsRowsToCSV(rows)) 52 | } 53 | 54 | /* 55 | Sample output: 56 | table_catalog,table_schema,table_name,column_name,ordinal_position,column_default,is_nullable,data_type,comment,extra_info 57 | awsdatacatalog,sampledb,elb_logs,request_timestamp,1,,YES,varchar,, 58 | awsdatacatalog,sampledb,elb_logs,elb_name,2,,YES,varchar,, 59 | awsdatacatalog,sampledb,elb_logs,request_ip,3,,YES,varchar,, 60 | awsdatacatalog,sampledb,elb_logs,request_port,4,,YES,integer,, 61 | awsdatacatalog,sampledb,elb_logs,backend_ip,5,,YES,varchar,, 62 | awsdatacatalog,sampledb,elb_logs,backend_port,6,,YES,integer,, 63 | awsdatacatalog,sampledb,elb_logs,request_processing_time,7,,YES,double,, 64 | awsdatacatalog,sampledb,elb_logs,backend_processing_time,8,,YES,double,, 65 | awsdatacatalog,sampledb,elb_logs,client_response_time,9,,YES,double,, 66 | awsdatacatalog,sampledb,elb_logs,elb_response_code,10,,YES,varchar,, 67 | awsdatacatalog,sampledb,elb_logs,backend_response_code,11,,YES,varchar,, 68 | awsdatacatalog,sampledb,elb_logs,received_bytes,12,,YES,bigint,, 69 | awsdatacatalog,sampledb,elb_logs,sent_bytes,13,,YES,bigint,, 70 | awsdatacatalog,sampledb,elb_logs,request_verb,14,,YES,varchar,, 71 | awsdatacatalog,sampledb,elb_logs,url,15,,YES,varchar,, 72 | awsdatacatalog,sampledb,elb_logs,protocol,16,,YES,varchar,, 73 | awsdatacatalog,sampledb,elb_logs,user_agent,17,,YES,varchar,, 74 | awsdatacatalog,sampledb,elb_logs,ssl_cipher,18,,YES,varchar,, 75 | awsdatacatalog,sampledb,elb_logs,ssl_protocol,19,,YES,varchar,, 76 | */ 77 | -------------------------------------------------------------------------------- /examples/query/dml_select_join.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package main 22 | 23 | import ( 24 | "database/sql" 25 | 26 | secret "github.com/uber/athenadriver/examples/constants" 27 | drv "github.com/uber/athenadriver/go" 28 | ) 29 | 30 | // main will query Athena and print all columns and rows information in csv format 31 | func main() { 32 | // 1. Set AWS Credential in Driver Config. 33 | conf, err := drv.NewDefaultConfig(secret.OutputBucket, secret.Region, 34 | secret.AccessID, secret.SecretAccessKey) 35 | if err != nil { 36 | return 37 | } 38 | // 2. Open Connection. 39 | dsn := conf.Stringify() 40 | db, _ := sql.Open(drv.DriverName, dsn) 41 | // 3. Query and print results 42 | query := "SELECT a.elb_name, " + 43 | "a.url FROM elb_logs_new2 a LEFT JOIN sampledb.elb_logs_new b ON a." + 44 | "request_timestamp = b.request_timestamp" 45 | rows, err := db.Query(query) 46 | if err != nil { 47 | return 48 | } 49 | defer rows.Close() 50 | println(drv.ColsRowsToCSV(rows)) 51 | } 52 | 53 | /* 54 | Sample output: 55 | elb_name,url 56 | elb_demo_009,https://www.example.com/articles/746 57 | */ 58 | -------------------------------------------------------------------------------- /examples/query/dml_select_json.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package main 22 | 23 | import ( 24 | "context" 25 | "database/sql" 26 | 27 | secret "github.com/uber/athenadriver/examples/constants" 28 | drv "github.com/uber/athenadriver/go" 29 | "go.uber.org/zap" 30 | ) 31 | 32 | // main will query Athena and print all columns and rows information in csv format 33 | func main() { 34 | // 1. Set AWS Credential in Driver Config. 35 | conf, err := drv.NewDefaultConfig(secret.OutputBucket, secret.Region, 36 | secret.AccessID, secret.SecretAccessKey) 37 | if err != nil { 38 | panic(err) 39 | return 40 | } 41 | // 2. Open Connection. 42 | dsn := conf.Stringify() 43 | db, _ := sql.Open(drv.DriverName, dsn) 44 | // 3. Query and print results 45 | /*query := "WITH dataset AS(SELECT '{\"name\": \"Susan Smith\"," + 46 | "\"org\": \"engineering\",\r\n" + 47 | "\"projects\": [{\"name\":\"project1\", \"completed\":false},\r\n" + 48 | "{\"name\":\"project2\", \"completed\":true}]}'\r\n" + 49 | "AS blob)\r\n" + 50 | "SELECT\r\njson_extract(blob, '$.name') AS name,\r\n" + 51 | "json_extract(blob, '$.projects') AS projects\r\n" + 52 | "FROM dataset"*/ 53 | logger, _ := zap.NewDevelopment() 54 | defer logger.Sync() 55 | // 3. Query cancellation after 2 seconds 56 | ctx := context.WithValue(context.Background(), drv.LoggerKey, logger) 57 | rows, err := db.QueryContext(ctx, "SELECT JSON '\"Hello Athena\"'") 58 | if err != nil { 59 | println(err.Error()) 60 | return 61 | } 62 | defer rows.Close() 63 | println(drv.ColsRowsToCSV(rows)) 64 | } 65 | 66 | /* 67 | Sample output: 68 | name,projects 69 | "Susan Smith",[{"name":"project1","completed":false},{"name":"project2","completed":true}] 70 | 71 | Sample output: 72 | _col0 73 | 2020-02-02T10:47:16.070-0800 DEBUG go/observability.go:103 type: json {"val": "\"Hello Athena\""} 74 | "Hello Athena" 75 | */ 76 | -------------------------------------------------------------------------------- /examples/query/dml_select_map.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package main 22 | 23 | import ( 24 | "database/sql" 25 | "log" 26 | 27 | secret "github.com/uber/athenadriver/examples/constants" 28 | drv "github.com/uber/athenadriver/go" 29 | ) 30 | 31 | // main will query Athena and print all columns and rows information in csv format 32 | func main() { 33 | // 1. Set AWS Credential in Driver Config. 34 | conf, err := drv.NewDefaultConfig(secret.OutputBucket, secret.Region, 35 | secret.AccessID, secret.SecretAccessKey) 36 | if err != nil { 37 | log.Fatal(err) 38 | return 39 | } 40 | // 2. Open Connection. 41 | dsn := conf.Stringify() 42 | db, _ := sql.Open(drv.DriverName, dsn) 43 | // 3. Query and print results 44 | rows, err := db.Query("select map(array['alice'], array['has a cat']);") 45 | if err != nil { 46 | println(err.Error()) 47 | return 48 | } 49 | defer rows.Close() 50 | drv.ColsToCSV(rows) 51 | // array, map, binary, structure are returned as string type. 52 | var aMap string 53 | for rows.Next() { 54 | if err := rows.Scan(&aMap); err != nil { 55 | log.Fatal(err) 56 | } 57 | } 58 | println(aMap) 59 | } 60 | 61 | /* 62 | Sample output: 63 | _col0 64 | {alice=has a cat} 65 | */ 66 | -------------------------------------------------------------------------------- /examples/query/dml_select_prepare.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package main 22 | 23 | import ( 24 | "database/sql" 25 | 26 | secret "github.com/uber/athenadriver/examples/constants" 27 | drv "github.com/uber/athenadriver/go" 28 | ) 29 | 30 | func main() { 31 | // 1. Set AWS Credential in Driver Config. 32 | var conf *drv.Config 33 | var err error 34 | if conf, err = drv.NewDefaultConfig(secret.OutputBucket, secret.Region, 35 | secret.AccessID, secret.SecretAccessKey); err != nil { 36 | panic(err) 37 | } 38 | // 2. Open Connection. 39 | db, _ := sql.Open(drv.DriverName, conf.Stringify()) 40 | // 3. Query and print results 41 | if _, err = db.Exec("DROP TABLE IF EXISTS sampledb.urls"); err != nil { 42 | panic(err) 43 | } 44 | 45 | statement, err := db.Prepare("CREATE TABLE sampledb.urls AS " + 46 | "SELECT url FROM sampledb.elb_logs where request_ip=? limit ?") 47 | if err != nil { 48 | panic(err) 49 | } 50 | if result, e := statement.Exec("244.157.42.179", 2); e == nil { 51 | if rowsAffected, err := result.RowsAffected(); err == nil { 52 | println(rowsAffected) 53 | } 54 | } 55 | 56 | rows, err := db.Query("SELECT request_timestamp,elb_name "+ 57 | "from sampledb.elb_logs where url=? limit 1", 58 | "https://www.example.com/jobs/878") 59 | if err != nil { 60 | return 61 | } 62 | println(drv.ColsRowsToCSV(rows)) 63 | 64 | } 65 | 66 | /* 67 | Sample Output: 68 | 2 69 | request_timestamp,elb_name 70 | 2015-01-02T04:11:59.697912Z,elb_demo_007 71 | */ 72 | -------------------------------------------------------------------------------- /examples/query/dml_select_row.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package main 22 | 23 | import ( 24 | "context" 25 | "database/sql" 26 | 27 | secret "github.com/uber/athenadriver/examples/constants" 28 | drv "github.com/uber/athenadriver/go" 29 | "go.uber.org/zap" 30 | ) 31 | 32 | // main will query Athena and print all columns and rows information in csv format 33 | func main() { 34 | // 1. Set AWS Credential in Driver Config. 35 | conf, err := drv.NewDefaultConfig(secret.OutputBucket, secret.Region, 36 | secret.AccessID, secret.SecretAccessKey) 37 | if err != nil { 38 | panic(err) 39 | return 40 | } 41 | // 2. Open Connection. 42 | db, _ := sql.Open(drv.DriverName, conf.Stringify()) 43 | // 3. Query and print results 44 | logger, _ := zap.NewDevelopment() 45 | defer logger.Sync() 46 | ctx := context.WithValue(context.Background(), drv.LoggerKey, logger) 47 | rows, err := db.QueryContext(ctx, "select ROW(1, 2.0)") 48 | if err != nil { 49 | panic(err) 50 | } 51 | defer rows.Close() 52 | println(drv.ColsRowsToCSV(rows)) 53 | } 54 | 55 | /* 56 | Sample output: 57 | _col0 58 | 2020-02-02T11:05:06.995-0800 DEBUG go/observability.go:103 type: row 59 | {"val": "{field0=1, field1=2.0}"} 60 | {field0=1, field1=2.0} 61 | */ 62 | -------------------------------------------------------------------------------- /examples/query/dml_select_simple.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package main 22 | 23 | import ( 24 | "database/sql" 25 | "fmt" 26 | 27 | secret "github.com/uber/athenadriver/examples/constants" 28 | drv "github.com/uber/athenadriver/go" 29 | ) 30 | 31 | func main() { 32 | // 1. Set AWS Credential in Driver Config. 33 | conf, err := drv.NewDefaultConfig(secret.OutputBucket, secret.Region, 34 | secret.AccessID, secret.SecretAccessKey) 35 | if err != nil { 36 | return 37 | } 38 | // 2. Open Connection. 39 | db, _ := sql.Open(drv.DriverName, conf.Stringify()) 40 | // 3. Query and print results 41 | var url string 42 | _ = db.QueryRow("SELECT url from sampledb.elb_logs limit 1").Scan(&url) 43 | fmt.Println(url) 44 | } 45 | 46 | /* 47 | Sample Output: 48 | https://www.example.com/jobs/553 49 | */ 50 | -------------------------------------------------------------------------------- /examples/query/dml_select_star.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package main 22 | 23 | import ( 24 | "context" 25 | "database/sql" 26 | 27 | secret "github.com/uber/athenadriver/examples/constants" 28 | drv "github.com/uber/athenadriver/go" 29 | "go.uber.org/zap" 30 | ) 31 | 32 | // main will query Athena and print all columns and rows information in csv format 33 | func main() { 34 | // 1. Set AWS Credential in Driver Config. 35 | conf, err := drv.NewDefaultConfig(secret.OutputBucket, secret.Region, 36 | secret.AccessID, secret.SecretAccessKey) 37 | if err != nil { 38 | return 39 | } 40 | // 2. Open Connection. 41 | dsn := conf.Stringify() 42 | db, _ := sql.Open(drv.DriverName, dsn) 43 | 44 | logger, _ := zap.NewProduction() 45 | defer logger.Sync() 46 | // 3. Query cancellation after 2 seconds 47 | ctx := context.WithValue(context.Background(), drv.LoggerKey, logger) 48 | rows, err := db.QueryContext(ctx, "select * from sampledb.elb_logs limit 3") 49 | if err != nil { 50 | println(err.Error()) 51 | return 52 | } 53 | defer rows.Close() 54 | println(drv.ColsRowsToCSV(rows)) 55 | } 56 | 57 | /* 58 | Sample output: 59 | request_timestamp,elb_name,request_ip,request_port,backend_ip,backend_port,request_processing_time,backend_processing_time,client_response_time,elb_response_code,backend_response_code,received_bytes,sent_bytes,request_verb,url,protocol,user_agent,ssl_cipher,ssl_protocol 60 | 2015-01-07T04:00:01.206255Z,elb_demo_005,245.85.197.169,8222,172.46.214.105,8888,0.001163,0.001233,0.000121,200,200,0,705,GET,http://www.example.com/images/858,HTTP/1.1,"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/602.1.50 (KHTML, like Gecko) Version/10.0 Safari/602.1.50",-,- 61 | 2015-01-07T04:00:01.612598Z,elb_demo_003,251.165.102.100,24615,172.41.185.247,80,0.000868,0.001232,0.000527,200,200,0,572,GET,https://www.example.com/images/905,HTTP/1.1,"Mozilla/5.0 (X11; CrOS x86_64 8172.45.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.64 Safari/537.36",DHE-RSA-AES128-SHA,TLSv1.2 62 | 2015-01-07T04:00:02.793335Z,elb_demo_007,250.120.176.53,24251,172.55.212.88,80,0.00087,0.001561,0.001009,200,200,0,2040,GET,http://www.example.com/articles/518,HTTP/1.1,"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.246",-,- 63 | */ 64 | -------------------------------------------------------------------------------- /examples/query/dml_select_time.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package main 22 | 23 | import ( 24 | "context" 25 | "database/sql" 26 | 27 | secret "github.com/uber/athenadriver/examples/constants" 28 | drv "github.com/uber/athenadriver/go" 29 | "go.uber.org/zap" 30 | ) 31 | 32 | // main will query Athena and print all columns and rows information in csv format 33 | func main() { 34 | // 1. Set AWS Credential in Driver Config. 35 | conf, err := drv.NewDefaultConfig(secret.OutputBucket, secret.Region, 36 | secret.AccessID, secret.SecretAccessKey) 37 | if err != nil { 38 | panic(err) 39 | } 40 | // 2. Open Connection. 41 | dsn := conf.Stringify() 42 | db, _ := sql.Open(drv.DriverName, dsn) 43 | // 3. Query and print results 44 | query := "select INTERVAL '2' DAY, INTERVAL '3' MONTH, " + 45 | "TIME '01:02:03.456', TIME '01:02:03.456 America/Los_Angeles', " + 46 | "TIMESTAMP '2001-08-22 03:04:05.321', " + 47 | "TIMESTAMP '2001-08-22 03:04:05.321 America/Los_Angeles';" 48 | logger, _ := zap.NewDevelopment() 49 | defer logger.Sync() 50 | ctx := context.WithValue(context.Background(), drv.LoggerKey, logger) 51 | rows, err := db.QueryContext(ctx, query) 52 | if err != nil { 53 | panic(err) 54 | } 55 | defer rows.Close() 56 | println(drv.ColsRowsToCSV(rows)) 57 | } 58 | 59 | /* 60 | select TIMESTAMP '2001-08-22 03:04:05.321 PDT'; 61 | SYNTAX_ERROR: line 1:145: '2001-08-22 03:04:05.321 PDT' is not a valid timestamp literal 62 | 63 | Sample output: 64 | _col0,_col1,_col2,_col3,_col4,_col5 65 | 2 00:00:00.000,0-3,0000-01-01T01:02:03.456-07:52,0000-01-01T01:02:03.456-07:52,2001-08-22T03:04:05.321-07:00,2001-08-22T03:04:05.321-07:00 66 | */ 67 | -------------------------------------------------------------------------------- /examples/query/dml_values.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package main 22 | 23 | import ( 24 | "context" 25 | "database/sql" 26 | 27 | secret "github.com/uber/athenadriver/examples/constants" 28 | drv "github.com/uber/athenadriver/go" 29 | "go.uber.org/zap" 30 | ) 31 | 32 | // main will query Athena and print all columns and rows information in csv format 33 | func main() { 34 | // 1. Set AWS Credential in Driver Config. 35 | conf, err := drv.NewDefaultConfig(secret.OutputBucket, secret.Region, 36 | secret.AccessID, secret.SecretAccessKey) 37 | if err != nil { 38 | panic(err) 39 | return 40 | } 41 | // 2. Open Connection. 42 | dsn := conf.Stringify() 43 | db, _ := sql.Open(drv.DriverName, dsn) 44 | 45 | logger, _ := zap.NewProduction() 46 | defer logger.Sync() 47 | // 3. Query cancellation after 2 seconds 48 | ctx := context.WithValue(context.Background(), drv.LoggerKey, logger) 49 | rows, err := db.QueryContext(ctx, "values 1,2,3") 50 | if err != nil { 51 | println(err.Error()) 52 | return 53 | } 54 | defer rows.Close() 55 | println(drv.ColsRowsToCSV(rows)) 56 | rows, err = db.QueryContext(ctx, "VALUES\n (1, 'a'),\n (2, 'b'),\n (3, 'c')") 57 | if err != nil { 58 | println(err.Error()) 59 | return 60 | } 61 | defer rows.Close() 62 | println(drv.ColsRowsToCSV(rows)) 63 | 64 | } 65 | 66 | /* 67 | Sample output: 68 | _col0 69 | 1 70 | 2 71 | 3 72 | 73 | _col0,_col1 74 | 1,a 75 | 2,b 76 | 3,c 77 | */ 78 | 79 | /* 80 | line 1:1: mismatched input 'call' expecting 81 | {'(', 'select', 'from', 'add', 'desc', 'with', 'values', 'create', 'table', 82 | 'insert', 'delete', 'describe', 'explain', 'show', 'use', 'drop', 'alter', 83 | 'map', 'set', 'reset', 'start', 'commit', 'rollback', 'reduce', 'refresh', 84 | 'clear', 'cache', 'uncache', 'dfs', 'truncate', 'analyze', 'list', 'revoke', 85 | 'grant', 'lock', 'unlock', 'msck', 'export', 'import', 'load'} 86 | (service: amazonathena; status code: 400; error code: invalidrequestexception; request id: 2f85b55c-4117-4ad2-9cd5-32d9777574b7) 87 | 88 | 89 | line 1:1: extraneous input 'map' expecting 90 | {'(', 'select', 'desc', 'using', 'with', 'values', 'create', 'table', 'insert', 91 | 'delete', 'describe', 'grant', 'revoke', 'explain', 'show', 'use', 'drop', 'alter', 92 | 'set', 'reset', 'start', 'commit', 'rollback', 'call', 'prepare', 'deallocate', 'execute'} 93 | (service: amazonathena; status code: 400; error code: invalidrequestexception; request id: 5a343890-e5c8-4a4c-835a-0d6c0cd8d650) 94 | */ 95 | -------------------------------------------------------------------------------- /examples/query/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | // The examples/query folder contains integration tests for all SQL statements, data types supported and unsupported by AWS Athena. 22 | // How to prepare integration end-to-end test? 23 | // 24 | // 1. Prerequisites - AWS Credentials & S3 Query Result Bucket. 25 | // 26 | // To be able to query AWS Athena, you need to have an AWS account at Amazon AWS's website. To give it a shot, 27 | // a free tier account is enough. You also need to have a pair of AWS access key ID and secret access key. 28 | // You can get it from AWS Security Credentials section of Identity and Access Management (IAM). 29 | // If you don't have one, please create it. 30 | // 31 | // In addition to AWS credentials, you also need an s3 bucket to store query result. 32 | // Just go to AWS S3 web console page to create one. In the examples below, 33 | // the s3 bucket I use is s3://henrywuqueryresults/. 34 | // 35 | // In most cases, you need the following 4 prerequisites : 36 | // 37 | // S3 Output bucket 38 | // access key ID 39 | // secret access key 40 | // AWS region 41 | // 42 | // For more details on athenadriver's support on AWS credentials & S3 query result bucket, 43 | // please refer to README section Support Multiple AWS Authorization Methods. 44 | // 45 | // 2. Installation athenadriver. 46 | // 47 | // Before Go 1.17, go get can be used to install athenadriver: 48 | // 49 | // go get -u github.com/uber/athenadriver 50 | // 51 | // Starting in Go 1.17, installing executables with go get is deprecated. go install may be used instead. 52 | // 53 | // go install github.com/uber/athenadriver@latest 54 | // 55 | // 3. Integration Test. 56 | // 57 | // To Build it: 58 | // 59 | // $cd $GOPATH/src/github.com/uber/athenadriver 60 | // $go build examples/query/dml_select_simple.go 61 | // 62 | // Run it and you can see output like: 63 | // 64 | // $./dml_select_simple 65 | // https://www.example.com/jobs/433 66 | package main 67 | -------------------------------------------------------------------------------- /examples/query/unsupported.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package main 22 | 23 | import ( 24 | "context" 25 | "database/sql" 26 | 27 | secret "github.com/uber/athenadriver/examples/constants" 28 | drv "github.com/uber/athenadriver/go" 29 | "go.uber.org/zap" 30 | ) 31 | 32 | // main will query Athena and print all columns and rows information in csv format 33 | func main() { 34 | // 1. Set AWS Credential in Driver Config. 35 | conf, err := drv.NewDefaultConfig(secret.OutputBucket, secret.Region, 36 | secret.AccessID, secret.SecretAccessKey) 37 | if err != nil { 38 | panic(err) 39 | return 40 | } 41 | // 2. Open Connection. 42 | dsn := conf.Stringify() 43 | db, _ := sql.Open(drv.DriverName, dsn) 44 | 45 | logger, _ := zap.NewProduction() 46 | defer logger.Sync() 47 | // 3. Query cancellation after 2 seconds 48 | ctx := context.WithValue(context.Background(), drv.LoggerKey, logger) 49 | for _, q := range []string{ 50 | "COMMIT;", 51 | "CALL catalog.schema.test();", 52 | "rollback", 53 | "SET SESSION hive.optimized_reader_enabled = true;", 54 | "DELETE FROM sampledb.elb_logs;", 55 | "EXPLAIN select 1;", 56 | "START TRANSACTION ISOLATION LEVEL REPEATABLE READ;", 57 | "SHOW CATALOGS", 58 | "CREATE TEMPORARY MACRO fixed_number() 42;", 59 | "SHOW ROLE GRANT USER henrywu;", 60 | "GRANT SDE TO USER henrywu;", 61 | "SHOW PRINCIPALS henrywu;", 62 | "DROP ROLE henrywu", 63 | } { 64 | rows, err := db.QueryContext(ctx, q) 65 | if err != nil { 66 | println(err.Error()) 67 | continue 68 | } 69 | defer rows.Close() 70 | println(drv.ColsRowsToCSV(rows)) 71 | } 72 | } 73 | 74 | /* 75 | Sample output: 76 | InvalidRequestException: Queries of this type are not supported 77 | status code: 400, request id: 7867246d-a1cf-4265-bb17-6f32a65ca5a8 78 | */ 79 | 80 | /* 81 | line 1:1: mismatched input 'call' expecting 82 | {'(', 'select', 'from', 'add', 'desc', 'with', 'values', 'create', 'table', 83 | 'insert', 'delete', 'describe', 'explain', 'show', 'use', 'drop', 'alter', 84 | 'map', 'set', 'reset', 'start', 'commit', 'rollback', 'reduce', 'refresh', 85 | 'clear', 'cache', 'uncache', 'dfs', 'truncate', 'analyze', 'list', 'revoke', 86 | 'grant', 'lock', 'unlock', 'msck', 'export', 'import', 'load'} 87 | (service: amazonathena; status code: 400; error code: invalidrequestexception; request id: 2f85b55c-4117-4ad2-9cd5-32d9777574b7) 88 | 89 | 90 | line 1:1: extraneous input 'map' expecting 91 | {'(', 'select', 'desc', 'using', 'with', 'values', 'create', 'table', 'insert', 92 | 'delete', 'describe', 'grant', 'revoke', 'explain', 'show', 'use', 'drop', 'alter', 93 | 'set', 'reset', 'start', 'commit', 'rollback', 'call', 'prepare', 'deallocate', 'execute'} 94 | (service: amazonathena; status code: 400; error code: invalidrequestexception; request id: 5a343890-e5c8-4a4c-835a-0d6c0cd8d650) 95 | */ 96 | -------------------------------------------------------------------------------- /examples/query/util_desc_table.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package main 22 | 23 | import ( 24 | "database/sql" 25 | "log" 26 | 27 | secret "github.com/uber/athenadriver/examples/constants" 28 | 29 | drv "github.com/uber/athenadriver/go" 30 | ) 31 | 32 | func main() { 33 | // 1. Set AWS Credential in Driver Config. 34 | conf, err := drv.NewDefaultConfig(secret.OutputBucket, secret.Region, 35 | secret.AccessID, secret.SecretAccessKey) 36 | if err != nil { 37 | log.Fatal(err) 38 | return 39 | } 40 | // 2. Open Connection. 41 | dsn := conf.Stringify() 42 | db, _ := sql.Open(drv.DriverName, dsn) 43 | // 3. Query and print results 44 | rows, err := db.Query("desc sampledb.elb_logs") 45 | if err != nil { 46 | log.Fatal(err) 47 | return 48 | } 49 | println(drv.ColsRowsToCSV(rows)) 50 | } 51 | 52 | /* 53 | Sample Output: 54 | col_name,data_type,comment 55 | request_timestamp,string, 56 | elb_name,string, 57 | request_ip,string, 58 | request_port,int, 59 | backend_ip,string, 60 | backend_port,int, 61 | request_processing_time,double, 62 | backend_processing_time,double, 63 | client_response_time,double, 64 | elb_response_code,string, 65 | backend_response_code,string, 66 | received_bytes,bigint, 67 | sent_bytes,bigint, 68 | request_verb,string, 69 | url,string, 70 | protocol,string, 71 | user_agent,string, 72 | ssl_cipher,string, 73 | ssl_protocol,string, 74 | */ 75 | -------------------------------------------------------------------------------- /examples/query/util_desc_view.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package main 22 | 23 | import ( 24 | "database/sql" 25 | "log" 26 | 27 | secret "github.com/uber/athenadriver/examples/constants" 28 | 29 | drv "github.com/uber/athenadriver/go" 30 | ) 31 | 32 | func main() { 33 | // 1. Set AWS Credential in Driver Config. 34 | conf, err := drv.NewDefaultConfig(secret.OutputBucket, secret.Region, 35 | secret.AccessID, secret.SecretAccessKey) 36 | if err != nil { 37 | log.Fatal(err) 38 | return 39 | } 40 | // 2. Open Connection. 41 | dsn := conf.Stringify() 42 | db, _ := sql.Open(drv.DriverName, dsn) 43 | // 3. Query and print results 44 | rows, err := db.Query("desc sampledb.elb_logs") 45 | if err != nil { 46 | log.Fatal(err) 47 | return 48 | } 49 | println(drv.ColsRowsToCSV(rows)) 50 | } 51 | 52 | /* 53 | Sample Output: 54 | col_name,data_type,comment 55 | request_timestamp,string, 56 | elb_name,string, 57 | request_ip,string, 58 | request_port,int, 59 | backend_ip,string, 60 | backend_port,int, 61 | request_processing_time,double, 62 | backend_processing_time,double, 63 | client_response_time,double, 64 | elb_response_code,string, 65 | backend_response_code,string, 66 | received_bytes,bigint, 67 | sent_bytes,bigint, 68 | request_verb,string, 69 | url,string, 70 | protocol,string, 71 | user_agent,string, 72 | ssl_cipher,string, 73 | ssl_protocol,string, 74 | */ 75 | -------------------------------------------------------------------------------- /examples/querycancel.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package main 22 | 23 | import ( 24 | "context" 25 | "database/sql" 26 | "log" 27 | "time" 28 | 29 | secret "github.com/uber/athenadriver/examples/constants" 30 | 31 | drv "github.com/uber/athenadriver/go" 32 | ) 33 | 34 | func main() { 35 | // 1. Set AWS Credential in Driver Config. 36 | conf, err := drv.NewDefaultConfig(secret.OutputBucket, secret.Region, 37 | secret.AccessID, secret.SecretAccessKey) 38 | if err != nil { 39 | log.Fatal(err) 40 | return 41 | } 42 | 43 | // 2. Open Connection. 44 | conf.SetMoneyWise(true) 45 | dsn := conf.Stringify() 46 | db, _ := sql.Open(drv.DriverName, dsn) 47 | // 3. Query cancellation after 2 seconds 48 | ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) 49 | defer cancel() 50 | rows, err := db.QueryContext(ctx, "select count(*) from sampledb.elb_logs") 51 | if err != nil { 52 | log.Fatal(err) 53 | return 54 | } 55 | defer rows.Close() 56 | 57 | var cnt int64 58 | for rows.Next() { 59 | if err := rows.Scan(&cnt); err != nil { 60 | log.Fatal(err) 61 | } 62 | println(cnt) 63 | } 64 | } 65 | 66 | /* 67 | Sample Output: 68 | 2020/01/20 15:28:35 context deadline exceeded 69 | */ 70 | -------------------------------------------------------------------------------- /examples/readonly.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package main 22 | 23 | import ( 24 | "context" 25 | "database/sql" 26 | "log" 27 | 28 | secret "github.com/uber/athenadriver/examples/constants" 29 | drv "github.com/uber/athenadriver/go" 30 | "go.uber.org/zap" 31 | ) 32 | 33 | func main() { 34 | // 1. Set AWS Credential in Driver Config. 35 | conf, err := drv.NewDefaultConfig(secret.OutputBucket, secret.Region, 36 | secret.AccessID, secret.SecretAccessKey) 37 | if err != nil { 38 | log.Fatal(err) 39 | return 40 | } 41 | conf.SetReadOnly(true) 42 | 43 | // 2. Open Connection. 44 | dsn := conf.Stringify() 45 | db, _ := sql.Open(drv.DriverName, dsn) 46 | logger, _ := zap.NewProduction() 47 | defer logger.Sync() 48 | // 3. Create Table with CTAS statement 49 | ctx := context.WithValue(context.Background(), drv.LoggerKey, logger) 50 | rows, err := db.QueryContext(ctx, "CREATE TABLE sampledb.elb_logs_new AS "+ 51 | "SELECT * FROM sampledb.elb_logs limit 10;") 52 | if err != nil { 53 | log.Fatal(err) 54 | return 55 | } 56 | defer rows.Close() 57 | } 58 | 59 | /* 60 | Sample Output: 61 | {"level":"warn","ts":1580029828.7197285,"caller":"go/observability.go:73", 62 | "msg":"write db violation","query":"CREATE TABLE sampledb.elb_logs_new AS SELECT * FROM sampledb.elb_logs limit 10;"} 63 | 2020/01/26 01:10:28 writing to Athena database is disallowed in read-only mode 64 | */ 65 | -------------------------------------------------------------------------------- /examples/reconnect.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package main 22 | 23 | import ( 24 | "context" 25 | "database/sql" 26 | "log" 27 | 28 | secret "github.com/uber/athenadriver/examples/constants" 29 | drv "github.com/uber/athenadriver/go" 30 | "go.uber.org/zap" 31 | ) 32 | 33 | // main will query Athena and print all columns and rows information in csv format 34 | func main() { 35 | // 1. Set AWS Credential in Driver Config. 36 | conf, err := drv.NewDefaultConfig(secret.OutputBucket, secret.Region, 37 | secret.AccessID, secret.SecretAccessKey) 38 | if err != nil { 39 | log.Fatal(err) 40 | return 41 | } 42 | // 2. Open Connection. 43 | dsn := conf.Stringify() 44 | db, _ := sql.Open(drv.DriverName, dsn) 45 | 46 | logger, _ := zap.NewProduction() 47 | defer logger.Sync() 48 | // 3. Query cancellation after 2 seconds 49 | ctx := context.WithValue(context.Background(), drv.LoggerKey, logger) 50 | rows, err := db.QueryContext(ctx, "select * from sampledb.elb_logs limit 3") 51 | if err != nil { 52 | println(err.Error()) 53 | return 54 | } 55 | defer rows.Close() 56 | println(drv.ColsRowsToCSV(rows)) 57 | } 58 | -------------------------------------------------------------------------------- /examples/trans.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package main 22 | 23 | import ( 24 | "context" 25 | "database/sql" 26 | "log" 27 | 28 | drv "github.com/uber/athenadriver/go" 29 | ) 30 | 31 | var ( 32 | ctx context.Context 33 | db *sql.DB 34 | ) 35 | 36 | func main() { 37 | // 1. Set AWS Credential in Driver Config. 38 | conf := drv.NewNoOpsConfig() 39 | 40 | // 2. Open Connection. 41 | dsn := conf.Stringify() 42 | db, _ := sql.Open(drv.DriverName, dsn) 43 | // A *DB is a pool of connections. Call Conn to reserve a connection for 44 | // exclusive use. 45 | tx, err := db.BeginTx(context.Background(), &sql.TxOptions{Isolation: sql. 46 | LevelSerializable}) 47 | if err != nil { 48 | log.Fatal(err) 49 | } 50 | _, execErr := tx.Exec("SELECT request_timestamp,elb_name "+ 51 | "from sampledb.elb_logs where url=? limit 1", 52 | "https://www.example.com/jobs/878") 53 | if execErr != nil { 54 | _ = tx.Rollback() 55 | log.Fatal(execErr) 56 | } 57 | if err := tx.Commit(); err != nil { 58 | log.Fatal(err) 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /examples/types.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package main 22 | 23 | import ( 24 | "context" 25 | "database/sql" 26 | "os" 27 | 28 | secret "github.com/uber/athenadriver/examples/constants" 29 | drv "github.com/uber/athenadriver/go" 30 | "go.uber.org/zap" 31 | "go.uber.org/zap/zapcore" 32 | ) 33 | 34 | // main will query Athena and print all columns and rows information in csv format 35 | func main() { 36 | // 1. Set AWS Credential in Driver Config. 37 | conf, err := drv.NewDefaultConfig(secret.OutputBucket, secret.Region, 38 | secret.AccessID, secret.SecretAccessKey) 39 | if err != nil { 40 | panic(err) 41 | } 42 | // 2. Open Connection. 43 | dsn := conf.Stringify() 44 | db, _ := sql.Open(drv.DriverName, dsn) 45 | // 3. Query and print results 46 | query := "select JSON '\"Hello Athena\"', " + 47 | "ST_POINT(-74.006801, 40.70522), " + 48 | "ROW(1, 2.0), INTERVAL '2' DAY, " + 49 | "INTERVAL '3' MONTH, " + 50 | "TIME '01:02:03.456', " + 51 | "TIME '01:02:03.456 America/Los_Angeles', " + 52 | "TIMESTAMP '2001-08-22 03:04:05.321 America/Los_Angeles';" 53 | encoderCfg := zap.NewProductionEncoderConfig() 54 | encoderCfg.TimeKey = "" 55 | atom := zap.NewAtomicLevel() 56 | logger := zap.New(zapcore.NewCore( 57 | zapcore.NewJSONEncoder(encoderCfg), 58 | zapcore.Lock(os.Stdout), 59 | atom, 60 | )) 61 | atom.SetLevel(drv.DebugLevel) 62 | ctx := context.WithValue(context.Background(), drv.LoggerKey, logger) 63 | rows, err := db.QueryContext(ctx, query) 64 | if err != nil { 65 | panic(err) 66 | } 67 | defer rows.Close() 68 | println(drv.ColsRowsToCSV(rows)) 69 | } 70 | 71 | /* 72 | select TIMESTAMP '2001-08-22 03:04:05.321 PDT'; 73 | SYNTAX_ERROR: line 1:145: '2001-08-22 03:04:05.321 PDT' is not a valid timestamp literal 74 | 75 | Sample output: 76 | _col0,_col1,_col2,_col3,_col4,_col5 77 | 2 00:00:00.000,0-3,0000-01-01T01:02:03.456-07:52,0000-01-01T01:02:03.456-07:52,2001-08-22T03:04:05.321-07:00,2001-08-22T03:04:05.321-07:00 78 | */ 79 | -------------------------------------------------------------------------------- /examples/workgroup_with_tag.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package main 22 | 23 | import ( 24 | "database/sql" 25 | "log" 26 | 27 | secret "github.com/uber/athenadriver/examples/constants" 28 | 29 | drv "github.com/uber/athenadriver/go" 30 | ) 31 | 32 | func main() { 33 | // 1. Set AWS Credential in Driver Config. 34 | conf, err := drv.NewDefaultConfig(secret.OutputBucket, secret.Region, 35 | secret.AccessID, secret.SecretAccessKey) 36 | if err != nil { 37 | log.Fatal(err) 38 | return 39 | } 40 | 41 | wgTags := drv.NewWGTags() 42 | wgTags.AddTag("Uber User", "henry.wu") 43 | wgTags.AddTag("Uber ID", "123456") 44 | wgTags.AddTag("Uber Role", "SDE") 45 | // Specify workgroup name henry_wu should be used for the following query 46 | wg := drv.NewWG("henry_wu", nil, wgTags) 47 | _ = conf.SetWorkGroup(wg) 48 | // comment out the line below to allow remote workgroup creation and the query will be successful!!! 49 | //conf.SetWGRemoteCreationAllowed(false) 50 | 51 | // 2. Open Connection. 52 | dsn := conf.Stringify() 53 | db, _ := sql.Open(drv.DriverName, dsn) 54 | // 3. Query and print results 55 | rows, err := db.Query("select request_timestamp, url from sampledb.elb_logs limit 3") 56 | if err != nil { 57 | log.Fatal(err) 58 | return 59 | } 60 | defer rows.Close() 61 | 62 | var requestTimestamp string 63 | var url string 64 | for rows.Next() { 65 | if err := rows.Scan(&requestTimestamp, &url); err != nil { 66 | log.Fatal(err) 67 | } 68 | println(requestTimestamp + "," + url) 69 | } 70 | } 71 | 72 | /* 73 | Sample Output: 74 | 2020/01/20 15:29:52 Workgroup henry_wu doesn't exist and workgroup remote creation is disabled. 75 | 76 | After commenting out `conf.SetWGRemoteCreationAllowed(false)` at line 27: 77 | 2015-01-07T16:00:00.516940Z,https://www.example.com/articles/553 78 | 2015-01-07T16:00:00.902953Z,http://www.example.com/images/501 79 | 2015-01-07T16:00:01.206255Z,https://www.example.com/images/183 80 | 81 | and you will see a new workgroup named `henry_wu` is created in AWS Athena console: https://us-east-2.console.aws.amazon.com/athena/workgroups/home?region=us-east-2 82 | */ 83 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/uber/athenadriver 2 | 3 | go 1.13 4 | 5 | require ( 6 | github.com/DATA-DOG/go-sqlmock v1.4.1 7 | github.com/aws/aws-sdk-go v1.51.3 8 | github.com/cactus/go-statsd-client/statsd v0.0.0-20200423205355-cb0885a1018c 9 | github.com/jedib0t/go-pretty/v6 v6.2.7 10 | github.com/stretchr/testify v1.9.0 11 | github.com/uber-go/tally/v4 v4.1.17 12 | github.com/xwb1989/sqlparser v0.0.0-20180606152119-120387863bf2 13 | go.uber.org/config v1.4.0 14 | go.uber.org/fx v1.12.0 15 | go.uber.org/zap v1.15.0 16 | ) 17 | -------------------------------------------------------------------------------- /go/cache.go: -------------------------------------------------------------------------------- 1 | package athenadriver 2 | 3 | // QIDMetaData is the meta data for QID 4 | type QIDMetaData struct { 5 | QID string 6 | dataScanned int64 7 | timestamp int64 8 | } 9 | 10 | // AthenaCache is for Cached Query 11 | type AthenaCache interface { 12 | // SetQID is to put query -> QIDMetaData into cache 13 | SetQID(query string, data QIDMetaData) 14 | 15 | // GetQID is to get QIDMetaData from cache by query string 16 | GetQID(query string) QIDMetaData 17 | 18 | // GetQuery is to get query string from cache by QID 19 | GetQuery(QID string) string 20 | } 21 | -------------------------------------------------------------------------------- /go/connector.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package athenadriver 22 | 23 | import ( 24 | "context" 25 | "database/sql/driver" 26 | 27 | "os" 28 | "strconv" 29 | "time" 30 | 31 | "github.com/uber-go/tally/v4" 32 | "go.uber.org/zap" 33 | 34 | "github.com/aws/aws-sdk-go/aws" 35 | "github.com/aws/aws-sdk-go/aws/credentials" 36 | "github.com/aws/aws-sdk-go/aws/session" 37 | "github.com/aws/aws-sdk-go/service/athena" 38 | ) 39 | 40 | // SQLConnector is the connector for AWS Athena Driver. 41 | type SQLConnector struct { 42 | config *Config 43 | tracer *DriverTracer 44 | } 45 | 46 | // NoopsSQLConnector is to create a noops SQLConnector. 47 | func NoopsSQLConnector() *SQLConnector { 48 | noopsConfig := NewNoOpsConfig() 49 | return &SQLConnector{ 50 | config: noopsConfig, 51 | tracer: NewDefaultObservability(noopsConfig), 52 | } 53 | } 54 | 55 | // Driver is to construct a new SQLConnector. 56 | func (c *SQLConnector) Driver() driver.Driver { 57 | return &SQLDriver{} 58 | } 59 | 60 | // Connect is to create an AWS session. 61 | // The order to find auth information to create session is: 62 | // 1. Manually set AWS profile in Config by calling config.SetAWSProfile(profileName) 63 | // 2. AWS_SDK_LOAD_CONFIG 64 | // 3. Static Credentials 65 | // Ref: https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html 66 | func (c *SQLConnector) Connect(ctx context.Context) (driver.Conn, error) { 67 | now := time.Now() 68 | c.tracer = NewDefaultObservability(c.config) 69 | if metrics, ok := ctx.Value(MetricsKey).(tally.Scope); ok { 70 | c.tracer.SetScope(metrics) 71 | } 72 | if logger, ok := ctx.Value(LoggerKey).(*zap.Logger); ok { 73 | c.tracer.SetLogger(logger) 74 | } 75 | 76 | var awsAthenaSession *session.Session 77 | var err error 78 | // respect AWS_SDK_LOAD_CONFIG and local ~/.aws/credentials, ~/.aws/config 79 | if ok, _ := strconv.ParseBool(os.Getenv("AWS_SDK_LOAD_CONFIG")); ok { 80 | if profile := c.config.GetAWSProfile(); profile != "" { 81 | awsAthenaSession, err = session.NewSession(&aws.Config{ 82 | Credentials: credentials.NewSharedCredentials("", profile), 83 | }) 84 | } else { 85 | awsAthenaSession, err = session.NewSession(&aws.Config{}) 86 | } 87 | } else if c.config.GetAccessID() != "" { 88 | staticCredentials := credentials.NewStaticCredentials(c.config.GetAccessID(), 89 | c.config.GetSecretAccessKey(), 90 | c.config.GetSessionToken()) 91 | awsConfig := &aws.Config{ 92 | Region: aws.String(c.config.GetRegion()), 93 | Credentials: staticCredentials, 94 | } 95 | awsAthenaSession, err = session.NewSession(awsConfig) 96 | } else { 97 | awsAthenaSession, err = session.NewSession(&aws.Config{ 98 | Region: aws.String(c.config.GetRegion()), 99 | }) 100 | } 101 | if err != nil { 102 | c.tracer.Scope().Counter(DriverName + ".failure.sqlconnector.newsession").Inc(1) 103 | return nil, err 104 | } 105 | 106 | athenaAPI := athena.New(awsAthenaSession) 107 | timeConnect := time.Since(now) 108 | conn := &Connection{ 109 | athenaAPI: athenaAPI, 110 | connector: c, 111 | } 112 | c.tracer.Scope().Timer(DriverName + ".connector.connect").Record(timeConnect) 113 | return conn, nil 114 | } 115 | -------------------------------------------------------------------------------- /go/datetime.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package athenadriver 22 | 23 | import ( 24 | "fmt" 25 | "strings" 26 | "time" 27 | "unicode" 28 | ) 29 | 30 | // AthenaTime represents a time.Time value that can be null. 31 | // The AthenaTime supports Athena's Date, Time and Timestamp data types, 32 | // with or without time zone. 33 | type AthenaTime struct { 34 | Time time.Time 35 | Valid bool 36 | } 37 | 38 | var timeLayouts = []string{ 39 | "2006-01-02", 40 | "15:04:05.000", 41 | "2006-01-02 15:04:05.000000000", 42 | "2006-01-02 15:04:05.000000", 43 | "2006-01-02 15:04:05.000", 44 | } 45 | 46 | func scanTime(vv string) (AthenaTime, error) { 47 | parts := strings.Split(vv, " ") 48 | if len(parts) > 1 && !unicode.IsDigit(rune(parts[len(parts)-1][0])) { 49 | return parseAthenaTimeWithLocation(vv) 50 | } 51 | return parseAthenaTime(vv) 52 | } 53 | 54 | func parseAthenaTime(v string) (AthenaTime, error) { 55 | var t time.Time 56 | var err error 57 | for _, layout := range timeLayouts { 58 | t, err = time.ParseInLocation(layout, v, time.Local) 59 | if err == nil { 60 | return AthenaTime{Valid: true, Time: t}, nil 61 | } 62 | } 63 | return AthenaTime{}, err 64 | } 65 | 66 | func parseAthenaTimeWithLocation(v string) (AthenaTime, error) { 67 | idx := strings.LastIndex(v, " ") 68 | if idx == -1 { 69 | return AthenaTime{}, fmt.Errorf("cannot convert %v (%T) to time+zone", v, v) 70 | } 71 | stamp, location := v[:idx], v[idx+1:] 72 | loc, err := time.LoadLocation(location) 73 | if err != nil { 74 | return AthenaTime{}, fmt.Errorf("cannot load timezone %q: %v", location, err) 75 | } 76 | var t time.Time 77 | for _, layout := range timeLayouts { 78 | t, err = time.ParseInLocation(layout, stamp, loc) 79 | if err == nil { 80 | return AthenaTime{Valid: true, Time: t}, nil 81 | } 82 | } 83 | return AthenaTime{}, err 84 | } 85 | -------------------------------------------------------------------------------- /go/datetime_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package athenadriver 22 | 23 | import ( 24 | "testing" 25 | 26 | "github.com/stretchr/testify/assert" 27 | ) 28 | 29 | func TestDateTime_ScanTime(t *testing.T) { 30 | r, e := scanTime("01:02:03.456") 31 | assert.Nil(t, e) 32 | assert.True(t, r.Valid) 33 | assert.NotEqual(t, r.Time.String(), ZeroDateTimeString) 34 | } 35 | 36 | func TestDateTime_ScanTimeWithTimeZone(t *testing.T) { 37 | r, e := scanTime("01:02:03.456 America/Los_Angeles") 38 | assert.Nil(t, e) 39 | assert.True(t, r.Valid) 40 | assert.NotEqual(t, r.Time.String(), ZeroDateTimeString) 41 | 42 | } 43 | 44 | func TestDateTime_ScanTimeStamp(t *testing.T) { 45 | r, e := scanTime("2001-08-22 03:04:05.321") 46 | assert.Nil(t, e) 47 | assert.True(t, r.Valid) 48 | assert.NotEqual(t, r.Time.String(), ZeroDateTimeString) 49 | 50 | } 51 | 52 | func TestDateTime_ScanTimeStampWithMicroseconds(t *testing.T) { 53 | r, e := scanTime("2001-08-22 03:04:05.321456") 54 | assert.Nil(t, e) 55 | assert.True(t, r.Valid) 56 | assert.NotEqual(t, r.Time.String(), ZeroDateTimeString) 57 | } 58 | 59 | func TestDateTime_ScanTimeStampWithNanoseconds(t *testing.T) { 60 | r, e := scanTime("2001-08-22 03:04:05.321456789") 61 | assert.Nil(t, e) 62 | assert.True(t, r.Valid) 63 | assert.NotEqual(t, r.Time.String(), ZeroDateTimeString) 64 | } 65 | 66 | func TestDateTime_ScanTimeStampWithTimeZone(t *testing.T) { 67 | r, e := scanTime("2001-08-22 03:04:05.321 America/Los_Angeles") 68 | assert.Nil(t, e) 69 | assert.True(t, r.Valid) 70 | assert.NotEqual(t, r.Time.String(), ZeroDateTimeString) 71 | } 72 | 73 | func TestDateTime_ScanTimeFail(t *testing.T) { 74 | r, e := scanTime("2001-08-22 03:04:05.321 PST") 75 | assert.NotNil(t, e) 76 | assert.False(t, r.Valid) 77 | assert.Equal(t, r.Time.String(), ZeroDateTimeString) 78 | 79 | r, e = scanTime("abc") 80 | assert.NotNil(t, e) 81 | assert.False(t, r.Valid) 82 | assert.Equal(t, r.Time.String(), ZeroDateTimeString) 83 | } 84 | 85 | func TestDateTime_ScanTimeFail_MonthOutOfRange(t *testing.T) { 86 | r, e := scanTime("2001-18-22 03:04:05.321 America/Los_Angeles") 87 | assert.NotNil(t, e) 88 | assert.False(t, r.Valid) 89 | assert.Equal(t, r.Time.String(), ZeroDateTimeString) 90 | } 91 | 92 | func TestDateTime_ParseAthenaTimeWithLocation(t *testing.T) { 93 | r, e := parseAthenaTimeWithLocation("abc") 94 | assert.NotNil(t, e) 95 | assert.False(t, r.Valid) 96 | assert.Equal(t, r.Time.String(), ZeroDateTimeString) 97 | 98 | r, e = parseAthenaTimeWithLocation("ab c") 99 | assert.NotNil(t, e) 100 | assert.False(t, r.Valid) 101 | assert.Equal(t, r.Time.String(), ZeroDateTimeString) 102 | } 103 | -------------------------------------------------------------------------------- /go/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | // Package athenadriver is a fully-featured Go database/sql driver for 22 | // Amazon AWS Athena developed at Uber Technologies Inc. 23 | // 24 | // It provides a hassle-free way of querying AWS Athena database with Go 25 | // standard library. It not only provides basic features of Athena Go SDK, but 26 | // addresses some of its limitation, improves and extends it.Except the basic 27 | // features provided by Go database/sql like error handling, database pool 28 | // and reconnection, athenadriver supports the following features out of box: 29 | // 30 | // - Support multiple AWS authorization methods 31 | // - Full support of Athena Basic Data Types 32 | // - Full support of Athena Advanced Type for queries with Geospatial identifiers, ML and UDFs 33 | // - Full support of ALL Athena Query Statements, including DDL, DML and UTILITY 34 | // - Support newly added INSERT INTO...VALUES 35 | // - Full support of Athena Basic Data Types 36 | // - Athena workgroup and tagging support including remote workgroup creation 37 | // - Go sql's Prepared statement support 38 | // - Go sql's DB.Exec() and db.ExecContext() support 39 | // - Query cancelling support 40 | // - Mask columns with specific values 41 | // - Database missing value handling 42 | // - Read-Only mode 43 | // 44 | // Amazon Athena is an interactive query service that lets you use standard 45 | // SQL to analyze data directly in Amazon S3. You can point Athena at your data 46 | // in Amazon S3 and run ad-hoc queries and get results in seconds. Athena is 47 | // serverless, so there is no infrastructure to set up or manage. You pay only 48 | // for the queries you run. Athena scales automatically—executing queries 49 | // in parallel—so results are fast, even with large datasets and complex queries. 50 | // Author: Henry Fuheng Wu (wufuheng@gmail.com, henry.wu@uber.com) 51 | package athenadriver 52 | -------------------------------------------------------------------------------- /go/driver.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package athenadriver 22 | 23 | import ( 24 | "context" 25 | "database/sql" 26 | "database/sql/driver" 27 | ) 28 | 29 | // SQLDriver is an implementation of sql/driver interface for AWS Athena. 30 | // https://vyskocilm.github.io/blog/implement-sql-database-driver-in-100-lines-of-go/ 31 | // https://golang.org/pkg/database/sql/driver/#Driver 32 | type SQLDriver struct { 33 | conn *SQLConnector 34 | } 35 | 36 | func init() { 37 | sql.Register(DriverName, &SQLDriver{}) 38 | } 39 | 40 | // Open returns a new connection to AWS Athena. 41 | // The dsn is a string in a driver-specific format. 42 | // the sql package maintains a pool of idle connections for efficient re-use. 43 | // The returned connection is only used by one goroutine at a time. 44 | func (d *SQLDriver) Open(dsn string) (driver.Conn, error) { 45 | config, err := NewConfig(dsn) 46 | if err != nil { 47 | return nil, err 48 | } 49 | c := &SQLConnector{ 50 | config: config, 51 | } 52 | return c.Connect(context.Background()) 53 | } 54 | 55 | // OpenConnector will be called upon query execution. 56 | // If a Driver implements DriverContext.OpenConnector, then sql.DB will call 57 | // OpenConnector to obtain a Connector and then invoke 58 | // that Connector's Conn method to obtain each needed connection, 59 | // instead of invoking the Driver's Open method for each connection. 60 | // The two-step sequence allows drivers to parse the name just once 61 | // and also provides access to per-Conn contexts. 62 | func (d *SQLDriver) OpenConnector(dsn string) (driver.Connector, error) { 63 | config, err := NewConfig(dsn) 64 | d.conn = &SQLConnector{ 65 | config: config, 66 | } 67 | return d.conn, err 68 | } 69 | -------------------------------------------------------------------------------- /go/driver_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package athenadriver 22 | 23 | import ( 24 | "database/sql" 25 | "testing" 26 | 27 | "github.com/stretchr/testify/assert" 28 | ) 29 | 30 | func TestDriver(t *testing.T) { 31 | dsn := "s3://henry.wu%40uber.com:@fake-query-results-arbitrary-bucket?db=default&" + 32 | "region=us-east-1&workgroup_config=%7B%0A++BytesScannedCutoffPerQuery%3A+1073741824%2C%0A++Enfo" + 33 | "rceWorkGroupConfiguration%3A+true%2C%0A++PublishCloudWatchMetricsEnabled%3A+true%2C%0A++Reques" + 34 | "terPaysEnabled%3A+false%0A%7D&workgroupName=henry_wu" 35 | pDB, err := sql.Open(DriverName, dsn) 36 | assert.Nil(t, err) 37 | assert.NotNil(t, pDB) 38 | 39 | pDB, err = sql.Open(DriverName+"x", "") 40 | assert.NotNil(t, err) 41 | assert.Nil(t, pDB) 42 | } 43 | 44 | func TestSQLDriver_Open(t *testing.T) { 45 | s := SQLDriver{ 46 | conn: NoopsSQLConnector(), 47 | } 48 | testConf := NewNoOpsConfig() 49 | c, e := s.Open(testConf.Stringify()) 50 | assert.Nil(t, e) 51 | assert.NotNil(t, c) 52 | 53 | s2 := SQLDriver{ 54 | conn: NoopsSQLConnector(), 55 | } 56 | c, e = s2.Open("") 57 | assert.Nil(t, c) 58 | assert.NotNil(t, e) 59 | } 60 | 61 | func TestSQLDriver_OpenConnector(t *testing.T) { 62 | s := SQLDriver{ 63 | conn: NoopsSQLConnector(), 64 | } 65 | testConf := NewNoOpsConfig() 66 | c, e := s.OpenConnector(testConf.Stringify()) 67 | assert.Nil(t, e) 68 | assert.NotNil(t, c) 69 | } 70 | -------------------------------------------------------------------------------- /go/errors.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package athenadriver 22 | 23 | import ( 24 | "errors" 25 | "fmt" 26 | ) 27 | 28 | // Various errors the driver might return. Can change between driver versions. 29 | var ( 30 | ErrInvalidQuery = errors.New("query is not valid") 31 | ErrConfigInvalidConfig = errors.New("driver config is invalid") 32 | ErrConfigOutputLocation = errors.New("output location must starts with s3") 33 | ErrConfigRegion = errors.New("region is required") 34 | ErrConfigWGPointer = errors.New("workgroup pointer is nil") 35 | ErrConfigAccessIDRequired = errors.New("AWS access ID is required") 36 | ErrConfigAccessKeyRequired = errors.New("AWS access Key is required") 37 | ErrQueryUnknownType = errors.New("query parameter type is unknown") 38 | ErrQueryBufferOF = errors.New("query buffer overflow") 39 | ErrQueryTimeout = errors.New("query timeout") 40 | ErrAthenaTransactionUnsupported = errors.New("Athena doesn't support transaction statements") 41 | ErrAthenaNilDatum = errors.New("*athena.Datum must not be nil") 42 | ErrAthenaNilAPI = errors.New("athenaAPI must not be nil") 43 | ErrTestMockGeneric = errors.New("some_mock_error_for_test") 44 | ErrTestMockFailedByAthena = errors.New("the reason why Athena failed the query") 45 | ErrServiceLimitOverride = fmt.Errorf("service limit override must be greater than %d", PoolInterval) 46 | ) 47 | -------------------------------------------------------------------------------- /go/result.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package athenadriver 22 | 23 | // AthenaResult is the result of an Athena query execution. 24 | type AthenaResult struct { 25 | lastInsertedID int64 26 | rowAffected int64 27 | } 28 | 29 | // LastInsertId returns the database's auto-generated ID 30 | // after, for example, an INSERT into a table with primary 31 | // key. For Athena, it is nil as Athena Go SDK doesn't support it. 32 | func (a AthenaResult) LastInsertId() (int64, error) { 33 | return -1, nil 34 | } 35 | 36 | // RowsAffected returns the number of rows affected by the query. 37 | func (a AthenaResult) RowsAffected() (int64, error) { 38 | return a.rowAffected, nil 39 | } 40 | -------------------------------------------------------------------------------- /go/result_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package athenadriver 22 | 23 | import ( 24 | "testing" 25 | 26 | "github.com/stretchr/testify/assert" 27 | ) 28 | 29 | func TestAthenaResult_LastInsertId(t *testing.T) { 30 | a := AthenaResult{} 31 | r, e := a.LastInsertId() 32 | assert.Equal(t, r, int64(-1)) 33 | assert.Nil(t, e) 34 | } 35 | 36 | func TestAthenaResult_RowsAffected(t *testing.T) { 37 | a := AthenaResult{} 38 | r, e := a.RowsAffected() 39 | assert.Equal(t, r, int64(0)) 40 | assert.Nil(t, e) 41 | } 42 | -------------------------------------------------------------------------------- /go/servicelimitoverride.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package athenadriver 22 | 23 | import ( 24 | "fmt" 25 | "net/url" 26 | "strconv" 27 | ) 28 | 29 | // ServiceLimitOverride allows users to override service limits, hardcoded in constants.go. 30 | // This assumes the service limits have been raised in the AWS account. 31 | // https://docs.aws.amazon.com/athena/latest/ug/service-limits.html 32 | type ServiceLimitOverride struct { 33 | ddlQueryTimeout int 34 | dmlQueryTimeout int 35 | } 36 | 37 | // NewServiceLimitOverride is to create an empty ServiceLimitOverride. 38 | // Values can be set using setters. 39 | func NewServiceLimitOverride() *ServiceLimitOverride { 40 | return &ServiceLimitOverride{} 41 | } 42 | 43 | // SetDDLQueryTimeout is to set the DDLQueryTimeout override. 44 | func (c *ServiceLimitOverride) SetDDLQueryTimeout(seconds int) error { 45 | if seconds < PoolInterval { 46 | return ErrServiceLimitOverride 47 | } 48 | c.ddlQueryTimeout = seconds 49 | return nil 50 | } 51 | 52 | // GetDDLQueryTimeout is to get the DDLQueryTimeout override. 53 | func (c *ServiceLimitOverride) GetDDLQueryTimeout() int { 54 | return c.ddlQueryTimeout 55 | } 56 | 57 | // SetDMLQueryTimeout is to set the DMLQueryTimeout override. 58 | func (c *ServiceLimitOverride) SetDMLQueryTimeout(seconds int) error { 59 | if seconds < PoolInterval { 60 | return ErrServiceLimitOverride 61 | } 62 | c.dmlQueryTimeout = seconds 63 | return nil 64 | } 65 | 66 | // GetDMLQueryTimeout is to get the DMLQueryTimeout override. 67 | func (c *ServiceLimitOverride) GetDMLQueryTimeout() int { 68 | return c.dmlQueryTimeout 69 | } 70 | 71 | // GetAsStringMap is to get the ServiceLimitOverride as a map of strings 72 | // and aids in setting url.Values in Config 73 | func (c *ServiceLimitOverride) GetAsStringMap() map[string]string { 74 | res := map[string]string{} 75 | res["DDLQueryTimeout"] = fmt.Sprintf("%d", c.ddlQueryTimeout) 76 | res["DMLQueryTimeout"] = fmt.Sprintf("%d", c.dmlQueryTimeout) 77 | return res 78 | } 79 | 80 | // SetFromValues is to set ServiceLimitOverride properties from a url.Values 81 | // which might be a list of override and other ignored values from a dsn 82 | func (c *ServiceLimitOverride) SetFromValues(kvp url.Values) { 83 | ddlQueryTimeout, _ := strconv.Atoi(kvp.Get("DDLQueryTimeout")) 84 | _ = c.SetDDLQueryTimeout(ddlQueryTimeout) 85 | dmlQueryTimeout, _ := strconv.Atoi(kvp.Get("DMLQueryTimeout")) 86 | _ = c.SetDMLQueryTimeout(dmlQueryTimeout) 87 | } 88 | -------------------------------------------------------------------------------- /go/servicelimitoverride_test.go: -------------------------------------------------------------------------------- 1 | package athenadriver 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | "testing" 6 | ) 7 | 8 | // Tests for ServiceLimitOverride. 9 | func TestNewServiceLimitOverride(t *testing.T) { 10 | testConf := NewServiceLimitOverride() 11 | assert.Zero(t, testConf.GetDDLQueryTimeout()) 12 | assert.Zero(t, testConf.GetDMLQueryTimeout()) 13 | 14 | ddlQueryTimeout := 30 * 60 // seconds 15 | dmlQueryTimeout := 60 * 60 // seconds 16 | testConf.SetDDLQueryTimeout(ddlQueryTimeout) 17 | assert.Equal(t, ddlQueryTimeout, testConf.GetDDLQueryTimeout()) // seconds 18 | 19 | testConf.SetDMLQueryTimeout(dmlQueryTimeout) 20 | assert.Equal(t, dmlQueryTimeout, testConf.GetDMLQueryTimeout()) // seconds 21 | 22 | ddlQueryTimeout = 0 23 | dmlQueryTimeout = 0 24 | err := testConf.SetDDLQueryTimeout(ddlQueryTimeout) 25 | assert.NotNil(t, err) 26 | 27 | err = testConf.SetDMLQueryTimeout(dmlQueryTimeout) 28 | assert.NotNil(t, err) 29 | 30 | ddlQueryTimeout = -1 31 | dmlQueryTimeout = -1 32 | err = testConf.SetDDLQueryTimeout(ddlQueryTimeout) 33 | assert.NotNil(t, err) 34 | 35 | err = testConf.SetDMLQueryTimeout(dmlQueryTimeout) 36 | assert.NotNil(t, err) 37 | } 38 | -------------------------------------------------------------------------------- /go/statement.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package athenadriver 22 | 23 | import ( 24 | "context" 25 | "database/sql/driver" 26 | "strings" 27 | ) 28 | 29 | // Statement is to implement Go's database/sql Statement. 30 | type Statement struct { 31 | connection *Connection 32 | closed bool 33 | query string 34 | numInput int 35 | } 36 | 37 | // Close is to close an open statement. 38 | func (s *Statement) Close() error { 39 | if s.connection == nil || s.closed { 40 | // driver.Stmt.Close can be called more than once, thus this function 41 | // has to be idempotent. 42 | // See also Issue #450 and golang/go#16019. 43 | return driver.ErrBadConn 44 | } 45 | s.query = "" 46 | s.closed = true 47 | s.numInput = 0 48 | return nil 49 | } 50 | 51 | // NumInput returns the number of prepared arguments. 52 | // It may also return -1, if the driver doesn't know 53 | // its number of placeholders. In that case, the sql package 54 | // will not sanity check Exec or Query argument counts. 55 | // -- From Go `sql/driver` 56 | func (s *Statement) NumInput() int { 57 | if s.numInput == 0 { 58 | s.numInput = strings.Count(s.query, "?") 59 | } 60 | return s.numInput 61 | } 62 | 63 | // ColumnConverter is to return driver's DefaultParameterConverter. 64 | func (s *Statement) ColumnConverter(idx int) driver.ValueConverter { 65 | return driver.DefaultParameterConverter 66 | } 67 | 68 | // Exec is to execute a prepared statement. 69 | func (s *Statement) Exec(args []driver.Value) (driver.Result, error) { 70 | if s.closed { 71 | return nil, driver.ErrBadConn 72 | } 73 | r, e := s.connection.ExecContext(context.Background(), s.query, 74 | valueToNamedValue(args)) 75 | s.closed = true 76 | return r, e 77 | } 78 | 79 | // Query is to query based on a prepared statement. 80 | func (s *Statement) Query(args []driver.Value) (driver.Rows, error) { 81 | if s.closed { 82 | return nil, driver.ErrBadConn 83 | } 84 | r, e := s.connection.QueryContext(context.Background(), s.query, 85 | valueToNamedValue(args)) 86 | s.closed = true 87 | return r, e 88 | } 89 | -------------------------------------------------------------------------------- /go/trace.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package athenadriver 22 | 23 | import ( 24 | "github.com/uber-go/tally/v4" 25 | "go.uber.org/zap" 26 | "go.uber.org/zap/zapcore" 27 | ) 28 | 29 | const ( 30 | // DebugLevel logs are typically voluminous, and are usually disabled in 31 | // production. 32 | DebugLevel = zap.DebugLevel 33 | // InfoLevel is the default logging priority. 34 | InfoLevel = zap.InfoLevel 35 | // WarnLevel logs are more important than Info, but don't need individual 36 | // human review. 37 | WarnLevel = zap.WarnLevel 38 | // ErrorLevel logs are high-priority. If an application is running smoothly, 39 | // it shouldn't generate any error-level logs. 40 | // DPanicLevel, PanicLevel and FatalLevel are not allowed in this package 41 | // to avoid terminating the whole process 42 | ErrorLevel = zap.ErrorLevel 43 | ) 44 | 45 | // DriverTracer is supported in athenadriver builtin. 46 | type DriverTracer struct { 47 | logger *zap.Logger 48 | scope tally.Scope 49 | config *Config 50 | } 51 | 52 | // NewObservability is to create an observability object. 53 | func NewObservability(config *Config, logger *zap.Logger, 54 | scope tally.Scope) *DriverTracer { 55 | o := DriverTracer{ 56 | logger: logger, 57 | scope: scope, 58 | config: config, 59 | } 60 | return &o 61 | } 62 | 63 | // NewDefaultObservability is to create an observability object with logger 64 | // and scope as default(noops object). 65 | func NewDefaultObservability(config *Config) *DriverTracer { 66 | o := DriverTracer{ 67 | logger: zap.NewNop(), 68 | scope: tally.NoopScope, 69 | config: config, 70 | } 71 | return &o 72 | } 73 | 74 | // NewNoOpsObservability is for testing purpose. 75 | func NewNoOpsObservability() *DriverTracer { 76 | o := DriverTracer{ 77 | logger: zap.NewNop(), 78 | scope: tally.NoopScope, 79 | config: NewNoOpsConfig(), 80 | } 81 | return &o 82 | } 83 | 84 | // Logger is a getter of logger. 85 | func (c *DriverTracer) Logger() *zap.Logger { 86 | if !c.config.IsLoggingEnabled() { 87 | return zap.NewNop() 88 | } 89 | return c.logger 90 | } 91 | 92 | // SetLogger is a setter of logger. 93 | func (c *DriverTracer) SetLogger(logger *zap.Logger) { 94 | c.logger = logger 95 | } 96 | 97 | // Scope is a getter of tally.Scope. 98 | func (c *DriverTracer) Scope() tally.Scope { 99 | if !c.config.IsMetricsEnabled() { 100 | return tally.NoopScope 101 | } 102 | return c.scope 103 | } 104 | 105 | // SetScope is a setter of tally.Scope. 106 | func (c *DriverTracer) SetScope(scope tally.Scope) { 107 | c.scope = scope 108 | } 109 | 110 | // Config is to get c.config 111 | func (c *DriverTracer) Config() *Config { 112 | return c.config 113 | } 114 | 115 | // Log is to log with zap.logger with 4 logging levels. 116 | // We threw away the panic and fatal level as we don't want to DB error terminates the whole process. 117 | func (c *DriverTracer) Log(lvl zapcore.Level, msg string, fields ...zap.Field) { 118 | if !c.config.IsLoggingEnabled() { 119 | return 120 | } 121 | switch lvl { 122 | case DebugLevel: 123 | c.logger.Debug(msg, fields...) 124 | case WarnLevel: 125 | c.logger.Warn(msg, fields...) 126 | case InfoLevel: 127 | c.logger.Info(msg, fields...) 128 | case ErrorLevel, zap.DPanicLevel, zap.PanicLevel, zap.FatalLevel: 129 | c.logger.Error(msg, fields...) 130 | 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /go/trace_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package athenadriver 22 | 23 | import ( 24 | "testing" 25 | 26 | "github.com/stretchr/testify/assert" 27 | "github.com/uber-go/tally/v4" 28 | "go.uber.org/zap" 29 | ) 30 | 31 | func TestObservability_Config(t *testing.T) { 32 | obs := NewNoOpsObservability() 33 | assert.Equal(t, obs.Config(), NewNoOpsConfig()) 34 | } 35 | 36 | func TestObservability_Scope(t *testing.T) { 37 | obs := NewNoOpsObservability() 38 | assert.Equal(t, obs.Scope(), tally.NoopScope) 39 | 40 | config := NewNoOpsConfig() 41 | config.SetMetrics(true) 42 | obs = NewDefaultObservability(config) 43 | assert.Equal(t, obs.Scope(), tally.NoopScope) 44 | } 45 | 46 | func TestObservability_Logger(t *testing.T) { 47 | obs := NewNoOpsObservability() 48 | assert.Equal(t, obs.Logger(), zap.NewNop()) 49 | 50 | config := NewNoOpsConfig() 51 | config.SetLogging(false) 52 | obs = NewDefaultObservability(config) 53 | assert.Equal(t, obs.Logger(), zap.NewNop()) 54 | } 55 | 56 | func TestObservability_Log(t *testing.T) { 57 | config := NewNoOpsConfig() 58 | config.SetLogging(false) 59 | obs := NewDefaultObservability(config) 60 | obs.Log(-1, "") 61 | config.SetLogging(true) 62 | obs = NewDefaultObservability(config) 63 | obs.Log(-1, "") 64 | obs.Log(ErrorLevel, "") 65 | obs.Log(WarnLevel, "") 66 | obs.Log(InfoLevel, "") 67 | obs.Log(DebugLevel, "") 68 | } 69 | 70 | func TestObservability_SetScope(t *testing.T) { 71 | obs := NewNoOpsObservability() 72 | obs.SetScope(tally.NoopScope) 73 | assert.Equal(t, obs.Scope(), tally.NoopScope) 74 | } 75 | 76 | func TestObservability_SetLogger(t *testing.T) { 77 | obs := NewNoOpsObservability() 78 | obs.SetLogger(nil) 79 | assert.Nil(t, obs.Logger()) 80 | } 81 | 82 | func TestObservability_NewObservability(t *testing.T) { 83 | obs := NewObservability(NewNoOpsConfig(), zap.NewNop(), tally.NoopScope) 84 | assert.NotNil(t, obs.Logger()) 85 | assert.Equal(t, obs.Logger(), zap.NewNop()) 86 | } 87 | -------------------------------------------------------------------------------- /go/version.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package athenadriver 22 | 23 | // Version of the library. 24 | const Version = "0.1.0" 25 | -------------------------------------------------------------------------------- /go/wg.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package athenadriver 22 | 23 | import ( 24 | "context" 25 | 26 | "github.com/aws/aws-sdk-go/aws" 27 | "github.com/aws/aws-sdk-go/service/athena" 28 | "github.com/aws/aws-sdk-go/service/athena/athenaiface" 29 | ) 30 | 31 | // Workgroup is a wrapper of Athena Workgroup. 32 | type Workgroup struct { 33 | Name string 34 | Config *athena.WorkGroupConfiguration 35 | Tags *WGTags 36 | } 37 | 38 | // NewDefaultWG is to create new default Workgroup. 39 | func NewDefaultWG(name string, config *athena.WorkGroupConfiguration, tags *WGTags) *Workgroup { 40 | wg := Workgroup{ 41 | Name: name, 42 | Config: config, 43 | } 44 | if config == nil { 45 | wg.Config = GetDefaultWGConfig() 46 | } 47 | if tags != nil { 48 | wg.Tags = tags 49 | } else { 50 | wg.Tags = NewWGTags() 51 | } 52 | return &wg 53 | } 54 | 55 | // NewWG is to create a new Workgroup. 56 | func NewWG(name string, config *athena.WorkGroupConfiguration, tags *WGTags) *Workgroup { 57 | return &Workgroup{ 58 | Name: name, 59 | Config: config, 60 | Tags: tags, 61 | } 62 | } 63 | 64 | // getWG is to get Athena Workgroup from AWS remotely. 65 | func getWG(ctx context.Context, athenaService athenaiface.AthenaAPI, Name string) (*athena.WorkGroup, error) { 66 | if athenaService == nil { 67 | return nil, ErrAthenaNilAPI 68 | } 69 | getWorkGroupOutput, err := athenaService.GetWorkGroupWithContext(ctx, 70 | &athena.GetWorkGroupInput{ 71 | WorkGroup: aws.String(Name), 72 | }) 73 | if err != nil { 74 | return nil, err 75 | } 76 | return getWorkGroupOutput.WorkGroup, nil 77 | } 78 | 79 | // CreateWGRemotely is to create a Workgroup remotely. 80 | func (w *Workgroup) CreateWGRemotely(athenaService athenaiface.AthenaAPI) error { 81 | tags := w.Tags.Get() 82 | var err error 83 | if len(tags) == 0 { 84 | _, err = athenaService.CreateWorkGroup(&athena.CreateWorkGroupInput{ 85 | Configuration: w.Config, 86 | Name: aws.String(w.Name), 87 | }) 88 | } else { 89 | _, err = athenaService.CreateWorkGroup(&athena.CreateWorkGroupInput{ 90 | Configuration: w.Config, 91 | Name: aws.String(w.Name), 92 | Tags: w.Tags.Get(), 93 | }) 94 | } 95 | return err 96 | } 97 | -------------------------------------------------------------------------------- /go/wg_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package athenadriver 22 | 23 | import ( 24 | "context" 25 | "testing" 26 | 27 | "github.com/stretchr/testify/assert" 28 | ) 29 | 30 | func TestNewWG(t *testing.T) { 31 | wgTags := NewWGTags() 32 | wgTags.AddTag("Uber User", "henry.wu") 33 | wgTags.AddTag("Uber ID", "123456") 34 | wgTags.AddTag("Uber Role", "SDE") 35 | wg := NewWG("henry_wu", nil, wgTags) 36 | assert.Equal(t, wg.Name, "henry_wu") 37 | assert.Equal(t, len(wg.Tags.Get()), 3) 38 | } 39 | 40 | func TestGetWG(t *testing.T) { 41 | w, e := getWG(context.Background(), nil, "SELECT_OK") 42 | assert.Nil(t, w) 43 | assert.NotNil(t, e) 44 | 45 | athenaClient := newMockAthenaClient() 46 | w, e = getWG(context.Background(), athenaClient, "SELECT_OK") 47 | assert.Nil(t, w) 48 | assert.NotNil(t, e) 49 | 50 | athenaClient.GetWGStatus = true 51 | w, e = getWG(context.Background(), athenaClient, "SELECT_OK") 52 | assert.NotNil(t, w) 53 | assert.Nil(t, e) 54 | } 55 | 56 | func TestWorkgroup_CreateWGRemotely(t *testing.T) { 57 | wgTags := NewWGTags() 58 | wgTags.AddTag("Uber User", "henry.wu") 59 | wgTags.AddTag("Uber ID", "123456") 60 | wgTags.AddTag("Uber Role", "SDE") 61 | wg := NewWG("henry_wu", nil, wgTags) 62 | athenaClient := newMockAthenaClient() 63 | e := wg.CreateWGRemotely(athenaClient) 64 | assert.NotNil(t, e) 65 | athenaClient.CreateWGStatus = true 66 | e = wg.CreateWGRemotely(athenaClient) 67 | assert.Nil(t, e) 68 | } 69 | 70 | func TestWorkgroup_CreateWGRemotely2(t *testing.T) { 71 | wgTags := NewWGTags() 72 | wg := NewWG("henry_wu", nil, wgTags) 73 | athenaClient := newMockAthenaClient() 74 | e := wg.CreateWGRemotely(athenaClient) 75 | assert.NotNil(t, e) 76 | athenaClient.CreateWGStatus = true 77 | e = wg.CreateWGRemotely(athenaClient) 78 | assert.Nil(t, e) 79 | } 80 | -------------------------------------------------------------------------------- /go/wgconfig.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package athenadriver 22 | 23 | import "github.com/aws/aws-sdk-go/service/athena" 24 | 25 | // WGConfig wraps WorkGroupConfiguration. 26 | type WGConfig struct { 27 | wgConfig *athena.WorkGroupConfiguration 28 | } 29 | 30 | // GetDefaultWGConfig to create a default WorkGroupConfiguration. 31 | func GetDefaultWGConfig() *athena.WorkGroupConfiguration { 32 | var bytesScannedCutoffPerQuery int64 = DefaultBytesScannedCutoffPerQuery 33 | var enforceWorkGroupConfiguration bool = true 34 | var publishCloudWatchMetricsEnabled bool = true 35 | var requesterPaysEnabled bool = false 36 | return &athena.WorkGroupConfiguration{ 37 | BytesScannedCutoffPerQuery: &bytesScannedCutoffPerQuery, // 1G by default 38 | EnforceWorkGroupConfiguration: &enforceWorkGroupConfiguration, 39 | PublishCloudWatchMetricsEnabled: &publishCloudWatchMetricsEnabled, 40 | RequesterPaysEnabled: &requesterPaysEnabled, 41 | ResultConfiguration: nil, 42 | } 43 | } 44 | 45 | // NewWGConfig to create a WorkGroupConfiguration. 46 | func NewWGConfig(bytesScannedCutoffPerQuery int64, 47 | enforceWorkGroupConfiguration bool, 48 | publishCloudWatchMetricsEnabled bool, 49 | requesterPaysEnabled bool, 50 | resultConfiguration *athena.ResultConfiguration) *athena.WorkGroupConfiguration { 51 | return &athena.WorkGroupConfiguration{ 52 | BytesScannedCutoffPerQuery: &bytesScannedCutoffPerQuery, 53 | EnforceWorkGroupConfiguration: &enforceWorkGroupConfiguration, 54 | PublishCloudWatchMetricsEnabled: &publishCloudWatchMetricsEnabled, 55 | RequesterPaysEnabled: &requesterPaysEnabled, 56 | ResultConfiguration: resultConfiguration, 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /go/wgtag.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package athenadriver 22 | 23 | import "github.com/aws/aws-sdk-go/service/athena" 24 | 25 | // WGTags is a wrapper of []*athena.Tag. 26 | type WGTags struct { 27 | tags []*athena.Tag 28 | } 29 | 30 | // NewWGTags is to create a new WGTags. 31 | func NewWGTags() *WGTags { 32 | return &WGTags{tags: make([]*athena.Tag, 0, 2)} 33 | } 34 | 35 | // AddTag is to add tag. 36 | func (t *WGTags) AddTag(k string, v string) { 37 | t.tags = append(t.tags, &athena.Tag{ 38 | Key: &k, 39 | Value: &v}) 40 | } 41 | 42 | // Get is a getter. 43 | func (t *WGTags) Get() []*athena.Tag { 44 | if t == nil { 45 | return nil 46 | } 47 | return t.tags 48 | } 49 | -------------------------------------------------------------------------------- /lib/configfx/util.go: -------------------------------------------------------------------------------- 1 | package configfx 2 | 3 | import ( 4 | "context" 5 | "flag" 6 | "fmt" 7 | "io" 8 | "net/http" 9 | "os" 10 | ) 11 | 12 | func setUpFlagUsage(context.Context) error { 13 | os.Setenv("AWS_SDK_LOAD_CONFIG", "1") 14 | var commandLine = flag.NewFlagSet(os.Args[0], flag.ExitOnError) 15 | flag.Usage = func() { 16 | preBody := "NAME\n\tathenareader - read athena data from command line\n\n" 17 | desc := "\nEXAMPLES\n\n" + 18 | "\t$ athenareader -d sampledb -q \"select request_timestamp,elb_name from elb_logs limit 2\"\n" + 19 | "\trequest_timestamp,elb_name\n" + 20 | "\t2015-01-03T00:00:00.516940Z,elb_demo_004\n" + 21 | "\t2015-01-03T00:00:00.902953Z,elb_demo_004\n\n" + 22 | "\t$ athenareader -d sampledb -q \"select request_timestamp,elb_name from elb_logs limit 2\" -r\n" + 23 | "\t2015-01-05T20:00:01.206255Z,elb_demo_002\n" + 24 | "\t2015-01-05T20:00:01.612598Z,elb_demo_008\n\n" + 25 | "\t$ athenareader -d sampledb -b s3://example-athena-query-result -q tools/query.sql\n" + 26 | "\trequest_timestamp,elb_name\n" + 27 | "\t2015-01-06T00:00:00.516940Z,elb_demo_009\n\n" + 28 | "\n\tAdd '-m' to enable moneywise mode. The first line will display query cost under moneywise mode.\n\n" + 29 | "\t$ athenareader -b s3://athena-query-result -q 'select count(*) as cnt from sampledb.elb_logs' -m\n" + 30 | "\tquery cost: 0.00184898369752772851 USD\n" + 31 | "\tcnt\n" + 32 | "\t1356206\n\n" + 33 | "\n\tAdd '-a' to enable admin mode. Database write is enabled at driver level under admin mode.\n\n" + 34 | "\t$ athenareader -b s3://athena-query-result -q 'DROP TABLE IF EXISTS depreacted_table' -a\n" + 35 | "\t\n" + 36 | "AUTHOR\n\tHenry Fuheng Wu (wufuheng@gmail.com)\n\n" + 37 | "REPORTING BUGS\n\thttps://github.com/uber/athenadriver\n" 38 | fmt.Fprintf(commandLine.Output(), preBody) 39 | fmt.Fprintf(commandLine.Output(), 40 | "SYNOPSIS\n\n\t%s [-v] [-b OUTPUT_BUCKET] [-d DATABASE_NAME] [-q QUERY_STRING_OR_FILE] [-r] [-a] [-m] [-y STYLE_NAME] [-o OUTPUT_FORMAT]\n\nDESCRIPTION\n\n", os.Args[0]) 41 | flag.PrintDefaults() 42 | fmt.Fprintf(commandLine.Output(), desc) 43 | } 44 | return nil 45 | } 46 | 47 | func copyFile(src, dst string) error { 48 | in, err := os.Open(src) 49 | if err != nil { 50 | return err 51 | } 52 | defer in.Close() 53 | 54 | out, err := os.Create(dst) 55 | if err != nil { 56 | return err 57 | } 58 | defer out.Close() 59 | 60 | _, err = io.Copy(out, in) 61 | if err != nil { 62 | return err 63 | } 64 | return out.Close() 65 | } 66 | 67 | func homeDir() string { 68 | if h := os.Getenv("HOME"); h != "" { 69 | return h 70 | } 71 | return os.Getenv("USERPROFILE") // windows 72 | } 73 | 74 | func downloadFile(filepath string, url string) (err error) { 75 | // Create the file 76 | out, err := os.Create(filepath) 77 | if err != nil { 78 | return err 79 | } 80 | defer out.Close() 81 | // Get the data 82 | resp, err := http.Get(url) 83 | if err != nil { 84 | return err 85 | } 86 | defer resp.Body.Close() 87 | // Check server response 88 | if resp.StatusCode != http.StatusOK { 89 | return fmt.Errorf("bad status: %s", resp.Status) 90 | } 91 | // Writer the body to file 92 | _, err = io.Copy(out, resp.Body) 93 | if err != nil { 94 | return err 95 | } 96 | return nil 97 | } 98 | 99 | func isFlagPassed(name string) bool { 100 | found := false 101 | flag.Visit(func(f *flag.Flag) { 102 | if f.Name == name { 103 | found = true 104 | } 105 | }) 106 | return found 107 | } 108 | -------------------------------------------------------------------------------- /lib/queryfx/module.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 Uber Technologies, Inc. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | package queryfx 22 | 23 | import ( 24 | "database/sql" 25 | 26 | drv "github.com/uber/athenadriver/go" 27 | "github.com/uber/athenadriver/lib/configfx" 28 | "go.uber.org/fx" 29 | ) 30 | 31 | // Module is to provide dependency of query to main app 32 | var Module = fx.Provide(new) 33 | 34 | // Params defines the dependencies or inputs 35 | type Params struct { 36 | fx.In 37 | 38 | // MyConfig is the current Athenadriver Config 39 | MyConfig configfx.AthenaDriverConfig 40 | } 41 | 42 | // Result defines output 43 | type Result struct { 44 | fx.Out 45 | 46 | // QAD is the Query and DB Connection 47 | QAD QueryAndDBConnection 48 | } 49 | 50 | // QueryAndDBConnection is the result of queryfx module 51 | type QueryAndDBConnection struct { 52 | // DB is the pointer to sql/database DB 53 | DB *sql.DB 54 | // Query is the query string 55 | Query []string 56 | } 57 | 58 | func new(p Params) (Result, error) { 59 | // Open Connection. 60 | dsn := p.MyConfig.DrvConfig.Stringify() 61 | db, _ := sql.Open(drv.DriverName, dsn) 62 | qad := QueryAndDBConnection{ 63 | DB: db, 64 | Query: p.MyConfig.QueryString, 65 | } 66 | return Result{ 67 | QAD: qad, 68 | }, nil 69 | } 70 | -------------------------------------------------------------------------------- /resources/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, 8 | body size, disability, ethnicity, gender identity and expression, level of 9 | experience, nationality, personal appearance, race, religion, or sexual 10 | identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an 52 | appointed representative at an online or offline event. Representation of a 53 | project may be further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at oss-conduct@uber.com. The project 59 | team will review and investigate all complaints, and will respond in a way 60 | that it deems appropriate to the circumstances. The project team is obligated 61 | to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 71 | version 1.4, available at 72 | [http://contributor-covenant.org/version/1/4][version]. 73 | 74 | [homepage]: http://contributor-covenant.org 75 | [version]: http://contributor-covenant.org/version/1/4/ 76 | -------------------------------------------------------------------------------- /resources/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | We'd love your help to improve athenadriver! 4 | 5 | Please [open an issue][open-issue] describing your proposal, idea and findings. 6 | In your issue, pull request, and any other communications, 7 | please remember to treat your fellow contributors with RESPECT! 8 | We take our [code of conduct](CODE_OF_CONDUCT.md) seriously. 9 | 10 | Note that you'll need to sign [Uber's Contributor License Agreement][cla] 11 | before we can accept any of your contributions. If necessary, a bot will remind 12 | you to accept the CLA when you open your pull request. 13 | 14 | ## Setup 15 | 16 | [Fork][fork], then clone the repository: 17 | 18 | ``` 19 | mkdir -p $GOPATH/src/uber 20 | cd $GOPATH/src/uber 21 | git clone git@github.com:your_github_username/athenadriver.git 22 | cd athenadriver 23 | git remote add upstream https://github.com/uber/athenadriver.git 24 | git fetch upstream 25 | ``` 26 | 27 | Install athenadriver's dependencies: 28 | 29 | ``` 30 | make dependencies 31 | ``` 32 | 33 | Make sure that the tests and the linters pass: 34 | 35 | ``` 36 | make test 37 | make lint 38 | ``` 39 | 40 | If you're not using the minor version of Go specified in the Makefile's 41 | `LINTABLE_MINOR_VERSIONS` variable, `make lint` doesn't do anything. This is 42 | fine, but it means that you'll only discover lint failures after you open your 43 | pull request. 44 | 45 | ## Making Changes 46 | 47 | Start by creating a new branch for your changes: 48 | 49 | ``` 50 | cd $GOPATH/src/uber/athenadriver 51 | git checkout master 52 | git fetch upstream 53 | git rebase upstream/master 54 | git checkout -b cool_new_feature 55 | ``` 56 | 57 | Make your changes, then ensure that `make lint` and `make test` still pass. If 58 | you're satisfied with your changes, push them to your fork. 59 | 60 | ``` 61 | git push origin cool_new_feature 62 | ``` 63 | 64 | Then use the GitHub UI to open a pull request. 65 | 66 | At this point, you're waiting on us to review your changes. We *try* to respond 67 | to issues and pull requests within a few business days, and we may suggest some 68 | improvements or alternatives. Once your changes are approved, one of the 69 | project maintainers will merge them. 70 | 71 | We're much more likely to approve your changes if you: 72 | 73 | * Add tests for new functionality. 74 | * Write a [good commit message][commit-message]. 75 | * Maintain backward compatibility. 76 | 77 | [fork]: https://github.com/uber/athenadriver/fork 78 | [open-issue]: https://github.com/uber/athenadriver/issues/new 79 | [cla]: https://cla-assistant.io/uber/athenadriver 80 | [commit-message]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html -------------------------------------------------------------------------------- /resources/ColumnInfo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uber/athenadriver/ed473510065ed1101f60270e27f6601eb1f41cea/resources/ColumnInfo.png -------------------------------------------------------------------------------- /resources/ResultSet_Uml.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uber/athenadriver/ed473510065ed1101f60270e27f6601eb1f41cea/resources/ResultSet_Uml.png -------------------------------------------------------------------------------- /resources/atg-infra.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uber/athenadriver/ed473510065ed1101f60270e27f6601eb1f41cea/resources/atg-infra.png -------------------------------------------------------------------------------- /resources/athenadriver.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uber/athenadriver/ed473510065ed1101f60270e27f6601eb1f41cea/resources/athenadriver.pdf -------------------------------------------------------------------------------- /resources/athenadriver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uber/athenadriver/ed473510065ed1101f60270e27f6601eb1f41cea/resources/athenadriver.png -------------------------------------------------------------------------------- /resources/athenadriver_engblog.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uber/athenadriver/ed473510065ed1101f60270e27f6601eb1f41cea/resources/athenadriver_engblog.pdf -------------------------------------------------------------------------------- /resources/aws_keys.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uber/athenadriver/ed473510065ed1101f60270e27f6601eb1f41cea/resources/aws_keys.png -------------------------------------------------------------------------------- /resources/issue_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uber/athenadriver/ed473510065ed1101f60270e27f6601eb1f41cea/resources/issue_1.png -------------------------------------------------------------------------------- /resources/issue_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uber/athenadriver/ed473510065ed1101f60270e27f6601eb1f41cea/resources/issue_2.png -------------------------------------------------------------------------------- /resources/issue_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uber/athenadriver/ed473510065ed1101f60270e27f6601eb1f41cea/resources/issue_3.png -------------------------------------------------------------------------------- /resources/issue_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uber/athenadriver/ed473510065ed1101f60270e27f6601eb1f41cea/resources/issue_4.png -------------------------------------------------------------------------------- /resources/issue_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uber/athenadriver/ed473510065ed1101f60270e27f6601eb1f41cea/resources/issue_5.png -------------------------------------------------------------------------------- /resources/issue_show_tblproperties.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uber/athenadriver/ed473510065ed1101f60270e27f6601eb1f41cea/resources/issue_show_tblproperties.png -------------------------------------------------------------------------------- /resources/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uber/athenadriver/ed473510065ed1101f60270e27f6601eb1f41cea/resources/logo.png -------------------------------------------------------------------------------- /resources/pin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uber/athenadriver/ed473510065ed1101f60270e27f6601eb1f41cea/resources/pin.png -------------------------------------------------------------------------------- /resources/select_query_with_column_as_first_row.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uber/athenadriver/ed473510065ed1101f60270e27f6601eb1f41cea/resources/select_query_with_column_as_first_row.png -------------------------------------------------------------------------------- /resources/sql_Rows.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uber/athenadriver/ed473510065ed1101f60270e27f6601eb1f41cea/resources/sql_Rows.png -------------------------------------------------------------------------------- /resources/style.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uber/athenadriver/ed473510065ed1101f60270e27f6601eb1f41cea/resources/style.png -------------------------------------------------------------------------------- /resources/workgroup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uber/athenadriver/ed473510065ed1101f60270e27f6601eb1f41cea/resources/workgroup.png -------------------------------------------------------------------------------- /scripts/buildkite.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Get build + test dependencies. -d also doesn't bother with installing the 4 | # packages, it just downloads them 5 | go get -t -d github.com/uber/athenadriver 6 | go test 7 | 8 | 9 | -------------------------------------------------------------------------------- /scripts/checklic.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | ERROR_COUNT=0 4 | while read -r file 5 | do 6 | case "$(head -1 "${file}")" in 7 | *"Copyright (c) "*" Uber Technologies, Inc.") 8 | # everything's cool 9 | ;; 10 | *) 11 | echo "$file is missing license header." 12 | (( ERROR_COUNT++ )) 13 | ;; 14 | esac 15 | done < <(git ls-files "../*\.go") 16 | 17 | exit $ERROR_COUNT 18 | --------------------------------------------------------------------------------