diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..572cb23 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,190 @@ +run: + # Timeout for analysis, e.g. 30s, 5m. + # Default: 1m + timeout: 5m + # Exit code when at least one issue was found. + # Default: 1 + issues-exit-code: 2 + # Include test files or not. + # Default: true + tests: true + skip-files: + +linters: + # Disable all linters. + # Default: false + disable-all: true + # Enable specific linter + # https://golangci-lint.run/usage/linters/#enabled-by-default-linters + enable: + - depguard + - exportloopref + - gocheckcompilerdirectives + - gofmt + - gosimple + - govet + - ineffassign + - prealloc + - reassign + - rowserrcheck + - sqlclosecheck + - staticcheck + - stylecheck + - tenv + - typecheck + - unused + +linters-settings: + stylecheck: + checks: + - ST1001 + - ST1005 + - ST1006 + - ST1008 + - ST1011 + - ST1012 + - ST1013 + - ST1015 + - ST1016 + - ST1017 + - ST1018 + - ST1019 + - ST1023 + gosimple: + checks: + - S1000 + - S1001 + - S1002 + - S1003 + - S1004 + - S1005 + - S1006 + - S1007 + - S1008 + - S1009 + - S1010 + - S1011 + - S1012 + - S1016 + - S1017 + - S1018 + - S1019 + - S1020 + - S1021 + - S1023 + - S1024 + - S1025 + - S1028 + - S1029 + - S1030 + - S1031 + - S1032 + - S1033 + - S1034 + - S1035 + - S1036 + - S1037 + - S1038 + - S1039 + - S1040 + + staticcheck: + checks: + - SA1000 + - SA1001 + - SA1002 + - SA1003 + - SA1004 + - SA1005 + - SA1006 + - SA1007 + - SA1008 + - SA1010 + - SA1011 + - SA1012 + - SA1013 + - SA1014 + - SA1015 + - SA1016 + - SA1017 + - SA1018 + - SA1019 + - SA1020 + - SA1021 + - SA1023 + - SA1024 + - SA1025 + - SA1026 + - SA1027 + - SA1028 + - SA1029 + - SA1030 + - SA2000 + - SA2001 + - SA2002 + - SA2003 + - SA3000 + - SA3001 + - SA4000 + - SA4001 + - SA4003 + - SA4004 + - SA4005 + - SA4006 + - SA4008 + - SA4009 + - SA4010 + - SA4011 + - SA4012 + - SA4013 + - SA4014 + - SA4015 + - SA4016 + - SA4017 + - SA4018 + - SA4019 + - SA4020 + - SA4021 + - SA4022 + - SA4023 + - SA4024 + - SA4025 + - SA4026 + - SA4027 + - SA4028 + - SA4029 + - SA4030 + - SA4031 + - SA5000 + - SA5001 + - SA5002 + - SA5003 + - SA5004 + - SA5005 + - SA5007 + - SA5008 + - SA5009 + - SA5010 + - SA5011 + - SA5012 + - SA6000 + - SA6001 + - SA6002 + - SA6003 + - SA6005 + - SA9001 + - SA9002 + - SA9003 + - SA9004 + - SA9005 + - SA9006 + - SA9007 + - SA9008 + +issues: + exclude-use-default: false + exclude-rules: + # Exclude some linters from running on tests files. + - path: _test\.go + linters: + - stylecheck diff --git a/.licenserc.yml b/.licenserc.yml new file mode 100644 index 0000000..f375bf7 --- /dev/null +++ b/.licenserc.yml @@ -0,0 +1,22 @@ +header: + license: + spdx-id: Apache-2.0 + copyright-owner: Matrix Origin + paths: + - '**/*.go' + - '**/*.c' + - '**/*.s' + - '**/*.h' + - '**/*.cpp' + - '**/*.proto' + paths-ignore: + - 'docs/' + - 'test/' + - 'optools/' + - '**/*.pb.go' + - '**/.gitignore' + - '**/goyacc.go' + comment: on-failure +dependency: + files: + - go.mod diff --git a/.markdownlint.yaml b/.markdownlint.yaml new file mode 100644 index 0000000..41a1ff8 --- /dev/null +++ b/.markdownlint.yaml @@ -0,0 +1,56 @@ +# disable all by default +default: false + +# MD003 +heading-style: + style: atx + +# MD012 +no-multiple-blanks: true + +# MD018 +no-missing-space-atx: true + +# MD019 +no-multiple-space-atx: true + +# MD022 +blanks-around-headings: true + +# MD023 +heading-start-left: true + +# MD024 +no-duplicate-heading: + siblings_only: true + +# MD026 +no-trailing-punctuation: + punctuation: '.,;:!。,;:!' + +# MD027 +no-multiple-space-blockquote: true + +# MD030 +list-marker-space: true + +# MD031 +blanks-around-fences: true + +# MD032 +blanks-around-lists: true + +# MD034 +no-bare-urls: true + +# MD037 +no-space-in-emphasis: true + +# MD038 +no-space-in-code: true + +# MD039 +no-space-in-links: true + +# MD042 +no-empty-links: true diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..7377789 --- /dev/null +++ b/Makefile @@ -0,0 +1,102 @@ +# Copyright 2021 - 2022 Matrix Origin +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# +# Examples +# +# By default, make builds the mo-service +# +# make +# +# To re-build MO - +# +# make clean +# make build +# +# To re-build MO in debug mode also with race detector enabled - +# +# make clean +# make debug +# +# To run static checks - +# +# make install-static-check-tools +# make static-check +# +# To construct a directory named vendor in the main module’s root directory that contains copies of all packages needed to support builds and tests of packages in the main module. +# make vendor +# + +# where am I +ROOT_DIR = $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) +MO_DUMP := mo-dump +UNAME_S := $(shell uname -s) +GOPATH := $(shell go env GOPATH) +GO_VERSION=$(shell go version) +BRANCH_NAME=$(shell git rev-parse --abbrev-ref HEAD) +LAST_COMMIT_ID=$(shell git rev-parse --short HEAD) +BUILD_TIME=$(shell date +%s) +MO_VERSION=$(shell git describe --always --tags $(shell git rev-list --tags --max-count=1)) +GO_MODULE=$(shell go list -m) + +# cross compilation has been disabled for now +ifneq ($(GOARCH)$(TARGET_ARCH)$(GOOS)$(TARGET_OS),) +$(error cross compilation has been disabled) +endif + +############################################################################### +# default target +############################################################################### + +all: build + +############################################################################### +# build vendor directory +############################################################################### + +.PHONY: vendor-build +vendor-build: + $(info [go mod vendor]) + @go mod vendor + + +############################################################################### +# clean +############################################################################### + +.PHONY: clean +clean: + $(info [Clean up]) + $(info Clean go test cache) + @go clean -testcache + rm -f $(BIN_NAME) + rm -rf $(ROOT_DIR)/vendor + + +############################################################################### +# modump +############################################################################### + +RACE_OPT := +DEBUG_OPT := +CGO_DEBUG_OPT := +CGO_OPTS=CGO_CFLAGS="-I$(ROOT_DIR)/cgo " CGO_LDFLAGS="-L$(ROOT_DIR)/cgo -lmo -lm" +GOLDFLAGS=-ldflags="-X '$(GO_MODULE)/pkg/version.GoVersion=$(GO_VERSION)' -X '$(GO_MODULE)/pkg/version.BranchName=$(BRANCH_NAME)' -X '$(GO_MODULE)/pkg/version.CommitID=$(LAST_COMMIT_ID)' -X '$(GO_MODULE)/pkg/version.BuildTime=$(BUILD_TIME)' -X '$(GO_MODULE)/pkg/version.Version=$(MO_VERSION)'" +.PHONY: modump +modump: + $(CGO_OPTS) go build $(RACE_OPT) $(GOLDFLAGS) -o $(MO_DUMP) ./cmd/mo-dump + +############################################################################### +# static checks +############################################################################### diff --git a/README.md b/README.md index 6430ba6..c8822b8 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,81 @@ # mo_dump MatrixOne supports logical backups through the mo_dump utility. mo_dump is a command-line utility designed to generate logical backups of the MatrixOne database. It produces SQL statements that can be used to recreate database objects and data. + +## 使用方法 + +### 语法结构 + +``` +./mo-dump -u ${user} -p ${password} -h ${host} -P ${port} -db ${database} [--local-infile=true] [-csv] [-tbl ${table}...] -net-buffer-length ${net-buffer-length} > {dumpfilename.sql} +``` + +**参数释义** + +- **-u [user]**:连接 MatrixOne 服务器的用户名。只有具有数据库和表读取权限的用户才能使用 `mo-dump` 实用程序,默认值 dump。 + +- **-p [password]**:MatrixOne 用户的有效密码。默认值:111。 + +- **-h [host]**:MatrixOne 服务器的主机 IP 地址。默认值:127.0.0.1 + +- **-P [port]**:MatrixOne 服务器的端口。默认值:6001 + +- **-db [数据库名称]**:必需参数。要备份的数据库的名称。 + +- **-net-buffer-length [数据包大小]**:数据包大小,即 SQL 语句字符的总大小。数据包是 SQL 导出数据的基本单位,如果不设置参数,则默认 1048576 Byte(1M),最大可设置 16777216 Byte(16M)。假如这里的参数设置为 16777216 Byte(16M),那么,当要导出大于 16M 的数据时,会把数据拆分成多个 16M 的数据包,除最后一个数据包之外,其它数据包大小都为 16M。 + +- **-csv**:默认值为 false。当设置为 true 时表示导出的数据为 *CSV* 格式。 + +- **--local-infile**:默认值为 true,仅在参数 **-csv** 设置为 true 时生效。表示支持本地导出 *CSV* 文件。 + +- **-tbl [表名]**:可选参数。如果参数为空,则导出整个数据库。如果要备份指定表,则可以在命令中指定多个 `-tbl` 和表名。 + + +### 构建 mo-dump 二进制文件 +__Tips:__ 由于 `mo-dump` 是基于 Go 语言进行开发,所以你同时需要安装部署 Go 语言。 + +1. 执行下面的代码即可从 MatrixOrigin/mo_dump 源代码构建 `mo-dump` 二进制文件: + + ``` + git clone https://github.com/matrixorigin/mo_dump.git + cd mo_dump + make modump + ``` + +2. 你可以在 mo_dump 文件夹中找到 `mo-dump` 可执行文件:*mo-dump*。 + +!!! note + 构建好的 `mo-dump` 文件也可以在相同的硬件平台上工作。但是需要注意在 x86 平台中构建的 `mo-dump` 二进制文件在 Darwin ARM 平台中则无法正常工作。你可以在同一套操作系统和硬件平台内构建并使用 `mo-dump` 二进制文件。`mo-dump` 目前只支持 Linux 和 macOS。 + +## 如何使用 `mo-dump` 导出 MatrixOne 数据库 + +`mo-dump` 在命令行中非常易用。参见以下步骤示例,导出 *sql* 文件格式完整数据库: + +在你本地计算机上打开终端窗口,输入以下命令,连接到 MatrixOne,并且导出数据库: + +``` +./mo-dump -u username -p password -h host_ip_address -P port -db database > exporteddb.sql +``` + +例如,如果你在与 MatrixOne 实例相同的服务器中启动终端,并且你想要生成单个数据库的备份,请运行以下命令。该命令将在 *t.sql* 文件中生成 **t** 数据库的结构和数据的备份。*t.sql* 文件将与您的 `mo-dump` 可执行文件位于同一目录中。 + +``` +./mo-dump -u root -p 111 -h 127.0.0.1 -P 6001 -db t > t.sql +``` + +如果你想将数据库 *t* 内的表导出为 *CSV* 格式,参考使用下面的命令: + +``` +./mo-dump -u root -p 111 -db t -csv --local-infile=false > ttt.csv +``` + +如果要在数据库中生成单个表的备份,可以运行以下命令。该命令将生成命名为 *t* 的数据库的 *t1* 表的备份,其中包含 *t.sql* 文件中的结构和数据。 + +``` +./mo-dump -u root -p 111 -db t -tbl t1 > t1.sql +``` + +* `mo-dump` 不仅支持导出单个数据库的备份,还支持导出多个表。 + + +## 限制 +* `mo-dump` 暂不支持只导出数据库的结构或数据。如果你想在没有数据库结构的情况下生成数据的备份,或者仅想导出数据库结构,那么,你需要手动拆分 `.sql` 文件。 diff --git a/cgo/.gitignore b/cgo/.gitignore new file mode 100644 index 0000000..a372a40 --- /dev/null +++ b/cgo/.gitignore @@ -0,0 +1,3 @@ +*.o +*.a +__.SYMDEF* diff --git a/cgo/Makefile b/cgo/Makefile new file mode 100644 index 0000000..897ed0f --- /dev/null +++ b/cgo/Makefile @@ -0,0 +1,18 @@ +DEBUG_OPT := +OPT_LV := -O3 +CFLAGS=-std=c99 -g ${OPT_LV} -Wall -Werror +OBJS=mo.o arith.o compare.o logic.o + +all: libmo.a + +libmo.a: $(OBJS) + ar -rcs libmo.a *.o + +.PHONY: debug +debug: override OPT_LV := -O0 +debug: override DEBUG_OPT := debug +debug: all + +.PHONY: clean +clean: + rm -f *.o *.a diff --git a/cgo/README.md b/cgo/README.md new file mode 100644 index 0000000..5699ca4 --- /dev/null +++ b/cgo/README.md @@ -0,0 +1,25 @@ +MatrixOne CGO Kernel +=============================== + +This directory contains cgo source code for MO. Running +make should produce two files to be used by go code. +On go side, go will `include "mo.h"` and `-lmo`. +``` +mo.h +libmo.a +``` + +`mo.h` should be pristine, meaning it only contains C function +prototype used by go. The only datatypes that can be passed +between go and c code are int and float/double and pointer. +Always explicitly specify int size such as `int32_t`, `uint64_t`. +Do not use `int`, `long`, etc. + +Implementation Notes +-------------------------------- + +1. Pure C. +2. Use memory passed from go. Try not allocate memory in C code. +3. Only depends on libc and libm. +4. If 3rd party lib is absolutely necessary, import source code + and build from source. If 3rd party lib is C++, wrap it completely in C. diff --git a/cgo/arith.c b/cgo/arith.c new file mode 100644 index 0000000..f1d69ca --- /dev/null +++ b/cgo/arith.c @@ -0,0 +1,581 @@ +/* + * Copyright 2021 Matrix Origin + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mo_impl.h" + +/* + * Signed int add with overflow check. + * + * The test checks if rt[i] and tmpx have different sign, and rt[i] + * and tmpy have different sign, therefore, tmpx and tmpy have same + * sign but the result has different sign, therefore, it is an overflow. + * + * DO NOT use __builtin_add_overflow, which gcc cannot vectorize with SIMD + * and is actually much much slower. + */ +#define ADD_SIGNED_OVFLAG(TGT, A, B) \ + TGT = (A) + (B); \ + opflag |= ((TGT) ^ (A)) & ((TGT) ^ (B)) + +#define ADD_SIGNED_OVFLAG_CHECK \ + if (opflag < 0) { \ + return RC_OUT_OF_RANGE; \ + } else return RC_SUCCESS + + +/* + * Unsigned int add with overflow check + * + * If result is less, we know it wrapped around. + */ +#define ADD_UNSIGNED_OVFLAG(TGT, A, B) \ + TGT = (A) + (B); \ + if ((TGT) < (A)) { \ + opflag = 1; \ + } else (void) 0 + +#define ADD_UNSIGNED_OVFLAG_CHECK \ + if (opflag != 0) { \ + return RC_OUT_OF_RANGE; \ + } else return RC_SUCCESS + +/* + * Float/Double overflow check. + * + * At this moment we don't do anything. + */ +#define ADD_FLOAT_OVFLAG(TGT, A, B) \ + TGT = (A) + (B) + +#define ADD_FLOAT_OVFLAG_CHECK \ + (void) opflag; \ + return RC_SUCCESS + +/* + * Signed int sub with overflow check. + */ +#define SUB_SIGNED_OVFLAG(TGT, A, B) \ + TGT = (A) - (B); \ + opflag |= ((A) ^ (B)) & ((TGT) ^ (A)) + +#define SUB_SIGNED_OVFLAG_CHECK \ + if (opflag < 0) { \ + return RC_OUT_OF_RANGE; \ + }else return RC_SUCCESS + + +/* + * Unsigned int sub with overflow check + * + * If A is less than B,, we know it wrapped around. + */ +#define SUB_UNSIGNED_OVFLAG(TGT, A, B) \ + TGT = (A) - (B); \ + if ((A) < (B)) { \ + opflag = 1; \ + } else (void) 0 + +#define SUB_UNSIGNED_OVFLAG_CHECK \ + if (opflag != 0) { \ + return RC_OUT_OF_RANGE; \ + } else return RC_SUCCESS + + +/* + * Float/Double overflow check. + * + * At this moment we don't do anything. + */ +#define SUB_FLOAT_OVFLAG(TGT, A, B) \ + TGT = (A) - (B) + +#define SUB_FLOAT_OVFLAG_CHECK \ + (void) opflag; \ + return RC_SUCCESS + +/* + * Signed int mul with overflow check. + */ +#define MUL_SIGNED_OVFLAG(TGT, A, B, MAXVAL, MINVAL, ZT ,UPTYPE) \ + temp = (UPTYPE)(A) * (UPTYPE)(B); \ + TGT = (ZT)temp; \ + opflag = ((A ^ B) > 0 && temp > MAXVAL) || ((A ^ B) < 0 && temp < MINVAL) + +#define MUL_SIGNED_OVFLAG_CHECK \ + if (opflag != 0) { \ + return RC_OUT_OF_RANGE; \ + }else return RC_SUCCESS + + +/* + * Unsigned int mul with overflow check + */ +#define MUL_UNSIGNED_OVFLAG(TGT, A, B, MAXVAL, MINVAL, ZT, UPTYPE) \ + temp = (UPTYPE)(A) * (UPTYPE)(B); \ + TGT = (ZT)temp; \ + opflag = (temp > MAXVAL) + +#define MUL_UNSIGNED_OVFLAG_CHECK \ + if (opflag != 0) { \ + return RC_OUT_OF_RANGE; \ + } else return RC_SUCCESS + + +/* + * Float/Double mul overflow check. + * + * At this moment we don't do anything. + */ +#define MUL_FLOAT_OVFLAG(TGT, A, B) \ + TGT = (A) * (B) + +#define MUL_FLOAT_OVFLAG_CHECK \ + (void) opflag; \ + return RC_SUCCESS + + +/* + * Float/Double div overflow check. + * + * At this moment we don't do anything. + */ +#define DIV_FLOAT_OVFLAG(TGT, A, B) \ + if ((B) == 0) { \ + opflag = 1; \ + } else TGT = (A) / (B) + +#define DIV_FLOAT_OVFLAG_CHECK \ + if (opflag == 1) { \ + return RC_DIVISION_BY_ZERO; \ + } else return RC_SUCCESS + +/* + * Signed int mod with overflow check. + */ +#define MOD_SIGNED_OVFLAG(TGT, A, B) \ + if ((B) == 0) { \ + opflag = 1; \ + } else TGT = (A) % (B) + + +#define MOD_SIGNED_OVFLAG_CHECK \ + if (opflag == 1) { \ + return RC_DIVISION_BY_ZERO; \ + } else return RC_SUCCESS + + +/* + * Unsigned int mod with overflow check + */ +#define MOD_UNSIGNED_OVFLAG(TGT, A, B) \ + if ((B) == 0) { \ + opflag = 1; \ + } else TGT = (A) % (B) + +#define MOD_UNSIGNED_OVFLAG_CHECK \ + if (opflag == 1) { \ + return RC_DIVISION_BY_ZERO; \ + } else return RC_SUCCESS + + +/* + * Float mod overflow check. + */ +#define MOD_FLOAT_OVFLAG(TGT, A, B) \ + if ((B) == 0) { \ + opflag = 1; \ + } else TGT = fmodf((A), (B)) + +#define MOD_FLOAT_OVFLAG_CHECK \ + if (opflag == 1) { \ + return RC_DIVISION_BY_ZERO; \ + } else return RC_SUCCESS + + +/* + * Double mod overflow check. + */ +#define MOD_DOUBLE_OVFLAG(TGT, A, B) \ + if ((B) == 0) { \ + opflag = 1; \ + } else TGT = fmod((A), (B)) + +#define MOD_DOUBLE_OVFLAG_CHECK \ + if (opflag == 1) { \ + return RC_DIVISION_BY_ZERO; \ + } else return RC_SUCCESS + +// MO_ARITH_T: Handle general arithmetic operations +#define MO_ARITH_T(OP, ZT) \ + ZT *rt = (ZT *) r; \ + ZT *at = (ZT *) a; \ + ZT *bt = (ZT *) b; \ + ZT opflag = 0; \ + if ((flag & LEFT_IS_SCALAR) != 0) { \ + if (nulls != NULL) { \ + for (uint64_t i = 0; i < n; i++) { \ + if (!bitmap_test(nulls, i)) { \ + OP(rt[i], at[0], bt[i]); \ + } \ + } \ + } else { \ + for (uint64_t i = 0; i < n; i++) { \ + OP(rt[i], at[0], bt[i]); \ + } \ + } \ + } else if ((flag & RIGHT_IS_SCALAR) != 0) { \ + if (nulls != NULL) { \ + for (uint64_t i = 0; i < n; i++) { \ + if (!bitmap_test(nulls, i)) { \ + OP(rt[i], at[i], bt[0]); \ + } \ + } \ + } else { \ + for (uint64_t i = 0; i < n; i++) { \ + OP(rt[i], at[i], bt[0]); \ + } \ + } \ + } else { \ + if (nulls != NULL) { \ + for (uint64_t i = 0; i < n; i++) { \ + if (!bitmap_test(nulls, i)) { \ + OP(rt[i], at[i], bt[i]); \ + } \ + } \ + } else { \ + for (uint64_t i = 0; i < n; i++) { \ + OP(rt[i], at[i], bt[i]); \ + } \ + } \ + } \ + OP ## _CHECK + + +// MO_MUL_T: Handle signed and unsigned integer multiplication +#define MO_MUL_T(OP, ZT, MAXVAL, MINVAL, UPTYPE) \ + ZT *rt = (ZT *) r; \ + ZT *at = (ZT *) a; \ + ZT *bt = (ZT *) b; \ + UPTYPE temp = 0; \ + ZT opflag = 0; \ + if ((flag & LEFT_IS_SCALAR) != 0) { \ + if (nulls != NULL) { \ + for (uint64_t i = 0; i < n; i++) { \ + if (!bitmap_test(nulls, i)) { \ + OP(rt[i], at[0], bt[i], MAXVAL, MINVAL, ZT, UPTYPE); \ + } \ + } \ + } else { \ + for (uint64_t i = 0; i < n; i++) { \ + OP(rt[i], at[0], bt[i], MAXVAL, MINVAL, ZT, UPTYPE); \ + } \ + } \ + } else if ((flag & RIGHT_IS_SCALAR) != 0) { \ + if (nulls != NULL) { \ + for (uint64_t i = 0; i < n; i++) { \ + if (!bitmap_test(nulls, i)) { \ + OP(rt[i], at[i], bt[0], MAXVAL, MINVAL, ZT, UPTYPE); \ + } \ + } \ + } else { \ + for (uint64_t i = 0; i < n; i++) { \ + OP(rt[i], at[i], bt[0], MAXVAL, MINVAL, ZT, UPTYPE); \ + } \ + } \ + } else { \ + if (nulls != NULL) { \ + for (uint64_t i = 0; i < n; i++) { \ + if (!bitmap_test(nulls, i)) { \ + OP(rt[i], at[i], bt[i], MAXVAL, MINVAL, ZT, UPTYPE); \ + } \ + } \ + } else { \ + for (uint64_t i = 0; i < n; i++) { \ + OP(rt[i], at[i], bt[i], MAXVAL, MINVAL, ZT, UPTYPE); \ + } \ + } \ + } \ + OP ## _CHECK + + + +// Addition operation +int32_t SignedInt_VecAdd(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t szof) +{ + if (szof == 1) { + MO_ARITH_T(ADD_SIGNED_OVFLAG, int8_t); + } else if (szof == 2) { + MO_ARITH_T(ADD_SIGNED_OVFLAG, int16_t); + } else if (szof == 4) { + MO_ARITH_T(ADD_SIGNED_OVFLAG, int32_t); + } else if (szof == 8) { + MO_ARITH_T(ADD_SIGNED_OVFLAG, int64_t); + } else { + return RC_INVALID_ARGUMENT; + } + return RC_SUCCESS; +} + +int32_t UnsignedInt_VecAdd(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t szof) +{ + if (szof == 1) { + MO_ARITH_T(ADD_UNSIGNED_OVFLAG, uint8_t); + } else if (szof == 2) { + MO_ARITH_T(ADD_UNSIGNED_OVFLAG, uint16_t); + } else if (szof == 4) { + MO_ARITH_T(ADD_UNSIGNED_OVFLAG, uint32_t); + } else if (szof == 8) { + MO_ARITH_T(ADD_UNSIGNED_OVFLAG, uint64_t); + } else { + return RC_INVALID_ARGUMENT; + } + return RC_SUCCESS; +} + +int32_t Float_VecAdd(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t szof) +{ + if (szof == 4) { + MO_ARITH_T(ADD_FLOAT_OVFLAG, float); + } else if (szof == 8) { + MO_ARITH_T(ADD_FLOAT_OVFLAG, double); + } else { + return RC_INVALID_ARGUMENT; + } + return RC_SUCCESS; +} + +// Subtraction operation +int32_t SignedInt_VecSub(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t szof) +{ + if (szof == 1) { + MO_ARITH_T(SUB_SIGNED_OVFLAG, int8_t); + } else if (szof == 2) { + MO_ARITH_T(SUB_SIGNED_OVFLAG, int16_t); + } else if (szof == 4) { + MO_ARITH_T(SUB_SIGNED_OVFLAG, int32_t); + } else if (szof == 8) { + MO_ARITH_T(SUB_SIGNED_OVFLAG, int64_t); + } else { + return RC_INVALID_ARGUMENT; + } + return RC_SUCCESS; +} + +int32_t UnsignedInt_VecSub(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t szof) +{ + if (szof == 1) { + MO_ARITH_T(SUB_UNSIGNED_OVFLAG, uint8_t); + } else if (szof == 2) { + MO_ARITH_T(SUB_UNSIGNED_OVFLAG, uint16_t); + } else if (szof == 4) { + MO_ARITH_T(SUB_UNSIGNED_OVFLAG, uint32_t); + } else if (szof == 8) { + MO_ARITH_T(SUB_UNSIGNED_OVFLAG, uint64_t); + } else { + return RC_INVALID_ARGUMENT; + } + return RC_SUCCESS; +} + +int32_t Float_VecSub(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t szof) +{ + if (szof == 4) { + MO_ARITH_T(SUB_FLOAT_OVFLAG, float); + } else if (szof == 8) { + MO_ARITH_T(SUB_FLOAT_OVFLAG, double); + } else { + return RC_INVALID_ARGUMENT; + } + return RC_SUCCESS; +} + +// Multiplication operation +int32_t SignedInt_VecMul(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t szof) +{ + if (szof == 1) { + MO_MUL_T(MUL_SIGNED_OVFLAG, int8_t, INT8_MAX, INT8_MIN, int16_t); + } else if (szof == 2) { + MO_MUL_T(MUL_SIGNED_OVFLAG, int16_t, INT16_MAX, INT16_MIN, int16_t); + } else if (szof == 4) { + MO_MUL_T(MUL_SIGNED_OVFLAG, int32_t, INT32_MAX, INT32_MIN, int64_t); + } else if (szof == 8) { + MO_MUL_T(MUL_SIGNED_OVFLAG, int64_t, INT64_MAX, INT64_MIN, __int128); + } else { + return RC_INVALID_ARGUMENT; + } + return RC_SUCCESS; +} + + +int32_t UnsignedInt_VecMul(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t szof) +{ + if (szof == 1) { + MO_MUL_T(MUL_UNSIGNED_OVFLAG, uint8_t, UINT8_MAX, 0, uint16_t); + } else if (szof == 2) { + MO_MUL_T(MUL_UNSIGNED_OVFLAG, uint16_t, UINT16_MAX, 0, uint32_t); + } else if (szof == 4) { + MO_MUL_T(MUL_UNSIGNED_OVFLAG, uint32_t, UINT32_MAX, 0, uint64_t); + } else if (szof == 8) { + MO_MUL_T(MUL_UNSIGNED_OVFLAG, uint64_t, UINT64_MAX, 0, __int128); + } else { + return RC_INVALID_ARGUMENT; + } + return RC_SUCCESS; +} + + +int32_t Float_VecMul(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t szof) +{ + if (szof == 4) { + MO_ARITH_T(MUL_FLOAT_OVFLAG, float); + } else if (szof == 8) { + MO_ARITH_T(MUL_FLOAT_OVFLAG, double); + } else { + return RC_INVALID_ARGUMENT; + } + return RC_SUCCESS; +} + +// Division operation +int32_t Float_VecDiv(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t szof) { + if (szof == 4) { + MO_ARITH_T(DIV_FLOAT_OVFLAG, float); + } else if (szof == 8) { + MO_ARITH_T(DIV_FLOAT_OVFLAG, double); + } else { + return RC_INVALID_ARGUMENT; + } + return RC_SUCCESS; +} + +// Mod operation +int32_t SignedInt_VecMod(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t szof) +{ + if (szof == 1) { + MO_ARITH_T(MOD_SIGNED_OVFLAG, int8_t); + } else if (szof == 2) { + MO_ARITH_T(MOD_SIGNED_OVFLAG, int16_t); + } else if (szof == 4) { + MO_ARITH_T(MOD_SIGNED_OVFLAG, int32_t); + } else if (szof == 8) { + MO_ARITH_T(MOD_SIGNED_OVFLAG, int64_t); + } else { + return RC_INVALID_ARGUMENT; + } + return RC_SUCCESS; +} + +int32_t UnsignedInt_VecMod(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t szof) +{ + if (szof == 1) { + MO_ARITH_T(MOD_UNSIGNED_OVFLAG, uint8_t); + } else if (szof == 2) { + MO_ARITH_T(MOD_UNSIGNED_OVFLAG, uint16_t); + } else if (szof == 4) { + MO_ARITH_T(MOD_UNSIGNED_OVFLAG, uint32_t); + } else if (szof == 8) { + MO_ARITH_T(MOD_UNSIGNED_OVFLAG, uint64_t); + } else { + return RC_INVALID_ARGUMENT; + } + return RC_SUCCESS; +} + +int32_t Float_VecMod(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t szof) +{ + if (szof == 4) { + MO_ARITH_T(MOD_FLOAT_OVFLAG, float); + } else if (szof == 8) { + MO_ARITH_T(MOD_DOUBLE_OVFLAG, double); + } else { + return RC_INVALID_ARGUMENT; + } + return RC_SUCCESS; +} + + +/* + * Float/Double integer div overflow check. + * + * At this moment we don't do anything. + */ +#define INTDIV_FLOAT_OVFLAG(TGT, A, B) \ + if ((B) == 0) { \ + opflag = 1; \ + } else TGT = (int64_t)((A) / (B)) + +#define INTDIV_FLOAT_OVFLAG_CHECK \ + if (opflag == 1) { \ + return RC_DIVISION_BY_ZERO; \ + } else return RC_SUCCESS + +// MO_INT_DIV : Handle floating-point integer division +#define MO_INT_DIV(OP, ZT, RT) \ + RT *rt = (RT *) r; \ + ZT *at = (ZT *) a; \ + ZT *bt = (ZT *) b; \ + ZT opflag = 0; \ + if ((flag & LEFT_IS_SCALAR) != 0) { \ + if (nulls != NULL) { \ + for (uint64_t i = 0; i < n; i++) { \ + if (!bitmap_test(nulls, i)) { \ + OP(rt[i], at[0], bt[i]); \ + } \ + } \ + } else { \ + for (uint64_t i = 0; i < n; i++) { \ + OP(rt[i], at[0], bt[i]); \ + } \ + } \ + } else if ((flag & RIGHT_IS_SCALAR) != 0) { \ + if (nulls != NULL) { \ + for (uint64_t i = 0; i < n; i++) { \ + if (!bitmap_test(nulls, i)) { \ + OP(rt[i], at[i], bt[0]); \ + } \ + } \ + } else { \ + for (uint64_t i = 0; i < n; i++) { \ + OP(rt[i], at[i], bt[0]); \ + } \ + } \ + } else { \ + if (nulls != NULL) { \ + for (uint64_t i = 0; i < n; i++) { \ + if (!bitmap_test(nulls, i)) { \ + OP(rt[i], at[i], bt[i]); \ + } \ + } \ + } else { \ + for (uint64_t i = 0; i < n; i++) { \ + OP(rt[i], at[i], bt[i]); \ + } \ + } \ + } \ + OP ## _CHECK + + +int32_t Float_VecIntegerDiv(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t szof) +{ + if (szof == 4) { + MO_INT_DIV(INTDIV_FLOAT_OVFLAG, float, int64_t); + } else if (szof == 8) { + MO_INT_DIV(INTDIV_FLOAT_OVFLAG, double, int64_t); + } else { + return RC_INVALID_ARGUMENT; + } + return RC_SUCCESS; +} \ No newline at end of file diff --git a/cgo/bitmap.h b/cgo/bitmap.h new file mode 100644 index 0000000..dfc831d --- /dev/null +++ b/cgo/bitmap.h @@ -0,0 +1,133 @@ +/* + * Copyright 2021 Matrix Origin + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _BITMAP_H_ +#define _BITMAP_H_ + +#include "mo.h" +#include + +/* + * Null bitmap operations. Bitmap is an array of unit64_t and nbits of bits, nbits > 0. + * Each of the nbits is a bit from position pos 0 to pos nbits - 1 + * + * MUST MATCH GO IMPLEMENTATION. + */ + +/* bitmap in number of bytes. */ +static inline uint64_t bitmap_nbyte(uint64_t nbits) { + return (nbits + 7) >> 3; +} +/* return number of uint64 that can holds nbits */ +static inline uint64_t bitmap_size(uint64_t nbits) { + return (nbits + 63) >> 6; +} +/* return index into array of the bit position */ +static inline uint64_t bitmap_pos2idx(uint64_t pos) { + return pos >> 6; +} +/* return mask of the bit position */ +static inline uint64_t bitmap_pos2mask(uint64_t pos) { + uint64_t mask = 1; + return mask << (pos & 63); +} + +static inline bool bitmap_test(uint64_t *p, uint64_t pos) { + return (p[bitmap_pos2idx(pos)] & bitmap_pos2mask(pos)) != 0; +} + +static inline void bitmap_set(uint64_t *p, uint64_t pos) { + p[bitmap_pos2idx(pos)] |= bitmap_pos2mask(pos); +} + +static inline void bitmap_clear(uint64_t *p, uint64_t pos) { + p[bitmap_pos2idx(pos)] &= ~bitmap_pos2mask(pos); +} + +static inline void bitmap_zeros(uint64_t *p, uint64_t nbits) { + memset(p, 0, bitmap_nbyte(nbits)); +} + +static inline void bitmap_ones(uint64_t *p, uint64_t nbits) { + memset(p, 0xFF, bitmap_nbyte(nbits)); +} + +static inline void bitmap_copy(uint64_t *dst, uint64_t *src, uint64_t nbits) { + memcpy(dst, src, bitmap_nbyte(nbits)); +} + +static inline void bitmap_and(uint64_t *dst, uint64_t *a, uint64_t *b, uint64_t nbits) { + uint64_t sz = bitmap_size(nbits); + for (uint64_t i = 0; i < sz; ++i) { + dst[i] = a[i] & b[i]; + } +} +static inline void bitmap_or(uint64_t *dst, uint64_t *a, uint64_t *b, uint64_t nbits) { + uint64_t sz = bitmap_size(nbits); + for (uint64_t i = 0; i < sz; ++i) { + dst[i] = a[i] | b[i]; + } +} + +static inline void bitmap_not(uint64_t *dst, uint64_t *a, uint64_t nbits) { + uint64_t sz = bitmap_size(nbits); + for (uint64_t i = 0; i < sz; ++i) { + dst[i] = ~a[i]; + } +} + +static inline uint64_t bitmap_lastmask(uint64_t nbits) { + uint64_t mask = bitmap_pos2mask(nbits - 1); + /* + * For nbits = 0, 64, ... mask will be 1 << 63. + * the following overflowed expression is the correct answer. + */ + return (mask << 1) - 1; +} + +static inline uint64_t bitmap_count(uint64_t *p, uint64_t nbits) { + if (nbits == 0) { + return 0; + } else { + uint64_t sz = bitmap_size(nbits); + uint64_t mask = bitmap_lastmask(nbits); + uint64_t cnt = __builtin_popcountll(p[sz - 1] & mask); + for (uint64_t i = 0; (i + 1) < sz; ++i) { + cnt += __builtin_popcountll(p[i]); + } + return cnt; + } +} + +static inline bool bitmap_empty(uint64_t *p, uint64_t nbits) { + if (nbits == 0) { + return true; + } else { + uint64_t sz = bitmap_size(nbits); + uint64_t mask = bitmap_lastmask(nbits); + if ((p[sz-1] & mask) != 0) { + return false; + } + for (uint64_t i = 0; (i + 1) < sz; ++i) { + if (p[i] != 0) { + return false; + } + } + return true; + } +} + +#endif /* _BITMAP_H_ */ diff --git a/cgo/compare.c b/cgo/compare.c new file mode 100644 index 0000000..584952e --- /dev/null +++ b/cgo/compare.c @@ -0,0 +1,384 @@ +/* + * Copyright 2021 Matrix Origin + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mo_impl.h" + + +#define Type_BOOL 10 +#define Type_INT8 20 +#define Type_INT16 21 +#define Type_INT32 22 +#define Type_INT64 23 +#define Type_INT128 24 +#define Type_UINT8 25 +#define Type_UINT16 26 +#define Type_UINT32 27 +#define Type_UINT64 28 +#define Type_UINT128 29 +#define Type_FLOAT32 30 +#define Type_FLOAT64 31 + +// Time +#define Type_DATE 50 +#define Type_TIME 51 +#define Type_DATETIME 52 +#define Type_TIMESTAMP 53 + + + +/* + * Equal operator (=) + */ +#define COMPARE_EQ(TGT, A, B) \ + TGT = ((A) == (B)) + + +/* + * Not Equal operator (<>) + */ +#define COMPARE_NE(TGT, A, B) \ + TGT = ((A) != (B)) + + +/* + * great than operator (>) + */ +#define COMPARE_GT(TGT, A, B) \ + TGT = ((A) > (B)) + + +/* + * great equal operator (>=) + */ +#define COMPARE_GE(TGT, A, B) \ + TGT = ((A) >= (B)) + + +/* + * less than operator (<) + */ +#define COMPARE_LT(TGT, A, B) \ + TGT = ((A) < (B)) + + +/* + * less equal operator (<=) + */ +#define COMPARE_LE(TGT, A, B) \ + TGT = ((A) <= (B)) + + +/* + * bool compare operator + */ +#define COMPARE_BOOL_EQ(TGT, A, B) \ + TGT = (((A) && (B)) || (!(A) && !(B))) + +#define COMPARE_BOOL_NE(TGT, A, B) \ + TGT = ((!(A) && (B)) || ((A) && !(B))) + +#define COMPARE_BOOL_LE(TGT, A, B) \ + TGT = (!(A) || (B)) + +#define COMPARE_BOOL_LT(TGT, A, B) \ + TGT = (!(A) && (B)) + +#define COMPARE_BOOL_GE(TGT, A, B) \ + TGT = ((A) || !(B)) + +#define COMPARE_BOOL_GT(TGT, A, B) \ + TGT = ((A) && !(B)) + + + + + +#define MO_COMPARE_T(OP, ZT) \ + bool *rt = (bool *) r; \ + ZT *at = (ZT *) a; \ + ZT *bt = (ZT *) b; \ + if ((flag & LEFT_IS_SCALAR) != 0) { \ + if (nulls != NULL) { \ + for (uint64_t i = 0; i < n; i++) { \ + if (!bitmap_test(nulls, i)) { \ + OP(rt[i], at[0], bt[i]); \ + } \ + } \ + } else { \ + for (uint64_t i = 0; i < n; i++) { \ + OP(rt[i], at[0], bt[i]); \ + } \ + } \ + } else if ((flag & RIGHT_IS_SCALAR) != 0) { \ + if (nulls != NULL) { \ + for (uint64_t i = 0; i < n; i++) { \ + if (!bitmap_test(nulls, i)) { \ + OP(rt[i], at[i], bt[0]); \ + } \ + } \ + } else { \ + for (uint64_t i = 0; i < n; i++) { \ + OP(rt[i], at[i], bt[0]); \ + } \ + } \ + } else { \ + if (nulls != NULL) { \ + for (uint64_t i = 0; i < n; i++) { \ + if (!bitmap_test(nulls, i)) { \ + OP(rt[i], at[i], bt[i]); \ + } \ + } \ + } else { \ + for (uint64_t i = 0; i < n; i++) { \ + OP(rt[i], at[i], bt[i]); \ + } \ + } \ + } + + + +int32_t Numeric_VecEq(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t type) +{ + if (type == Type_INT8) { + MO_COMPARE_T(COMPARE_EQ, int8_t); + } else if (type == Type_INT16) { + MO_COMPARE_T(COMPARE_EQ, int16_t); + } else if (type == Type_INT32) { + MO_COMPARE_T(COMPARE_EQ, int32_t); + } else if (type == Type_INT64) { + MO_COMPARE_T(COMPARE_EQ, int64_t); + } else if (type == Type_UINT8) { + MO_COMPARE_T(COMPARE_EQ, uint8_t); + } else if (type == Type_UINT16) { + MO_COMPARE_T(COMPARE_EQ, uint16_t); + } else if (type == Type_UINT32) { + MO_COMPARE_T(COMPARE_EQ, uint32_t); + } else if (type == Type_UINT64) { + MO_COMPARE_T(COMPARE_EQ, uint64_t); + } else if (type == Type_FLOAT32) { + MO_COMPARE_T(COMPARE_EQ, float); + } else if (type == Type_FLOAT64) { + MO_COMPARE_T(COMPARE_EQ, double); + } else if (type == Type_DATE) { + MO_COMPARE_T(COMPARE_EQ, int32_t); + } else if (type == Type_TIME) { + MO_COMPARE_T(COMPARE_EQ, int64_t); + } else if (type == Type_DATETIME) { + MO_COMPARE_T(COMPARE_EQ, int64_t); + } else if (type == Type_TIMESTAMP) { + MO_COMPARE_T(COMPARE_EQ, int64_t); + } else if (type == Type_BOOL) { + MO_COMPARE_T(COMPARE_BOOL_EQ, bool); + } else { + return RC_INVALID_ARGUMENT; + } + return RC_SUCCESS; +} + + +int32_t Numeric_VecNe(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t type) +{ + if (type == Type_INT8) { + MO_COMPARE_T(COMPARE_NE, int8_t); + } else if (type == Type_INT16) { + MO_COMPARE_T(COMPARE_NE, int16_t); + } else if (type == Type_INT32) { + MO_COMPARE_T(COMPARE_NE, int32_t); + } else if (type == Type_INT64) { + MO_COMPARE_T(COMPARE_NE, int64_t); + } else if (type == Type_UINT8) { + MO_COMPARE_T(COMPARE_NE, uint8_t); + } else if (type == Type_UINT16) { + MO_COMPARE_T(COMPARE_NE, uint16_t); + } else if (type == Type_UINT32) { + MO_COMPARE_T(COMPARE_NE, uint32_t); + } else if (type == Type_UINT64) { + MO_COMPARE_T(COMPARE_NE, uint64_t); + } else if (type == Type_FLOAT32) { + MO_COMPARE_T(COMPARE_NE, float); + } else if (type == Type_FLOAT64) { + MO_COMPARE_T(COMPARE_NE, double); + } else if (type == Type_DATE) { + MO_COMPARE_T(COMPARE_NE, int32_t); + } else if (type == Type_TIME){ + MO_COMPARE_T(COMPARE_NE, int64_t); + } else if (type == Type_DATETIME) { + MO_COMPARE_T(COMPARE_NE, int64_t); + } else if (type == Type_TIMESTAMP) { + MO_COMPARE_T(COMPARE_NE, int64_t); + } else if (type == Type_BOOL) { + MO_COMPARE_T(COMPARE_BOOL_NE, bool); + } else { + return RC_INVALID_ARGUMENT; + } + return RC_SUCCESS; +} + + +int32_t Numeric_VecGt(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t type) +{ + if (type == Type_INT8) { + MO_COMPARE_T(COMPARE_GT, int8_t); + } else if (type == Type_INT16) { + MO_COMPARE_T(COMPARE_GT, int16_t); + } else if (type == Type_INT32) { + MO_COMPARE_T(COMPARE_GT, int32_t); + } else if (type == Type_INT64) { + MO_COMPARE_T(COMPARE_GT, int64_t); + } else if (type == Type_UINT8) { + MO_COMPARE_T(COMPARE_GT, uint8_t); + } else if (type == Type_UINT16) { + MO_COMPARE_T(COMPARE_GT, uint16_t); + } else if (type == Type_UINT32) { + MO_COMPARE_T(COMPARE_GT, uint32_t); + } else if (type == Type_UINT64) { + MO_COMPARE_T(COMPARE_GT, uint64_t); + } else if (type == Type_FLOAT32) { + MO_COMPARE_T(COMPARE_GT, float); + } else if (type == Type_FLOAT64) { + MO_COMPARE_T(COMPARE_GT, double); + } else if (type == Type_DATE) { + MO_COMPARE_T(COMPARE_GT, int32_t); + } else if (type == Type_TIME) { + MO_COMPARE_T(COMPARE_GT, int64_t); + } else if (type == Type_DATETIME) { + MO_COMPARE_T(COMPARE_GT, int64_t); + } else if (type == Type_TIMESTAMP) { + MO_COMPARE_T(COMPARE_GT, int64_t); + } else if (type == Type_BOOL) { + MO_COMPARE_T(COMPARE_BOOL_GT, bool); + } else { + return RC_INVALID_ARGUMENT; + } + return RC_SUCCESS; +} + +int32_t Numeric_VecGe(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t type) +{ + if (type == Type_INT8) { + MO_COMPARE_T(COMPARE_GE, int8_t); + } else if (type == Type_INT16) { + MO_COMPARE_T(COMPARE_GE, int16_t); + } else if (type == Type_INT32) { + MO_COMPARE_T(COMPARE_GE, int32_t); + } else if (type == Type_INT64) { + MO_COMPARE_T(COMPARE_GE, int64_t); + } else if (type == Type_UINT8) { + MO_COMPARE_T(COMPARE_GE, uint8_t); + } else if (type == Type_UINT16) { + MO_COMPARE_T(COMPARE_GE, uint16_t); + } else if (type == Type_UINT32) { + MO_COMPARE_T(COMPARE_GE, uint32_t); + } else if (type == Type_UINT64) { + MO_COMPARE_T(COMPARE_GE, uint64_t); + } else if (type == Type_FLOAT32) { + MO_COMPARE_T(COMPARE_GE, float); + } else if (type == Type_FLOAT64) { + MO_COMPARE_T(COMPARE_GE, double); + } else if (type == Type_DATE) { + MO_COMPARE_T(COMPARE_GE, int32_t); + } else if (type == Type_TIME) { + MO_COMPARE_T(COMPARE_GE, int64_t); + } else if (type == Type_DATETIME) { + MO_COMPARE_T(COMPARE_GE, int64_t); + } else if (type == Type_TIMESTAMP) { + MO_COMPARE_T(COMPARE_GE, int64_t); + } else if (type == Type_BOOL) { + MO_COMPARE_T(COMPARE_BOOL_GE, bool); + } else { + return RC_INVALID_ARGUMENT; + } + + return RC_SUCCESS; +} + + +int32_t Numeric_VecLt(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t type) +{ + if (type == Type_INT8) { + MO_COMPARE_T(COMPARE_LT, int8_t); + } else if (type == Type_INT16) { + MO_COMPARE_T(COMPARE_LT, int16_t); + } else if (type == Type_INT32) { + MO_COMPARE_T(COMPARE_LT, int32_t); + } else if (type == Type_INT64) { + MO_COMPARE_T(COMPARE_LT, int64_t); + } else if (type == Type_UINT8) { + MO_COMPARE_T(COMPARE_LT, uint8_t); + } else if (type == Type_UINT16) { + MO_COMPARE_T(COMPARE_LT, uint16_t); + } else if (type == Type_UINT32) { + MO_COMPARE_T(COMPARE_LT, uint32_t); + } else if (type == Type_UINT64) { + MO_COMPARE_T(COMPARE_LT, uint64_t); + } else if (type == Type_FLOAT32) { + MO_COMPARE_T(COMPARE_LT, float); + } else if (type == Type_FLOAT64) { + MO_COMPARE_T(COMPARE_LT, double); + } else if (type == Type_DATE) { + MO_COMPARE_T(COMPARE_LT, int32_t); + } else if (type == Type_TIME) { + MO_COMPARE_T(COMPARE_LT, int64_t); + } else if (type == Type_DATETIME) { + MO_COMPARE_T(COMPARE_LT, int64_t); + } else if (type == Type_TIMESTAMP) { + MO_COMPARE_T(COMPARE_LT, int64_t); + } else if (type == Type_BOOL) { + MO_COMPARE_T(COMPARE_BOOL_LT, bool); + } else { + return RC_INVALID_ARGUMENT; + } + return RC_SUCCESS; +} + + +int32_t Numeric_VecLe(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t type) +{ + if (type == Type_INT8) { + MO_COMPARE_T(COMPARE_LE, int8_t); + } else if (type == Type_INT16) { + MO_COMPARE_T(COMPARE_LE, int16_t); + } else if (type == Type_INT32) { + MO_COMPARE_T(COMPARE_LE, int32_t); + } else if (type == Type_INT64) { + MO_COMPARE_T(COMPARE_LE, int64_t); + } else if (type == Type_UINT8) { + MO_COMPARE_T(COMPARE_LE, uint8_t); + } else if (type == Type_UINT16) { + MO_COMPARE_T(COMPARE_LE, uint16_t); + } else if (type == Type_UINT32) { + MO_COMPARE_T(COMPARE_LE, uint32_t); + } else if (type == Type_UINT64) { + MO_COMPARE_T(COMPARE_LE, uint64_t); + } else if (type == Type_FLOAT32) { + MO_COMPARE_T(COMPARE_LE, float); + } else if (type == Type_FLOAT64) { + MO_COMPARE_T(COMPARE_LE, double); + } else if (type == Type_DATE) { + MO_COMPARE_T(COMPARE_LE, int32_t); + } else if (type == Type_TIME) { + MO_COMPARE_T(COMPARE_LE, int64_t); + } else if (type == Type_DATETIME) { + MO_COMPARE_T(COMPARE_LE, int64_t); + } else if (type == Type_TIMESTAMP) { + MO_COMPARE_T(COMPARE_LE, int64_t); + } else if (type == Type_BOOL) { + MO_COMPARE_T(COMPARE_BOOL_LE, bool); + } else { + return RC_INVALID_ARGUMENT; + } + return RC_SUCCESS; +} \ No newline at end of file diff --git a/cgo/logic.c b/cgo/logic.c new file mode 100644 index 0000000..4012a5a --- /dev/null +++ b/cgo/logic.c @@ -0,0 +1,222 @@ +/* + * Copyright 2021 Matrix Origin + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mo_impl.h" + +/* + Logical and operator truth table + A | B | A AND B + ------|--------|---------- + true | true | true + true | false | false + true | null | null + false | true | false + false | false | false + false | null | false + null | true | null + null | false | false + null | null | null +*/ +int32_t Logic_VecAnd(void *r, void *a, void *b, uint64_t n, uint64_t *anulls, uint64_t *bnulls, uint64_t *rnulls, int32_t flag) { + bool *rt = (bool *) r; + bool *at = (bool *) a; + bool *bt = (bool *) b; + if ((flag & LEFT_IS_SCALAR) != 0) { + for (uint64_t i = 0; i < n; i++) { + rt[i] = at[0] && bt[i]; + } + if (rnulls != NULL && !at[0]) { + for (uint64_t i = 0; i < n; i++) { + if (Bitmap_Contains(rnulls, i)) { + Bitmap_Remove(rnulls, i); + } + } + } + } else if ((flag & RIGHT_IS_SCALAR) != 0) { + for (uint64_t i = 0; i < n; i++) { + rt[i] = at[i] && bt[0]; + } + if (rnulls != NULL && !bt[0]) { + for (uint64_t i = 0; i < n; i++) { + if (Bitmap_Contains(rnulls, i)) { + Bitmap_Remove(rnulls, i); + } + } + } + } else { + for (uint64_t i = 0; i < n; i++) { + rt[i] = at[i] && bt[i]; + } + if (anulls != NULL && bnulls != NULL) { + for (uint64_t i = 0; i < n; i++) { + if (Bitmap_Contains(anulls, i) && !Bitmap_Contains(bnulls, i)) { + if (!bt[i]) { + Bitmap_Remove(rnulls, i); + } + } + + if (Bitmap_Contains(bnulls, i) && !Bitmap_Contains(anulls, i)) { + if (!at[i]) { + Bitmap_Remove(rnulls, i); + } + } + } + } else if (anulls != NULL) { + for (uint64_t i = 0; i < n; i++) { + if (!bt[i] && Bitmap_Contains(anulls, i)) { + Bitmap_Remove(rnulls, i); + } + } + } else if (bnulls != NULL) { + for (uint64_t i = 0; i < n; i++) { + if (!at[i] && Bitmap_Contains(bnulls, i)) { + Bitmap_Remove(rnulls, i); + } + } + } + } + return RC_SUCCESS; +} + +/* + Logical or operator truth table + A | B | A OR B + ------|--------|---------- + true | true | true + true | false | true + true | null | true + false | true | true + false | false | false + false | null | null + null | true | true + null | false | null + null | null | null +*/ +int32_t Logic_VecOr(void *r, void *a, void *b, uint64_t n, uint64_t *anulls, uint64_t *bnulls, uint64_t *rnulls, int32_t flag) { + bool *rt = (bool *) r; + bool *at = (bool *) a; + bool *bt = (bool *) b; + if ((flag & LEFT_IS_SCALAR) != 0) { + for (uint64_t i = 0; i < n; i++) { + rt[i] = at[0] || bt[i]; + } + if (rnulls != NULL && at[0]) { + for (uint64_t i = 0; i < n; i++) { + if (Bitmap_Contains(rnulls, i)) { + Bitmap_Remove(rnulls, i); + } + } + } + } else if ((flag & RIGHT_IS_SCALAR) != 0) { + for (uint64_t i = 0; i < n; i++) { + rt[i] = at[i] || bt[0]; + } + if (rnulls != NULL && bt[0]) { + for (uint64_t i = 0; i < n; i++) { + if (Bitmap_Contains(rnulls, i)) { + Bitmap_Remove(rnulls, i); + } + } + } + } else { + for (uint64_t i = 0; i < n; i++) { + rt[i] = at[i] || bt[i]; + } + if (anulls != NULL && bnulls != NULL) { + for (uint64_t i = 0; i < n; i++) { + if (Bitmap_Contains(anulls, i) && !Bitmap_Contains(bnulls, i)) { + if (bt[i]) { + Bitmap_Remove(rnulls, i); + } + } + + if (Bitmap_Contains(bnulls, i) && !Bitmap_Contains(anulls, i)) { + if (at[i]) { + Bitmap_Remove(rnulls, i); + } + } + } + } else if (anulls != NULL) { + for (uint64_t i = 0; i < n; i++) { + if (bt[i] && Bitmap_Contains(anulls, i)) { + Bitmap_Remove(rnulls, i); + } + } + } else if (bnulls != NULL) { + for (uint64_t i = 0; i < n; i++) { + if (at[i] && Bitmap_Contains(bnulls, i)) { + Bitmap_Remove(rnulls, i); + } + } + } + } + return RC_SUCCESS; +} + +/* + Logical exclusive or truth table + A | B | A XOR B + ------|--------|---------- + true | true | false + true | false | true + true | null | null + false | true | true + false | false | false + false | null | null + null | true | true + null | false | null + null | null | null +*/ +int32_t Logic_VecXor(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag) { + bool *rt = (bool *) r; + bool *at = (bool *) a; + bool *bt = (bool *) b; + if ((flag & LEFT_IS_SCALAR) != 0) { + for (uint64_t i = 0; i < n; i++) { + rt[i] = (at[0] || bt[i]) && !(at[0] && bt[i]); + } + } else if ((flag & RIGHT_IS_SCALAR) != 0) { + for (uint64_t i = 0; i < n; i++) { + rt[i] = (at[i] || bt[0]) && !(at[i] && bt[0]); + } + } else { + for (uint64_t i = 0; i < n; i++) { + rt[i] = (at[i] || bt[i]) && !(at[i] && bt[i]); + } + } + return RC_SUCCESS; +} + +/* + Logical not truth table + P | NOT P + ---------------- + true | false + false | true + null | null +*/ +int32_t Logic_VecNot(void *r, void *a, uint64_t n, uint64_t *nulls, int32_t flag) { + bool *rt = (bool *) r; + bool *at = (bool *) a; + if ((flag & LEFT_IS_SCALAR) != 0) { + rt[0] = !at[0]; + } else { + for (uint64_t i = 0; i < n; i++) { + rt[i] = !at[i]; + } + } + return RC_SUCCESS; +} \ No newline at end of file diff --git a/cgo/mo.c b/cgo/mo.c new file mode 100644 index 0000000..1e431bd --- /dev/null +++ b/cgo/mo.c @@ -0,0 +1,47 @@ +/* + * Copyright 2021 Matrix Origin + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mo_impl.h" + +void Bitmap_Add(uint64_t *p, uint64_t pos) { + bitmap_set(p, pos); +} +void Bitmap_Remove(uint64_t *p, uint64_t pos) { + bitmap_clear(p, pos); +} +bool Bitmap_Contains(uint64_t *p, uint64_t pos) { + if (p != NULL) { + return bitmap_test(p, pos); + } + return false; +} + +bool Bitmap_IsEmpty(uint64_t *p, uint64_t nbits) { + return bitmap_empty(p, nbits); +} +uint64_t Bitmap_Count(uint64_t *p, uint64_t nbits) { + return bitmap_count(p, nbits); +} + +void Bitmap_And(uint64_t *dst, uint64_t *a, uint64_t *b, uint64_t nbits) { + bitmap_and(dst, a, b, nbits); +} +void Bitmap_Or(uint64_t *dst, uint64_t *a, uint64_t *b, uint64_t nbits) { + bitmap_or(dst, a, b, nbits); +} +void Bitmap_Not(uint64_t *dst, uint64_t *a, uint64_t nbits) { + bitmap_not(dst, a, nbits); +} diff --git a/cgo/mo.h b/cgo/mo.h new file mode 100644 index 0000000..091652b --- /dev/null +++ b/cgo/mo.h @@ -0,0 +1,72 @@ +/* + * Copyright 2021 Matrix Origin + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _MO_H_ +#define _MO_H_ + +#include +#include + +/* Bitmap ops */ +void Bitmap_Add(uint64_t *p, uint64_t pos); +void Bitmap_Remove(uint64_t *p, uint64_t pos); +bool Bitmap_Contains(uint64_t *p, uint64_t pos); +bool Bitmap_IsEmpty(uint64_t *p, uint64_t nbits); +uint64_t Bitmap_Count(uint64_t *p, uint64_t nbits); +void Bitmap_And(uint64_t *dst, uint64_t *a, uint64_t *b, uint64_t nbits); +void Bitmap_Or(uint64_t *dst, uint64_t *a, uint64_t *b, uint64_t nbits); +void Bitmap_Not(uint64_t *dst, uint64_t *a, uint64_t nbits); + +/* vector arithmatics */ +int32_t SignedInt_VecAdd(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t szof); +int32_t UnsignedInt_VecAdd(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t szof); +int32_t Float_VecAdd(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t szof); + +int32_t SignedInt_VecSub(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t szof); +int32_t UnsignedInt_VecSub(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t szof); +int32_t Float_VecSub(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t szof); + +int32_t SignedInt_VecMul(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t szof); +int32_t UnsignedInt_VecMul(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t szof); +int32_t Float_VecMul(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t szof); + +int32_t Float_VecDiv(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t szof); +int32_t Float_VecIntegerDiv(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t szof); + +int32_t SignedInt_VecMod(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t szof); +int32_t UnsignedInt_VecMod(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t szof); +int32_t Float_VecMod(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t szof); + +/* compare operator */ +int32_t Numeric_VecEq(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t type); + +int32_t Numeric_VecNe(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t type); + +int32_t Numeric_VecGt(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t type); + +int32_t Numeric_VecGe(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t type); + +int32_t Numeric_VecLt(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t type); + +int32_t Numeric_VecLe(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag, int32_t type); + +/* vector logical operation */ +int32_t Logic_VecAnd(void *r, void *a, void *b, uint64_t n, uint64_t *anulls, uint64_t *bnulls, uint64_t *rnulls, int32_t flag); +int32_t Logic_VecOr(void *r, void *a, void *b, uint64_t n, uint64_t *anulls, uint64_t *bnulls, uint64_t *rnulls, int32_t flag); +int32_t Logic_VecXor(void *r, void *a, void *b, uint64_t n, uint64_t *nulls, int32_t flag); +int32_t Logic_VecNot(void *r, void *a, uint64_t n, uint64_t *nulls, int32_t flag); + +#endif /* _MO_H_ */ diff --git a/cgo/mo_impl.h b/cgo/mo_impl.h new file mode 100644 index 0000000..658bda0 --- /dev/null +++ b/cgo/mo_impl.h @@ -0,0 +1,43 @@ +/* + * Copyright 2021 Matrix Origin + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _MO_IMPL_H_ +#define _MO_IMPL_H_ + +#include "mo.h" + +#include +#include +#include + +static const int32_t RC_SUCCESS = 0; +static const int32_t RC_INFO = 1; +static const int32_t RC_WARN = 2; + +static const int32_t RC_INTERNAL_ERROR = 20101; + +static const int32_t RC_DIVISION_BY_ZERO = 20200; +static const int32_t RC_OUT_OF_RANGE = 20201; +static const int32_t RC_DATA_TRUNCATED = 20202; +static const int32_t RC_INVALID_ARGUMENT = 20203; + +static const int32_t LEFT_IS_SCALAR = 1; +static const int32_t RIGHT_IS_SCALAR = 2; + + +#include "bitmap.h" + +#endif /* _MO_IMPL_H_ */ diff --git a/cgo/test/.gitignore b/cgo/test/.gitignore new file mode 100644 index 0000000..b883f1f --- /dev/null +++ b/cgo/test/.gitignore @@ -0,0 +1 @@ +*.exe diff --git a/cgo/test/Makefile b/cgo/test/Makefile new file mode 100644 index 0000000..bbd9936 --- /dev/null +++ b/cgo/test/Makefile @@ -0,0 +1,7 @@ +CFLAGS=-I.. -g -Wall -Werror -lm + +test_add.exe: test_add.c ../libmo.a + $(CC) $(CFLAGS) -o test_add.exe test_add.c -L.. -lmo + +clean: + rm -f *.o *.exe diff --git a/cgo/test/test_add.c b/cgo/test/test_add.c new file mode 100644 index 0000000..02ea4a1 --- /dev/null +++ b/cgo/test/test_add.c @@ -0,0 +1,85 @@ +/* + * Copyright 2021 Matrix Origin + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include "../mo.h" + +int test_addi32() { + int32_t r[8192]; + int32_t a[8192]; + int32_t b[8192]; + for (int i = 0; i < 8192; i++) { + a[i] = i; + b[i] = 1; + } + + int32_t rc = SignedInt_VecAdd(r, a, b, 8192, NULL, 0, 4); + return rc; +} + +int test_adddec64() { + int64_t r[8192]; + int64_t a[8192]; + int64_t b[8192]; + for (int i = 0; i < 8192; i++) { + a[i] = -i; + b[i] = i; + } + + int32_t rc = Decimal64_VecAdd(r, a, b, 8192, NULL, 0); + return rc; +} + + +int test_subdec64() { + int64_t r[8192]; + int64_t a[8192]; + int64_t b[8192]; + for (int i = 0; i < 8192; i++) { + a[i] = i; + b[i] = i*3; + } + int32_t rc = Decimal64_VecSub(r, a, b, 8192, NULL, 0); + return rc; +} + +int test_divedec64(){ + int64_t r[10]; + int64_t a[10]; + int64_t b[10]; + for (int i = 0; i < 10; i++) { + a[i] = (i+1)*1024; + b[i] = 2; + } + int32_t rc = Decimal64_VecDiv(r, a, b, 10, NULL, 0); + + for (int i = 0; i < 10; i++) { + printf("%ld / %ld = ", a[i], b[i]); + printf("r[%d]=%ld \n", i, r[i]); + } + + return rc; +} + +int main() { +// test_addi32(); + //test_subdec64(); + //test_divedec64(); + test_adddec64(); + return 0; +} diff --git a/cmd/mo-dump/main.go b/cmd/mo-dump/main.go new file mode 100644 index 0000000..3052122 --- /dev/null +++ b/cmd/mo-dump/main.go @@ -0,0 +1,632 @@ +// Copyright 2023 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package main + +import ( + "bytes" + "context" + "database/sql" + "encoding/csv" + "flag" + "fmt" + "io" + "os" + "strings" + "sync" + "time" + "unicode/utf8" + + _ "github.com/go-sql-driver/mysql" + "github.com/matrixorigin/matrixone/pkg/catalog" + "github.com/matrixorigin/matrixone/pkg/common/moerr" +) + +type Options struct { + username string + password string + host string + database string + tbl string + dbs []string + tables Tables + port int + netBufferLength int + toCsv bool + localInfile bool + noData bool + emptyTables bool + csvConf csvConfig + csvFieldDelimiterStr string +} + +func (t *Tables) String() string { + return fmt.Sprint(*t) +} + +func (t *Tables) Set(value string) error { + *t = append(*t, Table{value, ""}) + return nil +} + +func main() { + var ( + err error + opt Options + ) + dumpStart := time.Now() + defer func() { + if err != nil { + fmt.Fprintf(os.Stderr, "modump error: %v\n", err) + } + if conn != nil { + err := conn.Close() + if err != nil { + fmt.Fprintf(os.Stderr, "modump error while close connection: %v\n", err) + } + } + if err == nil { + fmt.Fprintf(os.Stdout, "/* MODUMP SUCCESS, COST %v */\n", time.Since(dumpStart)) + if opt.toCsv { + fmt.Fprintf(os.Stdout, "/* !!!MUST KEEP FILE IN CURRENT DIRECTORY, OR YOU SHOULD CHANGE THE PATH IN LOAD DATA STMT!!! */ \n") + } + } + }() + + ctx := context.Background() + flag.StringVar(&opt.username, "u", defaultUsername, "username") + flag.StringVar(&opt.password, "p", defaultPassword, "password") + flag.StringVar(&opt.host, "h", defaultHost, "hostname") + flag.IntVar(&opt.port, "P", defaultPort, "portNumber") + flag.IntVar(&opt.netBufferLength, "net-buffer-length", defaultNetBufferLength, "net_buffer_length") + flag.StringVar(&opt.database, "db", "", "databaseName, must be specified") + flag.StringVar(&opt.tbl, "tbl", "", "tableNameList, default all") + flag.BoolVar(&opt.toCsv, "csv", defaultCsv, "set export format to csv") + flag.StringVar(&opt.csvFieldDelimiterStr, "csv-field-delimiter", string(defaultFieldDelimiter), "set csv field delimiter (only one utf8 character). enabled only when the option 'csv' is set.") + flag.BoolVar(&opt.localInfile, "local-infile", defaultLocalInfile, "use load data local infile") + flag.BoolVar(&opt.noData, "no-data", defaultNoData, "dump database and table definitions only without data") + flag.Parse() + + if opt.netBufferLength < minNetBufferLength { + fmt.Fprintf(os.Stderr, "net_buffer_length must be greater than %d, set to %d\n", minNetBufferLength, minNetBufferLength) + opt.netBufferLength = minNetBufferLength + } + if opt.netBufferLength > maxNetBufferLength { + fmt.Fprintf(os.Stderr, "net_buffer_length must be less than %d, set to %d\n", maxNetBufferLength, maxNetBufferLength) + opt.netBufferLength = maxNetBufferLength + } + opt.dbs = strings.Split(opt.database, ",") + if len(opt.dbs) == 0 { + err = moerr.NewInvalidInput(ctx, "database must be specified") + return + } + if len(opt.tbl) > 0 { + tbls := strings.Split(opt.tbl, ",") + for _, t := range tbls { + if len(t) != 0 { + opt.tables = append(opt.tables, Table{t, ""}) + } + } + } + + //replace : in username to #, because : is used as separator in dsn. + //password can have ":". + opt.username = strings.ReplaceAll(opt.username, ":", "#") + + // if host has ":", reports error + if strings.Count(opt.host, ":") > 0 { + err = moerr.NewInvalidInput(ctx, "host can not have character ':'") + return + } + + if opt.toCsv { + opt.csvConf.enable = opt.toCsv + opt.csvConf.fieldDelimiter, err = checkFieldDelimiter(ctx, opt.csvFieldDelimiterStr) + if err != nil { + return + } + } + + if opt.database == "all" { + conn, err = opt.openDBConnection(ctx, "") + if err != nil { + return + } + defer conn.Close() + + opt.dbs, err = getDatabases(ctx) + if err != nil { + return + } + if opt.tables == nil { + opt.emptyTables = true + } + } + + err = opt.dumpData(ctx) + if err != nil { + return + } +} + +func (opt *Options) dumpData(ctx context.Context) error { + var ( + createDb string + createTable []string + err error + ) + + if conn == nil { + conn, err = opt.openDBConnection(ctx, opt.dbs[0]) + if err != nil { + return err + } + defer conn.Close() + } + + for _, db := range opt.dbs { + if opt.emptyTables { + opt.tables = nil + } + if len(opt.tables) == 0 { //dump all tables + createDb, err = getCreateDB(ctx, db) + if err != nil { + return err + } + fmt.Printf("DROP DATABASE IF EXISTS `%s`;\n", db) + fmt.Println(createDb, ";") + fmt.Printf("USE `%s`;\n\n\n", db) + } + opt.tables, err = getTables(db, opt.tables) + if err != nil { + return err + } + createTable = make([]string, len(opt.tables)) + for i, tbl := range opt.tables { + createTable[i], err = getCreateTable(db, tbl.Name) + if err != nil { + return err + } + } + bufPool := &sync.Pool{ + New: func() any { + return &bytes.Buffer{} + }, + } + left, right := 0, len(createTable)-1 + for left < right { + for left < len(createTable) && opt.tables[left].Kind != catalog.SystemViewRel { + left++ + } + for right >= 0 && opt.tables[right].Kind == catalog.SystemViewRel { + right-- + } + if left >= right { + break + } + createTable[left], createTable[right] = createTable[right], createTable[left] + opt.tables[left], opt.tables[right] = opt.tables[right], opt.tables[left] + } + adjustViewOrder(createTable, opt.tables, left) + for i, create := range createTable { + tbl := opt.tables[i] + switch tbl.Kind { + case catalog.SystemOrdinaryRel: + fmt.Printf("DROP TABLE IF EXISTS `%s`;\n", tbl.Name) + showCreateTable(create, false) + if !opt.noData { + err = genOutput(db, tbl.Name, bufPool, opt.netBufferLength, opt.localInfile, &opt.csvConf) + if err != nil { + return err + } + } + case catalog.SystemExternalRel: + fmt.Printf("/*!EXTERNAL TABLE `%s`*/\n", tbl.Name) + fmt.Printf("DROP TABLE IF EXISTS `%s`;\n", tbl.Name) + showCreateTable(create, true) + case catalog.SystemViewRel: + fmt.Printf("DROP VIEW IF EXISTS `%s`;\n", tbl.Name) + showCreateTable(create, true) + default: + err = moerr.NewNotSupported(ctx, "table type %s", tbl.Kind) + return err + } + } + } + return nil +} + +func (opt *Options) openDBConnection(ctx context.Context, database string) (*sql.DB, error) { + dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s", opt.username, opt.password, opt.host, opt.port, database) + + conn, err := sql.Open("mysql", dsn) + if err != nil { + return nil, err + } + + ch := make(chan error) + go func() { + err := conn.Ping() + ch <- err + }() + + select { + case err = <-ch: + case <-time.After(timeout): + return nil, moerr.NewInternalError(ctx, "connect to %s timeout", dsn) + } + if err != nil { + return nil, err + } + + return conn, nil +} + +func adjustViewOrder(createTable []string, tables Tables, start int) { + viewName := make([]string, 0) + viewPos := make(map[string]int) + cnt := len(tables) + for i := start; i < cnt; i++ { + viewPos[tables[i].Name] = i - start + viewName = append(viewName, tables[i].Name) + } + viewCount := make([]int, len(viewName)) + viewRef := make([][]int, len(viewName)) + for i := start; i < cnt; i++ { + for j := start; j < cnt; j++ { + if i == j { + continue + } + if strings.Count(createTable[i], tables[j].Name) > 0 { + viewCount[viewPos[tables[i].Name]]++ + viewRef[viewPos[tables[j].Name]] = append(viewRef[viewPos[tables[j].Name]], viewPos[tables[i].Name]) + } + } + } + order := 0 + orderArr := make([]int, 0) + visit := make([]bool, len(viewName)) + for order < len(viewName) { + for i := 0; i < len(viewName); i++ { + if viewCount[i] == 0 && !visit[i] { + visit[i] = true + order++ + orderArr = append(orderArr, i) + for j := 0; j < len(viewRef[i]); j++ { + viewCount[viewRef[i][j]]-- + } + } + } + } + newCreate := make([]string, cnt) + newTables := make([]Table, cnt) + for i := 0; i < len(orderArr); i++ { + newCreate[i] = createTable[orderArr[i]+start] + newTables[i] = tables[orderArr[i]+start] + } + _ = copy(createTable[start:], newCreate) + _ = copy(tables[start:], newTables) +} + +func showCreateTable(createSql string, withNextLine bool) { + var suffix string + if !strings.HasSuffix(createSql, ";") { + suffix = ";" + } + if withNextLine { + suffix += "\n\n" + } + fmt.Printf("%s%s\n", createSql, suffix) +} + +func getTables(db string, tables Tables) (Tables, error) { + sql := "select relname,relkind from mo_catalog.mo_tables where reldatabase = '" + db + "'" + if len(tables) > 0 { + sql += " and relname in (" + for i, tbl := range tables { + if i != 0 { + sql += "," + } + sql += "'" + tbl.Name + "'" + } + sql += ")" + } + r, err := conn.Query(sql) //TODO: after unified sys table prefix, add condition in where clause + if err != nil { + return nil, err + } + defer r.Close() + + if tables == nil { + tables = Tables{} + } + tables = tables[:0] + for r.Next() { + var table string + var kind string + err = r.Scan(&table, &kind) + if err != nil { + return nil, err + } + if strings.HasPrefix(table, "__mo_") || strings.HasPrefix(table, "%!%") { //TODO: after adding condition in where clause, remove this + continue + } + tables = append(tables, Table{table, kind}) + } + if err := r.Err(); err != nil { + return nil, err + } + return tables, nil +} + +func getCreateDB(ctx context.Context, db string) (string, error) { + r := conn.QueryRow("show create database `" + db + "`") + var create string + err := r.Scan(&db, &create) + if err != nil { + return "", err + } + // What if it is a subscription database? + return create, err +} + +func getDatabases(ctx context.Context) ([]string, error) { + r, err := conn.QueryContext(ctx, "show databases") + if err != nil { + return nil, err + } + if r.Err() != nil { + return nil, r.Err() + } + dbs := make([]string, 0) + + for r.Next() { + var dbName string + err := r.Scan(&dbName) + if err != nil { + return nil, err + } + dbs = append(dbs, dbName) + } + defer r.Close() + + return dbs, nil +} + +func getCreateTable(db, tbl string) (string, error) { + r := conn.QueryRow("show create table `" + db + "`.`" + tbl + "`") + var create string + err := r.Scan(&tbl, &create) + if err != nil { + return "", err + } + return create, nil +} + +func showInsert(r *sql.Rows, args []any, cols []*Column, tbl string, bufPool *sync.Pool, netBufferLength int) error { + var err error + buf := bufPool.Get().(*bytes.Buffer) + curBuf := bufPool.Get().(*bytes.Buffer) + buf.Grow(netBufferLength) + initInert := "INSERT INTO `" + tbl + "` VALUES " + for { + buf.WriteString(initInert) + preLen := buf.Len() + first := true + if curBuf.Len() > 0 { + bts := curBuf.Bytes() + if bts[0] == ',' { + bts = bts[1:] + } + buf.Write(bts) + curBuf.Reset() + first = false + } + for r.Next() { + err = r.Scan(args...) + if err != nil { + return err + } + if !first { + curBuf.WriteString(",(") + } else { + curBuf.WriteString("(") + first = false + } + + for i, v := range args { + if i > 0 { + curBuf.WriteString(",") + } + curBuf.WriteString(convertValue(v, cols[i].Type)) + } + curBuf.WriteString(")") + if buf.Len()+curBuf.Len() >= netBufferLength { + break + } + buf.Write(curBuf.Bytes()) + curBuf.Reset() + } + if buf.Len() > preLen { + buf.WriteString(";\n") + _, err = buf.WriteTo(os.Stdout) + if err != nil { + return err + } + continue + } + if curBuf.Len() > 0 { + continue + } + buf.Reset() + curBuf.Reset() + break + } + bufPool.Put(buf) + bufPool.Put(curBuf) + fmt.Printf("\n\n\n") + return nil +} + +func showLoad(r *sql.Rows, rowResults []any, cols []*Column, db string, tbl string, localInfile bool, csvConf *csvConfig) error { + fname := fmt.Sprintf("%s_%s.%s", db, tbl, "csv") + pwd := os.Getenv("PWD") + f, err := os.Create(fname) + if err != nil { + return err + } + defer f.Close() + + err = toCsv(r, f, rowResults, cols, csvConf) + if err != nil { + return err + } + if localInfile { + fmt.Printf("LOAD DATA LOCAL INFILE '%s' INTO TABLE `%s` FIELDS TERMINATED BY '\\t' ENCLOSED BY '\"' LINES TERMINATED BY '\\n' PARALLEL 'TRUE';\n", fmt.Sprintf("%s/%s", pwd, fname), tbl) + } else { + fmt.Printf("LOAD DATA INFILE '%s' INTO TABLE `%s` FIELDS TERMINATED BY '\\t' ENCLOSED BY '\"' LINES TERMINATED BY '\\n' PARALLEL 'TRUE';\n", fmt.Sprintf("%s/%s", pwd, fname), tbl) + } + return nil +} + +// toCsv converts the result from mo to csv file +func toCsv(r *sql.Rows, output io.Writer, rowResults []any, cols []*Column, csvConf *csvConfig) error { + var err error + csvWriter := csv.NewWriter(output) + csvWriter.Comma = csvConf.fieldDelimiter + line := make([]string, len(rowResults)) + + for r.Next() { + err = r.Scan(rowResults...) + if err != nil { + return err + } + err = toCsvLine(csvWriter, rowResults, cols, line) + if err != nil { + return err + } + } + return err +} + +// toCsvFields converts the result from mo to string +func toCsvFields(rowResults []any, cols []*Column, line []string) { + for i, v := range rowResults { + dt, format := convertValue2(v, cols[i].Type) + str := fmt.Sprintf(format, dt) + line[i] = str + } +} + +// toCsvLine converts the result from mo to csv single line +func toCsvLine(csvWriter *csv.Writer, rowResults []any, cols []*Column, line []string) error { + var err error + toCsvFields(rowResults, cols, line) + err = csvWriter.Write(line) + if err != nil { + return err + } + csvWriter.Flush() + return err +} + +func genOutput(db string, tbl string, bufPool *sync.Pool, netBufferLength int, localInfile bool, csvConf *csvConfig) error { + r, err := conn.Query("select * from `" + db + "`.`" + tbl + "`") + if err != nil { + return err + } + colTypes, err := r.ColumnTypes() + if err != nil { + return err + } + cols := make([]*Column, 0, len(colTypes)) + for _, col := range colTypes { + var c Column + c.Name = col.Name() + c.Type = col.DatabaseTypeName() + cols = append(cols, &c) + } + rowResults := make([]any, 0, len(cols)) + for range cols { + var v sql.RawBytes + rowResults = append(rowResults, &v) + } + if !csvConf.enable { + return showInsert(r, rowResults, cols, tbl, bufPool, netBufferLength) + } + return showLoad(r, rowResults, cols, db, tbl, localInfile, csvConf) +} + +func convertValue(v any, typ string) string { + ret := *(v.(*sql.RawBytes)) + if ret == nil { + return "NULL" + } + typ = strings.ToLower(typ) + switch typ { + case "float": + retStr := string(ret) + if (retStr[0] >= '0' && retStr[0] <= '9') || (retStr[0] == '-' && retStr[1] >= '0' && retStr[1] <= '9') { + return retStr + } + return "'" + retStr + "'" // NaN, +Inf, -Inf, maybe no hacking need in the future + case "int", "tinyint", "smallint", "bigint", "unsigned bigint", "unsigned int", "unsigned tinyint", "unsigned smallint", "double", "bool", "boolean", "": + // why empty string in column type? + // see https://github.com/matrixorigin/matrixone/issues/8050#issuecomment-1431251524 + return string(ret) + case "vecf32", "vecf64": + return string(ret) + default: + str := strings.Replace(string(ret), "\\", "\\\\", -1) + return "'" + strings.Replace(str, "'", "\\'", -1) + "'" + } +} + +func convertValue2(v any, typ string) (sql.RawBytes, string) { + ret := *(v.(*sql.RawBytes)) + if ret == nil { + return nullBytes, defaultFmt + } + typ = strings.ToLower(typ) + switch typ { + case "int", "tinyint", "smallint", "bigint", "unsigned bigint", "unsigned int", "unsigned tinyint", "unsigned smallint", "double", "bool", "boolean", "", "float": + // why empty string in column type? + // see https://github.com/matrixorigin/matrixone/issues/8050#issuecomment-1431251524 + return ret, defaultFmt + case "json": + return ret, jsonFmt + case "vecf32", "vecf64": + return ret, defaultFmt + default: + //note: do not use the quoteFmt instead of the standard package csv, + //it is error-prone. + return ret, defaultFmt + } +} + +// checkFieldDelimiter checks string is valid utf8 character and returns rune +func checkFieldDelimiter(ctx context.Context, s string) (rune, error) { + if utf8.ValidString(s) { + if utf8.RuneCountInString(s) > 1 { + return rune(0), moerr.NewInvalidInput(ctx, "there are multiple utf8 characters for csv field delimiter. only one utf8 character is allowed") + } + runCh, _ := utf8.DecodeRuneInString(s) + if runCh == utf8.RuneError { + return rune(0), moerr.NewInvalidInput(ctx, "csv field delimiter is invalid utf8 character") + } + return runCh, nil + } else { + return rune(0), moerr.NewInvalidInput(ctx, "csv field delimiter is invalid utf8 character") + } +} diff --git a/cmd/mo-dump/main_test.go b/cmd/mo-dump/main_test.go new file mode 100644 index 0000000..84b33e3 --- /dev/null +++ b/cmd/mo-dump/main_test.go @@ -0,0 +1,403 @@ +// Copyright 2023 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +package main + +import ( + "bytes" + "context" + "database/sql" + "encoding/csv" + "fmt" + "os" + "strings" + "testing" + "unicode/utf8" + + sqlmock "github.com/DATA-DOG/go-sqlmock" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestConvertValue(t *testing.T) { + kase := []struct { + val string + typ string + }{ + {"1", "int"}, + {"1", "tinyint"}, + {"1", "smallint"}, + {"1", "bigint"}, + {"1", "unsigned bigint"}, + {"1", "unsigned int"}, + {"1", "unsigned tinyint"}, + {"1", "unsigned smallint"}, + {"1.1", "float"}, + {"1.1", "double"}, + {"1.1", "decimal"}, + {"asa", "varchar"}, + {"asa", "char"}, + {"asa", "text"}, + {"asa", "blob"}, + {"asa", "uuid"}, + {"asa", "json"}, + {"2021-01-01", "date"}, + {"2021-01-01 00:00:00", "datetime"}, + {"2021-01-01 00:00:00", "timestamp"}, + {"[1,2,3]", "vecf32"}, + {"[4,5,6]", "vecf64"}, + } + for _, v := range kase { + s := convertValue(makeValue(v.val), v.typ) + switch v.typ { + case "int", "tinyint", "smallint", "bigint", "unsigned bigint", "unsigned int", "unsigned tinyint", "unsigned smallint", "float", "double", "vecf32", "vecf64": + require.Equal(t, v.val, s) + default: + + require.Equal(t, fmt.Sprintf("'%v'", v.val), s) + } + } +} + +func makeValue(val string) interface{} { + tmp := sql.RawBytes(val) + return &tmp +} + +func TestConvertValue2(t *testing.T) { + v := makeValue("\\10\\11\\12") + v2, f := convertValue2(v, "string") + assert.Equal(t, *(v.(*sql.RawBytes)), v2) + assert.Equal(t, f, defaultFmt) +} + +func TestShowCreateTable(t *testing.T) { + kases := []struct { + sql string + withNextLine bool + res string + }{ + { + sql: "create table t1 (a int, b int)", + withNextLine: false, + res: "create table t1 (a int, b int);\n", + }, + { + sql: "create table t1 (a int, b int)", + withNextLine: true, + res: "create table t1 (a int, b int);\n\n\n", + }, + { + sql: "create table t1 (a int, b int);", + withNextLine: false, + res: "create table t1 (a int, b int);\n", + }, + { + sql: "create table t1 (a int, b int);", + withNextLine: true, + res: "create table t1 (a int, b int);\n\n\n", + }, + } + old := os.Stdout + for _, v := range kases { + r, w, _ := os.Pipe() + os.Stdout = w + showCreateTable(v.sql, v.withNextLine) + + e := w.Close() + require.Nil(t, e) + var buf bytes.Buffer + _, e = buf.ReadFrom(r) + require.Nil(t, e) + require.Equal(t, v.res, buf.String()) + } + os.Stdout = old +} + +func TestViewOrder(t *testing.T) { + start := 1 + createTable := []string{ + "create table t1(a int);", + "create view t4 as select * from t2, t3;", + "create view t2 as select * from t1;", + "create view t3 as select * from t2;", + "create view t6 as select * from t4, t5;", + "create view t5 as select * from t4;", + } + tables := []Table{ + {Name: "t1"}, + {Name: "t4"}, + {Name: "t2"}, + {Name: "t3"}, + {Name: "t6"}, + {Name: "t5"}, + } + createTarget := []string{ + "create table t1(a int);", + "create view t2 as select * from t1;", + "create view t3 as select * from t2;", + "create view t4 as select * from t2, t3;", + "create view t5 as select * from t4;", + "create view t6 as select * from t4, t5;", + } + tableTarget := []Table{ + {Name: "t1"}, + {Name: "t2"}, + {Name: "t3"}, + {Name: "t4"}, + {Name: "t5"}, + {Name: "t6"}, + } + adjustViewOrder(createTable, tables, start) + for i := 0; i < len(createTable); i++ { + require.Equal(t, createTable[i], createTarget[i]) + require.Equal(t, tables[i], tableTarget[i]) + } +} + +func Test_toCsvFields(t *testing.T) { + bys1 := []byte{0x5C, 0x31, 0x30, 0x5C, 0x33, 0x36, 0x5C, 0x38, 0x36, 0x5c} + args1 := []any{makeValue(string(bys1))} + cols1 := []*Column{ + { + Name: "col1", + Type: "varchar", + }, + } + line := make([]string, 1) + toCsvFields(args1, cols1, line) + want := "\\10\\36\\86\\" + assert.Equal(t, want, line[0]) +} + +func Test_toCsvLine(t *testing.T) { + bys1 := []byte{0x5C, 0x31, 0x30, 0x5C, 0x33, 0x36, 0x5C, 0x38, 0x36, 0x5c} + args1 := []any{makeValue(string(bys1))} + cols1 := []*Column{ + { + Name: "col1", + Type: "varchar", + }, + } + line := make([]string, 1) + bb := bytes.Buffer{} + cw1 := csv.NewWriter(&bb) + cw1.Comma = '\t' + err := toCsvLine(cw1, args1, cols1, line) + assert.NoError(t, err) + want := "\\10\\36\\86\\" + assert.Equal(t, want, line[0]) + assert.Equal(t, bb.Bytes()[:len(bys1)], bys1) +} + +func Test_checkFieldDelimiter(t *testing.T) { + type args struct { + ctx context.Context + s string + } + tests := []struct { + name string + args args + want rune + wantErr assert.ErrorAssertionFunc + }{ + { + name: "t1", + args: args{ + ctx: nil, + s: "", + }, + want: defaultFieldDelimiter, + wantErr: func(t assert.TestingT, err error, i ...interface{}) bool { + assert.Error(t, err) + assert.True(t, strings.Contains(err.Error(), "csv field delimiter is invalid utf8 character")) + return false + }, + }, + { + name: "t2", + args: args{ + ctx: nil, + s: "fdaf", + }, + want: defaultFieldDelimiter, + wantErr: func(t assert.TestingT, err error, i ...interface{}) bool { + assert.Error(t, err) + assert.True(t, strings.Contains(err.Error(), "there are multiple utf8 characters for csv field delimiter.")) + return false + }, + }, + { + name: "t3", + args: args{ + ctx: nil, + s: string([]rune{utf8.RuneError}), + }, + want: defaultFieldDelimiter, + wantErr: func(t assert.TestingT, err error, i ...interface{}) bool { + assert.Error(t, err) + assert.True(t, strings.Contains(err.Error(), "csv field delimiter is invalid utf8 character")) + return false + }, + }, + { + name: "t4", + args: args{ + ctx: nil, + s: " ", + }, + want: defaultFieldDelimiter, + wantErr: func(t assert.TestingT, err error, i ...interface{}) bool { + assert.NoError(t, err) + return false + }, + }, + { + name: "t5", + args: args{ + ctx: nil, + s: "中文", + }, + want: defaultFieldDelimiter, + wantErr: func(t assert.TestingT, err error, i ...interface{}) bool { + assert.Error(t, err) + assert.True(t, strings.Contains(err.Error(), "there are multiple utf8 characters for csv field delimiter.")) + return false + }, + }, + { + name: "t6", + args: args{ + ctx: nil, + s: "中", + }, + want: defaultFieldDelimiter, + wantErr: func(t assert.TestingT, err error, i ...interface{}) bool { + assert.NoError(t, err) + return false + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := checkFieldDelimiter(tt.args.ctx, tt.args.s) + if !tt.wantErr(t, err, fmt.Sprintf("checkFieldDelimiter(%v, %v)", tt.args.ctx, tt.args.s)) { + return + } + assert.Equalf(t, tt.want, got, "checkFieldDelimiter(%v, %v)", tt.args.ctx, tt.args.s) + }) + } +} + +func TestGetDatabases(t *testing.T) { + // create mock database + db, mock, err := sqlmock.New() + if err != nil { + t.Fatalf("Failed to create mock database: %v", err) + } + defer db.Close() + + ctx := context.Background() + + rows := sqlmock.NewRows([]string{"Database"}). + AddRow("db1"). + AddRow("db2"). + AddRow("db3") + + mock.ExpectQuery("show databases").WillReturnRows(rows) + + conn = db + databases, err := getDatabases(ctx) + + // check the results + assert.NoError(t, err) + expected := []string{"db1", "db2", "db3"} + if len(databases) != len(expected) { + t.Errorf("Unexpected number of databases. Expected: %d, Got: %d", len(expected), len(databases)) + } + + for i, db := range databases { + if db != expected[i] { + t.Errorf("Unexpected database name at index %d. Expected: %s, Got: %s", i, expected[i], db) + } + } + + if err := mock.ExpectationsWereMet(); err != nil { + t.Errorf("Unfulfilled expectations: %s", err) + } +} + +func TestGetCreateDB(t *testing.T) { + // create mock database + db, mock, err := sqlmock.New() + if err != nil { + t.Fatalf("Failed to create mock database: %v", err) + } + defer db.Close() + + ctx := context.Background() + + rows := sqlmock.NewRows([]string{"Database", "Create"}). + AddRow("db1", "CREATE DATABASE db1"). + AddRow("db2", "CREATE DATABASE db2"). + AddRow("db3", "CREATE DATABASE db3") + + mock.ExpectQuery("show create database").WillReturnRows(rows) + conn = db + + // check the results + createDB, err := getCreateDB(ctx, "db1") + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + + expectedCreateDB := "CREATE DATABASE db1" + if createDB != expectedCreateDB { + t.Errorf("Unexpected create database statement. Expected: %s, Got: %s", expectedCreateDB, createDB) + } + + if err := mock.ExpectationsWereMet(); err != nil { + t.Errorf("Unfulfilled expectations: %s", err) + } +} + +func TestGetCreateTable(t *testing.T) { + // create mock database + db, mock, err := sqlmock.New() + if err != nil { + t.Fatalf("Failed to create mock database: %v", err) + } + defer db.Close() + + rows := sqlmock.NewRows([]string{"Table", "Create"}). + AddRow("table1", "CREATE TABLE table1 (id INT, name VARCHAR(255))"). + AddRow("table2", "CREATE TABLE table2 (id INT, age INT)") + + mock.ExpectQuery("show create table").WillReturnRows(rows) + conn = db + + // check the results + createTable, err := getCreateTable("db1", "table1") + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + + expectedCreateTable := "CREATE TABLE table1 (id INT, name VARCHAR(255))" + if createTable != expectedCreateTable { + t.Errorf("Unexpected create table statement. Expected: %s, Got: %s", expectedCreateTable, createTable) + } + + if err := mock.ExpectationsWereMet(); err != nil { + t.Errorf("Unfulfilled expectations: %s", err) + } +} diff --git a/cmd/mo-dump/types.go b/cmd/mo-dump/types.go new file mode 100644 index 0000000..8148784 --- /dev/null +++ b/cmd/mo-dump/types.go @@ -0,0 +1,67 @@ +// Copyright 2023 Matrix Origin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package main + +import ( + "database/sql" + "time" + + "github.com/matrixorigin/matrixone/pkg/common/mpool" +) + +const ( + defaultUsername = "dump" + defaultPassword = "111" + defaultHost = "127.0.0.1" + defaultPort = 6001 + defaultNetBufferLength = mpool.MB + minNetBufferLength = mpool.KB * 16 + maxNetBufferLength = mpool.MB * 16 + defaultCsv = false + defaultLocalInfile = true + defaultNoData = false + timeout = 10 * time.Second + //default Field delimiter (set to ',') + defaultFieldDelimiter rune = ',' +) + +const ( + quoteFmt = "%q" + defaultFmt = "%s" + jsonFmt = "\"%s\"" +) + +var ( + conn *sql.DB + nullBytes = []byte("\\N") +) + +type Column struct { + Name string + Type string +} + +type Table struct { + Name string + Kind string +} + +type Tables []Table + +// csvConfig is the configuration for csv output +type csvConfig struct { + enable bool + fieldDelimiter rune +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..99474aa --- /dev/null +++ b/go.mod @@ -0,0 +1,84 @@ +module github.com/matrixorigin/mo_dump + +go 1.20 + +require ( + github.com/DATA-DOG/go-sqlmock v1.5.0 + github.com/go-sql-driver/mysql v1.7.1 + github.com/matrixorigin/matrixone v0.7.1-0.20230906044843-ce0185d3a794 + github.com/stretchr/testify v1.8.4 +) + +require ( + github.com/FastFilter/xorfilter v0.1.3 // indirect + github.com/RoaringBitmap/roaring v1.2.3 // indirect + github.com/alibabacloud-go/debug v0.0.0-20190504072949-9472017b5c68 // indirect + github.com/alibabacloud-go/tea v1.1.8 // indirect + github.com/aliyun/credentials-go v1.2.7 // indirect + github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 // indirect + github.com/aws/aws-sdk-go-v2 v1.18.0 // indirect + github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10 // indirect + github.com/aws/aws-sdk-go-v2/config v1.18.25 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.13.24 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.3 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.33 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.27 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.3.34 // indirect + github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.25 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.11 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.28 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.27 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.14.2 // indirect + github.com/aws/aws-sdk-go-v2/service/s3 v1.33.1 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.12.10 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.10 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.19.0 // indirect + github.com/aws/smithy-go v1.13.5 // indirect + github.com/axiomhq/hyperloglog v0.0.0-20230201085229-3ddf4bad03dc // indirect + github.com/bits-and-blooms/bitset v1.2.0 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/cockroachdb/errors v1.9.1 // indirect + github.com/cockroachdb/redact v1.1.3 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/dgryski/go-metro v0.0.0-20180109044635-280f6062b5bc // indirect + github.com/docker/go-units v0.5.0 // indirect + github.com/fagongzi/goetty/v2 v2.0.3-0.20230628075727-26c9a2fd5fb8 // indirect + github.com/fagongzi/util v0.0.0-20210923134909-bccc37b5040d // indirect + github.com/getsentry/sentry-go v0.17.0 // indirect + github.com/go-ole/go-ole v1.2.6 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/google/btree v1.1.2 // indirect + github.com/google/go-cmp v0.5.9 // indirect + github.com/google/pprof v0.0.0-20230510103437-eeec1cb781c3 // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/kr/pretty v0.3.1 // indirect + github.com/kr/text v0.2.0 // indirect + github.com/lni/dragonboat/v4 v4.0.0-20220815145555-6f622e8bcbef // indirect + github.com/lni/goutils v1.3.1-0.20220604063047-388d67b4dbc4 // indirect + github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect + github.com/mschoch/smat v0.2.0 // indirect + github.com/petermattis/goid v0.0.0-20230518223814-80aa455d8761 // indirect + github.com/pierrec/lz4/v4 v4.1.17 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/plar/go-adaptive-radix-tree v1.0.5 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect + github.com/robfig/cron/v3 v3.0.1 // indirect + github.com/rogpeppe/go-internal v1.9.0 // indirect + github.com/samber/lo v1.38.1 // indirect + github.com/shirou/gopsutil/v3 v3.22.4 // indirect + github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.673 // indirect + github.com/tidwall/btree v1.6.0 // indirect + github.com/yusufpapurcu/wmi v1.2.2 // indirect + go.uber.org/atomic v1.11.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/ratelimit v0.2.0 // indirect + go.uber.org/zap v1.24.0 // indirect + golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc // indirect + golang.org/x/net v0.10.0 // indirect + golang.org/x/sys v0.8.0 // indirect + gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect + gopkg.in/ini.v1 v1.67.0 // indirect + gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..c8fa573 --- /dev/null +++ b/go.sum @@ -0,0 +1,498 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak= +github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= +github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo= +github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= +github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= +github.com/FastFilter/xorfilter v0.1.3 h1:c0nMe68qEoce/2NIolD2nvwQnIgIFBOYI34HcnsjQSc= +github.com/FastFilter/xorfilter v0.1.3/go.mod h1:RB6+tbWbRN163V4y7z10tNfZec6n1oTsOElP0Tu5hzU= +github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= +github.com/RoaringBitmap/roaring v1.2.3 h1:yqreLINqIrX22ErkKI0vY47/ivtJr6n+kMhVOVmhWBY= +github.com/RoaringBitmap/roaring v1.2.3/go.mod h1:plvDsJQpxOC5bw8LRteu/MLWHsHez/3y6cubLI4/1yE= +github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= +github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= +github.com/alibabacloud-go/debug v0.0.0-20190504072949-9472017b5c68 h1:NqugFkGxx1TXSh/pBcU00Y6bljgDPaFdh5MUSeJ7e50= +github.com/alibabacloud-go/debug v0.0.0-20190504072949-9472017b5c68/go.mod h1:6pb/Qy8c+lqua8cFpEy7g39NRRqOWc3rOwAy8m5Y2BY= +github.com/alibabacloud-go/tea v1.1.8 h1:vFF0707fqjGiQTxrtMnIXRjOCvQXf49CuDVRtTopmwU= +github.com/alibabacloud-go/tea v1.1.8/go.mod h1:/tmnEaQMyb4Ky1/5D+SE1BAsa5zj/KeGOFfwYm3N/p4= +github.com/aliyun/credentials-go v1.2.7 h1:gLtFylxLZ1TWi1pStIt1O6a53GFU1zkNwjtJir2B4ow= +github.com/aliyun/credentials-go v1.2.7/go.mod h1:/KowD1cfGSLrLsH28Jr8W+xwoId0ywIy5lNzDz6O1vw= +github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 h1:MzBOUgng9orim59UnfUTLRjMpd09C5uEVQ6RPGeCaVI= +github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129/go.mod h1:rFgpPQZYZ8vdbc+48xibu8ALc3yeyd64IhHS+PU6Yyg= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/aws/aws-sdk-go-v2 v1.18.0 h1:882kkTpSFhdgYRKVZ/VCgf7sd0ru57p2JCxz4/oN5RY= +github.com/aws/aws-sdk-go-v2 v1.18.0/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3ePWVW6EtJvvw= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10 h1:dK82zF6kkPeCo8J1e+tGx4JdvDIQzj7ygIoLg8WMuGs= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10/go.mod h1:VeTZetY5KRJLuD/7fkQXMU6Mw7H5m/KP2J5Iy9osMno= +github.com/aws/aws-sdk-go-v2/config v1.18.25 h1:JuYyZcnMPBiFqn87L2cRppo+rNwgah6YwD3VuyvaW6Q= +github.com/aws/aws-sdk-go-v2/config v1.18.25/go.mod h1:dZnYpD5wTW/dQF0rRNLVypB396zWCcPiBIvdvSWHEg4= +github.com/aws/aws-sdk-go-v2/credentials v1.13.24 h1:PjiYyls3QdCrzqUN35jMWtUK1vqVZ+zLfdOa/UPFDp0= +github.com/aws/aws-sdk-go-v2/credentials v1.13.24/go.mod h1:jYPYi99wUOPIFi0rhiOvXeSEReVOzBqFNOX5bXYoG2o= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.3 h1:jJPgroehGvjrde3XufFIJUZVK5A2L9a3KwSFgKy9n8w= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.3/go.mod h1:4Q0UFP0YJf0NrsEuEYHpM9fTSEVnD16Z3uyEF7J9JGM= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.33 h1:kG5eQilShqmJbv11XL1VpyDbaEJzWxd4zRiCG30GSn4= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.33/go.mod h1:7i0PF1ME/2eUPFcjkVIwq+DOygHEoK92t5cDqNgYbIw= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.27 h1:vFQlirhuM8lLlpI7imKOMsjdQLuN9CPi+k44F/OFVsk= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.27/go.mod h1:UrHnn3QV/d0pBZ6QBAEQcqFLf8FAzLmoUfPVIueOvoM= +github.com/aws/aws-sdk-go-v2/internal/ini v1.3.34 h1:gGLG7yKaXG02/jBlg210R7VgQIotiQntNhsCFejawx8= +github.com/aws/aws-sdk-go-v2/internal/ini v1.3.34/go.mod h1:Etz2dj6UHYuw+Xw830KfzCfWGMzqvUTCjUj5b76GVDc= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.25 h1:AzwRi5OKKwo4QNqPf7TjeO+tK8AyOK3GVSwmRPo7/Cs= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.25/go.mod h1:SUbB4wcbSEyCvqBxv/O/IBf93RbEze7U7OnoTlpPB+g= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.11 h1:y2+VQzC6Zh2ojtV2LoC0MNwHWc6qXv/j2vrQtlftkdA= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.11/go.mod h1:iV4q2hsqtNECrfmlXyord9u4zyuFEJX9eLgLpSPzWA8= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.28 h1:vGWm5vTpMr39tEZfQeDiDAMgk+5qsnvRny3FjLpnH5w= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.28/go.mod h1:spfrICMD6wCAhjhzHuy6DOZZ+LAIY10UxhUmLzpJTTs= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.27 h1:0iKliEXAcCa2qVtRs7Ot5hItA2MsufrphbRFlz1Owxo= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.27/go.mod h1:EOwBD4J4S5qYszS5/3DpkejfuK+Z5/1uzICfPaZLtqw= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.14.2 h1:NbWkRxEEIRSCqxhsHQuMiTH7yo+JZW1gp8v3elSVMTQ= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.14.2/go.mod h1:4tfW5l4IAB32VWCDEBxCRtR9T4BWy4I4kr1spr8NgZM= +github.com/aws/aws-sdk-go-v2/service/s3 v1.33.1 h1:O+9nAy9Bb6bJFTpeNFtd9UfHbgxO1o4ZDAM9rQp5NsY= +github.com/aws/aws-sdk-go-v2/service/s3 v1.33.1/go.mod h1:J9kLNzEiHSeGMyN7238EjJmBpCniVzFda75Gxl/NqB8= +github.com/aws/aws-sdk-go-v2/service/sso v1.12.10 h1:UBQjaMTCKwyUYwiVnUt6toEJwGXsLBI6al083tpjJzY= +github.com/aws/aws-sdk-go-v2/service/sso v1.12.10/go.mod h1:ouy2P4z6sJN70fR3ka3wD3Ro3KezSxU6eKGQI2+2fjI= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.10 h1:PkHIIJs8qvq0e5QybnZoG1K/9QTrLr9OsqCIo59jOBA= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.10/go.mod h1:AFvkxc8xfBe8XA+5St5XIHHrQQtkxqrRincx4hmMHOk= +github.com/aws/aws-sdk-go-v2/service/sts v1.19.0 h1:2DQLAKDteoEDI8zpCzqBMaZlJuoE9iTYD0gFmXVax9E= +github.com/aws/aws-sdk-go-v2/service/sts v1.19.0/go.mod h1:BgQOMsg8av8jset59jelyPW7NoZcZXLVpDsXunGDrk8= +github.com/aws/smithy-go v1.13.5 h1:hgz0X/DX0dGqTYpGALqXJoRKRj5oQ7150i5FdTePzO8= +github.com/aws/smithy-go v1.13.5/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= +github.com/axiomhq/hyperloglog v0.0.0-20230201085229-3ddf4bad03dc h1:Keo7wQ7UODUaHcEi7ltENhbAK2VgZjfat6mLy03tQzo= +github.com/axiomhq/hyperloglog v0.0.0-20230201085229-3ddf4bad03dc/go.mod h1:k08r+Yj1PRAmuayFiRK6MYuR5Ve4IuZtTfxErMIh0+c= +github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= +github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= +github.com/bits-and-blooms/bitset v1.2.0 h1:Kn4yilvwNtMACtf1eYDlG8H77R07mZSPbMjLyS07ChA= +github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cockroachdb/datadriven v1.0.2/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= +github.com/cockroachdb/errors v1.9.1 h1:yFVvsI0VxmRShfawbt/laCIDy/mtTqqnvoNgiy5bEV8= +github.com/cockroachdb/errors v1.9.1/go.mod h1:2sxOtL2WIc096WSZqZ5h8fa17rdDq9HZOZLBCor4mBk= +github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= +github.com/cockroachdb/redact v1.1.3 h1:AKZds10rFSIj7qADf0g46UixK8NNLwWTNdCIGS5wfSQ= +github.com/cockroachdb/redact v1.1.3/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= +github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dgryski/go-metro v0.0.0-20180109044635-280f6062b5bc h1:8WFBn63wegobsYAX0YjD+8suexZDga5CctH4CCTx2+8= +github.com/dgryski/go-metro v0.0.0-20180109044635-280f6062b5bc/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw= +github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= +github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= +github.com/fagongzi/goetty/v2 v2.0.3-0.20230628075727-26c9a2fd5fb8 h1:wvklsKgxbr2stvAtgUiUG/RwDN2nY3oovlhUG18wBIg= +github.com/fagongzi/goetty/v2 v2.0.3-0.20230628075727-26c9a2fd5fb8/go.mod h1:OwIBpVwRW1HjF/Jhc2Av3UvG2NygMg+bdqGxZaqwhU0= +github.com/fagongzi/util v0.0.0-20210923134909-bccc37b5040d h1:1pILVCatHj3eVo9i52dZyY4BwjTmSIeN+/hoJh8rD0Y= +github.com/fagongzi/util v0.0.0-20210923134909-bccc37b5040d/go.mod h1:5cqSns2zMRcJeVGvAqeTrbXFqh5AqBFr5uVKP9T2kiE= +github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= +github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= +github.com/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c= +github.com/getsentry/sentry-go v0.17.0 h1:UustVWnOoDFHBS7IJUB2QK/nB5pap748ZEp0swnQJak= +github.com/getsentry/sentry-go v0.17.0/go.mod h1:B82dxtBvxG0KaPD8/hfSV+VcHD+Lg/xUS4JuQn1P4cM= +github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= +github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= +github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= +github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI= +github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= +github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= +github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= +github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= +github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= +github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= +github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/pprof v0.0.0-20230510103437-eeec1cb781c3 h1:2XF1Vzq06X+inNqgJ9tRnGuw+ZVCB3FazXODD6JE1R8= +github.com/google/pprof v0.0.0-20230510103437-eeec1cb781c3/go.mod h1:79YE0hCXdHag9sBkw2o+N/YnZtTkXi0UT9Nnixa5eYk= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gopherjs/gopherjs v1.12.80 h1:aC68NT6VK715WeUapxcPSFq/a3gZdS32HdtghdOIgAo= +github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= +github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= +github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= +github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk= +github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g= +github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= +github.com/kataras/golog v0.0.10/go.mod h1:yJ8YKCmyL+nWjERB90Qwn+bdyBZsaQwU3bTVFgkFIp8= +github.com/kataras/iris/v12 v12.1.8/go.mod h1:LMYy4VlP67TQ3Zgriz8RE2h2kMZV2SgMYbq3UhfoFmE= +github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2R1rmoTE= +github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro= +github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y= +github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= +github.com/lni/dragonboat/v4 v4.0.0-20220815145555-6f622e8bcbef h1:Pk7v7YAMqQrL0nbHyoffdmr9BArHN03hEqBgeru8VcI= +github.com/lni/dragonboat/v4 v4.0.0-20220815145555-6f622e8bcbef/go.mod h1:bR6ZGoUwApH4/P4+AezNGT0xehljg+j+Z/Q2Fz+Y4a0= +github.com/lni/goutils v1.3.1-0.20220604063047-388d67b4dbc4 h1:6gzI38ZJmbzZ7oZebXz6jII0uVK+MZ3+ds+7mIt1ioI= +github.com/lni/goutils v1.3.1-0.20220604063047-388d67b4dbc4/go.mod h1:LIHvF0fflR+zyXUQFQOiHPpKANf3UIr7DFIv5CBPOoU= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/matrixorigin/matrixone v0.7.1-0.20230906044843-ce0185d3a794 h1:yLTSg8PCkC0KwUY6UCerEI24tM8SnNSWT+sEskIdv/Y= +github.com/matrixorigin/matrixone v0.7.1-0.20230906044843-ce0185d3a794/go.mod h1:iAtluuNIcesLk9pEIDZeo0VPWJWvXFXbIdkxjaXnhl4= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= +github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= +github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= +github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= +github.com/mschoch/smat v0.2.0 h1:8imxQsjDm8yFEAVBe7azKmKSgzSkZXDuKkSq9374khM= +github.com/mschoch/smat v0.2.0/go.mod h1:kc9mz7DoBKqDyiRL7VZN8KvXQMWeTaVnttLRXOlotKw= +github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= +github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= +github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/petermattis/goid v0.0.0-20230518223814-80aa455d8761 h1:W04oB3d0J01W5jgYRGKsV8LCM6g9EkCvPkZcmFuy0OE= +github.com/petermattis/goid v0.0.0-20230518223814-80aa455d8761/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= +github.com/pierrec/lz4/v4 v4.1.17 h1:kV4Ip+/hUBC+8T6+2EgburRtkE9ef4nbY3f4dFhGjMc= +github.com/pierrec/lz4/v4 v4.1.17/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/plar/go-adaptive-radix-tree v1.0.5 h1:rHR89qy/6c24TBAHullFMrJsU9hGlKmPibdBGU6/gbM= +github.com/plar/go-adaptive-radix-tree v1.0.5/go.mod h1:15VOUO7R9MhJL8HOJdpydR0rvanrtRE6fA6XSa/tqWE= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= +github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/samber/lo v1.38.1 h1:j2XEAqXKb09Am4ebOg31SpvzUTTs6EN3VfgeLUhPdXM= +github.com/samber/lo v1.38.1/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= +github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/shirou/gopsutil/v3 v3.22.4 h1:srAQaiX6jX/cYL6q29aE0m8lOskT9CurZ9N61YR3yoI= +github.com/shirou/gopsutil/v3 v3.22.4/go.mod h1:D01hZJ4pVHPpCTZ3m3T2+wDF2YAGfd+H4ifUguaQzHM= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/smartystreets-prototypes/go-disruptor v0.0.0-20200316140655-c96477fd7a6a/go.mod h1:slFCjqF2v0VgmCeB+J4uEy0d7HAgLkgEjVrG0DPO67M= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/assertions v1.1.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= +github.com/smartystreets/assertions v1.13.1 h1:Ef7KhSmjZcK6AVf9YbJdvPYG9avaF0ZxudX+ThRdWfU= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.673 h1:+QDlxKbbn2n6CbPHcoef/ODa/0yfYoxL5CC2UI96Qi8= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.673/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y= +github.com/tidwall/btree v1.6.0 h1:LDZfKfQIBHGHWSwckhXI0RPSXzlo+KYdjK7FWSqOzzg= +github.com/tidwall/btree v1.6.0/go.mod h1:twD9XRA5jj9VUQGELzDO4HPQTNJsoWWfYEL+EUQ2cKY= +github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= +github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk= +github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ= +github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= +github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= +github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= +github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= +github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= +github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= +github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= +github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= +go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/ratelimit v0.2.0 h1:UQE2Bgi7p2B85uP5dC2bbRtig0C+OeNRnNEafLjsLPA= +go.uber.org/ratelimit v0.2.0/go.mod h1:YYBV4e4naJvhpitQrWJu1vCpgB7CboMe0qhltKt6mUg= +go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= +go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc h1:mCRnTeVUjcrhlRmO0VK8a6k6Rrf6TF9htwo2pJVSjIU= +golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= +golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180518175338-11a468237815/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= +google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= +gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= +gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.56.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= +gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= +gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=