diff --git a/internal/sql/pg/histo_test.go b/internal/sql/pg/histo_test.go index 52738844a..9a602b281 100644 --- a/internal/sql/pg/histo_test.go +++ b/internal/sql/pg/histo_test.go @@ -27,6 +27,14 @@ func Test_histo_explicit_int(t *testing.T) { t.Log(hInt) } +func Test_bounds_string(t *testing.T) { + comp := strings.Compare + interp := interpString + bounds := makeBounds(100, "title_1", "title_99", comp, interp) + // Think this through more... + t.Log(bounds) +} + func Test_histo_num(t *testing.T) { bounds := makeBoundsNum[int](10, -100, 800) hInt := makeHisto(bounds, cmp.Compare[int]) diff --git a/internal/sql/pg/stats.go b/internal/sql/pg/stats.go index b03d82bcc..1456f6c8f 100644 --- a/internal/sql/pg/stats.go +++ b/internal/sql/pg/stats.go @@ -454,9 +454,9 @@ func colStatsInternal(ctx context.Context, firstPass []sql.ColumnStatistics, mcvs = mcvs[:statsCap] // mcvs = slices.Delete(mcvs, statsCap, len(mcvs)) } - valCompFun := compFun(vals[0]) // based on prototype value + // valCompFun := compFun(vals[0]) // based on prototype value slices.SortFunc(mcvs, func(a, b mcv) int { - return valCompFun(b.val, a.val) // ascending value + return compareStatsVal(b.val, a.val) // ascending value }) // extract the values and frequencies slices @@ -525,6 +525,7 @@ func (m mcvAscendingValue) Swap(i int, j int) { } */ +/* // the pain of []any vs. []T (in an any) func wrapCompFun[T any](f func(a, b T) int) func(a, b any) int { return func(a, b any) int { // must not be nil @@ -550,7 +551,7 @@ func compFun(val any) func(a, b any) int { case *types.Uint256: return wrapCompFun(types.CmpUint256) case types.UUID: - return wrapCompFun(types.CmpUint256) + return wrapCompFun(types.CmpUUID) case decimal.DecimalArray: // TODO case types.Uint256Array: // TODO @@ -559,13 +560,15 @@ func compFun(val any) func(a, b any) int { } panic(fmt.Sprintf("no comp fun for type %T", val)) -} +}*/ // maybe we do this instead a comp field of histo[T]. It's simpler, but slower. func compareStatsVal(a, b any) int { //nolint:unused switch at := a.(type) { case int64: return cmp.Compare(at, b.(int64)) + case []int64: + return slices.Compare(at, b.([]int64)) case bool: return cmpBool(at, b.(bool)) case []bool: @@ -574,20 +577,20 @@ func compareStatsVal(a, b any) int { //nolint:unused return strings.Compare(at, b.(string)) case []string: return slices.Compare(at, b.([]string)) - case []int64: - return slices.Compare(at, b.([]int64)) case float64: return cmp.Compare(at, b.(float64)) + case []float64: + return slices.Compare(at, b.([]float64)) case []byte: return bytes.Compare(at, b.([]byte)) case [][]byte: return slices.CompareFunc(at, b.([][]byte), bytes.Compare) + case *decimal.Decimal: + return cmpDecimal(at, b.(*decimal.Decimal)) case []*decimal.Decimal: return slices.CompareFunc(at, b.([]*decimal.Decimal), cmpDecimal) case decimal.DecimalArray: return slices.CompareFunc(at, b.(decimal.DecimalArray), cmpDecimal) - case *decimal.Decimal: - return cmpDecimal(at, b.(*decimal.Decimal)) case *types.Uint256: return at.Cmp(b.(*types.Uint256)) case types.Uint256Array: @@ -602,6 +605,8 @@ func compareStatsVal(a, b any) int { //nolint:unused return slices.CompareFunc(at, b.([]*types.UUID), func(a, b *types.UUID) int { return types.CmpUUID(*a, *b) }) + case []types.UUID: + return slices.CompareFunc(at, b.([]types.UUID), types.CmpUUID) default: panic(fmt.Sprintf("unrecognized type %T", a)) } @@ -649,11 +654,16 @@ func upColStatsWithInsert(stats *sql.ColumnStatistics, val any) error { return ins(stats, nil, nt.Clone(), types.CmpUint256, interpUint256) case types.UUID: - return ins(stats, nil, nt, types.CmpUUID, interpUUID) + case *types.UUID: + return del(stats, nt, func(a, b *types.UUID) int { + return types.CmpUUID(*a, *b) + }) case decimal.DecimalArray: // TODO case types.Uint256Array: // TODO + case []*decimal.Decimal: // TODO + case []*types.Uint256: // TODO case []string: case []int64: @@ -661,7 +671,7 @@ func upColStatsWithInsert(stats *sql.ColumnStatistics, val any) error { return fmt.Errorf("unrecognized tuple column type %T", val) } - fmt.Printf("unhandled %T", val) + fmt.Printf("unhandled insert %T", val) return nil // known type, just no stats handling } @@ -707,11 +717,16 @@ func upColStatsWithDelete(stats *sql.ColumnStatistics, old any) error { return del(stats, nt.Clone(), types.CmpUint256) case types.UUID: - return del(stats, nt, types.CmpUUID) + case *types.UUID: + return del(stats, nt, func(a, b *types.UUID) int { + return types.CmpUUID(*a, *b) + }) case decimal.DecimalArray: // TODO case types.Uint256Array: // TODO + case []*decimal.Decimal: // TODO + case []*types.Uint256: // TODO case []string: case []int64: @@ -719,6 +734,8 @@ func upColStatsWithDelete(stats *sql.ColumnStatistics, old any) error { return fmt.Errorf("unrecognized tuple column type %T", old) } + fmt.Printf("unhandled delete %T", old) + return nil } diff --git a/internal/sql/pg/system.go b/internal/sql/pg/system.go index 9ffef5338..5fe7f518c 100644 --- a/internal/sql/pg/system.go +++ b/internal/sql/pg/system.go @@ -301,7 +301,6 @@ func typeFor[T any]() reflect.Type { //nolint } func statsVal(ct ColType) any { - // return reflect.New(statsValType(ct)).Interface() switch ct { case ColTypeInt: return int64(0) @@ -328,28 +327,6 @@ func statsVal(ct ColType) any { func statsValType(ct ColType) reflect.Type { return reflect.TypeOf(statsVal(ct)) - /*switch ct { - case ColTypeInt: - return typeFor[int64]() - case ColTypeText: - return typeFor[string]() - case ColTypeBool: - return typeFor[bool]() - case ColTypeByteA: - return typeFor[[]byte]() - case ColTypeUUID: - return typeFor[*types.UUID]() - case ColTypeNumeric: - return typeFor[*decimal.Decimal]() - case ColTypeUINT256: - return typeFor[*types.Uint256]() - case ColTypeFloat: - return typeFor[float64]() - case ColTypeTime: - return typeFor[time.Time]() - default: - return nil - }*/ } func scanVal(ct ColType) any { @@ -478,14 +455,30 @@ func init() { gob.RegisterName("kwil_"+string(ColTypeUUID), statsVal(ColTypeUUID)) gob.RegisterName("kwil_"+string(ColTypeNumeric), statsVal(ColTypeNumeric)) gob.RegisterName("kwil_"+string(ColTypeUINT256), statsVal(ColTypeUINT256)) + gob.Register(unknown{}) + gob.Register(histo[int64]{}) gob.Register(histo[[]byte]{}) gob.Register(histo[float64]{}) gob.Register(histo[string]{}) + gob.Register(histo[*decimal.Decimal]{}) gob.Register(histo[types.UUID]{}) gob.Register(histo[*types.UUID]{}) gob.Register(histo[*types.Uint256]{}) + + gob.Register(histo[[]int64]{}) + gob.Register(histo[[][]byte]{}) + gob.Register(histo[[]float64]{}) + gob.Register(histo[[]string]{}) + + gob.Register(histo[[]*decimal.Decimal]{}) + gob.Register(histo[[]types.UUID]{}) + gob.Register(histo[[]*types.UUID]{}) + gob.Register(histo[[]*types.Uint256]{}) + gob.Register(histo[decimal.DecimalArray]{}) + gob.Register(histo[types.UUIDArray]{}) + gob.Register(histo[types.Uint256Array]{}) } func arrayType(ct ColType) ColType {