Skip to content

Commit

Permalink
Merge pull request scylladb#433 from CodeLieutenant/fix--prettyCQL
Browse files Browse the repository at this point in the history
fix(prettyCQL): prettyCQL crashes on ouf-of-bound access
  • Loading branch information
CodeLieutenant authored Nov 12, 2024
2 parents a76d896 + 70e5926 commit 9b15797
Show file tree
Hide file tree
Showing 33 changed files with 896 additions and 372 deletions.
18 changes: 9 additions & 9 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ require (
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed
github.com/mitchellh/mapstructure v1.5.0
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.20.0
github.com/prometheus/client_golang v1.20.5
github.com/scylladb/go-set v1.0.2
github.com/scylladb/gocqlx/v2 v2.8.0
github.com/spf13/cobra v1.8.1
go.uber.org/multierr v1.11.0
go.uber.org/zap v1.27.0
golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa
golang.org/x/net v0.28.0
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c
golang.org/x/net v0.30.0
golang.org/x/sync v0.8.0
gonum.org/v1/gonum v0.15.1
gopkg.in/inf.v0 v0.9.1
Expand All @@ -25,21 +25,21 @@ require (
require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/fatih/color v1.17.0 // indirect
github.com/fatih/color v1.18.0 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/klauspost/compress v1.17.9 // indirect
github.com/klauspost/compress v1.17.11 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common v0.55.0 // indirect
github.com/prometheus/common v0.60.1 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
github.com/scylladb/go-reflectx v1.0.1 // indirect
github.com/spf13/pflag v1.0.5 // indirect
golang.org/x/sys v0.24.0 // indirect
golang.org/x/term v0.23.0 // indirect
google.golang.org/protobuf v1.34.2 // indirect
golang.org/x/sys v0.26.0 // indirect
golang.org/x/term v0.25.0 // indirect
google.golang.org/protobuf v1.35.1 // indirect
)

replace github.com/gocql/gocql => github.com/scylladb/gocql v1.14.3
18 changes: 18 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ 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/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4=
github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI=
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
github.com/fatih/set v0.2.1 h1:nn2CaJyknWE/6txyUDGwysr3G5QC6xWB/PtVjPBbeaA=
github.com/fatih/set v0.2.1/go.mod h1:+RKtMCH+favT2+3YecHGxcc0b4KyVWA1QWWJUs4E0CI=
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
Expand All @@ -31,6 +33,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
Expand All @@ -55,12 +59,16 @@ github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQ
github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho=
github.com/prometheus/client_golang v1.20.0 h1:jBzTZ7B099Rg24tny+qngoynol8LtVYlA2bqx3vEloI=
github.com/prometheus/client_golang v1.20.0/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
github.com/prometheus/common v0.54.0 h1:ZlZy0BgJhTwVZUn7dLOkwCZHUkrAqd3WYtcFCWnM1D8=
github.com/prometheus/common v0.54.0/go.mod h1:/TQgMJP5CuVYveyT7n/0Ix8yLNNXy9yRSkhnLTHPDIQ=
github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc=
github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8=
github.com/prometheus/common v0.60.1 h1:FUas6GcOw66yB/73KC+BOZoFJmbo/1pojoILArPAaSc=
github.com/prometheus/common v0.60.1/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw=
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
Expand Down Expand Up @@ -94,11 +102,15 @@ golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8 h1:LoYXNGAShUG3m/ehNk4iFctuh
golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI=
golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI=
golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ=
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBnqWrJc+rq0DPKyvvdbY=
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8=
golang.org/x/net v0.0.0-20220526153639-5463443f8c37/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
Expand All @@ -111,11 +123,15 @@ golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA=
golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0=
golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU=
golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk=
golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24=
golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
Expand All @@ -127,6 +143,8 @@ google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFW
google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA=
google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
Expand Down
40 changes: 40 additions & 0 deletions pkg/jobs/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright 2024 ScyllaDB
//
// 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 jobs

import (
"fmt"

"github.com/scylladb/gemini/pkg/typedef"
)

type PrettyCQLError struct {
PrettyCQL error
Err error
Stmt *typedef.Stmt
}

func (e PrettyCQLError) Error() string {
query, _ := e.Stmt.Query.ToCql()
values := e.Stmt.Values.Copy()

return fmt.Sprintf(
"Failed to format CQL Statement: prettyCQL {Query(%s) Values(%+v) PrettyCQLError(%+v) Error(%+v)}",
query,
values,
e.PrettyCQL,
e.Err,
)
}
2 changes: 1 addition & 1 deletion pkg/jobs/gen_utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ func convertStmtToResults(stmt *typedef.Stmt) *result {
Names: strings.TrimSpace(fmt.Sprintf("%s", names)),
Values: strings.TrimSpace(fmt.Sprintf("%v", stmt.Values)),
Types: types,
QueryType: fmt.Sprintf("%v", stmt.QueryType),
QueryType: stmt.QueryType.String(),
}
}

Expand Down
116 changes: 93 additions & 23 deletions pkg/jobs/jobs.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,20 @@ package jobs
import (
"context"
"encoding/json"
"errors"
"fmt"
"time"

"github.com/scylladb/gemini/pkg/generators"
"github.com/scylladb/gemini/pkg/store"
"github.com/scylladb/gemini/pkg/typedef"
"github.com/pkg/errors"
"go.uber.org/zap"
"golang.org/x/exp/rand"
"golang.org/x/sync/errgroup"

"github.com/scylladb/gemini/pkg/generators"
"github.com/scylladb/gemini/pkg/joberror"
"github.com/scylladb/gemini/pkg/status"
"github.com/scylladb/gemini/pkg/stop"

"go.uber.org/zap"
"golang.org/x/exp/rand"
"golang.org/x/sync/errgroup"
"github.com/scylladb/gemini/pkg/store"
"github.com/scylladb/gemini/pkg/typedef"
)

