Skip to content

Commit

Permalink
Merge #53153 #53215
Browse files Browse the repository at this point in the history
53153: colexec: clean up vectorized stats r=yuzefovich a=yuzefovich

Release note (sql change): `selectivity` information has been removed
from EXPLAIN ANALYZE diagrams which would be present if the query was
executed via the vectorized engine because it has been quite confusing
and probably not helpful information.

Release note (sql change): `stall time` has been renamed to
`IO + execution time` in EXPLAIN ANALYZE diagrams for the queries that are
executed via the vectorized engine.

53215: sql/opt/invertedexpr: avoid per-span allocations in GeoUnionKeySpansToSpanExpr r=nvanbenschoten a=nvanbenschoten

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.

Co-authored-by: Yahor Yuzefovich <[email protected]>
Co-authored-by: Nathan VanBenschoten <[email protected]>
  • Loading branch information
3 people committed Aug 25, 2020
3 parents 620f0a4 + e7065f7 + 6ae5c97 commit 72cb52d
Show file tree
Hide file tree
Showing 20 changed files with 218 additions and 211 deletions.
2 changes: 1 addition & 1 deletion pkg/roachpb/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,7 @@ func (v *Value) SetDuration(t duration.Duration) error {
// receiver, sets the tag and clears the checksum.
func (v *Value) SetBitArray(t bitarray.BitArray) {
words, _ := t.EncodingParts()
v.ensureRawBytes(headerSize + encoding.NonsortingUvarintMaxLen + 8*len(words))
v.ensureRawBytes(headerSize + encoding.MaxNonsortingUvarintLen + 8*len(words))
v.RawBytes = encoding.EncodeUntaggedBitArrayValue(v.RawBytes[:headerSize], t)
v.setTag(ValueType_BITARRAY)
}
Expand Down
27 changes: 6 additions & 21 deletions pkg/sql/colexec/execpb/stats.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (
"fmt"
"time"

"github.com/cockroachdb/cockroach/pkg/col/coldata"
"github.com/cockroachdb/cockroach/pkg/sql/execinfrapb"
"github.com/cockroachdb/cockroach/pkg/util/humanizeutil"
"github.com/cockroachdb/cockroach/pkg/util/tracing"
Expand All @@ -26,8 +25,7 @@ var _ execinfrapb.DistSQLSpanStats = &VectorizedStats{}
const (
batchesOutputTagSuffix = "output.batches"
tuplesOutputTagSuffix = "output.tuples"
selectivityTagSuffix = "selectivity"
stallTimeTagSuffix = "time.stall"
ioTimeTagSuffix = "time.io"
executionTimeTagSuffix = "time.execution"
maxVecMemoryBytesTagSuffix = "mem.vectorized.max"
maxVecDiskBytesTagSuffix = "disk.vectorized.max"
Expand All @@ -36,19 +34,14 @@ const (
// Stats is part of SpanStats interface.
func (vs *VectorizedStats) Stats() map[string]string {
var timeSuffix string
if vs.Stall {
timeSuffix = stallTimeTagSuffix
if vs.IO {
timeSuffix = ioTimeTagSuffix
} else {
timeSuffix = executionTimeTagSuffix
}
selectivity := float64(0)
if vs.NumBatches > 0 {
selectivity = float64(vs.NumTuples) / float64(int64(coldata.BatchSize())*vs.NumBatches)
}
return map[string]string{
batchesOutputTagSuffix: fmt.Sprintf("%d", vs.NumBatches),
tuplesOutputTagSuffix: fmt.Sprintf("%d", vs.NumTuples),
selectivityTagSuffix: fmt.Sprintf("%.2f", selectivity),
timeSuffix: fmt.Sprintf("%v", vs.Time.Round(time.Microsecond)),
maxVecMemoryBytesTagSuffix: fmt.Sprintf("%d", vs.MaxAllocatedMem),
maxVecDiskBytesTagSuffix: fmt.Sprintf("%d", vs.MaxAllocatedDisk),
Expand All @@ -58,8 +51,7 @@ func (vs *VectorizedStats) Stats() map[string]string {
const (
batchesOutputQueryPlanSuffix = "batches output"
tuplesOutputQueryPlanSuffix = "tuples output"
selectivityQueryPlanSuffix = "selectivity"
stallTimeQueryPlanSuffix = "stall time"
ioTimeQueryPlanSuffix = "IO time"
executionTimeQueryPlanSuffix = "execution time"
maxVecMemoryBytesQueryPlanSuffix = "max vectorized memory allocated"
maxVecDiskBytesQueryPlanSuffix = "max vectorized disk allocated"
Expand All @@ -68,27 +60,20 @@ const (
// StatsForQueryPlan is part of DistSQLSpanStats interface.
func (vs *VectorizedStats) StatsForQueryPlan() []string {
var timeSuffix string
if vs.Stall {
timeSuffix = stallTimeQueryPlanSuffix
if vs.IO {
timeSuffix = ioTimeQueryPlanSuffix
} else {
timeSuffix = executionTimeQueryPlanSuffix
}
selectivity := float64(0)
if vs.NumBatches > 0 {
selectivity = float64(vs.NumTuples) / float64(int64(coldata.BatchSize())*vs.NumBatches)
}
stats := []string{
fmt.Sprintf("%s: %d", batchesOutputQueryPlanSuffix, vs.NumBatches),
fmt.Sprintf("%s: %d", tuplesOutputQueryPlanSuffix, vs.NumTuples),
fmt.Sprintf("%s: %.2f", selectivityQueryPlanSuffix, selectivity),
fmt.Sprintf("%s: %v", timeSuffix, vs.Time.Round(time.Microsecond)),
}

if vs.MaxAllocatedMem != 0 {
stats = append(stats,
fmt.Sprintf("%s: %s", maxVecMemoryBytesQueryPlanSuffix, humanizeutil.IBytes(vs.MaxAllocatedMem)))
}

if vs.MaxAllocatedDisk != 0 {
stats = append(stats,
fmt.Sprintf("%s: %s", maxVecDiskBytesQueryPlanSuffix, humanizeutil.IBytes(vs.MaxAllocatedDisk)))
Expand Down
66 changes: 33 additions & 33 deletions pkg/sql/colexec/execpb/stats.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions pkg/sql/colexec/execpb/stats.proto
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ message VectorizedStats {
int64 num_tuples = 3;
google.protobuf.Duration time = 4 [(gogoproto.nullable) = false,
(gogoproto.stdduration) = true];
// stall indicates whether stall time or execution time is being tracked.
bool stall = 5;
// io indicates whether time contains IO or execution time.
bool io = 5 [(gogoproto.customname) = "IO"];
int64 max_allocated_mem = 6;
int64 max_allocated_disk = 7;
}
9 changes: 4 additions & 5 deletions pkg/sql/colexec/stats.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,13 @@ var _ colexecbase.Operator = &VectorizedStatsCollector{}

// NewVectorizedStatsCollector creates a new VectorizedStatsCollector which
// wraps 'op' that corresponds to a component with either ProcessorID or
// StreamID 'id' (with 'idTagKey' distinguishing between the two). 'isStall'
// indicates whether stall or execution time is being measured. 'stopwatch'
// must be non-nil.
// StreamID 'id' (with 'idTagKey' distinguishing between the two). 'ioTime'
// indicates whether IO time is being measured.
func NewVectorizedStatsCollector(
op colexecbase.Operator,
id int32,
idTagKey string,
isStall bool,
ioTime bool,
inputWatch *timeutil.StopWatch,
memMonitors []*mon.BytesMonitor,
diskMonitors []*mon.BytesMonitor,
Expand All @@ -71,7 +70,7 @@ func NewVectorizedStatsCollector(
}
return &VectorizedStatsCollector{
Operator: op,
VectorizedStats: execpb.VectorizedStats{ID: id, Stall: isStall},
VectorizedStats: execpb.VectorizedStats{ID: id, IO: ioTime},
idTagKey: idTagKey,
stopwatch: inputWatch,
memMonitors: memMonitors,
Expand Down
10 changes: 5 additions & 5 deletions pkg/sql/colexec/stats_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func TestNumBatches(t *testing.T) {
nBatches := 10
noop := NewNoop(makeFiniteChunksSourceWithBatchSize(nBatches, coldata.BatchSize()))
vsc := NewVectorizedStatsCollector(
noop, 0 /* id */, execinfrapb.ProcessorIDTagKey, true, /* isStall */
noop, 0 /* id */, execinfrapb.ProcessorIDTagKey, true, /* ioTime */
timeutil.NewStopWatch(), nil /* memMonitors */, nil, /* diskMonitors */
nil, /* inputStatsCollectors */
)
Expand All @@ -56,7 +56,7 @@ func TestNumTuples(t *testing.T) {
for _, batchSize := range []int{1, 16, 1024} {
noop := NewNoop(makeFiniteChunksSourceWithBatchSize(nBatches, batchSize))
vsc := NewVectorizedStatsCollector(
noop, 0 /* id */, execinfrapb.ProcessorIDTagKey, true, /* isStall */
noop, 0 /* id */, execinfrapb.ProcessorIDTagKey, true, /* ioTime */
timeutil.NewStopWatch(), nil /* memMonitors */, nil, /* diskMonitors */
nil, /* inputStatsCollectors */
)
Expand Down Expand Up @@ -88,7 +88,7 @@ func TestVectorizedStatsCollector(t *testing.T) {
timeSource: timeSource,
}
leftInput := NewVectorizedStatsCollector(
leftSource, 0 /* id */, execinfrapb.ProcessorIDTagKey, true, /* isStall */
leftSource, 0 /* id */, execinfrapb.ProcessorIDTagKey, true, /* ioTime */
timeutil.NewTestStopWatch(timeSource.Now), nil /* memMonitors */, nil, /* diskMonitors */
nil, /* inputStatsCollectors */
)
Expand All @@ -97,7 +97,7 @@ func TestVectorizedStatsCollector(t *testing.T) {
timeSource: timeSource,
}
rightInput := NewVectorizedStatsCollector(
rightSource, 1 /* id */, execinfrapb.ProcessorIDTagKey, true, /* isStall */
rightSource, 1 /* id */, execinfrapb.ProcessorIDTagKey, true, /* ioTime */
timeutil.NewTestStopWatch(timeSource.Now), nil /* memMonitors */, nil, /* diskMonitors */
nil, /* inputStatsCollectors */
)
Expand All @@ -118,7 +118,7 @@ func TestVectorizedStatsCollector(t *testing.T) {
}

mjStatsCollector := NewVectorizedStatsCollector(
timeAdvancingMergeJoiner, 2 /* id */, execinfrapb.ProcessorIDTagKey, false, /* isStall */
timeAdvancingMergeJoiner, 2 /* id */, execinfrapb.ProcessorIDTagKey, false, /* ioTime */
mjInputWatch, nil /* memMonitors */, nil, /* diskMonitors */
[]*VectorizedStatsCollector{leftInput, rightInput},
)
Expand Down
4 changes: 2 additions & 2 deletions pkg/sql/logictest/testdata/logic_test/dist_vectorize
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,12 @@ NULL /1 {5} 5
query T
SELECT url FROM [EXPLAIN ANALYZE SELECT count(*) FROM kv]
----
https://cockroachdb.github.io/distsqlplan/decode.html#eJzMlV1vm0wQhe_fX7GaK_vVunzacbiKlbqSJQenxlE_IhQRGLkomKW7i5XI8n-vgEgFq12oWsVcssxhzuEZmAOI7wk44M2X8-sNyXlCPqxXN-R-_vl2OVu4ZObOll--zsng_cLbeB-XQ_JaGrI8lYP_h1X9094HCimL0A12KMC5BwMomEDBAgo2UBiDTyHjLEQhGC9KDqVgET2Do1OI0yyXxbFPIWQcwTmAjGWC4MAmeExwjUGEXNOBQoQyiJOyzdP-KuPxLuAvQMHLglQ4ZKQVjVe5dIjLUgQKj4EMv6EgLJdZcVw8ROZZUjsq_ApMMJTxPpYvDtHf6UWZkEGSEBnv0CG6AP9IoZK8ehUy2CI4xpF2zzPbbjluA8m4Nm7GuV7duZuH9eqTNxj-nW98xjCXMUvbvZu_9f7Tcp4yHiHHqOHXP6rTGSe0vLubh4W7GVwZb5fOaqQzuk-a0T5pmjnSrDPPWkuiGo1J72bN7E7D7EDDGmn2mWm0JKrRuOgdDas7DasDDXtU_t3OSaMlUY3GtHc07O407A40xqMzs2jJU2Nx2TsWLft8jSJjqcCT3fjrJ-vFzsRoi9WCFSznId5yFpZtqstVqSsPIhSyumtUF4u0ulUYrIsNpdhsiI1Tsanu3NLaUqpttdj-E9_lWyxf6L-d36alsdLSRJ1n0r88F0pLU3Weaf_yXKqnVW_5UNSf2dsk8o___QgAAP__AeJk1w==
https://cockroachdb.github.io/distsqlplan/decode.html#eJzMlV1vmzAUhu_3K6xzlU6OCB9JU64adZmElEIXUu2jQhWFowyVYGabqlOU_z4BlQZRZ9i0hV1i-_A-fnLC2YP4loIN_nK1vNqQgqfk_dq7JnfLTzerheOShbtYff6yJKN3jr_xP6zOyMvRiBWZHL09q88_PgVAIWMxuuEOBdh3oAMFAyiYQMECClMIKOScRSgE4-WRfVXgxM9gTygkWV7IcjmgEDGOYO9BJjJFsGETPqS4xjBGrk2AQowyTNIq5vHpMufJLuTfgYKfh5mwyVgrg71C2sRlGQKFh1BGX1EQVsi8XC5fIos8bSyVvI5HZLJDm0wEBAcK9d4LlJDhFsHWD7Q_-GK75bgNJePatM195d26m_u199EfnfUHxGeMCpmwrJvT-CXnT7wiYzxGjnGLLTiob6If_QT-7fW9425Gl_q_uYnZuonev1X07lbRjLFmnqpZOtAbimeDNovRX7HRQ7E51qxTKe5Abyg-H1Sx2V-x2UOxNa6-LydR3IHeUDwfVLHVX7HVQ_F0fCrBHeANwRf_zUx5hXONImeZwKPZ8vqbJ-XMwXiL9YASrOAR3nAWVTH1o1fVVQsxClnv6vWDk9VbJWCzWFcWG61i_bjYUCd3RJvKaktdbP0Od2WxEvqHTdnOniqzZ2rw2YDg58rsuRp8PiD4hbrRJh09rv6H_GX04PDmRwAAAP___V_5bQ==

query T
SELECT url FROM [EXPLAIN ANALYZE SELECT * FROM kv JOIN kw ON kv.k = kw.k]
----
https://cockroachdb.github.io/distsqlplan/decode.html#eJzUmF9vqkgYxu_3U0zeq3P2jIXhj60kTWx23cTGarf2YncbL6jMKpECC4Nt0_jdN8g2rVZhgIUZ76rOn9_z8gxP532D-B8PLJgORoNf7lESeei3u8kNehj8cTu6Go7R1fhq9OdfA_Tt1-H0fvr76Dv6b-jP2cDVGl1PhmO0ekaTMVqtz1boEq2ez1YzwOAHDh3bTzQG6wEIYNAAgw4YDMBgwgxDGAVzGsdBlA55204YOi9gqRhcP0xY-vUMwzyIKFhvwFzmUbDg3n706B21HRopKmBwKLNdb7vNat0PI_fJjl4BwzS0_dhCHSXd-NFm8yWNUZCwMGEWSieyJPQ-fZUyxtSjc-auXfZqIfVMTYfFzPY8xNwnaiE1htkGQzYlw37HenxFSzte7gL1Ccw2s-0aCwoW2eBqOrt7Op-_6lSITEq1o0o_1gkih0bU2V_nR7ox16gDRbuh0YJeB65PI4XsucOjf7NvffLj-2XkLpbZn4BhkpakT3Bfw30d9416NaQvdJ4wN_CP1fGjRjpHjRL_kP6D0sdBJwgVYu6K5pBi1pdi7Egh_MYmxQdY0TqKLo2xSVWl5xxHWCql2lGlLR5hckpHWON3g8bhe72j1FTSmO9LKL3g8L1USrWjSlv0vXZKvtf53aBz-N7oKKY0biBVlfY4fC-VUu2o0hZ9r5-S7w1-Nxgcvjc70niBVNVpFru-oxBk-w4iKGBLGkmjWTuquUX_G6fk_4IL7B2Nw8CP6d7V5fDKaloa6ixoVvA4SKI5vY2C-Xab7ONkO2_7v6hDY5b9qmUfhv77TzGzGe_VR-W2VRmkrnxIvTpI_IevDBKR8MkRUwQTKWFwTQakrnxIvTpIVQ2ej0QkfHJ7Bm-JSdtnUj8z6btnbn-ynjuZ7HpRbUeQIV8k5SMJiaR8pFqR1AySmEgqYKoVSVXfbKZ8kZSPJCSS8pFqRVIzSGIiqYCpViRVNXi3TCS1g3QuX6jkIwkJlXwkIaGSj1QvVJoxk5h7zoV8oZKPJCRU8pGEhEo-Ur1QqWrwAiYh95yefKFCJOyeFTDVipWG6iQkVwqYxNxWiqDEdNBkbKE12EOr7PIGm2gN1UlQF03GNhop1UdryVFf2nP_X740xCTk2lLAJCZf8pkE5UsBlJh8KdPwbetdXqbj29YbqkzLVw4mQflSqunbFtSXRp2AfJltfvo3AAD__-GC5ik=
https://cockroachdb.github.io/distsqlplan/decode.html#eJzMmFtP-zYYxu_3Kaz3CoZL6hwKjYRUtHVSUWkZ5WIb6kVovDZqSbLE4SDU7z6l-SPoKY7_juve0cTOz8_rx4_M-wHpfwtwYdTtd397QFmyQH_cD2_RY_evu_51b4CuB9f9v__popPfe6OH0Z_9U_Rj6K_FwPkLuhn2Bmj-ioYDNH85n6MrNH89n48BQxj5dOA90xTcRyCAwQQMFmCwAYMDYwxxEk1omkZJPuRjNaHnv4HbxBCEccbyx2MMkyih4H4AC9iCggsP3tOC3lPPp4nRBAw-ZV6wWGHmL504CZ695B0wjGIvTF3UMHLwk8cmM5qiKGNxxlyUT2RZvPj2KF9jb4hY8Exd1ExhvMRQvCvW98l_ekczL52tkzsExssxhpR5UwouWeKfE9TaEPS6LcggWiSZeyV9fSdKfJpQf_M7Zzm40qgd1bmlyZTeREFIE4Ns7PeC_stOOuTs9CoJprPiT8AwzLV3CO6YuGPhjl29WPSNTjIWROG-mn3Vw6pQjyzcpXWnzEHUiGKDOOsCKyzbEVu2vbZsUt2ZhH_UDLNhWLoPm4CkiwqHTY8kc6-kAx42cqyHzay-xWYF11oNQ2DValwrIOmygmv1SDL3Sjqga81jda1VfYutCq61G4aj27UCktoVXKtHkrlX0gFdax2ra-3qW2xXcK3T0O1ZAUEO37MNgyAv9BFBEZvRRLd7bT3utY_VvZz_vO5pGkdhSjeu57u_3MzLQP0pLYqbRlkyoXdJNFlhip_D1bzVjc2nKSvemsWPXvj5KmUeq3q9b257RYTd0shuy7B3nBERNtFZdOIohRMBt5kHZbc0stsybK7bytlEZ9E33FY33NyEN7_DrXWnb062SieTdb80a165rTGVy9lqU7mcLZXKkmzFqcyBS6UyNyEcjalczlabyuVsqVSWZCtOZQ5cKpW5bmuJpHLN7AuNuVrOVpur5Wy1uVrOlstVyQ1XfNu91Jir5Wy1uVrOVpur5Wy5XOW6jQNXe9tta8xVorONwIFLJauscrXRyoErvrPy6IpbCVp7CQqbCXzLKewmyCpX3U7Q2k8gQg2Fund9qyFRX8TKwtVeXjlwxRFbDlcdsRy64ogVaUPVnnIifajaT7pII-rAcNURK9SKqp2-1ZpQGbHj5S__BwAA__8BPceY

# Verify execution.
statement ok
Expand Down
Loading

0 comments on commit 72cb52d

Please sign in to comment.