Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

enable forcetypeassert linter #1195

Merged
merged 18 commits into from
May 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,6 @@ linters:
- exhaustivestruct
- exhaustruct
- forbidigo
- forcetypeassert
- funlen
- gochecknoglobals
- gocognit
Expand Down Expand Up @@ -297,6 +296,7 @@ issues:
- unused
- unparam
- gocritic
- forcetypeassert
- path: topic/topicreader/reader_example_test.go
linters:
- staticcheck
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
* Added type assertion checks to enhance type safety and prevent unexpected panics in critical sections of the codebase

## v3.66.3
* Fixed the OAuth2 test

Expand Down
8 changes: 7 additions & 1 deletion internal/allocator/allocator.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package allocator

import (
"fmt"
"sync"

"github.com/ydb-platform/ydb-go-genproto/protos/Ydb"
Expand Down Expand Up @@ -1108,7 +1109,12 @@ func (p *Pool[T]) Get() *T {
v = &zero
}

return v.(*T)
val, ok := v.(*T)
if !ok {
panic(fmt.Sprintf("unsupported type conversion from %T to *T", val))
}

return val
}

func (p *Pool[T]) Put(t *T) {
Expand Down
6 changes: 5 additions & 1 deletion internal/bind/numeric_args.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,11 @@ func (m NumericArgs) RewriteQuery(sql string, args ...interface{}) (yql string,
)
}
paramIndex := int(p - 1)
buffer.WriteString(newArgs[paramIndex].(table.ParameterOption).Name())
val, ok := newArgs[paramIndex].(table.ParameterOption)
if !ok {
panic(fmt.Sprintf("unsupported type conversion from %T to table.ParameterOption", val))
}
buffer.WriteString(val.Name())
}
}

Expand Down
15 changes: 12 additions & 3 deletions internal/cmd/gtrace/writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,10 @@ func (w *Writer) init() {
}

