Skip to content
This repository has been archived by the owner on Aug 21, 2023. It is now read-only.

Commit

Permalink
remove information_schema.key_column_usage table select
Browse files Browse the repository at this point in the history
  • Loading branch information
lichunzhu committed Jul 12, 2021
1 parent 7dac228 commit bdb3c26
Show file tree
Hide file tree
Showing 10 changed files with 180 additions and 216 deletions.
3 changes: 0 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,6 @@ require (
github.com/pingcap/tidb-tools v4.0.9-0.20201127090955-2707c97b3853+incompatible
github.com/prometheus/client_golang v1.5.1
github.com/prometheus/client_model v0.2.0
github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b // indirect
github.com/siddontang/go-log v0.0.0-20190221022429-1e957dd83bed // indirect
github.com/siddontang/go-mysql v0.0.0-20200222075837-12e89848f047
github.com/soheilhy/cmux v0.1.4
github.com/spaolacci/murmur3 v1.1.0 // indirect
github.com/spf13/pflag v1.0.5
Expand Down
13 changes: 0 additions & 13 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,6 @@ github.com/pingcap/log v0.0.0-20200511115504-543df19646ad/go.mod h1:4rbK1p9ILyIf
github.com/pingcap/log v0.0.0-20201112100606-8f1e84a3abc8/go.mod h1:4rbK1p9ILyIfb6hU7OG2CiWSqMXnp3JMbiaVJ6mvoY8=
github.com/pingcap/log v0.0.0-20210317133921-96f4fcab92a4 h1:ERrF0fTuIOnwfGbt71Ji3DKbOEaP189tjym50u8gpC8=
github.com/pingcap/log v0.0.0-20210317133921-96f4fcab92a4/go.mod h1:4rbK1p9ILyIfb6hU7OG2CiWSqMXnp3JMbiaVJ6mvoY8=
github.com/pingcap/parser v0.0.0-20190506092653-e336082eb825/go.mod h1:1FNvfp9+J0wvc4kl8eGNh7Rqrxveg15jJoWo/a0uHwA=
github.com/pingcap/parser v0.0.0-20210513020953-ae2c4497c07b h1:eLuDQ6eJCEKCbGwhGrkjzagwev1GJGU2Y2kFkAsBzV0=
github.com/pingcap/parser v0.0.0-20210513020953-ae2c4497c07b/go.mod h1:xZC8I7bug4GJ5KtHhgAikjTfU4kBv1Sbo3Pf1MZ6lVw=
github.com/pingcap/sysutil v0.0.0-20200206130906-2bfa6dc40bcd/go.mod h1:EB/852NMQ+aRKioCpToQ94Wl7fktV+FNnxf3CX/TTXI=
Expand All @@ -455,7 +454,6 @@ github.com/pingcap/tidb v1.1.0-beta.0.20210517044538-8ad868f801fc/go.mod h1:MTGi
github.com/pingcap/tidb-dashboard v0.0.0-20210312062513-eef5d6404638/go.mod h1:OzFN8H0EDMMqeulPhPMw2i2JaiZWOKFQ7zdRPhENNgo=
github.com/pingcap/tidb-tools v4.0.9-0.20201127090955-2707c97b3853+incompatible h1:ceznmu/lLseGHP/jKyOa/3u/5H3wtLLLqkH2V3ssSjg=
github.com/pingcap/tidb-tools v4.0.9-0.20201127090955-2707c97b3853+incompatible/go.mod h1:XGdcy9+yqlDSEMTpOXnwf3hiTeqrV6MN/u1se9N8yIM=
github.com/pingcap/tipb v0.0.0-20190428032612-535e1abaa330/go.mod h1:RtkHW8WbcNxj8lsbzjaILci01CtYnYbIkQhjyZWrWVI=
github.com/pingcap/tipb v0.0.0-20210422074242-57dd881b81b1 h1:Kcp3jIcQrqG+pT1JQ0oWyRncVKQtDgnMFzRt3zJBaBo=
github.com/pingcap/tipb v0.0.0-20210422074242-57dd881b81b1/go.mod h1:nsEhnMokcn7MRqd2J60yxpn/ac3ZH8A6GOJ9NslabUo=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
Expand Down Expand Up @@ -504,30 +502,19 @@ github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sasha-s/go-deadlock v0.2.0/go.mod h1:StQn567HiB1fF2yJ44N9au7wOhrPS3iZqiDbRupzT10=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b h1:gQZ0qzfKHQIybLANtM3mBXNUtOfsCFXeTsnBqCsx1KM=
github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/sergi/go-diff v1.0.1-0.20180205163309-da645544ed44/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/shirou/gopsutil v2.19.10+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shirou/gopsutil v3.21.2+incompatible h1:U+YvJfjCh6MslYlIAXvPtzhW3YZEtc9uncueUNpD/0A=
github.com/shirou/gopsutil v3.21.2+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc=
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 h1:bUGsEnyNbVPw06Bs80sCeARAlK8lhwqGyi6UT8ymuGk=
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
github.com/shurcooL/httpgzip v0.0.0-20190720172056-320755c1c1b0/go.mod h1:919LwcH0M7/W4fcZ0/jy0qGght1GIhqyS/EgWGH2j5Q=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd h1:ug7PpSOB5RBPK1Kg6qskGBoP3Vnj/aNYFTznWvlkGo0=
github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726 h1:xT+JlYxNGqyT+XcU8iUrN18JYed2TvG9yN5ULG2jATM=
github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw=
github.com/siddontang/go-log v0.0.0-20180807004314-8d05993dda07/go.mod h1:yFdBgwXP24JziuRl2NMUahT7nGLNOKi1SIiFxMttVD4=
github.com/siddontang/go-log v0.0.0-20190221022429-1e957dd83bed h1:KMgQoLJGCq1IoZpLZE3AIffh9veYWoVlsvA4ib55TMM=
github.com/siddontang/go-log v0.0.0-20190221022429-1e957dd83bed/go.mod h1:yFdBgwXP24JziuRl2NMUahT7nGLNOKi1SIiFxMttVD4=
github.com/siddontang/go-mysql v0.0.0-20200222075837-12e89848f047 h1:boyJ8EgQN/aC3grvx8QUoJrptt7RvneezSJSCbW25a4=
github.com/siddontang/go-mysql v0.0.0-20200222075837-12e89848f047/go.mod h1:+W4RCzesQDI11HvIkaDjS8yM36SpAnGNQ7jmTLn5BnU=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
Expand Down
47 changes: 23 additions & 24 deletions v4/export/dump.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,12 +213,6 @@ func (d *Dumper) Dump() (dumpErr error) {
}
})