const (
Expand Down Expand Up @@ -177,9 +176,15 @@ func mutationJob(
}
ind := r.Intn(1000000)
if ind%100000 == 0 {
_ = ddl(ctx, schema, schemaConfig, table, s, r, p, globalStatus, logger, verbose)
err := ddl(ctx, schema, schemaConfig, table, s, r, p, globalStatus, logger, verbose)
if err != nil {
return err
}
} else {
_ = mutation(ctx, schema, schemaConfig, table, s, r, p, g, globalStatus, true, logger)
err := mutation(ctx, schema, schemaConfig, table, s, r, p, g, globalStatus, true, logger)
if err != nil {
return err
}
}
if failFast && globalStatus.HasErrors() {
stopFlag.SetSoft(true)
Expand Down Expand Up @@ -239,11 +244,20 @@ func validationJob(
case errors.Is(err, context.Canceled):
return nil
default:
query, prettyErr := stmt.PrettyCQL()
if prettyErr != nil {
return PrettyCQLError{
PrettyCQL: prettyErr,
Stmt: stmt,
Err: err,
}
}

globalStatus.AddReadError(&joberror.JobError{
Timestamp: time.Now(),
StmtType: stmt.QueryType.ToString(),
StmtType: stmt.QueryType.String(),
Message: "Validation failed: " + err.Error(),
Query: stmt.PrettyCQL(),
Query: query,
})
}

Expand Down Expand Up @@ -283,7 +297,11 @@ func warmupJob(
return nil
}
// Do we care about errors during warmup?
_ = mutation(ctx, schema, schemaConfig, table, s, r, p, g, globalStatus, false, logger)
err := mutation(ctx, schema, schemaConfig, table, s, r, p, g, globalStatus, false, logger)
if err != nil {
return err
}

if failFast && globalStatus.HasErrors() {
stopFlag.SetSoft(true)
return nil
Expand Down Expand Up @@ -319,26 +337,48 @@ func ddl(
globalStatus.WriteErrors.Add(1)
return err
}

if ddlStmts == nil {
if w := logger.Check(zap.DebugLevel, "no statement generated"); w != nil {
w.Write(zap.String("job", "ddl"))
}
return nil
}

for _, ddlStmt := range ddlStmts.List {
if w := logger.Check(zap.DebugLevel, "ddl statement"); w != nil {
w.Write(zap.String("pretty_cql", ddlStmt.PrettyCQL()))
prettyCQL, prettyCQLErr := ddlStmt.PrettyCQL()
if prettyCQLErr != nil {
return PrettyCQLError{
PrettyCQL: prettyCQLErr,
Stmt: ddlStmt,
}
}

w.Write(zap.String("pretty_cql", prettyCQL))
}

if err = s.Mutate(ctx, ddlStmt); err != nil {
if errors.Is(err, context.Canceled) {
return nil
}

prettyCQL, prettyCQLErr := ddlStmt.PrettyCQL()
if prettyCQLErr != nil {
return PrettyCQLError{
PrettyCQL: prettyCQLErr,
Stmt: ddlStmt,
Err: err,
}
}

globalStatus.AddWriteError(&joberror.JobError{
Timestamp: time.Now(),
StmtType: ddlStmts.QueryType.ToString(),
StmtType: ddlStmts.QueryType.String(),
Message: "DDL failed: " + err.Error(),
Query: ddlStmt.PrettyCQL(),
Query: prettyCQL,
})

return err
}
globalStatus.WriteOps.Add(1)
Expand Down Expand Up @@ -378,22 +418,44 @@ func mutation(
}

if w := logger.Check(zap.DebugLevel, "mutation statement"); w != nil {
w.Write(zap.String("pretty_cql", mutateStmt.PrettyCQL()))
prettyCQL, prettyCQLErr := mutateStmt.PrettyCQL()
if prettyCQLErr != nil {
return PrettyCQLError{
PrettyCQL: prettyCQLErr,
Stmt: mutateStmt,
Err: err,
}
}

w.Write(zap.String("pretty_cql", prettyCQL))
}
if err = s.Mutate(ctx, mutateStmt); err != nil {
if errors.Is(err, context.Canceled) {
return nil
}

prettyCQL, prettyCQLErr := mutateStmt.PrettyCQL()
if prettyCQLErr != nil {
return PrettyCQLError{
PrettyCQL: prettyCQLErr,
Stmt: mutateStmt,
Err: err,
}
}

globalStatus.AddWriteError(&joberror.JobError{
Timestamp: time.Now(),
StmtType: mutateStmt.QueryType.ToString(),
StmtType: mutateStmt.QueryType.String(),
Message: "Mutation failed: " + err.Error(),
Query: mutateStmt.PrettyCQL(),
Query: prettyCQL,
})
} else {
globalStatus.WriteOps.Add(1)
g.GiveOlds(mutateStmt.ValuesWithToken)

return err
}

globalStatus.WriteOps.Add(1)
g.GiveOlds(mutateStmt.ValuesWithToken)

return nil
}

Expand All @@ -406,7 +468,15 @@ func validation(
logger *zap.Logger,
) error {
if w := logger.Check(zap.DebugLevel, "validation statement"); w != nil {
w.Write(zap.String("pretty_cql", stmt.PrettyCQL()))
prettyCQL, prettyCQLErr := stmt.PrettyCQL()
if prettyCQLErr != nil {
return PrettyCQLError{
PrettyCQL: prettyCQLErr,
Stmt: stmt,
}
}

w.Write(zap.String("pretty_cql", prettyCQL))
}

maxAttempts := 1
Expand Down
Loading

0 comments on commit 9b15797

Please sign in to comment.