From 6437b7eba69620cd6faf79a4027d9f269e5a8b5a Mon Sep 17 00:00:00 2001 From: Daylon Wilkins Date: Tue, 19 Dec 2023 04:54:29 -0800 Subject: [PATCH] Added static analyzer & linter --- .github/workflows/ci-staticcheck.yaml | 27 +++++++ main.go | 27 +------ postgres/connection/message_decode_encode.go | 4 +- postgres/parser/encoding/decimal.go | 18 ----- postgres/parser/encoding/encoding.go | 22 +----- postgres/parser/geo/parse.go | 14 ---- postgres/parser/json/json.go | 36 +++------ postgres/parser/parser/help.go | 4 +- postgres/parser/protoutil/marshaler.go | 3 +- postgres/parser/sem/tree/datum.go | 40 ---------- postgres/parser/sem/tree/eval.go | 57 +------------ postgres/parser/sem/tree/expr.go | 19 ----- postgres/parser/sem/tree/overload.go | 4 +- postgres/parser/uuid/uuid_wrapper.go | 42 +--------- server/ast/staticcheck.conf | 1 + server/system_checks.go | 79 ------------------- staticcheck.conf | 3 + .../generation/command_docs/create_tests.go | 7 +- testing/logictest/harness/doltgres_harness.go | 5 -- 19 files changed, 61 insertions(+), 351 deletions(-) create mode 100644 .github/workflows/ci-staticcheck.yaml create mode 100644 server/ast/staticcheck.conf delete mode 100644 server/system_checks.go create mode 100644 staticcheck.conf diff --git a/.github/workflows/ci-staticcheck.yaml b/.github/workflows/ci-staticcheck.yaml new file mode 100644 index 0000000000..7af9f473e5 --- /dev/null +++ b/.github/workflows/ci-staticcheck.yaml @@ -0,0 +1,27 @@ +name: Static Analysis & Linter +on: [pull_request] + +concurrency: + group: ci-staticcheck-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + ci: + name: Run Staticcheck + runs-on: ubuntu-22.04 + steps: + - name: Setup Go 1.x + uses: actions/setup-go@v3 + with: + go-version: ^1.21 + - uses: actions/checkout@v3 + with: + submodules: true + - name: Build SQL Syntax + run: ./build.sh + working-directory: ./postgres/parser + shell: bash + - name: Run check + run: | + go install honnef.co/go/tools/cmd/staticcheck@2023.1.6 + staticcheck ./... diff --git a/main.go b/main.go index 739e2c04b6..ad98eeb4ec 100644 --- a/main.go +++ b/main.go @@ -16,10 +16,7 @@ package main import ( "context" - crand "crypto/rand" - "encoding/binary" "fmt" - "math/rand" "os" "strconv" "strings" @@ -69,7 +66,6 @@ const stdOutAndErrFlag = "--out-and-err" func main() { ctx := context.Background() - seedGlobalRand() args := os.Args[1:] @@ -112,7 +108,7 @@ func main() { } // Otherwise, attempt to run the command indicated - cliCtx, err := configureCliCtx(subCommandName, apr, fs, dEnv, err, ctx) + cliCtx, err := configureCliCtx(subCommandName, apr, fs, dEnv, ctx) if err != nil { cli.PrintErrln(err.Error()) os.Exit(1) @@ -122,7 +118,7 @@ func main() { os.Exit(exitCode) } -func configureCliCtx(subcommand string, apr *argparser.ArgParseResults, fs filesys.Filesys, dEnv *env.DoltEnv, err error, ctx context.Context) (cli.CliContext, error) { +func configureCliCtx(subcommand string, apr *argparser.ArgParseResults, fs filesys.Filesys, dEnv *env.DoltEnv, ctx context.Context) (cli.CliContext, error) { dataDir, hasDataDir := apr.GetValue(commands.DataDirFlag) if hasDataDir { // If a relative path was provided, this ensures we have an absolute path everywhere. @@ -144,7 +140,7 @@ func configureCliCtx(subcommand string, apr *argparser.ArgParseResults, fs files "To use the current directory as a database, start the server from the parent directory.") } - err = reconfigIfTempFileMoveFails(dEnv) + err := reconfigIfTempFileMoveFails(dEnv) if err != nil { return nil, fmt.Errorf("failed to set up the temporary directory: %w", err) } @@ -297,15 +293,6 @@ func getProfile(apr *argparser.ArgParseResults, profileName, profiles string) (r } } -func seedGlobalRand() { - bs := make([]byte, 8) - _, err := crand.Read(bs) - if err != nil { - panic("failed to initial rand " + err.Error()) - } - rand.Seed(int64(binary.LittleEndian.Uint64(bs))) -} - // buildLateBinder builds a LateBindQueryist for which is used to obtain the Queryist used for the length of the // command execution. func buildLateBinder(ctx context.Context, cwdFS filesys.Filesys, rootEnv *env.DoltEnv, mrEnv *env.MultiRepoEnv, creds *cli.UserPassword, apr *argparser.ArgParseResults, subcommandName string, verbose bool) (cli.LateBindQueryist, error) { @@ -370,12 +357,6 @@ func buildLateBinder(ctx context.Context, cwdFS filesys.Filesys, rootEnv *env.Do }, nil } - // nil targetEnv will happen if the user ran a command in an empty directory or when there is a server running with - // no databases. CLI will try to connect to the server in this case. - if targetEnv == nil { - targetEnv = rootEnv - } - if verbose { cli.Println("verbose: starting local mode") } @@ -515,5 +496,5 @@ func emitUsageEvent(dEnv *env.DoltEnv) { return } - err = emitter.LogEvents(server.Version, clientEvents) + _ = emitter.LogEvents(server.Version, clientEvents) } diff --git a/postgres/connection/message_decode_encode.go b/postgres/connection/message_decode_encode.go index cf61fc20da..1df1721e7a 100644 --- a/postgres/connection/message_decode_encode.go +++ b/postgres/connection/message_decode_encode.go @@ -102,7 +102,7 @@ func decode(buffer *decodeBuffer, fields []FieldGroup, iterations int32) error { } data := make([]byte, byteCount) copy(data, buffer.data) - if field.Flags&StaticData != 0 && bytes.Compare(field.Data.([]byte), data) != 0 { + if field.Flags&StaticData != 0 && !bytes.Equal(field.Data.([]byte), data) { return errors.New("static data differs from the buffer data") } field.Data = data @@ -110,7 +110,7 @@ func decode(buffer *decodeBuffer, fields []FieldGroup, iterations int32) error { } else { data := make([]byte, len(buffer.data)) copy(data, buffer.data) - if field.Flags&StaticData != 0 && bytes.Compare(field.Data.([]byte), data) != 0 { + if field.Flags&StaticData != 0 && !bytes.Equal(field.Data.([]byte), data) { return errors.New("static data differs from the buffer data") } field.Data = data diff --git a/postgres/parser/encoding/decimal.go b/postgres/parser/encoding/decimal.go index 853fe6e8e9..43c1e62526 100644 --- a/postgres/parser/encoding/decimal.go +++ b/postgres/parser/encoding/decimal.go @@ -31,7 +31,6 @@ package encoding import ( "bytes" "fmt" - "math" "math/big" "unsafe" @@ -730,23 +729,6 @@ func UpperBoundNonsortingDecimalSize(d *apd.Decimal) int { return 1 + MaxVarintLen + WordLen(d.Coeff.Bits()) } -// upperBoundNonsortingDecimalUnscaledSize is the same as -// UpperBoundNonsortingDecimalSize but for a decimal with the given unscaled -// length. The upper bound here may not be as tight as the one returned by -// UpperBoundNonsortingDecimalSize. -func upperBoundNonsortingDecimalUnscaledSize(unscaledLen int) int { - // The number of digits needed to represent a base 10 number of length - // unscaledLen in base 2. - unscaledLenBase2 := float64(unscaledLen) * math.Log2(10) - unscaledLenBase2Words := math.Ceil(unscaledLenBase2 / 8 / float64(bigWordSize)) - unscaledLenWordRounded := int(unscaledLenBase2Words) * bigWordSize - // Makeup of upper bound size: - // - 1 byte for the prefix - // - MaxVarintLen for the exponent - // - unscaledLenWordRounded for the big.Int bytes - return 1 + MaxVarintLen + unscaledLenWordRounded -} - // Taken from math/big/arith.go. const bigWordSize = int(unsafe.Sizeof(big.Word(0))) diff --git a/postgres/parser/encoding/encoding.go b/postgres/parser/encoding/encoding.go index 9243d69bfd..65d4487c5d 100644 --- a/postgres/parser/encoding/encoding.go +++ b/postgres/parser/encoding/encoding.go @@ -28,7 +28,6 @@ import ( "bytes" "encoding/binary" "fmt" - "reflect" "unsafe" "github.com/cockroachdb/apd/v2" @@ -161,8 +160,6 @@ func DecodeUint32Ascending(b []byte) ([]byte, uint32, error) { return b[4:], v, nil } -const uint64AscendingEncodedLength = 8 - // EncodeUint64Ascending encodes the uint64 value using a big-endian 8 byte // representation. The bytes are appended to the supplied buffer and // the final buffer is returned. @@ -461,10 +458,10 @@ func UnsafeConvertStringToBytes(s string) []byte { // kosher because we know that EncodeBytes{,Descending} does // not keep a reference to the value it encodes. The first // step is getting access to the string internals. - hdr := (*reflect.StringHeader)(unsafe.Pointer(&s)) + data := unsafe.StringData(s) // Next we treat the string data as a maximally sized array which we // slice. This usage is safe because the pointer value remains in the string. - return (*[0x7fffffff]byte)(unsafe.Pointer(hdr.Data))[:len(s):len(s)] + return (*[0x7fffffff]byte)(unsafe.Pointer(data))[:len(s):len(s)] } // EncodeStringAscending encodes the string value using an escape-based encoding. See @@ -694,19 +691,6 @@ func GetMultiVarintLen(b []byte, num int) (int, error) { return p, nil } -// getMultiNonsortingVarintLen finds the length of encoded nonsorting varints. -func getMultiNonsortingVarintLen(b []byte, num int) (int, error) { - p := 0 - for i := 0; i < num && p < len(b); i++ { - _, len, _, err := DecodeNonsortingStdlibVarint(b[p:]) - if err != nil { - return 0, err - } - p += len - } - return p, nil -} - // getArrayLength returns the length of a key encoded array. The input // must have had the array type marker stripped from the front. func getArrayLength(buf []byte, dir Direction) (int, error) { @@ -883,8 +867,6 @@ func DecodeNonsortingStdlibUvarint( return buf[n:], n, i, nil } -const floatValueEncodedLength = uint64AscendingEncodedLength - // EncodeUntaggedDecimalValue encodes an apd.Decimal value, appends it to the supplied // buffer, and returns the final buffer. func EncodeUntaggedDecimalValue(appendTo []byte, d *apd.Decimal) []byte { diff --git a/postgres/parser/geo/parse.go b/postgres/parser/geo/parse.go index e21c0e4904..7b3e321652 100644 --- a/postgres/parser/geo/parse.go +++ b/postgres/parser/geo/parse.go @@ -35,8 +35,6 @@ import ( "github.com/twpayne/go-geom/encoding/ewkb" "github.com/twpayne/go-geom/encoding/ewkbhex" "github.com/twpayne/go-geom/encoding/geojson" - "github.com/twpayne/go-geom/encoding/wkb" - "github.com/twpayne/go-geom/encoding/wkbcommon" "github.com/dolthub/doltgresql/postgres/parser/geo/geopb" "github.com/dolthub/doltgresql/postgres/parser/geo/geos" @@ -109,18 +107,6 @@ func parseEWKB( return spatialObjectFromGeomT(t, soType) } -// parseWKB takes given bytes assumed to be WKB and transforms it into a SpatialObject. -func parseWKB( - soType geopb.SpatialObjectType, b []byte, defaultSRID geopb.SRID, -) (geopb.SpatialObject, error) { - t, err := wkb.Unmarshal(b, wkbcommon.WKBOptionEmptyPointHandling(wkbcommon.EmptyPointHandlingNaN)) - if err != nil { - return geopb.SpatialObject{}, err - } - AdjustGeomTSRID(t, defaultSRID) - return spatialObjectFromGeomT(t, soType) -} - // parseGeoJSON takes given bytes assumed to be GeoJSON and transforms it into a SpatialObject. func parseGeoJSON( soType geopb.SpatialObjectType, b []byte, defaultSRID geopb.SRID, diff --git a/postgres/parser/json/json.go b/postgres/parser/json/json.go index 67d9da92b7..0cea86b341 100644 --- a/postgres/parser/json/json.go +++ b/postgres/parser/json/json.go @@ -64,8 +64,8 @@ const ( const ( wordSize = unsafe.Sizeof(big.Word(0)) decimalSize = unsafe.Sizeof(apd.Decimal{}) - stringHeaderSize = unsafe.Sizeof(reflect.StringHeader{}) - sliceHeaderSize = unsafe.Sizeof(reflect.SliceHeader{}) + stringHeaderSize = unsafe.Sizeof(reflect.StringHeader{}) //lint:ignore SA1019 Still useful here + sliceHeaderSize = unsafe.Sizeof(reflect.SliceHeader{}) //lint:ignore SA1019 Still useful here keyValuePairSize = unsafe.Sizeof(jsonKeyValuePair{}) jsonInterfaceSize = unsafe.Sizeof((JSON)(nil)) ) @@ -1423,12 +1423,8 @@ func (j jsonObject) RemoveString(s string) (JSON, bool, error) { } newVal := make([]jsonKeyValuePair, len(j)-1) - for i, elem := range j[:idx] { - newVal[i] = elem - } - for i, elem := range j[idx+1:] { - newVal[idx+i] = elem - } + copy(newVal, j[:idx]) + copy(newVal[idx:], j[idx+1:]) return jsonObject(newVal), true, nil } @@ -1487,9 +1483,7 @@ func scalarConcat(left, other JSON) (JSON, error) { right := decoded.(jsonArray) result := make(jsonArray, len(right)+1) result[0] = left - for i := range right { - result[i+1] = right[i] - } + copy(result[1:], right) return result, nil case ObjectJSONType: return nil, errInvalidConcat @@ -1514,18 +1508,12 @@ func (j jsonArray) Concat(other JSON) (JSON, error) { } right := decoded.(jsonArray) result := make(jsonArray, len(left)+len(right)) - for i := range left { - result[i] = left[i] - } - for i := range right { - result[len(left)+i] = right[i] - } + copy(result, left) + copy(result[len(left):], right) return result, nil default: result := make(jsonArray, len(left)+1) - for i := range left { - result[i] = left[i] - } + copy(result, left) result[len(left)] = other return result, nil } @@ -1833,9 +1821,7 @@ func (j jsonArray) doRemovePath(path []string) (JSON, bool, error) { } result := make(jsonArray, len(j)) - for i := range j { - result[i] = j[i] - } + copy(result, j) result[idx] = newVal return result, true, nil @@ -1862,9 +1848,7 @@ func (j jsonObject) doRemovePath(path []string) (JSON, bool, error) { } result := make(jsonObject, len(j)) - for i := range j { - result[i] = j[i] - } + copy(result, j) result[idx].v = newVal return result, true, nil diff --git a/postgres/parser/parser/help.go b/postgres/parser/parser/help.go index b3e7f3e68e..332b56e4db 100644 --- a/postgres/parser/parser/help.go +++ b/postgres/parser/parser/help.go @@ -33,6 +33,8 @@ import ( "text/tabwriter" "github.com/cockroachdb/errors" + "golang.org/x/text/cases" + "golang.org/x/text/language" "github.com/dolthub/doltgresql/postgres/parser/pgcode" "github.com/dolthub/doltgresql/postgres/parser/pgerror" @@ -240,7 +242,7 @@ var AllHelp = func(h map[string]HelpMessageBody) string { var buf bytes.Buffer w := tabwriter.NewWriter(&buf, 0, 0, 1, ' ', 0) for _, cat := range categories { - fmt.Fprintf(w, "%s:\n", strings.Title(cat)) + fmt.Fprintf(w, "%s:\n", cases.Title(language.English).String(cat)) for _, item := range cmds[cat] { fmt.Fprintf(w, "\t\t%s\t%s\n", item, h[item].ShortDescription) } diff --git a/postgres/parser/protoutil/marshaler.go b/postgres/parser/protoutil/marshaler.go index b8e7edbbf1..30c4757d0e 100644 --- a/postgres/parser/protoutil/marshaler.go +++ b/postgres/parser/protoutil/marshaler.go @@ -26,7 +26,6 @@ package protoutil import ( "io" - "io/ioutil" "github.com/cockroachdb/errors" "github.com/gogo/protobuf/proto" @@ -72,7 +71,7 @@ func (*ProtoPb) NewDecoder(r io.Reader) gwruntime.Decoder { // NB: we use proto.Message here because grpc-gateway passes us protos that // we don't control and thus don't implement protoutil.Message. if p, ok := v.(proto.Message); ok { - bytes, err := ioutil.ReadAll(r) + bytes, err := io.ReadAll(r) if err == nil { err = proto.Unmarshal(bytes, p) } diff --git a/postgres/parser/sem/tree/datum.go b/postgres/parser/sem/tree/datum.go index 3890760270..7280240ac4 100644 --- a/postgres/parser/sem/tree/datum.go +++ b/postgres/parser/sem/tree/datum.go @@ -37,8 +37,6 @@ import ( "github.com/cockroachdb/apd/v2" "github.com/cockroachdb/errors" "github.com/lib/pq/oid" - "golang.org/x/text/collate" - "golang.org/x/text/language" "github.com/dolthub/doltgresql/postgres/parser/duration" "github.com/dolthub/doltgresql/postgres/parser/geo" @@ -611,40 +609,6 @@ type DCollatedString struct { Key []byte } -// CollationEnvironment stores the state needed by NewDCollatedString to -// construct collation keys efficiently. -type CollationEnvironment struct { - cache map[string]collationEnvironmentCacheEntry - buffer *collate.Buffer -} - -type collationEnvironmentCacheEntry struct { - // locale is interned. - locale string - // collator is an expensive factory. - collator *collate.Collator -} - -func (env *CollationEnvironment) getCacheEntry( - locale string, -) (collationEnvironmentCacheEntry, error) { - entry, ok := env.cache[locale] - if !ok { - if env.cache == nil { - env.cache = make(map[string]collationEnvironmentCacheEntry) - } - tag, err := language.Parse(locale) - if err != nil { - err = errors.NewAssertionErrorWithWrappedErrf(err, "failed to parse locale %q", locale) - return collationEnvironmentCacheEntry{}, err - } - - entry = collationEnvironmentCacheEntry{locale, collate.New(tag)} - env.cache[locale] = entry - } - return entry, nil -} - // AmbiguousFormat implements the Datum interface. func (*DCollatedString) AmbiguousFormat() bool { return false } @@ -770,10 +734,6 @@ func (*DIPAddr) ResolvedType() *types.T { return types.INet } -func (d DIPAddr) equal(other *DIPAddr) bool { - return d.IPAddr.Equal(&other.IPAddr) -} - // AmbiguousFormat implements the Datum interface. func (*DIPAddr) AmbiguousFormat() bool { return true diff --git a/postgres/parser/sem/tree/eval.go b/postgres/parser/sem/tree/eval.go index 416ec54a39..dbd213d7ac 100644 --- a/postgres/parser/sem/tree/eval.go +++ b/postgres/parser/sem/tree/eval.go @@ -27,11 +27,8 @@ package tree import ( "context" "fmt" - "math/big" - "regexp" "github.com/cockroachdb/errors" - "github.com/lib/pq/oid" "github.com/dolthub/doltgresql/postgres/parser/geo" "github.com/dolthub/doltgresql/postgres/parser/pgcode" @@ -41,21 +38,8 @@ import ( ) var ( - // ErrIntOutOfRange is reported when integer arithmetic overflows. - ErrIntOutOfRange = pgerror.New(pgcode.NumericValueOutOfRange, "integer out of range") - // ErrFloatOutOfRange is reported when float arithmetic overflows. - ErrFloatOutOfRange = pgerror.New(pgcode.NumericValueOutOfRange, "float out of range") - errDecOutOfRange = pgerror.New(pgcode.NumericValueOutOfRange, "decimal out of range") - // ErrDivByZero is reported on a division by zero. - ErrDivByZero = pgerror.New(pgcode.DivisionByZero, "division by zero") - errSqrtOfNegNumber = pgerror.New(pgcode.InvalidArgumentForPowerFunction, "cannot take square root of a negative number") - - // ErrShiftArgOutOfRange is reported when a shift argument is out of range. - ErrShiftArgOutOfRange = pgerror.New(pgcode.InvalidParameterValue, "shift argument out of range") - - big10E6 = big.NewInt(1e6) - big10E10 = big.NewInt(1e10) + ErrDivByZero = pgerror.New(pgcode.DivisionByZero, "division by zero") ) // UnaryOp is a unary operator. @@ -1478,19 +1462,6 @@ func init() { } } -func boolFromCmp(cmp int, op ComparisonOperator) *DBool { - switch op { - case EQ, IsNotDistinctFrom: - return MakeDBool(cmp == 0) - case LT: - return MakeDBool(cmp < 0) - case LE: - return MakeDBool(cmp <= 0) - default: - panic(errors.AssertionFailedf("unexpected ComparisonOperator in boolFromCmp: %v", errors.Safe(op))) - } -} - func makeEvalTupleIn(typ *types.T, v Volatility) *CmpOp { return &CmpOp{ LeftType: typ, @@ -1652,32 +1623,6 @@ type EvalContextTestingKnobs struct { OptimizerCostPerturbation float64 } -// pgSignatureRegexp matches a Postgres function type signature, capturing the -// name of the function into group 1. -// e.g. function(a, b, c) or function( a ) -var pgSignatureRegexp = regexp.MustCompile(`^\s*([\w\.]+)\s*\((?:(?:\s*\w+\s*,)*\s*\w+)?\s*\)\s*$`) - -// regTypeInfo contains details on a pg_catalog table that has a reg* type. -type regTypeInfo struct { - tableName string - // nameCol is the name of the column that contains the table's entity name. - nameCol string - // objName is a human-readable name describing the objects in the table. - objName string - // errType is the pg error code in case the object does not exist. - errType pgcode.Code -} - -// regTypeInfos maps an oid.Oid to a regTypeInfo that describes the pg_catalog -// table that contains the entities of the type of the key. -var regTypeInfos = map[oid.Oid]regTypeInfo{ - oid.T_regclass: {"pg_class", "relname", "relation", pgcode.UndefinedTable}, - oid.T_regtype: {"pg_type", "typname", "type", pgcode.UndefinedObject}, - oid.T_regproc: {"pg_proc", "proname", "function", pgcode.UndefinedFunction}, - oid.T_regprocedure: {"pg_proc", "proname", "function", pgcode.UndefinedFunction}, - oid.T_regnamespace: {"pg_namespace", "nspname", "namespace", pgcode.UndefinedObject}, -} - // FoldComparisonExpr folds a given comparison operation and its expressions // into an equivalent operation that will hit in the CmpOps map, returning // this new operation, along with potentially flipped operands and "flipped" diff --git a/postgres/parser/sem/tree/expr.go b/postgres/parser/sem/tree/expr.go index ce8b646b3b..87813c35f4 100644 --- a/postgres/parser/sem/tree/expr.go +++ b/postgres/parser/sem/tree/expr.go @@ -1200,25 +1200,6 @@ func (node *BinaryExpr) memoizeFn() { node.Fn = fn } -// newBinExprIfValidOverload constructs a new BinaryExpr if and only -// if the pair of arguments have a valid implementation for the given -// BinaryOperator. -func newBinExprIfValidOverload(op BinaryOperator, left TypedExpr, right TypedExpr) *BinaryExpr { - leftRet, rightRet := left.ResolvedType(), right.ResolvedType() - fn, ok := BinOps[op].lookupImpl(leftRet, rightRet) - if ok { - expr := &BinaryExpr{ - Operator: op, - Left: left, - Right: right, - Fn: fn, - } - expr.typ = returnTypeToFixedType(fn.returnType()) - return expr - } - return nil -} - // Format implements the NodeFormatter interface. func (node *BinaryExpr) Format(ctx *FmtCtx) { binExprFmtWithParen(ctx, node.Left, node.Operator.String(), node.Right, node.Operator.isPadded()) diff --git a/postgres/parser/sem/tree/overload.go b/postgres/parser/sem/tree/overload.go index 98512fa417..1143e8184a 100644 --- a/postgres/parser/sem/tree/overload.go +++ b/postgres/parser/sem/tree/overload.go @@ -323,9 +323,7 @@ func (v VariadicType) Length() int { // Types is part of the TypeList interface. func (v VariadicType) Types() []*types.T { result := make([]*types.T, len(v.FixedTypes)+1) - for i := range v.FixedTypes { - result[i] = v.FixedTypes[i] - } + copy(result, v.FixedTypes) result[len(result)-1] = v.VarType return result } diff --git a/postgres/parser/uuid/uuid_wrapper.go b/postgres/parser/uuid/uuid_wrapper.go index 53c441b9c1..d714c530e2 100644 --- a/postgres/parser/uuid/uuid_wrapper.go +++ b/postgres/parser/uuid/uuid_wrapper.go @@ -25,14 +25,11 @@ package uuid import ( - "encoding/binary" + "crypto/rand" "encoding/json" "fmt" - "math/rand" "github.com/dolthub/doltgresql/postgres/parser/utils" - - "github.com/cockroachdb/errors" ) // Short returns the first eight characters of the output of String(). @@ -109,21 +106,6 @@ func (u *UUID) UnmarshalJSON(data []byte) error { return err } -// MakeV4 calls Must(NewV4) -func MakeV4() UUID { - return Must(NewV4()) -} - -// FastMakeV4 generates a UUID using a fast but not cryptographically secure -// source of randomness. -func FastMakeV4() UUID { - u, err := fastGen.NewV4() - if err != nil { - panic(errors.Wrap(err, "should never happen with math/rand.Rand")) - } - return u -} - // defaultRandReader is an io.Reader that calls through to "math/rand".Read // which is safe for concurrent use. type defaultRandReader struct{} @@ -131,25 +113,3 @@ type defaultRandReader struct{} func (r defaultRandReader) Read(p []byte) (n int, err error) { return rand.Read(p) } - -// fastGen is a non-cryptographically secure Generator. -var fastGen = NewGenWithReader(defaultRandReader{}) - -// NewPopulatedUUID returns a populated UUID. -func NewPopulatedUUID(r interface { - Int63() int64 -}) *UUID { - var u UUID - binary.LittleEndian.PutUint64(u[:8], uint64(r.Int63())) - binary.LittleEndian.PutUint64(u[8:], uint64(r.Int63())) - return &u -} - -// FromUint128 delegates to FromBytes and wraps the result in a UUID. -func FromUint128(input utils.Uint128) UUID { - u, err := FromBytes(input.GetBytes()) - if err != nil { - panic(errors.Wrap(err, "should never happen with 16 byte slice")) - } - return u -} diff --git a/server/ast/staticcheck.conf b/server/ast/staticcheck.conf new file mode 100644 index 0000000000..d533ce21a7 --- /dev/null +++ b/server/ast/staticcheck.conf @@ -0,0 +1 @@ +checks = ["inherit", "-U1000"] \ No newline at end of file diff --git a/server/system_checks.go b/server/system_checks.go deleted file mode 100644 index 68ae0e889c..0000000000 --- a/server/system_checks.go +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright 2023 Dolthub, Inc. -// -// 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 server - -import ( - "fmt" - "os" - - "github.com/dolthub/dolt/go/libraries/doltcore/env" - "github.com/dolthub/dolt/go/libraries/utils/file" - "github.com/dolthub/dolt/go/store/util/tempfiles" -) - -// returns false if it fails to verify that it can move files from the default temp directory to the local directory. -func canMoveTempFile() bool { - const testfile = "./testfile" - - f, err := os.CreateTemp("", "") - - if err != nil { - return false - } - - name := f.Name() - err = f.Close() - - if err != nil { - return false - } - - err = file.Rename(name, testfile) - - if err != nil { - _ = file.Remove(name) - return false - } - - _ = file.Remove(testfile) - return true -} - -// If we cannot verify that we can move files for any reason, use a ./.dolt/tmp as the temp dir. -func reconfigIfTempFileMoveFails(dEnv *env.DoltEnv) error { - if !canMoveTempFile() { - tmpDir := "./.dolt/tmp" - - if !dEnv.HasDoltDir() { - tmpDir = "./.tmp" - } - - stat, err := os.Stat(tmpDir) - - if err != nil { - err := os.MkdirAll(tmpDir, os.ModePerm) - - if err != nil { - return fmt.Errorf("failed to create temp dir '%s': %s", tmpDir, err.Error()) - } - } else if !stat.IsDir() { - return fmt.Errorf("attempting to use '%s' as a temp directory, but there exists a file with that name", tmpDir) - } - - tempfiles.MovableTempFileProvider = tempfiles.NewTempFileProviderAt(tmpDir) - } - - return nil -} diff --git a/staticcheck.conf b/staticcheck.conf new file mode 100644 index 0000000000..ee764ccb1c --- /dev/null +++ b/staticcheck.conf @@ -0,0 +1,3 @@ +checks = ["all", "-SA6002", "-ST1000", "-ST1003", "-ST1005", "-ST1016", "-ST1020", "-ST1021", "-ST1022", "-ST1023"] +initialisms = ["ACL", "API", "ASCII", "CPU", "CSS", "DNS", "EOF", "GUID", "HTML", "HTTP", "HTTPS", "ID", "IP", "JSON", "QPS", "RAM", "RPC", "SLA", "SMTP", "SQL", "SSH", "TCP", "TLS", "TTL", "UDP", "UI", "GID", "UID", "UUID", "URI", "URL", "UTF8", "VM", "XML", "XMPP", "XSRF", "XSS", "SIP", "RTP", "AMQP", "DB", "TS"] +http_status_code_whitelist = ["200", "400", "404", "500"] \ No newline at end of file diff --git a/testing/generation/command_docs/create_tests.go b/testing/generation/command_docs/create_tests.go index f341047c67..8f2be83e75 100644 --- a/testing/generation/command_docs/create_tests.go +++ b/testing/generation/command_docs/create_tests.go @@ -27,6 +27,8 @@ import ( "github.com/dolthub/vitess/go/vt/sqlparser" "github.com/jackc/pgx/v5" "github.com/sergi/go-diff/diffmatchpatch" + "golang.org/x/text/cases" + "golang.org/x/text/language" "github.com/dolthub/doltgresql/postgres/parser/parser" "github.com/dolthub/doltgresql/server/ast" @@ -121,7 +123,7 @@ FileLoop: } includeRepetition := len(repetitionDisabled) == 0 || repetitionDisabled[0] != "*" for _, bans := range repetitionDisabled { - if strings.ToLower(bans) == strings.ToLower(prefix) { + if strings.EqualFold(bans, prefix) { includeRepetition = false break } @@ -157,7 +159,8 @@ FileLoop: continue FileLoop } sb := strings.Builder{} - sb.WriteString(fmt.Sprintf(TestHeader, time.Now().Year(), strings.ReplaceAll(strings.Title(strings.ToLower(prefix)), " ", ""))) + sb.WriteString(fmt.Sprintf(TestHeader, time.Now().Year(), + strings.ReplaceAll(cases.Title(language.English).String(strings.ToLower(prefix)), " ", ""))) permutations := stmtGen.Permutations() if permutations.Cmp(big.NewInt(MaxTestCount)) <= 0 { diff --git a/testing/logictest/harness/doltgres_harness.go b/testing/logictest/harness/doltgres_harness.go index f2ce6ea6d6..fb06020bfa 100755 --- a/testing/logictest/harness/doltgres_harness.go +++ b/testing/logictest/harness/doltgres_harness.go @@ -26,11 +26,6 @@ import ( var _ logictest.Harness = &PostgresqlServerHarness{} -const ( - name = "sqllogictest runner" - email = "sqllogictestrunner@dolthub.com" -) - // sqllogictest harness for postgres databases. type PostgresqlServerHarness struct { dsn string