├── .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 | 
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------