func (w *Writer) mustDeclare(name string) {
s := w.scope.Back().Value.(*scope)
s, ok := w.scope.Back().Value.(*scope)
if !ok {
panic(fmt.Sprintf("unsupported type conversion from %T to *scope", s))
}
if !s.set(name) {
where := s.where(name)
panic(fmt.Sprintf(
Expand All @@ -100,7 +103,10 @@ func (w *Writer) declare(name string) string {
if isPredeclared(name) {
name = firstChar(name)
}
s := w.scope.Back().Value.(*scope)
s, ok := w.scope.Back().Value.(*scope)
if !ok {
panic(fmt.Sprintf("unsupported type conversion from %T to *scope", s))
}
for i := 0; ; i++ {
v := name
if i > 0 {
Expand All @@ -127,7 +133,10 @@ func (w *Writer) isGlobalScope() bool {
}

func (w *Writer) capture(vars ...string) {
s := w.scope.Back().Value.(*scope)
s, ok := w.scope.Back().Value.(*scope)
if !ok {
panic(fmt.Sprintf("unsupported type conversion from %T to *scope", s))
}
for _, v := range vars {
if !s.set(v) {
panic(fmt.Sprintf("can't capture variable %q", v))
Expand Down
7 changes: 6 additions & 1 deletion internal/conn/conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -559,7 +559,12 @@ func getContextMark(ctx context.Context) *modificationMark {
return &modificationMark{}
}

return v.(*modificationMark)
val, ok := v.(*modificationMark)
if !ok {
panic(fmt.Sprintf("unsupported type conversion from %T to *modificationMark", val))
}

return val
}

type modificationMark struct {
Expand Down
25 changes: 20 additions & 5 deletions internal/table/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -615,12 +615,18 @@ func (c *Client) Close(ctx context.Context) (err error) {
c.limit = 0

for el := c.waitQ.Front(); el != nil; el = el.Next() {
ch := el.Value.(*chan *session)
ch, ok := el.Value.(*chan *session)
if !ok {
panic(fmt.Sprintf("unsupported type conversion from %T to *chan *session", ch))
}
close(*ch)
}

for e := c.idle.Front(); e != nil; e = e.Next() {
s := e.Value.(*session)
s, ok := e.Value.(*session)
if !ok {
panic(fmt.Sprintf("unsupported type conversion from %T to *session", s))
}
s.SetStatus(table.SessionClosing)
c.wg.Add(1)
go func() {
Expand Down Expand Up @@ -745,7 +751,10 @@ func (c *Client) internalPoolGCTick(ctx context.Context, idleThreshold time.Dura
return
}
for e := c.idle.Front(); e != nil; e = e.Next() {
s := e.Value.(*session)
s, ok := e.Value.(*session)
if !ok {
panic(fmt.Sprintf("unsupported type conversion from %T to *session", s))
}
info, has := c.index[s]
if !has {
panic("session not found in pool")
Expand Down Expand Up @@ -818,7 +827,10 @@ func (c *Client) internalPoolPeekFirstIdle() (s *session, touched time.Time) {
if el == nil {
return
}
s = el.Value.(*session)
s, ok := el.Value.(*session)
if !ok {
panic(fmt.Sprintf("unsupported type conversion from %T to *session", s))
}
info, has := c.index[s]
if !has || el != info.idle {
panic("inconsistent session client index")
Expand Down Expand Up @@ -857,7 +869,10 @@ func (c *Client) internalPoolNotify(s *session) (notified bool) {
// missed something and may want to retry (especially for case (3)).
//
// After that we taking a next waiter and repeat the same.
ch := c.waitQ.Remove(el).(*chan *session)
ch, ok := c.waitQ.Remove(el).(*chan *session)
if !ok {
panic(fmt.Sprintf("unsupported type conversion from %T to *chan *session", ch))
}
select {
case *ch <- s:
// Case (1).
Expand Down
6 changes: 5 additions & 1 deletion internal/table/scanner/scan_raw.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package scanner

import (
"bytes"
"fmt"
"io"
"reflect"
"strconv"
Expand Down Expand Up @@ -584,7 +585,10 @@ func (s *rawConverter) IsDecimal() bool {
}

func isEqualDecimal(d *Ydb.DecimalType, t types.Type) bool {
w := t.(*types.Decimal)
w, ok := t.(*types.Decimal)
if !ok {
panic(fmt.Sprintf("unsupported type conversion from %T to *types.Decimal", w))
}

return d.GetPrecision() == w.Precision() && d.GetScale() == w.Scale()
}
Expand Down
7 changes: 6 additions & 1 deletion internal/table/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,15 @@ func (tx *transaction) ExecuteStatement(
a := allocator.New()
defer a.Free()

val, ok := stmt.(*statement)
if !ok {
panic(fmt.Sprintf("unsupported type conversion from %T to *statement", val))
}

onDone := trace.TableOnTxExecuteStatement(
tx.s.config.Trace(), &ctx,
stack.FunctionID("github.com/ydb-platform/ydb-go-sdk/3/internal/table.(*transaction).ExecuteStatement"),
tx.s, tx, stmt.(*statement).query, parameters,
tx.s, tx, val.query, parameters,
)
defer func() {
onDone(r, err)
Expand Down
14 changes: 12 additions & 2 deletions internal/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -824,7 +824,12 @@ func (v *VariantStruct) ToYDB(a *allocator.Allocator) *Ydb.Type {
typeVariant.VariantType = a.Variant()

structItems := a.VariantStructItems()
structItems.StructItems = v.Struct.ToYDB(a).GetType().(*Ydb.Type_StructType).StructType

val, ok := v.Struct.ToYDB(a).GetType().(*Ydb.Type_StructType)
if !ok {
panic(fmt.Sprintf("unsupported type conversion from %T to *Ydb.Type_StructType", val))
}
structItems.StructItems = val.StructType

typeVariant.VariantType.Type = structItems

Expand Down Expand Up @@ -877,7 +882,12 @@ func (v *VariantTuple) ToYDB(a *allocator.Allocator) *Ydb.Type {
typeVariant.VariantType = a.Variant()

tupleItems := a.VariantTupleItems()
tupleItems.TupleItems = v.Tuple.ToYDB(a).GetType().(*Ydb.Type_TupleType).TupleType

val, ok := v.Tuple.ToYDB(a).GetType().(*Ydb.Type_TupleType)
if !ok {
panic(fmt.Sprintf("unsupported type conversion from %T to *Ydb.Type_TupleType", val))
}
tupleItems.TupleItems = val.TupleType

typeVariant.VariantType.Type = tupleItems

Expand Down
77 changes: 66 additions & 11 deletions internal/value/nullable.go
Original file line number Diff line number Diff line change
Expand Up @@ -303,27 +303,82 @@ func NullableDyNumberValue(v *string) Value {
func Nullable(t types.Type, v interface{}) Value {
switch t {
case types.Bool:
return NullableBoolValue(v.(*bool))
tt, ok := v.(*bool)
if !ok {
panic(fmt.Sprintf("unsupported type conversion from %T to TypeBool", tt))
}

return NullableBoolValue(tt)
case types.Int8:
return NullableInt8Value(v.(*int8))
tt, ok := v.(*int8)
if !ok {
panic(fmt.Sprintf("unsupported type conversion from %T to TypeBool", tt))
}

return NullableInt8Value(tt)
case types.Uint8:
return NullableUint8Value(v.(*uint8))
tt, ok := v.(*uint8)
if !ok {
panic(fmt.Sprintf("unsupported type conversion from %T to TypeUint8", tt))
}

return NullableUint8Value(tt)
case types.Int16:
return NullableInt16Value(v.(*int16))
tt, ok := v.(*int16)
if !ok {
panic(fmt.Sprintf("unsupported type conversion from %T to TypeInt16", tt))
}

return NullableInt16Value(tt)
case types.Uint16:
return NullableUint16Value(v.(*uint16))
tt, ok := v.(*uint16)
if !ok {
panic(fmt.Sprintf("unsupported type conversion from %T to TypeUint16", tt))
}

return NullableUint16Value(tt)
case types.Int32:
return NullableInt32Value(v.(*int32))
tt, ok := v.(*int32)
if !ok {
panic(fmt.Sprintf("unsupported type conversion from %T to TypeInt32", tt))
}

return NullableInt32Value(tt)
case types.Uint32:
return NullableUint32Value(v.(*uint32))
tt, ok := v.(*uint32)
if !ok {
panic(fmt.Sprintf("unsupported type conversion from %T to Uint32", tt))
}

return NullableUint32Value(tt)
case types.Int64:
return NullableInt64Value(v.(*int64))
tt, ok := v.(*int64)
if !ok {
panic(fmt.Sprintf("unsupported type conversion from %T to TypeInt64", tt))
}

return NullableInt64Value(tt)
case types.Uint64:
return NullableUint64Value(v.(*uint64))
tt, ok := v.(*uint64)
if !ok {
panic(fmt.Sprintf("unsupported type conversion from %T to TypeUint64", tt))
}

return NullableUint64Value(tt)
case types.Float:
return NullableFloatValue(v.(*float32))
tt, ok := v.(*float32)
if !ok {
panic(fmt.Sprintf("unsupported type conversion from %T to TypeFloat", tt))
}

return NullableFloatValue(tt)
case types.Double:
return NullableDoubleValue(v.(*float64))
tt, ok := v.(*float64)
if !ok {
panic(fmt.Sprintf("unsupported type conversion from %T to TypeDouble", tt))
}

return NullableDoubleValue(tt)
case types.Date:
switch tt := v.(type) {
case *uint32:
Expand Down
20 changes: 17 additions & 3 deletions internal/value/value.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,11 @@ func fromYDB(t *Ydb.Type, v *Ydb.Value) (Value, error) {
return DecimalValue(BigEndianUint128(v.GetHigh_128(), v.GetLow_128()), ttt.Precision(), ttt.Scale()), nil

case types.Optional:
t = t.GetType().(*Ydb.Type_OptionalType).OptionalType.GetItem()
tt, ok := t.GetType().(*Ydb.Type_OptionalType)
if !ok {
panic(fmt.Sprintf("unsupported type conversion from %T to *Ydb.Type_OptionalType", tt))
}
t = tt.OptionalType.GetItem()
if nestedValue, ok := v.GetValue().(*Ydb.Value_NestedValue); ok {
return OptionalValue(FromYDB(t, nestedValue.NestedValue)), nil
}
Expand Down Expand Up @@ -265,10 +269,15 @@ func fromYDB(t *Ydb.Type, v *Ydb.Value) (Value, error) {
a := allocator.New()
defer a.Free()

val, ok := v.GetValue().(*Ydb.Value_NestedValue)
if !ok {
panic(fmt.Sprintf("unsupported type conversion from %T to *Ydb.Value_NestedValue", val))
}

return VariantValueStruct(
FromYDB(
ttt.Struct.Field(int(v.GetVariantIndex())).T.ToYDB(a),
v.GetValue().(*Ydb.Value_NestedValue).NestedValue,
val.NestedValue,
),
ttt.Struct.Field(int(v.GetVariantIndex())).Name,
ttt.Struct,
Expand All @@ -278,10 +287,15 @@ func fromYDB(t *Ydb.Type, v *Ydb.Value) (Value, error) {
a := allocator.New()
defer a.Free()

val, ok := v.GetValue().(*Ydb.Value_NestedValue)
if !ok {
panic(fmt.Sprintf("unsupported type conversion from %T to *Ydb.Value_NestedValue", val))
}

return VariantValueTuple(
FromYDB(
ttt.Tuple.ItemType(int(v.GetVariantIndex())).ToYDB(a),
v.GetValue().(*Ydb.Value_NestedValue).NestedValue,
val.NestedValue,
),
v.GetVariantIndex(),
ttt.Tuple,
Expand Down
12 changes: 10 additions & 2 deletions internal/xcontext/local_dc.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package xcontext

import "context"
import (
"context"
"fmt"
)

type localDcKey struct{}

Expand All @@ -10,7 +13,12 @@ func WithLocalDC(ctx context.Context, dc string) context.Context {

func ExtractLocalDC(ctx context.Context) string {
if val := ctx.Value(localDcKey{}); val != nil {
return val.(string)
s, ok := val.(string)
if !ok {
panic(fmt.Sprintf("unsupported type conversion from %T to string", s))
}

return s
}

return ""
Expand Down
Loading
Loading