// get estimate total count
err = d.getEstimateTotalRowsCount(tctx, metaConn)
if err != nil {
tctx.L().Error("fail to get estimate total count", zap.Error(err))
}

if conf.SQL == "" {
if err = d.dumpDatabases(writerCtx, metaConn, taskChan); err != nil && !errors.ErrorEqual(err, context.Canceled) {
return err
Expand Down Expand Up @@ -338,6 +332,12 @@ func (d *Dumper) dumpTableData(tctx *tcontext.Context, conn *sql.Conn, meta Tabl
if conf.NoData {
return nil
}

// Update total rows
fieldName, _ := pickupPossibleField(meta, conn)
c := estimateCount(tctx, meta.DatabaseName(), meta.TableName(), conn, fieldName, conf)
AddCounter(estimateTotalRowsCounter, conf.Labels, float64(c))

if conf.Rows == UnspecifiedSize {
return d.sequentialDumpTable(tctx, conn, meta, taskChan)
}
Expand Down Expand Up @@ -451,11 +451,9 @@ func (d *Dumper) concurrentDumpTable(tctx *tcontext.Context, conn *sql.Conn, met
(conf.ServerInfo.ServerVersion.Compare(*tableSampleVersion) >= 0 ||
(conf.ServerInfo.HasTiKV && conf.ServerInfo.ServerVersion.Compare(*gcSafePointVersion) >= 0)) {
err := d.concurrentDumpTiDBTables(tctx, conn, meta, taskChan)
if err == nil {
return err
}
// don't retry on context error
if errors.ErrorEqual(err, context.Canceled) || errors.ErrorEqual(err, context.DeadlineExceeded) {
// don't retry on context error and successful tasks
if errors.ErrorEqual(err, context.Canceled) || errors.ErrorEqual(err, context.DeadlineExceeded) ||
err == nil {
return err
}
tctx.L().Warn("fallback to concurrent dump tables using rows due to tidb error",
Expand Down Expand Up @@ -582,7 +580,7 @@ func (d *Dumper) selectMinAndMaxIntValue(conn *sql.Conn, db, tbl, field string)
}

func (d *Dumper) concurrentDumpTiDBTables(tctx *tcontext.Context, conn *sql.Conn, meta TableMeta, taskChan chan<- Task) error {
db, tbl, hasImplicitRowID := meta.DatabaseName(), meta.TableName(), meta.HasImplicitRowID()
db, tbl := meta.DatabaseName(), meta.TableName()

var (
handleColNames []string
Expand All @@ -592,15 +590,15 @@ func (d *Dumper) concurrentDumpTiDBTables(tctx *tcontext.Context, conn *sql.Conn
if d.conf.ServerInfo.ServerVersion.Compare(*tableSampleVersion) >= 0 {
tctx.L().Debug("dumping TiDB tables with TABLESAMPLE",
zap.String("database", db), zap.String("table", tbl))
handleColNames, handleVals, err = selectTiDBTableSample(tctx, conn, db, tbl, hasImplicitRowID)
handleColNames, handleVals, err = selectTiDBTableSample(tctx, conn, meta)
} else {
tctx.L().Debug("dumping TiDB tables with TABLE REGIONS",
zap.String("database", db), zap.String("table", tbl))
var partitions []string
partitions, err = GetPartitionNames(conn, db, tbl)
if err == nil {
if len(partitions) == 0 {
handleColNames, handleVals, err = selectTiDBTableRegion(tctx, conn, db, tbl, hasImplicitRowID)
handleColNames, handleVals, err = selectTiDBTableRegion(tctx, conn, meta)
} else {
return d.concurrentDumpTiDBPartitionTables(tctx, conn, meta, taskChan, partitions)
}
Expand All @@ -613,15 +611,15 @@ func (d *Dumper) concurrentDumpTiDBTables(tctx *tcontext.Context, conn *sql.Conn
}

func (d *Dumper) concurrentDumpTiDBPartitionTables(tctx *tcontext.Context, conn *sql.Conn, meta TableMeta, taskChan chan<- Task, partitions []string) error {
db, tbl, hasImplicitRowID := meta.DatabaseName(), meta.TableName(), meta.HasImplicitRowID()
db, tbl := meta.DatabaseName(), meta.TableName()
tctx.L().Debug("dumping TiDB tables with TABLE REGIONS for partition table",
zap.String("database", db), zap.String("table", tbl), zap.Strings("partitions", partitions))

startChunkIdx := 0
totalChunk := 0
cachedHandleVals := make([][][]string, len(partitions))

handleColNames, _, err := selectTiDBRowKeyFields(conn, db, tbl, hasImplicitRowID, checkTiDBTableRegionPkFields)
handleColNames, _, err := selectTiDBRowKeyFields(conn, meta, checkTiDBTableRegionPkFields)
if err != nil {
return err
}
Expand Down Expand Up @@ -676,13 +674,13 @@ func (d *Dumper) L() log.Logger {
return d.tctx.L()
}

func selectTiDBTableSample(tctx *tcontext.Context, conn *sql.Conn, dbName, tableName string, hasImplicitRowID bool) (pkFields []string, pkVals [][]string, err error) {
pkFields, pkColTypes, err := selectTiDBRowKeyFields(conn, dbName, tableName, hasImplicitRowID, nil)
func selectTiDBTableSample(tctx *tcontext.Context, conn *sql.Conn, meta TableMeta) (pkFields []string, pkVals [][]string, err error) {
pkFields, pkColTypes, err := selectTiDBRowKeyFields(conn, meta, nil)
if err != nil {
return nil, nil, errors.Trace(err)
}

query := buildTiDBTableSampleQuery(pkFields, dbName, tableName)
query := buildTiDBTableSampleQuery(pkFields, meta.DatabaseName(), meta.TableName())
rows, err := conn.QueryContext(tctx, query)
if err != nil {
return nil, nil, errors.Trace(err)
Expand Down Expand Up @@ -721,11 +719,11 @@ func buildTiDBTableSampleQuery(pkFields []string, dbName, tblName string) string
return fmt.Sprintf(template, pks, escapeString(dbName), escapeString(tblName), pks)
}

func selectTiDBRowKeyFields(conn *sql.Conn, dbName, tableName string, hasImplicitRowID bool, checkPkFields func([]string, []string) error) (pkFields, pkColTypes []string, err error) {
if hasImplicitRowID {
func selectTiDBRowKeyFields(conn *sql.Conn, meta TableMeta, checkPkFields func([]string, []string) error) (pkFields, pkColTypes []string, err error) {
if meta.HasImplicitRowID() {
pkFields, pkColTypes = []string{"_tidb_rowid"}, []string{"BIGINT"}
} else {
pkFields, pkColTypes, err = GetPrimaryKeyAndColumnTypes(conn, dbName, tableName)
pkFields, pkColTypes, err = GetPrimaryKeyAndColumnTypes(conn, meta)
if err == nil {
if checkPkFields != nil {
err = checkPkFields(pkFields, pkColTypes)
Expand All @@ -746,8 +744,8 @@ func checkTiDBTableRegionPkFields(pkFields, pkColTypes []string) (err error) {
return
}

func selectTiDBTableRegion(tctx *tcontext.Context, conn *sql.Conn, dbName, tableName string, hasImplicitRowID bool) (pkFields []string, pkVals [][]string, err error) {
pkFields, _, err = selectTiDBRowKeyFields(conn, dbName, tableName, hasImplicitRowID, checkTiDBTableRegionPkFields)
func selectTiDBTableRegion(tctx *tcontext.Context, conn *sql.Conn, meta TableMeta) (pkFields []string, pkVals [][]string, err error) {
pkFields, _, err = selectTiDBRowKeyFields(conn, meta, checkTiDBTableRegionPkFields)
if err != nil {
return
}
Expand All @@ -760,6 +758,7 @@ func selectTiDBTableRegion(tctx *tcontext.Context, conn *sql.Conn, dbName, table
tableRegionSQL = "SELECT START_KEY,tidb_decode_key(START_KEY) from INFORMATION_SCHEMA.TIKV_REGION_STATUS s WHERE s.DB_NAME = ? AND s.TABLE_NAME = ? AND IS_INDEX = 0 ORDER BY START_KEY;"
tidbRowID = "_tidb_rowid="
)
dbName, tableName := meta.DatabaseName(), meta.TableName()
logger := tctx.L().With(zap.String("database", dbName), zap.String("table", tableName))
err = simpleQueryWithArgs(conn, func(rows *sql.Rows) error {
rowID++
Expand Down
3 changes: 0 additions & 3 deletions v4/export/dump_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,6 @@ func (s *testSQLSuite) TestDumpTableMeta(c *C) {
c.Assert(err, IsNil)
defer db.Close()

database := "foo"
table := "bar"

tctx, cancel := tcontext.Background().WithLogger(appLogger).WithCancel()
defer cancel()
conn, err := db.Conn(tctx)
Expand Down
85 changes: 36 additions & 49 deletions v4/export/sql.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,14 +160,17 @@ func ListAllDatabasesTables(tctx *tcontext.Context, db *sql.Conn, databaseNames
for _, schema := range databaseNames {
dbTables[schema] = make([]*TableInfo, 0)
}
if err := simpleQueryWithArgs(db, func(rows *sql.Rows) error {
var sqlAvgRowLength sql.NullInt64
if err := rows.Scan(&schema, &table, &tableTypeStr, &sqlAvgRowLength); err != nil {
return errors.Trace(err)
if err = simpleQueryWithArgs(db, func(rows *sql.Rows) error {
var (
sqlAvgRowLength sql.NullInt64
err2 error
)
if err2 = rows.Scan(&schema, &table, &tableTypeStr, &sqlAvgRowLength); err != nil {
return errors.Trace(err2)
}
tableType, err = ParseTableType(tableTypeStr)
if err != nil {
return errors.Trace(err)
tableType, err2 = ParseTableType(tableTypeStr)
if err2 != nil {
return errors.Trace(err2)
}

if sqlAvgRowLength.Valid {
Expand All @@ -185,7 +188,7 @@ func ListAllDatabasesTables(tctx *tcontext.Context, db *sql.Conn, databaseNames
}
} else {
queryTemplate := "SHOW TABLE STATUS FROM `%s`"
selectedTableType := make(map[TableType]struct{}, 0)
selectedTableType := make(map[TableType]struct{})
for _, tableType = range tableTypes {
selectedTableType[tableType] = struct{}{}
}
Expand Down Expand Up @@ -345,63 +348,47 @@ func GetColumnTypes(db *sql.Conn, fields, database, table string) ([]*sql.Column
}

// GetPrimaryKeyAndColumnTypes gets all primary columns and their types in ordinal order
func GetPrimaryKeyAndColumnTypes(conn *sql.Conn, database, table string) ([]string, []string, error) {
query :=
`SELECT c.COLUMN_NAME, DATA_TYPE FROM
INFORMATION_SCHEMA.COLUMNS c INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE k ON
c.column_name = k.column_name and
c.table_schema = k.table_schema and
c.table_name = k.table_name and
c.table_schema = ? and
c.table_name = ?
WHERE COLUMN_KEY = 'PRI'
ORDER BY k.ORDINAL_POSITION;`
var colNames, colTypes []string
if err := simpleQueryWithArgs(conn, func(rows *sql.Rows) error {
var colName, colType string
if err := rows.Scan(&colName, &colType); err != nil {
return errors.Trace(err)
}
colNames = append(colNames, colName)
colTypes = append(colTypes, strings.ToUpper(colType))
return nil
}, query, database, table); err != nil {
return nil, nil, errors.Annotatef(err, "sql: %s", query)
func GetPrimaryKeyAndColumnTypes(conn *sql.Conn, meta TableMeta) ([]string, []string, error) {
var (
colNames, colTypes []string
err error
)
colNames, err = GetPrimaryKeyColumns(conn, meta.DatabaseName(), meta.TableName())
if err != nil {
return nil, nil, err
}
colName2Type := string2Map(meta.ColumnNames(), meta.ColumnTypes())
colTypes = make([]string, len(colNames))
for i, colName := range colNames {
colTypes[i] = colName2Type[colName]
}
return colNames, colTypes, nil
}

// GetPrimaryKeyColumns gets all primary columns in ordinal order
func GetPrimaryKeyColumns(db *sql.Conn, database, table string) ([]string, error) {
priKeyColsQuery := "SELECT column_name FROM information_schema.KEY_COLUMN_USAGE " +
"WHERE table_schema = ? AND table_name = ? AND CONSTRAINT_NAME = 'PRIMARY' order by ORDINAL_POSITION;"
rows, err := db.QueryContext(context.Background(), priKeyColsQuery, database, table)
priKeyColsQuery := fmt.Sprintf("SHOW INDEX FROM `%s`.`%s`", escapeString(database), escapeString(table))
rows, err := db.QueryContext(context.Background(), priKeyColsQuery)
if err != nil {
return nil, errors.Annotatef(err, "sql: %s", priKeyColsQuery)
}
defer rows.Close()
var cols []string
var col string
for rows.Next() {
err = rows.Scan(&col)
if err != nil {
return nil, errors.Annotatef(err, "sql: %s", priKeyColsQuery)
}
cols = append(cols, col)
}
if err = rows.Err(); err != nil {
results, err := GetSpecifiedColumnValuesAndClose(rows, "KEY_NAME", "COLUMN_NAME")
if err != nil {
return nil, errors.Annotatef(err, "sql: %s", priKeyColsQuery)
}
cols := make([]string, 0, len(results))
for _, oneRow := range results {
keyName, columnName := oneRow[0], oneRow[1]
if keyName == "PRIMARY" {
cols = append(cols, columnName)
}
}
return cols, nil
}

func getNumericIndex(db *sql.Conn, meta TableMeta) (string, error) {
database, table := meta.DatabaseName(), meta.TableName()
colNames, colTypes := meta.ColumnNames(), meta.ColumnTypes()
colName2Type := make(map[string]string, len(colNames))
for i := range colNames {
colName2Type[colNames[i]] = colTypes[i]
}
colName2Type := string2Map(meta.ColumnNames(), meta.ColumnTypes())
keyQuery := fmt.Sprintf("SHOW INDEX FROM `%s`.`%s`", escapeString(database), escapeString(table))
rows, err := db.QueryContext(context.Background(), keyQuery)
if err != nil {
Expand Down
Loading

0 comments on commit bdb3c26

Please sign in to comment.