Skip to content

Commit 77acc5c

Browse files
authored
Merge pull request #79 from dolthub/daylon/staticcheck
Added static analyzer & linter
2 parents d264839 + 6437b7e commit 77acc5c

File tree

19 files changed

+61
-351
lines changed

19 files changed

+61
-351
lines changed

.github/workflows/ci-staticcheck.yaml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: Static Analysis & Linter
2+
on: [pull_request]
3+
4+
concurrency:
5+
group: ci-staticcheck-${{ github.event.pull_request.number || github.ref }}
6+
cancel-in-progress: true
7+
8+
jobs:
9+
ci:
10+
name: Run Staticcheck
11+
runs-on: ubuntu-22.04
12+
steps:
13+
- name: Setup Go 1.x
14+
uses: actions/setup-go@v3
15+
with:
16+
go-version: ^1.21
17+
- uses: actions/checkout@v3
18+
with:
19+
submodules: true
20+
- name: Build SQL Syntax
21+
run: ./build.sh
22+
working-directory: ./postgres/parser
23+
shell: bash
24+
- name: Run check
25+
run: |
26+
go install honnef.co/go/tools/cmd/[email protected]
27+
staticcheck ./...

main.go

Lines changed: 4 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,7 @@ package main
1616

1717
import (
1818
"context"
19-
crand "crypto/rand"
20-
"encoding/binary"
2119
"fmt"
22-
"math/rand"
2320
"os"
2421
"strconv"
2522
"strings"
@@ -69,7 +66,6 @@ const stdOutAndErrFlag = "--out-and-err"
6966

7067
func main() {
7168
ctx := context.Background()
72-
seedGlobalRand()
7369

7470
args := os.Args[1:]
7571

@@ -112,7 +108,7 @@ func main() {
112108
}
113109

114110
// Otherwise, attempt to run the command indicated
115-
cliCtx, err := configureCliCtx(subCommandName, apr, fs, dEnv, err, ctx)
111+
cliCtx, err := configureCliCtx(subCommandName, apr, fs, dEnv, ctx)
116112
if err != nil {
117113
cli.PrintErrln(err.Error())
118114
os.Exit(1)
@@ -122,7 +118,7 @@ func main() {
122118
os.Exit(exitCode)
123119
}
124120

125-
func configureCliCtx(subcommand string, apr *argparser.ArgParseResults, fs filesys.Filesys, dEnv *env.DoltEnv, err error, ctx context.Context) (cli.CliContext, error) {
121+
func configureCliCtx(subcommand string, apr *argparser.ArgParseResults, fs filesys.Filesys, dEnv *env.DoltEnv, ctx context.Context) (cli.CliContext, error) {
126122
dataDir, hasDataDir := apr.GetValue(commands.DataDirFlag)
127123
if hasDataDir {
128124
// 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
144140
"To use the current directory as a database, start the server from the parent directory.")
145141
}
146142

147-
err = reconfigIfTempFileMoveFails(dEnv)
143+
err := reconfigIfTempFileMoveFails(dEnv)
148144
if err != nil {
149145
return nil, fmt.Errorf("failed to set up the temporary directory: %w", err)
150146
}
@@ -297,15 +293,6 @@ func getProfile(apr *argparser.ArgParseResults, profileName, profiles string) (r
297293
}
298294
}
299295

300-
func seedGlobalRand() {
301-
bs := make([]byte, 8)
302-
_, err := crand.Read(bs)
303-
if err != nil {
304-
panic("failed to initial rand " + err.Error())
305-
}
306-
rand.Seed(int64(binary.LittleEndian.Uint64(bs)))
307-
}
308-
309296
// buildLateBinder builds a LateBindQueryist for which is used to obtain the Queryist used for the length of the
310297
// command execution.
311298
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
370357
}, nil
371358
}
372359

373-
// nil targetEnv will happen if the user ran a command in an empty directory or when there is a server running with
374-
// no databases. CLI will try to connect to the server in this case.
375-
if targetEnv == nil {
376-
targetEnv = rootEnv
377-
}
378-
379360
if verbose {
380361
cli.Println("verbose: starting local mode")
381362
}
@@ -515,5 +496,5 @@ func emitUsageEvent(dEnv *env.DoltEnv) {
515496
return
516497
}
517498

518-
err = emitter.LogEvents(server.Version, clientEvents)
499+
_ = emitter.LogEvents(server.Version, clientEvents)
519500
}

