From eec2c1d4fdb33dc2dbfd455e760c69c80f85803a Mon Sep 17 00:00:00 2001 From: Nathan VanBenschoten Date: Fri, 21 Aug 2020 13:29:54 -0400 Subject: [PATCH] sql/opt/invertedexpr: avoid per-span allocations in GeoUnionKeySpansToSpanExpr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit optimizes a few heap allocations in `GeoUnionKeySpansToSpanExpr` and in `GeoRPKeyExprToSpanExpr` to avoid per-span/per-expression heap allocations. Before this change, these heap allocations accounted for 27.52% of all heap allocations (by object, `alloc_objects`) in a geospatial query of interest: ``` Type: alloc_objects Time: Aug 21, 2020 at 4:59pm (UTC) Active filters: focus=geoKeyToEncInvertedVal Showing nodes accounting for 61277094, 27.52% of 222698492 total ----------------------------------------------------------+------------- flat flat% sum% cum cum% calls calls% + context ----------------------------------------------------------+------------- 15270121 99.79% | github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoToSpan /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:46 32768 0.21% | github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoToSpan /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:45 15302889 6.87% 6.87% 15302889 6.87% | github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoKeyToEncInvertedVal /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:31 ----------------------------------------------------------+------------- 16187639 53.52% | github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoToSpan /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:46 14057686 46.48% | github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoToSpan /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:45 0 0% 6.87% 30245325 13.58% | github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoKeyToEncInvertedVal /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:32 30245325 100% | github.com/cockroachdb/cockroach/pkg/sql/sqlbase.EncodeTableKey /go/src/github.com/cockroachdb/cockroach/pkg/sql/sqlbase/column_type_encoding.go:75 ----------------------------------------------------------+------------- 15728880 100% | github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoToSpan /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:46 0 0% 6.87% 15728880 7.06% | github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoKeyToEncInvertedVal /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:38 15728880 100% | github.com/cockroachdb/cockroach/pkg/roachpb.Key.PrefixEnd /go/src/github.com/cockroachdb/cockroach/pkg/roachpb/data.go:188 ----------------------------------------------------------+------------- ``` These allocations were largely avoidable. This commit removes some of them entirely and reworks the code structure in order to amortize the unavoidable allocations over the set of keys being encoded. The result is a large reduction in allocations. On the same workload, allocations under `geoKeyToEncInvertedVal` dropped from **27.52%** of the workload to **2.23%** of the workload: ``` Type: alloc_objects Time: Aug 21, 2020 at 5:04pm (UTC) Active filters: focus=geoKeyToEncInvertedVal Showing nodes accounting for 3632555, 2.23% of 162651628 total ----------------------------------------------------------+------------- flat flat% sum% cum cum% calls calls% + context ----------------------------------------------------------+------------- 2014518 55.46% | github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoToSpan /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:53 1618037 44.54% | github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoToSpan /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:54 0 0% 0% 3632555 2.23% | github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr.geoKeyToEncInvertedVal /go/src/github.com/cockroachdb/cockroach/pkg/sql/opt/invertedexpr/geo_expression.go:44 3632555 100% | github.com/cockroachdb/cockroach/pkg/util/encoding.EncodeUvarintAscending /go/src/github.com/cockroachdb/cockroach/pkg/util/encoding/encoding.go:375 ----------------------------------------------------------+------------- ``` When applied on top of #53181, this results in a **1.71%** speedup on the following geospatial query: ```sql SELECT Count(census.blkid), Count(subways.name) FROM nyc_census_blocks AS census JOIN nyc_subway_stations AS subways ON ST_Intersects(subways.geom, census.geom); ``` ``` name old ms new ms delta Test/postgis_geometry_tutorial/nyc 136 ±12% 134 ±11% -1.71% (p=0.000 n=976+977) ``` In making this change, we also fix a bug where `geoindex.Key` (a uint64) was being cast to a `tree.DInt` (an int64) during encoding. This could result in overflow and could cause inverted key spans to be generated. --- .../logic_test/inverted_index_geospatial | 2 +- pkg/sql/opt/invertedexpr/geo_expression.go | 54 +++++--- pkg/sql/opt/memo/testdata/stats/inverted-geo | 16 +-- .../testdata/external/postgis-tutorial-idx | 20 +-- pkg/sql/opt/xform/testdata/rules/join | 4 +- pkg/sql/opt/xform/testdata/rules/limit | 4 +- pkg/sql/opt/xform/testdata/rules/select | 131 +++++++++--------- pkg/sql/rowenc/index_encoding.go | 19 ++- 8 files changed, 134 insertions(+), 116 deletions(-) diff --git a/pkg/sql/logictest/testdata/logic_test/inverted_index_geospatial b/pkg/sql/logictest/testdata/logic_test/inverted_index_geospatial index 2eaaf7896346..b1a3c07862bd 100644 --- a/pkg/sql/logictest/testdata/logic_test/inverted_index_geospatial +++ b/pkg/sql/logictest/testdata/logic_test/inverted_index_geospatial @@ -30,7 +30,7 @@ SELECT k FROM geo_table WHERE ST_Intersects('SRID=26918;POINT(400003 4000003)':: query T SELECT url FROM [EXPLAIN ANALYZE SELECT k FROM geo_table WHERE ST_Intersects('SRID=26918;POINT(400003 4000003)'::geometry, geom) ORDER BY k] ---- -https://cockroachdb.github.io/distsqlplan/decode.html#eJykU9FO20AQfO9XrPYFoh7KnW0l4apKCWBatyGhTqSW4giZeIUsbF96d26DUP69sg0FIsUC1S_W7s7szWi092h-ZShx5o_94zmUOoPTcHoGl_6P8_EomMBoMhpf_PRh_ySYzWffxh14gN42wBtSVza-zgi-f_ZDH4y9SgtL2tDSmv29WRicfHR6h2Lw4XwaTOb7Huecu1D_uNvZk_KTPz3z5-EFq3blHZiGJ34IRxdwu0CGhUpoEudkUF6iwAXDlVZLMkbpqnVfA4JkjZIzTItVaav2guFSaUJ5jza1GaHEeSUypDgh3eXIMCEbp1m99p-HYaXgKi0SWiPD2SoujITugTioGVr9MaApTiT0kKGxcZaBTXOSwA0yvL6z9AgQfQ-OcLFhqEr7JMrY-IZQig17vfCg-E3aUnKaZpY06a54qf5x7q9XGlQBQyHBVNLB2FhbGWEUObwfRW6_HyFQkTQtwSMEZDgtrYSheIXBPF5DTrnSd1AaSiQ4HL6mu206b7H5RaXFQzzOrnhWOs1jffckmg2dV-iuA4UtVNPcwu5y4r7FyUxpS7rrvnQxFO-RYROi3D4TLrioDsLhTq93yJ9_x72RGHiiKQZ8IAae53tiTz6_nKHT-b8kRXuS3lv8h2RWqjD0wv-uzXyzYEjJDTXXbFSpl3Su1bJ-pimnNa9uJGRsMxVNERTNqBL4nCxayU472Wklu-1kt5XsbZEXm3d_AwAA__8x3buh +https://cockroachdb.github.io/distsqlplan/decode.html#eJykU2FP2zAQ_b5fcbsvUM1T7SQLxdNEC4QtW2lZ2mljtEKhOaGIJO5sdytC_e9TEhhQqVHR-sGVz-9d3runu0PzK0OJo6AfHI1hoTM4iYancBH8OOv3wgH0Br3--c8Ado_D0Xj0td-Ce-hNDbwmdWnjq4zg-6cgCsDYy7SwpA3NrNndGUXh8QfH3xed92fDcDDe9Tjn3IXqj7utHSk_BsPTYByds7JX3oJhdBxEcHgON1NkWKiEBnFOBuUFCpwynGs1I2OULkt3FSBMlig5w7SYL2xZnjKcKU0o79CmNiOUOC5FRhQnpNscGSZk4zSr2v7z0C0VXKZFQktkOJrHhZHQPjg4eNt-PfjW7yNDrf4Y0BQnEnxkaGycZWDTnCRwgwyvbi09ABzhwyFOVwzVwj4qMza-JpRixbZXHxa_SVtKTtLMkibdFs8tPLwHy7kGVUBXSDClfjA21lZOcDJx996Vx942BwIVyT3LnyAgw-HCSuiKLWaQx0vIKVf6FhaGykFw-JJunoTzkkl8VmlxH6OzKca5TvNY3z6KZl1nC91V8LCGqotr2E1O3Jc4GSltSbfd5y664g0yrHOW6-vEBRfl4jjc8f19_vR35PdExxP1pcM7ouN5gSd25NMN6zqt_0tSNCfpvcR_RGauCkPP_G_qzFdThpRcU731Ri30jM60mlWfqa_DilcVEjK2fhX1JSzqp1LgU7JoJDvNZKeR7DaT3Uayt0aerl79DQAA__-mUsar statement ok DROP TABLE geo_table diff --git a/pkg/sql/opt/invertedexpr/geo_expression.go b/pkg/sql/opt/invertedexpr/geo_expression.go index 40089dabc712..5e82c633afe1 100644 --- a/pkg/sql/opt/invertedexpr/geo_expression.go +++ b/pkg/sql/opt/invertedexpr/geo_expression.go @@ -11,10 +11,10 @@ package invertedexpr import ( + "math" + "github.com/cockroachdb/cockroach/pkg/geo/geoindex" "github.com/cockroachdb/cockroach/pkg/roachpb" - "github.com/cockroachdb/cockroach/pkg/sql/rowenc" - "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" "github.com/cockroachdb/cockroach/pkg/util/encoding" "github.com/cockroachdb/errors" ) @@ -27,24 +27,33 @@ import ( // // TODO(sumeer): change geoindex to produce SpanExpressions directly. -func geoKeyToEncInvertedVal(k geoindex.Key, end bool) EncInvertedVal { - dint := tree.DInt(k) - encoded, err := rowenc.EncodeTableKey(nil, &dint, encoding.Ascending) - if err != nil { - panic(errors.NewAssertionErrorWithWrappedErrf(err, "unexpected encoding error: %d", k)) - } +func geoKeyToEncInvertedVal(k geoindex.Key, end bool, b []byte) (EncInvertedVal, []byte) { + // geoindex.KeySpan.End is inclusive, while InvertedSpan.end is exclusive. + // For all but k == math.MaxUint64, we can account for this before the key + // encoding. For k == math.MaxUint64, we must PrefixEnd after, which incurs + // a separate memory allocation. + prefixEnd := false if end { - // geoindex.KeySpan.End is inclusive, while InvertedSpan.end is exclusive. - encoded = roachpb.Key(encoded).PrefixEnd() + if k < math.MaxUint64 { + k++ + } else { + prefixEnd = true + } } - return encoded + prev := len(b) + b = encoding.EncodeUvarintAscending(b, uint64(k)) + // Set capacity so that the caller appending does not corrupt later keys. + enc := b[prev:len(b):len(b)] + if prefixEnd { + enc = roachpb.Key(enc).PrefixEnd() + } + return enc, b } -func geoToSpan(span geoindex.KeySpan) InvertedSpan { - return InvertedSpan{ - Start: geoKeyToEncInvertedVal(span.Start, false), - End: geoKeyToEncInvertedVal(span.End, true), - } +func geoToSpan(span geoindex.KeySpan, b []byte) (InvertedSpan, []byte) { + start, b := geoKeyToEncInvertedVal(span.Start, false, b) + end, b := geoKeyToEncInvertedVal(span.End, true, b) + return InvertedSpan{Start: start, End: end}, b } // GeoUnionKeySpansToSpanExpr converts geoindex.UnionKeySpans to a @@ -54,8 +63,9 @@ func GeoUnionKeySpansToSpanExpr(ukSpans geoindex.UnionKeySpans) *SpanExpression return nil } spans := make([]InvertedSpan, len(ukSpans)) + var b []byte // avoid per-span heap allocations for i, ukSpan := range ukSpans { - spans[i] = geoToSpan(ukSpan) + spans[i], b = geoToSpan(ukSpan, b) } return &SpanExpression{ SpansToRead: spans, @@ -69,19 +79,23 @@ func GeoRPKeyExprToSpanExpr(rpExpr geoindex.RPKeyExpr) (*SpanExpression, error) return nil, nil } spansToRead := make([]InvertedSpan, 0, len(rpExpr)) + var b []byte // avoid per-expr heap allocations for _, elem := range rpExpr { // The keys in the RPKeyExpr are unique. if key, ok := elem.(geoindex.Key); ok { - spansToRead = append(spansToRead, geoToSpan(geoindex.KeySpan{Start: key, End: key})) + var span InvertedSpan + span, b = geoToSpan(geoindex.KeySpan{Start: key, End: key}, b) + spansToRead = append(spansToRead, span) } } var stack []*SpanExpression for _, elem := range rpExpr { switch e := elem.(type) { case geoindex.Key: + var span InvertedSpan + span, b = geoToSpan(geoindex.KeySpan{Start: e, End: e}, b) stack = append(stack, &SpanExpression{ - FactoredUnionSpans: []InvertedSpan{ - geoToSpan(geoindex.KeySpan{Start: e, End: e})}, + FactoredUnionSpans: []InvertedSpan{span}, }) case geoindex.RPSetOperator: if len(stack) < 2 { diff --git a/pkg/sql/opt/memo/testdata/stats/inverted-geo b/pkg/sql/opt/memo/testdata/stats/inverted-geo index fce192ef1813..b75e4f9a172e 100644 --- a/pkg/sql/opt/memo/testdata/stats/inverted-geo +++ b/pkg/sql/opt/memo/testdata/stats/inverted-geo @@ -174,13 +174,13 @@ project │ │ ├── columns: rowid:3(int!null) │ │ ├── inverted expression: /5 │ │ │ ├── tight: false - │ │ │ └── union spans: ["\x87\xff", "\x87\xff"] + │ │ │ └── union spans: ["\xfd\xff\xff\xff\xff\xff\xff\xff\xff", "\xfd\xff\xff\xff\xff\xff\xff\xff\xff"] │ │ ├── stats: [rows=7e-07] │ │ ├── key: (3) │ │ └── scan t@secondary │ │ ├── columns: rowid:3(int!null) g_inverted_key:5(geometry!null) │ │ ├── inverted constraint: /5/3 - │ │ │ └── spans: ["\x87\xff", "\x87\xff"] + │ │ │ └── spans: ["\xfd\xff\xff\xff\xff\xff\xff\xff\xff", "\xfd\xff\xff\xff\xff\xff\xff\xff\xff"] │ │ ├── stats: [rows=7e-07, distinct(3)=1.99999931e-07, null(3)=0, distinct(5)=7e-07, null(5)=0] │ │ │ histogram(5)= │ │ ├── key: (3) @@ -394,13 +394,13 @@ project │ │ ├── columns: rowid:3(int!null) │ │ ├── inverted expression: /5 │ │ │ ├── tight: false - │ │ │ └── union spans: ["\x87\xff", "\x87\xff"] + │ │ │ └── union spans: ["\xfd\xff\xff\xff\xff\xff\xff\xff\xff", "\xfd\xff\xff\xff\xff\xff\xff\xff\xff"] │ │ ├── stats: [rows=7e-07] │ │ ├── key: (3) │ │ └── scan t@secondary │ │ ├── columns: rowid:3(int!null) g_inverted_key:5(geometry!null) │ │ ├── inverted constraint: /5/3 - │ │ │ └── spans: ["\x87\xff", "\x87\xff"] + │ │ │ └── spans: ["\xfd\xff\xff\xff\xff\xff\xff\xff\xff", "\xfd\xff\xff\xff\xff\xff\xff\xff\xff"] │ │ ├── stats: [rows=7e-07, distinct(3)=1.99999931e-07, null(3)=0, distinct(5)=7e-07, null(5)=0] │ │ │ histogram(5)= │ │ ├── key: (3) @@ -470,7 +470,7 @@ select │ │ ├── tight: false │ │ └── union spans │ │ ├── ["\xfd\x10\x00\x00\x00\x00\x00\x00\x00", "\xfd\x10\x00\x00\x00\x00\x00\x00\x00"] - │ │ ├── ["\xfd\x10\x00\x00\x00\x00\x00\x00\x01", "\xfd\x12") + │ │ ├── ["\xfd\x10\x00\x00\x00\x00\x00\x00\x01", "\xfd\x12\x00\x00\x00\x00\x00\x00\x00") │ │ └── ["\xfd\x14\x00\x00\x00\x00\x00\x00\x00", "\xfd\x14\x00\x00\x00\x00\x00\x00\x00"] │ ├── stats: [rows=100] │ ├── key: (3) @@ -479,7 +479,7 @@ select │ ├── inverted constraint: /5/3 │ │ └── spans │ │ ├── ["\xfd\x10\x00\x00\x00\x00\x00\x00\x00", "\xfd\x10\x00\x00\x00\x00\x00\x00\x00"] - │ │ ├── ["\xfd\x10\x00\x00\x00\x00\x00\x00\x01", "\xfd\x12") + │ │ ├── ["\xfd\x10\x00\x00\x00\x00\x00\x00\x01", "\xfd\x12\x00\x00\x00\x00\x00\x00\x00") │ │ └── ["\xfd\x14\x00\x00\x00\x00\x00\x00\x00", "\xfd\x14\x00\x00\x00\x00\x00\x00\x00"] │ ├── stats: [rows=100, distinct(3)=100, null(3)=0, distinct(5)=1, null(5)=0] │ │ histogram(5)= 0 100 0 0 @@ -510,7 +510,7 @@ project │ │ ├── tight: false │ │ └── union spans │ │ ├── ["\xfd\x10\x00\x00\x00\x00\x00\x00\x00", "\xfd\x10\x00\x00\x00\x00\x00\x00\x00"] - │ │ ├── ["\xfd\x10\x00\x00\x00\x00\x00\x00\x01", "\xfd\x12") + │ │ ├── ["\xfd\x10\x00\x00\x00\x00\x00\x00\x01", "\xfd\x12\x00\x00\x00\x00\x00\x00\x00") │ │ └── ["\xfd\x14\x00\x00\x00\x00\x00\x00\x00", "\xfd\x14\x00\x00\x00\x00\x00\x00\x00"] │ ├── stats: [rows=100] │ ├── key: (3) @@ -519,7 +519,7 @@ project │ ├── inverted constraint: /5/3 │ │ └── spans │ │ ├── ["\xfd\x10\x00\x00\x00\x00\x00\x00\x00", "\xfd\x10\x00\x00\x00\x00\x00\x00\x00"] - │ │ ├── ["\xfd\x10\x00\x00\x00\x00\x00\x00\x01", "\xfd\x12") + │ │ ├── ["\xfd\x10\x00\x00\x00\x00\x00\x00\x01", "\xfd\x12\x00\x00\x00\x00\x00\x00\x00") │ │ └── ["\xfd\x14\x00\x00\x00\x00\x00\x00\x00", "\xfd\x14\x00\x00\x00\x00\x00\x00\x00"] │ ├── flags: force-index=secondary │ ├── stats: [rows=100, distinct(3)=100, null(3)=0, distinct(5)=1, null(5)=0] diff --git a/pkg/sql/opt/xform/testdata/external/postgis-tutorial-idx b/pkg/sql/opt/xform/testdata/external/postgis-tutorial-idx index 7fd8bca82096..f439b3d27ff6 100644 --- a/pkg/sql/opt/xform/testdata/external/postgis-tutorial-idx +++ b/pkg/sql/opt/xform/testdata/external/postgis-tutorial-idx @@ -39,12 +39,12 @@ project │ ├── columns: gid:1!null │ ├── inverted expression: /6 │ │ ├── tight: false - │ │ └── union spans: ["\x87\xff", "\x87\xff"] + │ │ └── union spans: ["\xfd\xff\xff\xff\xff\xff\xff\xff\xff", "\xfd\xff\xff\xff\xff\xff\xff\xff\xff"] │ ├── key: (1) │ └── scan nyc_neighborhoods@nyc_neighborhoods_geom_idx │ ├── columns: gid:1!null geom_inverted_key:6!null │ ├── inverted constraint: /6/1 - │ │ └── spans: ["\x87\xff", "\x87\xff"] + │ │ └── spans: ["\xfd\xff\xff\xff\xff\xff\xff\xff\xff", "\xfd\xff\xff\xff\xff\xff\xff\xff\xff"] │ ├── key: (1) │ └── fd: (1)-->(6) └── filters @@ -82,12 +82,12 @@ project │ ├── columns: gid:1!null │ ├── inverted expression: /8 │ │ ├── tight: false - │ │ └── union spans: ["\x87\xff", "\x87\xff"] + │ │ └── union spans: ["\xfd\xff\xff\xff\xff\xff\xff\xff\xff", "\xfd\xff\xff\xff\xff\xff\xff\xff\xff"] │ ├── key: (1) │ └── scan nyc_streets@nyc_streets_geom_idx │ ├── columns: gid:1!null geom_inverted_key:8!null │ ├── inverted constraint: /8/1 - │ │ └── spans: ["\x87\xff", "\x87\xff"] + │ │ └── spans: ["\xfd\xff\xff\xff\xff\xff\xff\xff\xff", "\xfd\xff\xff\xff\xff\xff\xff\xff\xff"] │ ├── key: (1) │ └── fd: (1)-->(8) └── filters @@ -127,12 +127,12 @@ project │ ├── columns: gid:1!null │ ├── inverted expression: /6 │ │ ├── tight: false - │ │ └── union spans: ["\x87\xff", "\x87\xff"] + │ │ └── union spans: ["\xfd\xff\xff\xff\xff\xff\xff\xff\xff", "\xfd\xff\xff\xff\xff\xff\xff\xff\xff"] │ ├── key: (1) │ └── scan nyc_neighborhoods@nyc_neighborhoods_geom_idx │ ├── columns: gid:1!null geom_inverted_key:6!null │ ├── inverted constraint: /6/1 - │ │ └── spans: ["\x87\xff", "\x87\xff"] + │ │ └── spans: ["\xfd\xff\xff\xff\xff\xff\xff\xff\xff", "\xfd\xff\xff\xff\xff\xff\xff\xff\xff"] │ ├── key: (1) │ └── fd: (1)-->(6) └── filters @@ -173,12 +173,12 @@ project │ ├── columns: gid:1!null │ ├── inverted expression: /8 │ │ ├── tight: false - │ │ └── union spans: ["\x87\xff", "\x87\xff"] + │ │ └── union spans: ["\xfd\xff\xff\xff\xff\xff\xff\xff\xff", "\xfd\xff\xff\xff\xff\xff\xff\xff\xff"] │ ├── key: (1) │ └── scan nyc_streets@nyc_streets_geom_idx │ ├── columns: gid:1!null geom_inverted_key:8!null │ ├── inverted constraint: /8/1 - │ │ └── spans: ["\x87\xff", "\x87\xff"] + │ │ └── spans: ["\xfd\xff\xff\xff\xff\xff\xff\xff\xff", "\xfd\xff\xff\xff\xff\xff\xff\xff\xff"] │ ├── key: (1) │ └── fd: (1)-->(8) └── filters @@ -215,12 +215,12 @@ scalar-group-by │ │ ├── columns: gid:1!null │ │ ├── inverted expression: /12 │ │ │ ├── tight: false - │ │ │ └── union spans: ["\x87\xff", "\x87\xff"] + │ │ │ └── union spans: ["\xfd\xff\xff\xff\xff\xff\xff\xff\xff", "\xfd\xff\xff\xff\xff\xff\xff\xff\xff"] │ │ ├── key: (1) │ │ └── scan nyc_census_blocks@nyc_census_blocks_geom_idx │ │ ├── columns: gid:1!null geom_inverted_key:12!null │ │ ├── inverted constraint: /12/1 - │ │ │ └── spans: ["\x87\xff", "\x87\xff"] + │ │ │ └── spans: ["\xfd\xff\xff\xff\xff\xff\xff\xff\xff", "\xfd\xff\xff\xff\xff\xff\xff\xff\xff"] │ │ ├── key: (1) │ │ └── fd: (1)-->(12) │ └── filters diff --git a/pkg/sql/opt/xform/testdata/rules/join b/pkg/sql/opt/xform/testdata/rules/join index fb1c2d82dc61..78a1647ff830 100644 --- a/pkg/sql/opt/xform/testdata/rules/join +++ b/pkg/sql/opt/xform/testdata/rules/join @@ -3441,12 +3441,12 @@ project │ │ │ ├── columns: n.gid:13!null │ │ │ ├── inverted expression: /18 │ │ │ │ ├── tight: false - │ │ │ │ └── union spans: ["\x89", "\xfd ") + │ │ │ │ └── union spans: ["\x89", "\xfd \x00\x00\x00\x00\x00\x00\x00") │ │ │ ├── key: (13) │ │ │ └── scan n@nyc_neighborhoods_geo_idx │ │ │ ├── columns: n.gid:13!null n.geom_inverted_key:18!null │ │ │ ├── inverted constraint: /18/13 - │ │ │ │ └── spans: ["\x89", "\xfd ") + │ │ │ │ └── spans: ["\x89", "\xfd \x00\x00\x00\x00\x00\x00\x00") │ │ │ ├── flags: force-index=nyc_neighborhoods_geo_idx │ │ │ ├── key: (13) │ │ │ └── fd: (13)-->(18) diff --git a/pkg/sql/opt/xform/testdata/rules/limit b/pkg/sql/opt/xform/testdata/rules/limit index bec23e5a34d8..56d9b8ff8b65 100644 --- a/pkg/sql/opt/xform/testdata/rules/limit +++ b/pkg/sql/opt/xform/testdata/rules/limit @@ -1175,7 +1175,7 @@ select │ │ └── union spans │ │ ├── ["\xfd\x10\x00\x00\x00\x00\x00\x00\x00", "\xfd\x10\x00\x00\x00\x00\x00\x00\x00"] │ │ ├── ["\xfd\x14\x00\x00\x00\x00\x00\x00\x00", "\xfd\x14\x00\x00\x00\x00\x00\x00\x00"] - │ │ └── ["\xfd\x14\x00\x00\x00\x00\x00\x00\x01", "\xfd\x16") + │ │ └── ["\xfd\x14\x00\x00\x00\x00\x00\x00\x01", "\xfd\x16\x00\x00\x00\x00\x00\x00\x00") │ ├── key: (1) │ └── scan index_tab@geomidx │ ├── columns: id:1!null geom_inverted_key:10!null @@ -1183,7 +1183,7 @@ select │ │ └── spans │ │ ├── ["\xfd\x10\x00\x00\x00\x00\x00\x00\x00", "\xfd\x10\x00\x00\x00\x00\x00\x00\x00"] │ │ ├── ["\xfd\x14\x00\x00\x00\x00\x00\x00\x00", "\xfd\x14\x00\x00\x00\x00\x00\x00\x00"] - │ │ └── ["\xfd\x14\x00\x00\x00\x00\x00\x00\x01", "\xfd\x16") + │ │ └── ["\xfd\x14\x00\x00\x00\x00\x00\x00\x01", "\xfd\x16\x00\x00\x00\x00\x00\x00\x00") │ ├── key: (1) │ └── fd: (1)-->(10) └── filters diff --git a/pkg/sql/opt/xform/testdata/rules/select b/pkg/sql/opt/xform/testdata/rules/select index 9feb7568dbfe..c7e6d76f163c 100644 --- a/pkg/sql/opt/xform/testdata/rules/select +++ b/pkg/sql/opt/xform/testdata/rules/select @@ -1564,7 +1564,7 @@ project │ │ ├── tight: false │ │ └── union spans │ │ ├── ["\xfdL\x00\x00\x00\x00\x00\x00\x00", "\xfdL\x00\x00\x00\x00\x00\x00\x00"] - │ │ ├── ["\xfdN\x00\x00\x00\x00\x00\x00\x01", "\xfdP") + │ │ ├── ["\xfdN\x00\x00\x00\x00\x00\x00\x01", "\xfdP\x00\x00\x00\x00\x00\x00\x00") │ │ └── ["\xfdP\x00\x00\x00\x00\x00\x00\x00", "\xfdP\x00\x00\x00\x00\x00\x00\x00"] │ ├── key: (1) │ └── scan g@geog_idx @@ -1572,7 +1572,7 @@ project │ ├── inverted constraint: /7/1 │ │ └── spans │ │ ├── ["\xfdL\x00\x00\x00\x00\x00\x00\x00", "\xfdL\x00\x00\x00\x00\x00\x00\x00"] - │ │ ├── ["\xfdN\x00\x00\x00\x00\x00\x00\x01", "\xfdP") + │ │ ├── ["\xfdN\x00\x00\x00\x00\x00\x00\x01", "\xfdP\x00\x00\x00\x00\x00\x00\x00") │ │ └── ["\xfdP\x00\x00\x00\x00\x00\x00\x00", "\xfdP\x00\x00\x00\x00\x00\x00\x00"] │ ├── key: (1) │ └── fd: (1)-->(7) @@ -1602,7 +1602,7 @@ project │ │ ├── tight: false │ │ └── union spans │ │ ├── ["\xfdL\x00\x00\x00\x00\x00\x00\x00", "\xfdL\x00\x00\x00\x00\x00\x00\x00"] - │ │ ├── ["\xfdN\x00\x00\x00\x00\x00\x00\x01", "\xfdP") + │ │ ├── ["\xfdN\x00\x00\x00\x00\x00\x00\x01", "\xfdP\x00\x00\x00\x00\x00\x00\x00") │ │ └── ["\xfdP\x00\x00\x00\x00\x00\x00\x00", "\xfdP\x00\x00\x00\x00\x00\x00\x00"] │ ├── key: (1) │ └── scan g@geog_idx @@ -1610,7 +1610,7 @@ project │ ├── inverted constraint: /7/1 │ │ └── spans │ │ ├── ["\xfdL\x00\x00\x00\x00\x00\x00\x00", "\xfdL\x00\x00\x00\x00\x00\x00\x00"] - │ │ ├── ["\xfdN\x00\x00\x00\x00\x00\x00\x01", "\xfdP") + │ │ ├── ["\xfdN\x00\x00\x00\x00\x00\x00\x01", "\xfdP\x00\x00\x00\x00\x00\x00\x00") │ │ └── ["\xfdP\x00\x00\x00\x00\x00\x00\x00", "\xfdP\x00\x00\x00\x00\x00\x00\x00"] │ ├── key: (1) │ └── fd: (1)-->(7) @@ -1675,12 +1675,12 @@ project │ ├── columns: k:1!null │ ├── inverted expression: /6 │ │ ├── tight: false - │ │ └── union spans: ["\x89", "\xfd ") + │ │ └── union spans: ["\x89", "\xfd \x00\x00\x00\x00\x00\x00\x00") │ ├── key: (1) │ └── scan g@geom_idx │ ├── columns: k:1!null geom_inverted_key:6!null │ ├── inverted constraint: /6/1 - │ │ └── spans: ["\x89", "\xfd ") + │ │ └── spans: ["\x89", "\xfd \x00\x00\x00\x00\x00\x00\x00") │ ├── key: (1) │ └── fd: (1)-->(6) └── filters @@ -1706,12 +1706,12 @@ project │ ├── columns: k:1!null │ ├── inverted expression: /6 │ │ ├── tight: false - │ │ └── union spans: ["\x89", "\xfd ") + │ │ └── union spans: ["\x89", "\xfd \x00\x00\x00\x00\x00\x00\x00") │ ├── key: (1) │ └── scan g@geom_idx │ ├── columns: k:1!null geom_inverted_key:6!null │ ├── inverted constraint: /6/1 - │ │ └── spans: ["\x89", "\xfd ") + │ │ └── spans: ["\x89", "\xfd \x00\x00\x00\x00\x00\x00\x00") │ ├── key: (1) │ └── fd: (1)-->(6) └── filters @@ -1737,12 +1737,12 @@ project │ ├── columns: k:1!null │ ├── inverted expression: /6 │ │ ├── tight: false - │ │ └── union spans: ["\x89", "\xfd ") + │ │ └── union spans: ["\x89", "\xfd \x00\x00\x00\x00\x00\x00\x00") │ ├── key: (1) │ └── scan g@geom_idx │ ├── columns: k:1!null geom_inverted_key:6!null │ ├── inverted constraint: /6/1 - │ │ └── spans: ["\x89", "\xfd ") + │ │ └── spans: ["\x89", "\xfd \x00\x00\x00\x00\x00\x00\x00") │ ├── key: (1) │ └── fd: (1)-->(6) └── filters @@ -1770,14 +1770,14 @@ project │ │ ├── tight: false │ │ └── union spans │ │ ├── ["\xfdD\x00\x00\x00\x00\x00\x00\x00", "\xfdD\x00\x00\x00\x00\x00\x00\x00"] - │ │ ├── ["\xfdD\x00\x00\x00\x00\x00\x00\x01", "\xfdF") - │ │ ├── ["\xfdF\x00\x00\x00\x00\x00\x00\x01", "\xfdH") - │ │ ├── ["\xfdH\x00\x00\x00\x00\x00\x00\x01", "\xfdP") + │ │ ├── ["\xfdD\x00\x00\x00\x00\x00\x00\x01", "\xfdF\x00\x00\x00\x00\x00\x00\x00") + │ │ ├── ["\xfdF\x00\x00\x00\x00\x00\x00\x01", "\xfdH\x00\x00\x00\x00\x00\x00\x00") + │ │ ├── ["\xfdH\x00\x00\x00\x00\x00\x00\x01", "\xfdP\x00\x00\x00\x00\x00\x00\x00") │ │ ├── ["\xfdP\x00\x00\x00\x00\x00\x00\x00", "\xfdP\x00\x00\x00\x00\x00\x00\x00"] - │ │ ├── ["\xfdP\x00\x00\x00\x00\x00\x00\x01", "\xfdR") - │ │ ├── ["\xfdR\x00\x00\x00\x00\x00\x00\x01", "\xfdT") + │ │ ├── ["\xfdP\x00\x00\x00\x00\x00\x00\x01", "\xfdR\x00\x00\x00\x00\x00\x00\x00") + │ │ ├── ["\xfdR\x00\x00\x00\x00\x00\x00\x01", "\xfdT\x00\x00\x00\x00\x00\x00\x00") │ │ ├── ["\xfdT\x00\x00\x00\x00\x00\x00\x00", "\xfdT\x00\x00\x00\x00\x00\x00\x00"] - │ │ ├── ["\xfdZ\x00\x00\x00\x00\x00\x00\x01", "\xfd\\") + │ │ ├── ["\xfdZ\x00\x00\x00\x00\x00\x00\x01", "\xfd\\\x00\x00\x00\x00\x00\x00\x00") │ │ └── ["\xfd\\\x00\x00\x00\x00\x00\x00\x00", "\xfd\\\x00\x00\x00\x00\x00\x00\x00"] │ ├── key: (1) │ └── scan g@geog_idx @@ -1785,14 +1785,14 @@ project │ ├── inverted constraint: /7/1 │ │ └── spans │ │ ├── ["\xfdD\x00\x00\x00\x00\x00\x00\x00", "\xfdD\x00\x00\x00\x00\x00\x00\x00"] - │ │ ├── ["\xfdD\x00\x00\x00\x00\x00\x00\x01", "\xfdF") - │ │ ├── ["\xfdF\x00\x00\x00\x00\x00\x00\x01", "\xfdH") - │ │ ├── ["\xfdH\x00\x00\x00\x00\x00\x00\x01", "\xfdP") + │ │ ├── ["\xfdD\x00\x00\x00\x00\x00\x00\x01", "\xfdF\x00\x00\x00\x00\x00\x00\x00") + │ │ ├── ["\xfdF\x00\x00\x00\x00\x00\x00\x01", "\xfdH\x00\x00\x00\x00\x00\x00\x00") + │ │ ├── ["\xfdH\x00\x00\x00\x00\x00\x00\x01", "\xfdP\x00\x00\x00\x00\x00\x00\x00") │ │ ├── ["\xfdP\x00\x00\x00\x00\x00\x00\x00", "\xfdP\x00\x00\x00\x00\x00\x00\x00"] - │ │ ├── ["\xfdP\x00\x00\x00\x00\x00\x00\x01", "\xfdR") - │ │ ├── ["\xfdR\x00\x00\x00\x00\x00\x00\x01", "\xfdT") + │ │ ├── ["\xfdP\x00\x00\x00\x00\x00\x00\x01", "\xfdR\x00\x00\x00\x00\x00\x00\x00") + │ │ ├── ["\xfdR\x00\x00\x00\x00\x00\x00\x01", "\xfdT\x00\x00\x00\x00\x00\x00\x00") │ │ ├── ["\xfdT\x00\x00\x00\x00\x00\x00\x00", "\xfdT\x00\x00\x00\x00\x00\x00\x00"] - │ │ ├── ["\xfdZ\x00\x00\x00\x00\x00\x00\x01", "\xfd\\") + │ │ ├── ["\xfdZ\x00\x00\x00\x00\x00\x00\x01", "\xfd\\\x00\x00\x00\x00\x00\x00\x00") │ │ └── ["\xfd\\\x00\x00\x00\x00\x00\x00\x00", "\xfd\\\x00\x00\x00\x00\x00\x00\x00"] │ ├── key: (1) │ └── fd: (1)-->(7) @@ -1821,14 +1821,14 @@ project │ │ ├── tight: false │ │ └── union spans │ │ ├── ["\xfdD\x00\x00\x00\x00\x00\x00\x00", "\xfdD\x00\x00\x00\x00\x00\x00\x00"] - │ │ ├── ["\xfdD\x00\x00\x00\x00\x00\x00\x01", "\xfdF") - │ │ ├── ["\xfdF\x00\x00\x00\x00\x00\x00\x01", "\xfdH") - │ │ ├── ["\xfdH\x00\x00\x00\x00\x00\x00\x01", "\xfdP") + │ │ ├── ["\xfdD\x00\x00\x00\x00\x00\x00\x01", "\xfdF\x00\x00\x00\x00\x00\x00\x00") + │ │ ├── ["\xfdF\x00\x00\x00\x00\x00\x00\x01", "\xfdH\x00\x00\x00\x00\x00\x00\x00") + │ │ ├── ["\xfdH\x00\x00\x00\x00\x00\x00\x01", "\xfdP\x00\x00\x00\x00\x00\x00\x00") │ │ ├── ["\xfdP\x00\x00\x00\x00\x00\x00\x00", "\xfdP\x00\x00\x00\x00\x00\x00\x00"] - │ │ ├── ["\xfdP\x00\x00\x00\x00\x00\x00\x01", "\xfdR") - │ │ ├── ["\xfdR\x00\x00\x00\x00\x00\x00\x01", "\xfdT") + │ │ ├── ["\xfdP\x00\x00\x00\x00\x00\x00\x01", "\xfdR\x00\x00\x00\x00\x00\x00\x00") + │ │ ├── ["\xfdR\x00\x00\x00\x00\x00\x00\x01", "\xfdT\x00\x00\x00\x00\x00\x00\x00") │ │ ├── ["\xfdT\x00\x00\x00\x00\x00\x00\x00", "\xfdT\x00\x00\x00\x00\x00\x00\x00"] - │ │ ├── ["\xfdZ\x00\x00\x00\x00\x00\x00\x01", "\xfd\\") + │ │ ├── ["\xfdZ\x00\x00\x00\x00\x00\x00\x01", "\xfd\\\x00\x00\x00\x00\x00\x00\x00") │ │ └── ["\xfd\\\x00\x00\x00\x00\x00\x00\x00", "\xfd\\\x00\x00\x00\x00\x00\x00\x00"] │ ├── key: (1) │ └── scan g@geog_idx @@ -1836,14 +1836,14 @@ project │ ├── inverted constraint: /7/1 │ │ └── spans │ │ ├── ["\xfdD\x00\x00\x00\x00\x00\x00\x00", "\xfdD\x00\x00\x00\x00\x00\x00\x00"] - │ │ ├── ["\xfdD\x00\x00\x00\x00\x00\x00\x01", "\xfdF") - │ │ ├── ["\xfdF\x00\x00\x00\x00\x00\x00\x01", "\xfdH") - │ │ ├── ["\xfdH\x00\x00\x00\x00\x00\x00\x01", "\xfdP") + │ │ ├── ["\xfdD\x00\x00\x00\x00\x00\x00\x01", "\xfdF\x00\x00\x00\x00\x00\x00\x00") + │ │ ├── ["\xfdF\x00\x00\x00\x00\x00\x00\x01", "\xfdH\x00\x00\x00\x00\x00\x00\x00") + │ │ ├── ["\xfdH\x00\x00\x00\x00\x00\x00\x01", "\xfdP\x00\x00\x00\x00\x00\x00\x00") │ │ ├── ["\xfdP\x00\x00\x00\x00\x00\x00\x00", "\xfdP\x00\x00\x00\x00\x00\x00\x00"] - │ │ ├── ["\xfdP\x00\x00\x00\x00\x00\x00\x01", "\xfdR") - │ │ ├── ["\xfdR\x00\x00\x00\x00\x00\x00\x01", "\xfdT") + │ │ ├── ["\xfdP\x00\x00\x00\x00\x00\x00\x01", "\xfdR\x00\x00\x00\x00\x00\x00\x00") + │ │ ├── ["\xfdR\x00\x00\x00\x00\x00\x00\x01", "\xfdT\x00\x00\x00\x00\x00\x00\x00") │ │ ├── ["\xfdT\x00\x00\x00\x00\x00\x00\x00", "\xfdT\x00\x00\x00\x00\x00\x00\x00"] - │ │ ├── ["\xfdZ\x00\x00\x00\x00\x00\x00\x01", "\xfd\\") + │ │ ├── ["\xfdZ\x00\x00\x00\x00\x00\x00\x01", "\xfd\\\x00\x00\x00\x00\x00\x00\x00") │ │ └── ["\xfd\\\x00\x00\x00\x00\x00\x00\x00", "\xfd\\\x00\x00\x00\x00\x00\x00\x00"] │ ├── key: (1) │ └── fd: (1)-->(7) @@ -1871,12 +1871,12 @@ project │ ├── columns: k:1!null │ ├── inverted expression: /6 │ │ ├── tight: false - │ │ └── union spans: ["\x89", "\xfd ") + │ │ └── union spans: ["\x89", "\xfd \x00\x00\x00\x00\x00\x00\x00") │ ├── key: (1) │ └── scan g@geom_idx │ ├── columns: k:1!null geom_inverted_key:6!null │ ├── inverted constraint: /6/1 - │ │ └── spans: ["\x89", "\xfd ") + │ │ └── spans: ["\x89", "\xfd \x00\x00\x00\x00\x00\x00\x00") │ ├── key: (1) │ └── fd: (1)-->(6) └── filters @@ -1903,12 +1903,12 @@ project │ ├── columns: k:1!null │ ├── inverted expression: /6 │ │ ├── tight: false - │ │ └── union spans: ["\x89", "\xfd ") + │ │ └── union spans: ["\x89", "\xfd \x00\x00\x00\x00\x00\x00\x00") │ ├── key: (1) │ └── scan g@geom_idx │ ├── columns: k:1!null geom_inverted_key:6!null │ ├── inverted constraint: /6/1 - │ │ └── spans: ["\x89", "\xfd ") + │ │ └── spans: ["\x89", "\xfd \x00\x00\x00\x00\x00\x00\x00") │ ├── key: (1) │ └── fd: (1)-->(6) └── filters @@ -1934,12 +1934,12 @@ project │ ├── columns: k:1!null │ ├── inverted expression: /6 │ │ ├── tight: false - │ │ └── union spans: ["\x89", "\xfd ") + │ │ └── union spans: ["\x89", "\xfd \x00\x00\x00\x00\x00\x00\x00") │ ├── key: (1) │ └── scan g@geom_idx │ ├── columns: k:1!null geom_inverted_key:6!null │ ├── inverted constraint: /6/1 - │ │ └── spans: ["\x89", "\xfd ") + │ │ └── spans: ["\x89", "\xfd \x00\x00\x00\x00\x00\x00\x00") │ ├── key: (1) │ └── fd: (1)-->(6) └── filters @@ -1974,7 +1974,7 @@ project │ │ │ ├── tight: false │ │ │ └── union spans │ │ │ ├── ["\xfdL\x00\x00\x00\x00\x00\x00\x00", "\xfdL\x00\x00\x00\x00\x00\x00\x00"] - │ │ │ └── ["\xfdN\x00\x00\x00\x00\x00\x00\x01", "\xfdP") + │ │ │ └── ["\xfdN\x00\x00\x00\x00\x00\x00\x01", "\xfdP\x00\x00\x00\x00\x00\x00\x00") │ │ └── span expression │ │ ├── tight: false │ │ └── union spans @@ -1986,8 +1986,9 @@ project │ ├── inverted constraint: /7/1 │ │ └── spans │ │ ├── ["\xfdL\x00\x00\x00\x00\x00\x00\x00", "\xfdL\x00\x00\x00\x00\x00\x00\x00"] - │ │ ├── ["\xfdN\x00\x00\x00\x00\x00\x00\x01", "\xfdP") - │ │ └── ["\xfdP\x00\x00\x00\x00\x00\x00\x00", "\xfdP\x00\x00\x00\x00\x00\x00\x00"] + │ │ ├── ["\xfdN\x00\x00\x00\x00\x00\x00\x01", "\xfdP\x00\x00\x00\x00\x00\x00\x01") + │ │ ├── ["\xfdL\x00\x00\x00\x00\x00\x00\x00", "\xfdL\x00\x00\x00\x00\x00\x00\x00"] + │ │ └── ["\xfdO\x00\x00\x00\x00\x00\x00\x00", "\xfdO\x00\x00\x00\x00\x00\x00\x00"] │ ├── key: (1) │ └── fd: (1)-->(7) └── filters @@ -2018,16 +2019,18 @@ project │ │ ├── tight: false │ │ └── union spans │ │ ├── ["\xfdL\x00\x00\x00\x00\x00\x00\x00", "\xfdL\x00\x00\x00\x00\x00\x00\x00"] - │ │ ├── ["\xfdN\x00\x00\x00\x00\x00\x00\x01", "\xfdP") - │ │ └── ["\xfdP\x00\x00\x00\x00\x00\x00\x00", "\xfdP\x00\x00\x00\x00\x00\x00\x00"] + │ │ ├── ["\xfdN\x00\x00\x00\x00\x00\x00\x01", "\xfdP\x00\x00\x00\x00\x00\x00\x01") + │ │ ├── ["\xfdL\x00\x00\x00\x00\x00\x00\x00", "\xfdL\x00\x00\x00\x00\x00\x00\x00"] + │ │ └── ["\xfdO\x00\x00\x00\x00\x00\x00\x00", "\xfdO\x00\x00\x00\x00\x00\x00\x00"] │ ├── key: (1) │ └── scan g@geog_idx │ ├── columns: k:1!null geog_inverted_key:7!null │ ├── inverted constraint: /7/1 │ │ └── spans │ │ ├── ["\xfdL\x00\x00\x00\x00\x00\x00\x00", "\xfdL\x00\x00\x00\x00\x00\x00\x00"] - │ │ ├── ["\xfdN\x00\x00\x00\x00\x00\x00\x01", "\xfdP") - │ │ └── ["\xfdP\x00\x00\x00\x00\x00\x00\x00", "\xfdP\x00\x00\x00\x00\x00\x00\x00"] + │ │ ├── ["\xfdN\x00\x00\x00\x00\x00\x00\x01", "\xfdP\x00\x00\x00\x00\x00\x00\x01") + │ │ ├── ["\xfdL\x00\x00\x00\x00\x00\x00\x00", "\xfdL\x00\x00\x00\x00\x00\x00\x00"] + │ │ └── ["\xfdO\x00\x00\x00\x00\x00\x00\x00", "\xfdO\x00\x00\x00\x00\x00\x00\x00"] │ ├── key: (1) │ └── fd: (1)-->(7) └── filters @@ -2058,7 +2061,7 @@ project │ │ ├── tight: false │ │ ├── union spans │ │ │ ├── ["\xfdL\x00\x00\x00\x00\x00\x00\x00", "\xfdL\x00\x00\x00\x00\x00\x00\x00"] - │ │ │ ├── ["\xfdN\x00\x00\x00\x00\x00\x00\x01", "\xfdP") + │ │ │ ├── ["\xfdN\x00\x00\x00\x00\x00\x00\x01", "\xfdP\x00\x00\x00\x00\x00\x00\x00") │ │ │ └── ["\xfdP\x00\x00\x00\x00\x00\x00\x00", "\xfdP\x00\x00\x00\x00\x00\x00\x00"] │ │ └── INTERSECTION │ │ ├── span expression @@ -2068,9 +2071,9 @@ project │ │ │ ├── span expression │ │ │ │ ├── tight: false │ │ │ │ └── union spans - │ │ │ │ ├── ["\x80\x90\x00\x00\x00\x00\x00\x00\x00", "\x80\x90\x00\x00\x00\x00\x00\x00\x00"] - │ │ │ │ ├── ["\x80\x84\x00\x00\x00\x00\x00\x00\x00", "\x80\x84\x00\x00\x00\x00\x00\x00\x00"] - │ │ │ │ └── ["\x80\x81\x00\x00\x00\x00\x00\x00\x00", "\x80\x81\x00\x00\x00\x00\x00\x00\x00"] + │ │ │ │ ├── ["\xfd\x90\x00\x00\x00\x00\x00\x00\x00", "\xfd\x90\x00\x00\x00\x00\x00\x00\x00"] + │ │ │ │ ├── ["\xfd\x84\x00\x00\x00\x00\x00\x00\x00", "\xfd\x84\x00\x00\x00\x00\x00\x00\x00"] + │ │ │ │ └── ["\xfd\x81\x00\x00\x00\x00\x00\x00\x00", "\xfd\x81\x00\x00\x00\x00\x00\x00\x00"] │ │ │ └── span expression │ │ │ ├── tight: false │ │ │ └── union spans @@ -2089,8 +2092,12 @@ project │ ├── inverted constraint: /7/1 │ │ └── spans │ │ ├── ["\xfdL\x00\x00\x00\x00\x00\x00\x00", "\xfdL\x00\x00\x00\x00\x00\x00\x00"] - │ │ ├── ["\xfdN\x00\x00\x00\x00\x00\x00\x01", "\xfdP") - │ │ └── ["\xfdP\x00\x00\x00\x00\x00\x00\x00", "\xfdP\x00\x00\x00\x00\x00\x00\x00"] + │ │ ├── ["\xfdN\x00\x00\x00\x00\x00\x00\x01", "\xfdP\x00\x00\x00\x00\x00\x00\x01") + │ │ ├── ["\xfdD\x00\x00\x00\x00\x00\x00\x00", "\xfdD\x00\x00\x00\x00\x00\x00\x00"] + │ │ ├── ["\xfdG\x00\x00\x00\x00\x00\x00\x00", "\xfdG\x00\x00\x00\x00\x00\x00\x00"] + │ │ ├── ["\xfd\x90\x00\x00\x00\x00\x00\x00\x00", "\xfd\x90\x00\x00\x00\x00\x00\x00\x00"] + │ │ ├── ["\xfd\x84\x00\x00\x00\x00\x00\x00\x00", "\xfd\x84\x00\x00\x00\x00\x00\x00\x00"] + │ │ └── ["\xfd\x81\x00\x00\x00\x00\x00\x00\x00", "\xfd\x81\x00\x00\x00\x00\x00\x00\x00"] │ ├── key: (1) │ └── fd: (1)-->(7) └── filters @@ -2119,12 +2126,12 @@ project │ ├── columns: k:1!null │ ├── inverted expression: /6 │ │ ├── tight: false - │ │ └── union spans: ["\x89", "\xfd ") + │ │ └── union spans: ["\x89", "\xfd \x00\x00\x00\x00\x00\x00\x00") │ ├── key: (1) │ └── scan g@geom_idx │ ├── columns: k:1!null geom_inverted_key:6!null │ ├── inverted constraint: /6/1 - │ │ └── spans: ["\x89", "\xfd ") + │ │ └── spans: ["\x89", "\xfd \x00\x00\x00\x00\x00\x00\x00") │ ├── key: (1) │ └── fd: (1)-->(6) └── filters @@ -2178,16 +2185,14 @@ project │ │ ├── tight: false │ │ └── union spans │ │ ├── ["\xfdL\x00\x00\x00\x00\x00\x00\x00", "\xfdL\x00\x00\x00\x00\x00\x00\x00"] - │ │ ├── ["\xfdN\x00\x00\x00\x00\x00\x00\x01", "\xfdP") - │ │ └── ["\xfdP\x00\x00\x00\x00\x00\x00\x00", "\xfdP\x00\x00\x00\x00\x00\x00\x00"] + │ │ └── ["\xfdN\x00\x00\x00\x00\x00\x00\x01", "\xfdP\x00\x00\x00\x00\x00\x00\x01") │ ├── key: (1) │ └── scan g@geog_idx │ ├── columns: k:1!null geog_inverted_key:7!null │ ├── inverted constraint: /7/1 │ │ └── spans │ │ ├── ["\xfdL\x00\x00\x00\x00\x00\x00\x00", "\xfdL\x00\x00\x00\x00\x00\x00\x00"] - │ │ ├── ["\xfdN\x00\x00\x00\x00\x00\x00\x01", "\xfdP") - │ │ └── ["\xfdP\x00\x00\x00\x00\x00\x00\x00", "\xfdP\x00\x00\x00\x00\x00\x00\x00"] + │ │ └── ["\xfdN\x00\x00\x00\x00\x00\x00\x01", "\xfdP\x00\x00\x00\x00\x00\x00\x01") │ ├── key: (1) │ └── fd: (1)-->(7) └── filters @@ -2218,7 +2223,7 @@ project │ │ ├── tight: false │ │ └── union spans │ │ ├── ["\xfdL\x00\x00\x00\x00\x00\x00\x00", "\xfdL\x00\x00\x00\x00\x00\x00\x00"] - │ │ ├── ["\xfdN\x00\x00\x00\x00\x00\x00\x01", "\xfdP") + │ │ ├── ["\xfdN\x00\x00\x00\x00\x00\x00\x01", "\xfdP\x00\x00\x00\x00\x00\x00\x00") │ │ └── ["\xfdP\x00\x00\x00\x00\x00\x00\x00", "\xfdP\x00\x00\x00\x00\x00\x00\x00"] │ ├── key: (1) │ └── select @@ -2230,7 +2235,7 @@ project │ │ ├── inverted constraint: /7/1 │ │ │ └── spans │ │ │ ├── ["\xfdL\x00\x00\x00\x00\x00\x00\x00", "\xfdL\x00\x00\x00\x00\x00\x00\x00"] - │ │ │ ├── ["\xfdN\x00\x00\x00\x00\x00\x00\x01", "\xfdP") + │ │ │ ├── ["\xfdN\x00\x00\x00\x00\x00\x00\x01", "\xfdP\x00\x00\x00\x00\x00\x00\x00") │ │ │ └── ["\xfdP\x00\x00\x00\x00\x00\x00\x00", "\xfdP\x00\x00\x00\x00\x00\x00\x00"] │ │ ├── key: (1) │ │ └── fd: (1)-->(7) @@ -2263,14 +2268,14 @@ project │ │ ├── tight: false │ │ └── union spans │ │ ├── ["\xfd\x10\x00\x00\x00\x00\x00\x00\x00", "\xfd\x10\x00\x00\x00\x00\x00\x00\x00"] - │ │ └── ["\xfd\x10\x00\x00\x00\x00\x00\x00\x01", "\xfd\x18") + │ │ └── ["\xfd\x10\x00\x00\x00\x00\x00\x00\x01", "\xfd\x18\x00\x00\x00\x00\x00\x00\x00") │ ├── key: (1) │ └── scan g@geom_idx │ ├── columns: k:1!null geom_inverted_key:6!null │ ├── inverted constraint: /6/1 │ │ └── spans │ │ ├── ["\xfd\x10\x00\x00\x00\x00\x00\x00\x00", "\xfd\x10\x00\x00\x00\x00\x00\x00\x00"] - │ │ └── ["\xfd\x10\x00\x00\x00\x00\x00\x00\x01", "\xfd\x18") + │ │ └── ["\xfd\x10\x00\x00\x00\x00\x00\x00\x01", "\xfd\x18\x00\x00\x00\x00\x00\x00\x00") │ ├── key: (1) │ └── fd: (1)-->(6) └── filters diff --git a/pkg/sql/rowenc/index_encoding.go b/pkg/sql/rowenc/index_encoding.go index af8fe31320ca..d13d3ff80e51 100644 --- a/pkg/sql/rowenc/index_encoding.go +++ b/pkg/sql/rowenc/index_encoding.go @@ -848,16 +848,15 @@ func EncodeGeoInvertedIndexTableKeys( } func encodeGeoKeys(inKey []byte, geoKeys []geoindex.Key) (keys [][]byte, err error) { - keys = make([][]byte, 0, len(geoKeys)) - for _, k := range geoKeys { - outKey := make([]byte, len(inKey)) - copy(outKey, inKey) - d := (tree.DInt)(k) - newKey, err := EncodeTableKey(outKey, &d, encoding.Ascending) - if err != nil { - return nil, err - } - keys = append(keys, newKey) + keys = make([][]byte, len(geoKeys)) + var b []byte // avoid per-key heap allocations + for i, k := range geoKeys { + prev := len(b) + b = append(b, inKey...) + b = encoding.EncodeUvarintAscending(b, uint64(k)) + // Set capacity so that the caller appending does not corrupt later keys. + newKey := b[prev:len(b):len(b)] + keys[i] = newKey } return keys, nil }