postgres/connection/message_decode_encode.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,15 +102,15 @@ func decode(buffer *decodeBuffer, fields []FieldGroup, iterations int32) error {
102102
}
103103
data := make([]byte, byteCount)
104104
copy(data, buffer.data)
105-
if field.Flags&StaticData != 0 && bytes.Compare(field.Data.([]byte), data) != 0 {
105+
if field.Flags&StaticData != 0 && !bytes.Equal(field.Data.([]byte), data) {
106106
return errors.New("static data differs from the buffer data")
107107
}
108108
field.Data = data
109109
buffer.advance(byteCount)
110110
} else {
111111
data := make([]byte, len(buffer.data))
112112
copy(data, buffer.data)
113-
if field.Flags&StaticData != 0 && bytes.Compare(field.Data.([]byte), data) != 0 {
113+
if field.Flags&StaticData != 0 && !bytes.Equal(field.Data.([]byte), data) {
114114
return errors.New("static data differs from the buffer data")
115115
}
116116
field.Data = data

postgres/parser/encoding/decimal.go

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ package encoding
3131
import (
3232
"bytes"
3333
"fmt"
34-
"math"
3534
"math/big"
3635
"unsafe"
3736

@@ -730,23 +729,6 @@ func UpperBoundNonsortingDecimalSize(d *apd.Decimal) int {
730729
return 1 + MaxVarintLen + WordLen(d.Coeff.Bits())
731730
}
732731

733-
// upperBoundNonsortingDecimalUnscaledSize is the same as
734-
// UpperBoundNonsortingDecimalSize but for a decimal with the given unscaled
735-
// length. The upper bound here may not be as tight as the one returned by
736-
// UpperBoundNonsortingDecimalSize.
737-
func upperBoundNonsortingDecimalUnscaledSize(unscaledLen int) int {
738-
// The number of digits needed to represent a base 10 number of length
739-
// unscaledLen in base 2.
740-
unscaledLenBase2 := float64(unscaledLen) * math.Log2(10)
741-
unscaledLenBase2Words := math.Ceil(unscaledLenBase2 / 8 / float64(bigWordSize))
742-
unscaledLenWordRounded := int(unscaledLenBase2Words) * bigWordSize
743-
// Makeup of upper bound size:
744-
// - 1 byte for the prefix
745-
// - MaxVarintLen for the exponent
746-
// - unscaledLenWordRounded for the big.Int bytes
747-
return 1 + MaxVarintLen + unscaledLenWordRounded
748-
}
749-
750732
// Taken from math/big/arith.go.
751733
const bigWordSize = int(unsafe.Sizeof(big.Word(0)))
752734

postgres/parser/encoding/encoding.go

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ import (
2828
"bytes"
2929
"encoding/binary"
3030
"fmt"
31-
"reflect"
3231
"unsafe"
3332

3433
"github.com/cockroachdb/apd/v2"
@@ -161,8 +160,6 @@ func DecodeUint32Ascending(b []byte) ([]byte, uint32, error) {
161160
return b[4:], v, nil
162161
}
163162

164-
const uint64AscendingEncodedLength = 8
165-
166163
// EncodeUint64Ascending encodes the uint64 value using a big-endian 8 byte
167164
// representation. The bytes are appended to the supplied buffer and
168165
// the final buffer is returned.
@@ -461,10 +458,10 @@ func UnsafeConvertStringToBytes(s string) []byte {
461458
// kosher because we know that EncodeBytes{,Descending} does
462459
// not keep a reference to the value it encodes. The first
463460
// step is getting access to the string internals.
464-
hdr := (*reflect.StringHeader)(unsafe.Pointer(&s))
461+
data := unsafe.StringData(s)
465462
// Next we treat the string data as a maximally sized array which we
466463
// slice. This usage is safe because the pointer value remains in the string.
467-
return (*[0x7fffffff]byte)(unsafe.Pointer(hdr.Data))[:len(s):len(s)]
464+
return (*[0x7fffffff]byte)(unsafe.Pointer(data))[:len(s):len(s)]
468465
}
469466

470467
// EncodeStringAscending encodes the string value using an escape-based encoding. See
@@ -694,19 +691,6 @@ func GetMultiVarintLen(b []byte, num int) (int, error) {
694691
return p, nil
695692
}
696693

697-
// getMultiNonsortingVarintLen finds the length of <num> encoded nonsorting varints.
698-
func getMultiNonsortingVarintLen(b []byte, num int) (int, error) {
699-
p := 0
700-
for i := 0; i < num && p < len(b); i++ {
701-
_, len, _, err := DecodeNonsortingStdlibVarint(b[p:])
702-
if err != nil {
703-
return 0, err
704-
}
705-
p += len
706-
}
707-
return p, nil
708-
}
709-
710694
// getArrayLength returns the length of a key encoded array. The input
711695
// must have had the array type marker stripped from the front.
712696
func getArrayLength(buf []byte, dir Direction) (int, error) {
@@ -883,8 +867,6 @@ func DecodeNonsortingStdlibUvarint(
883867
return buf[n:], n, i, nil
884868
}
885869

886-
const floatValueEncodedLength = uint64AscendingEncodedLength
887-
888870
// EncodeUntaggedDecimalValue encodes an apd.Decimal value, appends it to the supplied
889871
// buffer, and returns the final buffer.
890872
func EncodeUntaggedDecimalValue(appendTo []byte, d *apd.Decimal) []byte {

postgres/parser/geo/parse.go

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,6 @@ import (
3535
"github.com/twpayne/go-geom/encoding/ewkb"
3636
"github.com/twpayne/go-geom/encoding/ewkbhex"
3737
"github.com/twpayne/go-geom/encoding/geojson"
38-
"github.com/twpayne/go-geom/encoding/wkb"
39-
"github.com/twpayne/go-geom/encoding/wkbcommon"
4038

4139
"github.com/dolthub/doltgresql/postgres/parser/geo/geopb"
4240
"github.com/dolthub/doltgresql/postgres/parser/geo/geos"
@@ -109,18 +107,6 @@ func parseEWKB(
109107
return spatialObjectFromGeomT(t, soType)
110108
}
111109

112-
// parseWKB takes given bytes assumed to be WKB and transforms it into a SpatialObject.
113-
func parseWKB(
114-
soType geopb.SpatialObjectType, b []byte, defaultSRID geopb.SRID,
115-
) (geopb.SpatialObject, error) {
116-
t, err := wkb.Unmarshal(b, wkbcommon.WKBOptionEmptyPointHandling(wkbcommon.EmptyPointHandlingNaN))
117-
if err != nil {
118-
return geopb.SpatialObject{}, err
119-
}
120-
AdjustGeomTSRID(t, defaultSRID)
121-
return spatialObjectFromGeomT(t, soType)
122-
}
123-
124110
// parseGeoJSON takes given bytes assumed to be GeoJSON and transforms it into a SpatialObject.
125111
func parseGeoJSON(
126112
soType geopb.SpatialObjectType, b []byte, defaultSRID geopb.SRID,

postgres/parser/json/json.go

Lines changed: 10 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ const (
6464
const (
6565
wordSize = unsafe.Sizeof(big.Word(0))
6666
decimalSize = unsafe.Sizeof(apd.Decimal{})
67-
stringHeaderSize = unsafe.Sizeof(reflect.StringHeader{})
68-
sliceHeaderSize = unsafe.Sizeof(reflect.SliceHeader{})
67+
stringHeaderSize = unsafe.Sizeof(reflect.StringHeader{}) //lint:ignore SA1019 Still useful here
68+
sliceHeaderSize = unsafe.Sizeof(reflect.SliceHeader{}) //lint:ignore SA1019 Still useful here
6969
keyValuePairSize = unsafe.Sizeof(jsonKeyValuePair{})
7070
jsonInterfaceSize = unsafe.Sizeof((JSON)(nil))
7171
)
@@ -1423,12 +1423,8 @@ func (j jsonObject) RemoveString(s string) (JSON, bool, error) {
14231423
}
14241424

14251425
newVal := make([]jsonKeyValuePair, len(j)-1)
1426-
for i, elem := range j[:idx] {
1427-
newVal[i] = elem
1428-
}
1429-
for i, elem := range j[idx+1:] {
1430-
newVal[idx+i] = elem
1431-
}
1426+
copy(newVal, j[:idx])
1427+
copy(newVal[idx:], j[idx+1:])
14321428
return jsonObject(newVal), true, nil
14331429
}
14341430

@@ -1487,9 +1483,7 @@ func scalarConcat(left, other JSON) (JSON, error) {
14871483
right := decoded.(jsonArray)
14881484
result := make(jsonArray, len(right)+1)
14891485
result[0] = left
1490-
for i := range right {
1491-
result[i+1] = right[i]
1492-
}
1486+
copy(result[1:], right)
14931487
return result, nil
14941488
case ObjectJSONType:
14951489
return nil, errInvalidConcat
@@ -1514,18 +1508,12 @@ func (j jsonArray) Concat(other JSON) (JSON, error) {
15141508
}
15151509
right := decoded.(jsonArray)
15161510
result := make(jsonArray, len(left)+len(right))
1517-
for i := range left {
1518-
result[i] = left[i]
1519-
}
1520-
for i := range right {
1521-
result[len(left)+i] = right[i]
1522-
}
1511+
copy(result, left)
1512+
copy(result[len(left):], right)
15231513
return result, nil
15241514
default:
15251515
result := make(jsonArray, len(left)+1)
1526-
for i := range left {
1527-
result[i] = left[i]
1528-
}
1516+
copy(result, left)
15291517
result[len(left)] = other
15301518
return result, nil
15311519
}
@@ -1833,9 +1821,7 @@ func (j jsonArray) doRemovePath(path []string) (JSON, bool, error) {
18331821
}
18341822

18351823
result := make(jsonArray, len(j))
1836-
for i := range j {
1837-
result[i] = j[i]
1838-
}
1824+
copy(result, j)
18391825
result[idx] = newVal
18401826

18411827
return result, true, nil
@@ -1862,9 +1848,7 @@ func (j jsonObject) doRemovePath(path []string) (JSON, bool, error) {
18621848
}
18631849

18641850
result := make(jsonObject, len(j))
1865-
for i := range j {
1866-
result[i] = j[i]
1867-
}
1851+
copy(result, j)
18681852
result[idx].v = newVal
18691853

18701854
return result, true, nil

postgres/parser/parser/help.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ import (
3333
"text/tabwriter"
3434

3535
"github.com/cockroachdb/errors"
36+
"golang.org/x/text/cases"
37+
"golang.org/x/text/language"
3638

3739
"github.com/dolthub/doltgresql/postgres/parser/pgcode"
3840
"github.com/dolthub/doltgresql/postgres/parser/pgerror"
@@ -240,7 +242,7 @@ var AllHelp = func(h map[string]HelpMessageBody) string {
240242
var buf bytes.Buffer
241243
w := tabwriter.NewWriter(&buf, 0, 0, 1, ' ', 0)
242244
for _, cat := range categories {
243-
fmt.Fprintf(w, "%s:\n", strings.Title(cat))
245+
fmt.Fprintf(w, "%s:\n", cases.Title(language.English).String(cat))
244246
for _, item := range cmds[cat] {
245247
fmt.Fprintf(w, "\t\t%s\t%s\n", item, h[item].ShortDescription)
246248
}

postgres/parser/protoutil/marshaler.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ package protoutil
2626

2727
import (
2828
"io"
29-
"io/ioutil"
3029

3130
"github.com/cockroachdb/errors"
3231
"github.com/gogo/protobuf/proto"
@@ -72,7 +71,7 @@ func (*ProtoPb) NewDecoder(r io.Reader) gwruntime.Decoder {
7271
// NB: we use proto.Message here because grpc-gateway passes us protos that
7372
// we don't control and thus don't implement protoutil.Message.
7473
if p, ok := v.(proto.Message); ok {
75-
bytes, err := ioutil.ReadAll(r)
74+
bytes, err := io.ReadAll(r)
7675
if err == nil {
7776
err = proto.Unmarshal(bytes, p)
7877
}

0 commit comments

Comments
 (0)