From 2cd87ed5f00cd32f05280b1f34d2fd738ec083ff Mon Sep 17 00:00:00 2001 From: Jordan Lewis Date: Fri, 5 Mar 2021 19:30:35 -0400 Subject: [PATCH] sql: issue GetRequests from SQL when possible Previously, SQL unconditionally emitted ScanRequests for every read that it produced, even if we were completely sure that the scan could contain only a single key that was fully known at request time. This was less efficient than necessary, because ScanRequests cause the KV layer to do more work than GetRequests. Here are the reasons why GetRequests are more efficient: - MVCCGet, unlike MVCCScan, is able to use a prefix iterator, which allows it to make use of RocksDB/Pebble bloom filters. There may also be other wins at the storage layer, like avoiding prefetching - various data structures have optimizations and fast-paths for single-key operations (e.g. timestamp cache, latch manager, refresh span tracking) - various code paths are simpler in the point operation case - a point operation implies only needing a single key allocation instead of a start and end key allocation - a point operation implies only needing to return up to a single result, which means that we can avoid some indirection in various places - A scan over a span that has at most 1 key, but does not know it, needs to iterate over all the versions (or eventually do a second expensive seek), looking for the non-existent next key in the span. A Get can do a single seek, read the key, and be done. Release note (performance improvement): SQL will now emit GetRequests when possible to KV instead of always emitting ScanRequests. This manifests as a modest performance improvement for some workloads. --- .../testdata/logic_test/multi_region | 4 +- .../testdata/logic_test/regional_by_row | 10 +- pkg/kv/kvclient/kvcoord/dist_sender.go | 2 +- pkg/sql/as_of_test.go | 2 +- pkg/sql/distsql_physical_planner.go | 16 ++- .../testdata/logic_test/explain_analyze_plans | 2 +- .../inverted_filter_json_array_dist | 6 +- .../testdata/logic_test/merge_join_dist_vec | 2 +- .../testdata/logic_test/vectorize_local | 8 +- .../testdata/autocommit_nonmetamorphic | 4 +- .../execbuilder/testdata/distsql_merge_join | 4 +- .../testdata/distsql_tighten_spans | 4 +- .../opt/exec/execbuilder/testdata/interleaved | 2 +- .../exec/execbuilder/testdata/inverted_index | 10 +- .../testdata/inverted_index_multi_column | 18 +-- pkg/sql/opt/exec/execbuilder/testdata/join | 16 +-- .../opt/exec/execbuilder/testdata/join_order | 4 +- .../testdata/lookup_join_nonmetamorphic | 6 +- pkg/sql/opt/exec/execbuilder/testdata/orderby | 2 +- .../testdata/partial_index_nonmetamorphic | 136 +++++++++--------- ...ndary_index_column_families_nonmetamorphic | 4 +- pkg/sql/opt/exec/execbuilder/testdata/select | 38 +++-- .../execbuilder/testdata/select_for_update | 36 ++--- pkg/sql/opt/exec/execbuilder/testdata/unique | 6 +- pkg/sql/opt/exec/execbuilder/testdata/upsert | 4 +- .../testdata/upsert_nonmetamorphic | 6 +- .../exec/execbuilder/testdata/virtual_columns | 2 +- pkg/sql/row/fk_spans.go | 2 +- pkg/sql/row/kv_batch_fetcher.go | 99 ++++++++++--- pkg/sql/rowenc/index_encoding.go | 15 +- pkg/sql/span/span_builder.go | 100 ++++++++----- pkg/sql/span/span_builder_test.go | 2 +- pkg/sql/span_builder_test.go | 4 +- pkg/sql/testdata/explain_tree | 2 +- pkg/sql/txn_restart_test.go | 6 +- pkg/sql/upsert_test.go | 32 ++++- 36 files changed, 382 insertions(+), 234 deletions(-) diff --git a/pkg/ccl/logictestccl/testdata/logic_test/multi_region b/pkg/ccl/logictestccl/testdata/logic_test/multi_region index 176bb8ae8257..615d3703431b 100644 --- a/pkg/ccl/logictestccl/testdata/logic_test/multi_region +++ b/pkg/ccl/logictestccl/testdata/logic_test/multi_region @@ -1474,7 +1474,7 @@ vectorized: true table: orders@primary spans: [/'ap-southeast-2'/'94e4b847-8f2f-4ac5-83f1-641d6e3df727' - /'ap-southeast-2'/'94e4b847-8f2f-4ac5-83f1-641d6e3df727'] [/'us-east-1'/'94e4b847-8f2f-4ac5-83f1-641d6e3df727' - /'us-east-1'/'94e4b847-8f2f-4ac5-83f1-641d6e3df727'] · -Diagram: https://cockroachdb.github.io/distsqlplan/decode.html#eJykk9tO20AQhu_7FKPhgoM2cnyABEtIRm1Kg9KEJlSt1I2Q8U5g22TX3V2rrlCu-mx9r8o2FIIaBOmFrT3MNzP_P_YN2u9zjLH3-Wxw3B_Czpv-5HzyYbALk96g9_octBFkLqRgkBu90LcrmREcT5rFxQ_prnXhLuqAu9s9ENJmulBuNbCJgrfj0fsmt4XTUX_YZLfwcdIfnsDOXa1d-PSuN-797QKOYPswouiyG3Va3Vkwa0Vptt_qhjO_dRD54oBCMesEnW1kqLSgYbogi_EXjHDKMDc6I2u1qY5u6oC-KDFuM5QqL1x1PGWYaUMY36CTbk4Y43l6OacxpYKM10aGglwq53XaRkGSG7lIzU9kOMlTZWPwOCYcPY6cl4cR5yVVr8vuCedld-ad_v7FeTnzBeelL9RRtelsc2xtyHlbkCoBPmh3TQYZjgoXQ-KzJGBJiNMlQ124e4XWpVeEsb9km7ngP9uFqu_2hk5synpbz3YgWOvAvfBC1fpIrIieLv_h0VC3dO4Fq-4M5EI68Nf20H7JFE61VLdDCFfLND_QgyEMtP5W5PBVSwVaxZBUwJiUIFM7A0nIIAmqZy_ZX9te-JL2xmRzrSw9smqd8ClDElfU-G11YTI6MzqryzTbUc3VB4Ksa26DZtNX9VX9FT-E_f-BgyfhcAVuP4bDJ-HoETxdvvoTAAD__499yik= +Diagram: https://cockroachdb.github.io/distsqlplan/decode.html#eJykUttO20AQfe9XjOaFizZKfIEES0hGbUqD0oQmVK3UtZDxjmHbZNfdXauuUJ76bf2vyjYUghoE9MHWzuXMnHM012i_LzDC4efT8dFoAttvRvOz-YfxDsyH4-HrM9BGkDmXgkFh9FLfvGRGcDRvH-c_pLvSpTtvGm6ruyCkzXSp3Hpj2wVvZ9P37WwLJ9PRpJ1u4eN8NDmG7dtdO_Dp3XA2_MsCDmHrIKTwYhD2O4Pczzthmu11BkHudfZDT-xTIPK-399ChkoLmqRLshh9wRAThoXRGVmrTZ26bhpGosKox1CqonR1OmGYaUMYXaOTbkEY4Vl6saAZpYJMt4cMBblULpqxrYK4MHKZmp_IcF6kykbQ5Rhz7HLkvDoIOa-o_l0MjjmvBnn35PcvzqvcE5xXnlCHddDf4tjtdSBVAjzQ7ooMMpyWLoLYY7HP4gCTFUNdujuq1qWXhJG3Yi-T4z1ZTk289zJJT5bhb5Rxx75UDUkSa8yT1T-ETnRHF11_XeJYLqUDbyOH3nOsPNFS3TgZrK9pz_mek2Otv5UFfNVSgVYRxDVgRkqQaZyBOGAQ-_W3G-9tpBc8h96MbKGVpQdWbRKeMCRxSa3fVpcmo1Ojs2ZNG04bXJMQZF1b9dtgpJpSc4r3wd7_gP1HwcEauPcQHDwKDh-Ak9WrPwEAAP__jsyklQ== query T nodeidx=3 USE multi_region_test_db; EXPLAIN (DISTSQL) SELECT @@ -1511,4 +1511,4 @@ vectorized: true table: orders@primary spans: [/'ap-southeast-2'/'94e4b847-8f2f-4ac5-83f1-641d6e3df727' - /'ap-southeast-2'/'94e4b847-8f2f-4ac5-83f1-641d6e3df727'] [/'us-east-1'/'94e4b847-8f2f-4ac5-83f1-641d6e3df727' - /'us-east-1'/'94e4b847-8f2f-4ac5-83f1-641d6e3df727'] · -Diagram: https://cockroachdb.github.io/distsqlplan/decode.html#eJykk19v2jwUxu_fT2GdXvRdZZq_BRqpkquNbVQMOqi0STNCaXzSegM7c5wtU8XVPtu-15SEtgMN1LILSHx8fjnPeexzB_nXOUTQ-3g5OO8Pyf-v-pOryfvBCzLpDXovr4g2As1MCkoyoxc6P64fq4BMkJxPmpfZd2lvdWFndcL97hERMk90oex6YpNFXo9H75oSObkY9YerImR0_3YsVaoJ44XrBrjKbGIf3vbGvQd55IwcnoYYXnfDTqub-mkrjJOTVjdIvVY79EQbA5F2_M4hUFBa4DBeYA7RJwhhSiEzOsE816YK3dUJfVFC5FKQKitsFZ5SSLRBiO7ASjtHiOAqvp7jGGOBxnGBgkAby3n92UYpy4xcxOYHUJhkscoj4nBgHBwOnJenIeclVn_X3Tecl93Uufj1k_My9QTnpSfUWbXoHHJo7ck5ByRWgnhE21s0QGFU2IgwjzKfshCmSwq6sI8d5ja-QYi8Jd3PBe_JLlS63T2d2Jd1Dp7sgL_VgcfGC1X3h2Kt6enyLx4NdUtnjr_uzkAupCXeVg3uc06hr76hsSgutFRonGC9VDNMrHnMqvmZSVECfcB6ZWYIaz9MGgs2rAp2uRU8R2mlcHVdwi0q76_LQOsvRUY-a6mIVhFhFTAaEtZZFzpGJdDUWgk7oYT51e-ItbcqDp-jeIx5plWOG-e87dSmFFDcYHNZcl2YBC-NTuoyzXJUc3VAYG6bXb9Z9FW9VY_gn7D3L7C_Ew7WYHcTDnbC4W443AmfbMDT5X-_AwAA___uBSO6 +Diagram: https://cockroachdb.github.io/distsqlplan/decode.html#eJykk99uGjsQxu_PU1hzk9PIhP0XICtFctTSlohCCpFaqUZos55N3IK9tb3tVhFXfba-V7W7JCmooCS9ANvj-Zjf5xluwX5dQAz9jxfDs8GI_P9qML2cvh--INP-sP_ykmgj0MyloCQ3eqntUb2sAzJFcjZtNvPv0t3ows3rhLvbQyKkTXWh3GZik0VeT8bvmhKWnI8Ho3URMr7bHUmVacJ44XkhrjOb2Ie3_Un_Ho-ckoOTCKOrXtRt9bIga0VJetzqhZnf6kS-6GAosm7QPQAKSgscJUu0EH-CCGYUcqNTtFabKnRbJwxECbFHQaq8cFV4RiHVBiG-BSfdAiGGy-RqgRNMBJq2BxQEukQu6p9tSFlu5DIxP4DCNE-UjUmbA-PQ5sB5eRJxXmL1ddV7w3nZy9rnv35yXma-4Lz0hTqtDt0DDm2vRRIliE-0u0EDFMaFiwnzKQsoi2C2oqAL94BqXXKNEPsr-jw7_qPtVODe8yw92kaw08YDfaFqSBQb5LPVX4yOdEvn7WDT4lAupSP-TgbvKU85UN_QOBTnWio07XCzVDParFnm1TTPpSiB3sv6ZW4I69zPPQu3nirc91rhU0grwnXPox2Udz0fav2lyMlnLRXRKiasEoxHhHU3QSeoBJqalbBjSlhQfQ5ZZydx9BTiCdpcK4tbfd7VtRkFFNfYDIvVhUnxwui0LtMcx7WuDgi0rrkNmsNA1Vf1_-hPsf8v4mCvONwQe9vicK842i-O9oqPt8Sz1X-_AwAA__8IW_4X diff --git a/pkg/ccl/logictestccl/testdata/logic_test/regional_by_row b/pkg/ccl/logictestccl/testdata/logic_test/regional_by_row index e6667d7a2c33..68ea2fc6f18d 100644 --- a/pkg/ccl/logictestccl/testdata/logic_test/regional_by_row +++ b/pkg/ccl/logictestccl/testdata/logic_test/regional_by_row @@ -646,7 +646,7 @@ SELECT message FROM [SHOW KV TRACE FOR SESSION] WITH ORDINALITY OR message LIKE 'Scan%' ORDER BY ordinality ASC ---- -Scan /Table/73/1/"@"/1{-/#}, /Table/73/1/"\x80"/1{-/#}, /Table/73/1/"\xc0"/1{-/#} +Scan /Table/73/1/"@"/1/0, /Table/73/1/"\x80"/1/0, /Table/73/1/"\xc0"/1/0 fetched: /regional_by_row_table/primary/'ap-southeast-2'/1/pk2/a/b/j -> /1/2/3/'{"a": "b"}' output row: [1 1 2 3 '{"a": "b"}'] @@ -673,7 +673,7 @@ vectorized: true table: regional_by_row_table@primary spans: [/'ca-central-1'/1 - /'ca-central-1'/1] [/'us-east-1'/1 - /'us-east-1'/1] · -Diagram: https://cockroachdb.github.io/distsqlplan/decode.html#eJykkVEL0zAQx9_9FOF8Uclo0ylIQIhoxULdZjtQsGVkzTGLXVKTFDdGv7usRbbJJmw-3l3-l98vOYD72QCH-OsifZvMyLP3Sb7MP6fPSR6n8bsleUE-ZPNPxOKmNlo2q_V-Zc2vlZfrBsmXj3EWk_YHeUMYUNBG4Uxu0QH_BgxKCq01FTpn7LF1GA4kagc8pFDrtvPHdkmhMhaBH8DXvkHgsDxuz1AqtEEIFBR6WTfD2qsgorX1Vto9UMhbqR0nQQFFsXsdFhCwyXkRPCVSK8KI8d_RAoV55zkRjIqIiikVL6l4BWVPwXT-BOi83CBw1tPHJNijEuKPgBjh7wSObgKfODttrEKL6oKx7K8ozczEtEF0KZPW29oTdpMhvOfRMnSt0Q7_Yrm1uaSAaoOjkDOdrXBhTTVcM5bzITc0FDo_TqOxSPQwGn71PMz-Jxz9Mzy9CId92T_5HQAA__-b4SGh +Diagram: https://cockroachdb.github.io/distsqlplan/decode.html#eJykkVFr2zAUhd_3K8R92oaCLWeDIRh4bB4zeElmB1aoTVCsS2rqSK4k04Tg_15iF9KUpJD08Z6rc_QdaQf2oQYO0c0s-RFPyMdfcTbP_iWfSBYl0c85-Ux-p9O_xOCq0krUi-V2YfTjwolljeT_nyiNSHNPvhMGFJSWOBFrtMBvgUFBoTG6RGu12Uu7_kAsN8B9CpVqWreXCwqlNgh8B65yNQKH-T49RSHReD5QkOhEVfexJ0HCxlRrYbZAIWuEspx4OeT55pufg8c8f0SEkoQR7e7QAIVp6zgJGQ0DGo5p-IWGX6HoKOjWHaCsEysEzjp6HTi7Fjx8hr4QNDgLeuBrlTYSDcojtqI7UWWiR7rxguMSSbWuHGFnGfxLHitF22hl8RXLueSCAsoVDoWsbk2JM6PL_pphnPa-XpBo3bANhiFW_ar_zZdm9h5z8KZ5fGT2u6L78BQAAP__zHAczQ== statement ok SET tracing = on,kv,results; SELECT * FROM regional_by_row_table WHERE pk = 1; SET tracing = off @@ -685,7 +685,7 @@ SELECT message FROM [SHOW KV TRACE FOR SESSION] WITH ORDINALITY OR message LIKE 'Scan%' ORDER BY ordinality ASC ---- -Scan /Table/73/1/"@"/1{-/#} +Scan /Table/73/1/"@"/1/0 fetched: /regional_by_row_table/primary/'ap-southeast-2'/1/pk2/a/b/j -> /1/2/3/'{"a": "b"}' output row: [1 1 2 3 '{"a": "b"}'] @@ -700,8 +700,8 @@ SELECT message FROM [SHOW KV TRACE FOR SESSION] WITH ORDINALITY OR message LIKE 'Scan%' ORDER BY ordinality ASC ---- -Scan /Table/73/1/"@"/10{-/#} -Scan /Table/73/1/"\x80"/10{-/#}, /Table/73/1/"\xc0"/10{-/#} +Scan /Table/73/1/"@"/10/0 +Scan /Table/73/1/"\x80"/10/0, /Table/73/1/"\xc0"/10/0 fetched: /regional_by_row_table/primary/'ca-central-1'/10/pk2/a/b -> /10/11/12 output row: [10 10 11 12 NULL] diff --git a/pkg/kv/kvclient/kvcoord/dist_sender.go b/pkg/kv/kvclient/kvcoord/dist_sender.go index 7c28222f955a..091331c73809 100644 --- a/pkg/kv/kvclient/kvcoord/dist_sender.go +++ b/pkg/kv/kvclient/kvcoord/dist_sender.go @@ -613,7 +613,7 @@ func (ds *DistSender) initAndVerifyBatch( case *roachpb.ReverseScanRequest: // Accepted reverse range requests. - case *roachpb.QueryIntentRequest, *roachpb.EndTxnRequest: + case *roachpb.QueryIntentRequest, *roachpb.EndTxnRequest, *roachpb.GetRequest: // Accepted point requests that can be in batches with limit. default: diff --git a/pkg/sql/as_of_test.go b/pkg/sql/as_of_test.go index 0941401ba4bc..e87c95cd3742 100644 --- a/pkg/sql/as_of_test.go +++ b/pkg/sql/as_of_test.go @@ -311,7 +311,7 @@ func TestAsOfRetry(t *testing.T) { defer magicVals.Unlock() switch req := args.Req.(type) { - case *roachpb.ScanRequest: + case *roachpb.GetRequest: if kv.TestingIsRangeLookupRequest(req) { return nil } diff --git a/pkg/sql/distsql_physical_planner.go b/pkg/sql/distsql_physical_planner.go index 40ab3d9137bd..4bdf6b1d8eb7 100644 --- a/pkg/sql/distsql_physical_planner.go +++ b/pkg/sql/distsql_physical_planner.go @@ -907,7 +907,21 @@ func (dsp *DistSQLPlanner) PartitionSpans( // nodeMap maps a nodeID to an index inside the partitions array. nodeMap := make(map[roachpb.NodeID]int) it := planCtx.spanIter - for _, span := range spans { + for i := range spans { + + span := spans[i] + if len(span.EndKey) == 0 { + // If we see a span to partition that has no end key, it means that we're + // going to do a point lookup on the start key of this span. + // + // The code below us doesn't really tolerate spans without an EndKey, so + // we manufacture a single-key span for this case. + span = roachpb.Span{ + Key: span.Key, + EndKey: span.Key.Next(), + } + } + // rSpan is the span we are currently partitioning. rSpan, err := keys.SpanAddr(span) if err != nil { diff --git a/pkg/sql/logictest/testdata/logic_test/explain_analyze_plans b/pkg/sql/logictest/testdata/logic_test/explain_analyze_plans index 8bae08f9e2f0..364465e875d1 100644 --- a/pkg/sql/logictest/testdata/logic_test/explain_analyze_plans +++ b/pkg/sql/logictest/testdata/logic_test/explain_analyze_plans @@ -262,7 +262,7 @@ network usage: table: kv@primary spans: [/0 - /0] · -Diagram: https://cockroachdb.github.io/distsqlplan/decode.html#eJyMkMFK80AUhff_U1zOv52fJNuBH4oSsVStpKUuJItpcqkh6UycmVRLyWP5Aj6ZZEYUEcHl-c6953LuCe6xg8Qqv8rP19TSRbG8pvZAd5d5kVNL_ymFgDY136g9O8h7ZCgFemsqds7YCZ3CwLx-hkwFGt0PfsKlQGUsQ57gG98xJNZq23HBqmabTME1e9V0IbY9zHrb7JU9QmDVK-0kJem_JE3-QmA5eEmzDAKLDflmz5LS1xcXdWW0Z-0bo79Z1jw5sqxqGYosNrQ9ev5AdAaBrfLVAzsyg--nM9Ng2PsE5SgQ1Xsx59WOIbNR_L58wa432vGX3j8lp2MpwPWO44OdGWzFt9ZU4UyUy7AXQM3ORzeLYq6jNZbjn7cAAAD__0UFm94= +Diagram: https://cockroachdb.github.io/distsqlplan/decode.html#eJyMkFFLwzAUhd_9FZfzHGn7GhCGUnFsbtLN-SB9yNrLLO2SmqTTMfqz_AP-MmkjiojgS-B8J_dczj3BPTeQWKXz9GpNNV1ny1uqD_Rwk2Yp1XRBMQS0KXmh9uwgH5EgF2itKdg5Ywd0Gj9My1fIWKDSbecHnAsUxjLkCb7yDUNirbYNZ6xKttEQXLJXVTPG1odJa6u9skcIrFqlnaQojuLz4YkW9_M5BJadlzRJIDDbkK_2LCl-f3NBF0Z71r4y-pdlzYsjy6qUY5_ZhrZHz1-ILiGwVb54Ykem8-2wZvg4zn2DvBcI6rOf82rHkEkv_n-DjF1rtOMf9f9KjvtcgMsdhzs709mC76wpxjVBLse5EZTsfHCTIKY6WH3en30EAAD___6pnbQ= # Test a query that has a subquery and a postquery. statement ok diff --git a/pkg/sql/logictest/testdata/logic_test/inverted_filter_json_array_dist b/pkg/sql/logictest/testdata/logic_test/inverted_filter_json_array_dist index 47ddc75e5cd2..0fdaa809f51c 100644 --- a/pkg/sql/logictest/testdata/logic_test/inverted_filter_json_array_dist +++ b/pkg/sql/logictest/testdata/logic_test/inverted_filter_json_array_dist @@ -313,7 +313,7 @@ vectorized: true table: json_tab@primary spans: [/44 - /44] · -Diagram: https://cockroachdb.github.io/distsqlplan/decode.html#eJy8lF9v2jwUxu_fT2Gd96Kt5ipxEqCNNIluzTQmBiwgbVMXTYZ4bSYaZ7aZWiG--5SE8bfYobDeOXF-5zz2eZ5MQf4agw_Bl177qtVBp9et_qD_qX2G-kE7eDtAFL0Lux_RT8nT74oO0ef3QRig0yFqfpvYtsvQyQ2JTs5QN0SnFL1Gnpevr4MQvfmKKGBIecw69J5J8G-AAAYHMLgQYcgEHzEpuci3psWHrfgBfBtDkmYTlb-OMIy4YOBPQSVqzMCHAR2OWchozIRlA4aYKZqMi_J_VTYzkdxT8QgY-hlNpY8szzu3PM_6HzB0J8pHTYKbDkQzDHyils2korcMfDLD1QX1uVBMWI11LU3yamd5b5_y14lUSTpSFrE3O-SHETETLM4PtNFuWWH4iO6ovNuio9lSUm2npGUdXvZ66pxa3a5B92IkOy-sfnR1HX7OM4t4a5_vat9Ya0-q-5Ps8GexSNLfKwYltnUlhEXOFyurJ9iP5CFI4wo35Owj8QNP0rlC15igCnFx92k-j0vtuXExlF_Y7uLF0kKOmhZy5LQ41e3qVLers7Crc7hdDRJX7Ood366G5nO71p9rV0P5xdwvX8yuzlHt6vzDn_sTjUMmM55KVum_befSWXzLyqNKPhEj1hN8VLQpH7sFV7yImVTlLikfWmm5lQtchYkWdvSwswmTVfhyDSb7wcQ7hHb1sKs9tKGzp7_umv7Kalq6rofrWrihhxta-EIPXxwyaT1smrSeNkz68pBJE0OyTNHSZ4sYwkW2LL6OuwZ8y-T7jMxAm2ZmwA1DI_qIbfaOZv_9CQAA___7R4gK +Diagram: https://cockroachdb.github.io/distsqlplan/decode.html#eJy8lF9v2jwUxu_fT2Gdm7Z6XSVOArSRJtGtmcbEgAWmbeqiyRCvzUTjzDZTK8R3n5Iw_hY7FNYbZOL8znns8zyZgvw1Bh-CL732VauDTq9b_UH_Y_sM9YN28GaAKHobdj-gn5Kn3xUdos_vgjBAp0PU_DaxbZehkxsSnZyhbohOKXqFPC9fXwchev0VUcCQ8ph16D2T4N8AAQwOYHAhwpAJPmJScpFvTYsXW_ED-DaGJM0mKn8cYRhxwcCfgkrUmIEPAzocs5DRmAnLBgwxUzQZF-X_qmxmIrmn4hEw9DOaSh9ZnmfZ58Wv1fnUbgOG7kT5qElw04FohoFP1LKnVPSWgU9muLquPheKCauxLqlJ_t9Z3tun_HUiVZKOlEXszQ75YUTMBIvzA220W1YYPqI7Ku-26Gi2lFTbKWlZh5e9njqnVrdr0L0Yyc4Lqx9dXYef88wi3trru9o31tqT6jYlO2xaLJL094pPiW1dCWGR88XK6gn2I3kI0rjCDTn7SHzPk3Su0DUGqUJc3H2az-NSe25cDOUXtrt4sbSQo6aFHDktTnW7OtXt6izs6hxuV4PEFbt6x7erofncrvXn2tVQfjH3yxezq3NUuzr_8OP-ROOQyYynklX6btu5dBbfsvKokk_EiPUEHxVtyr_dgisexEyqcpeUf1ppuZULXIWJFnb0sLMJk1X4cg0m-8HEO4R29bCrPbShs6e_7pr-ympauq6H61q4oYcbWvhCD18cMmk9bJq0njZM-vKQSRNDskzR0meLGMJFtiy-jrsGfMvk-4zMQJtmZsANQyP6iG32jmb__QkAAP__5vuJ4A== # We cannot use the index for this query. query T @@ -431,7 +431,7 @@ vectorized: true table: array_tab@primary spans: [/1 - /1] · -Diagram: https://cockroachdb.github.io/distsqlplan/decode.html#eJy0k19r2zAUxd_3KcTdQ1umYEv5O8Mg2-KxjCzp7MA2NlMU-1IMqeVJ8lgJ-e7DdmnqUKtOx16MpavfPUc63B3oX1vwwP92uXg7X5Lz2Txch18WFyT0F_77NRHkQ7D6TIRS4vbKiA35-tEPfHK-IdOfhev2kZzt2P7sgqwCci7IG8LK35kfkHffiQAKmUxwKW5Qg_cDGFDgQKEPEYVcyRi1lqos7aqD8-QPeC6FNMsLU2-b1GwRPCgyqRJUmACFBI1It2U92kcUYqkQvMPRpezJ3BkdHaQgC3PXNqKgjbhG8AZ72iL9SONQKoPKGTc6w5S9grb2w1Paz1Jt0iw2zuRYACis6tt7pF4Vpvpr0x01dJlddy02WwxQJKgc1pS-z30qlLpKs99AIcxFpj3iMNdhvfLLOxjipxj6JNPszk-_zU-u0huhbg_SdMpb1fsNdd79Odyn5e-fo-cw52U3P-y5fnj3eHgVD39OPE8YehDP4D_HcxB9bPoBLPM_7DT_7ikDGqDOZaaxY-eIAibXWN9Dy0LFeKlkXMnUy1XFVRsJalNXWb2YZ3WpNPgQZlaY22FuhV_b4b4VHtjhgRV2GzA7hodWeGKHR1Z4bLc9_hflyUl3jvYv_gYAAP__5A1x4g== +Diagram: https://cockroachdb.github.io/distsqlplan/decode.html#eJy0lF9r2zAUxd_3KcR9acsUbCl_ZxhkWzyWkSWdnbGNzRTFvhRDanmSPFZCvvuwXZo61KrTsRcj6ep3z5EO1g70ry144H-7XLyZL8n5bB6uw8-LCxL6C__dmgjyPlh9IkIpcXtlxIZ8_eAHPjnfkOnPwnX7SM52bH92QVYBORfkNWHlcOYH5O13IoBCJhNcihvU4P0ABhQ4UOhDRCFXMkatpSpLu2rjPPkDnkshzfLC1MsmNVsED4pMqgQVJkAhQSPSbVmP9hGFWCoE77B1KXsyd0ZHGynIwty1jShoI64RvMGetkg_0jiUyqByxo3OMGUvoa398JT2s1SbNIuNMzkWAAqr-vQeqWeFqUZtuqOGLrPrrsVmiwGKBJXDmtL3uU-FUldp9hsohLnItEcc5jqsV355B0P8FEMfZZrd-em3-clVeiPU7UGaTnmrer-hzrtfh_u0_P11OG6v_DjLL4tFN1vsubZ495R4lRJ_TkpPGHqQ0uA_p3QQfewRALA8A8NOz4B7yn8aoM5lprFj54gCJtdYn0PLQsV4qWRcydTTVcVVCwlqU1dZPZlndak0-BBmVpjbYW6FX9nhvhUe2OGBFXYbMDuGh1Z4YodHVnhstz3-F-XJSWeO9i_-BgAA____53O4 # The split disjunction rule allows us to use the index for this query. query T @@ -467,7 +467,7 @@ vectorized: true table: array_tab@primary spans: [/1 - /1] · -Diagram: https://cockroachdb.github.io/distsqlplan/decode.html#eJzMVGFv2jAQ_b5fYd0-tNVSJedAaSNNYltTjakrHVTapoEqQ05tJGpntqlaVfz3KQRBU8AB1E37grDP7967u5d7AvN7BBHEPy7PP7Qu2P5pq3vV_XZ-wLrxefzpigl21ml_ZUJr8XhtxYB9_xx3Yra_P2DN3jgIQmJ7TzjZO2DtDitd8sneQXEr2HuG-d_TuMM-_mQCPJAqoQtxRwaiX4DgAQcPQuh7kGk1JGOUzkNP04et5AGiwINUZmNbXNvUjggiGEulE9KUgAcJWZGO8nh_0vdgqDRBtHh6mhqbyqH166W30Mzp22MbsSZCf-KBGtsZT98DY8UNQVSbeGu0rGD6olLZIZGQ9o_KXPM-NjOd3gn9uKD2mnwte30b9q7SlrTfeFnlu7Xpj7ZJP2_jyao2FsNY0cpFgsEjuxXmdgk9HdpMUWOtokWeVYOflemSjVihu9oMx6-u7kIdqszH8IWLV9OflOjRPa4rMRjRzIy4zoxC6-tU3oMH3UxIEzEfAx8P899wM4fybTS15D1pS8lZOrKkSfvluufx-CHTTEnWxIiZXBgzVmgb9aDX44g9YCST2SnsAVurLiyp45t3LKj-fOcdO_TRf7tZt3BXPXzzCfLpBPmOE6zQtDTB2v80wdkGPN51A1akX6yS4J-tQP6qK5D_xRW4grhDJlPS0EbbLcilU3JDRalGjfWQLrUaTmmKY3uKm14kZGwRxeLQkkUoF_gcjE4wd4O5Exy6weFLMD4H10pg3A6MoRtdc-quu8F1d7tr7qqPnOiGG9xwggO37mO37gqfnLjRQYXL3B6tUI5uk2KFS3HJpts4rQJdZTVccqrTa_3Jmz8BAAD__zm3B-Y= +Diagram: https://cockroachdb.github.io/distsqlplan/decode.html#eJzMVGFv2jAQ_b5fYd2Xtlqq5BwobaRJbGuqMTHooNM2DVQZcmoj0TizTdWq4r9PIQiaQhxA3bQvEfb53Xt397gn0L8nEED447L9vtVhh-et_lX_a_uI9cN2-PGKCXbR635hQinxeG3EiH3_FPZCdng4Ys3B1PN8YgdPODs4Yt0eK1zy2cFRfivYO4bZz_Owxz78ZAIcSGREHXFHGoJfgOAABwd8GDqQKjkmraXKQk_zh63oAQLPgThJpya_NrGZEAQwTaSKSFEEDkRkRDzJ4sPZ0IGxVATB6ul5rE2cjI1bL7yFZkbfnZqANRGGMwfk1Cx4hg5oI24IgtrMKdGygemzjJMeiYiUe1LkWvaxmar4TqjHFbXT5KXs9V3Y-1IZUm7jZZVvS9Of7JJ-2cazTW3Mh7GhlasEo0d2K_TtGno-tIWiRqmiVZ5Ng1-UaZONWKG72gynr66uI49l6qL_wsWb6c8K9Ggf15UYTWhhRiwzo1DqOk7uwYF-KhIdMBc9F4-zr7-dQ_kumlrJPSlD0UU8MaRIucW6l_HwIVVMJqyJAdOZMKaNUCYYwGDAEQfAKIkWJ38ArFSdX1DHt--YV_33XXbM9Y6zj9v51m5v1zTcVxbffpB8Pki-5yArNK0NsvY_DXKxCE_3XYQV6Vcbxftnm5C_6ibkf3ETbiDukU5lommrJedl0im6obxULadqTJdKjuc0-bE7x80vItImj2J-aCV5KBP4HIxWMLeDuRXs28H-SzA-B9cKYNwNjL4dXbPqrtvBdXu7a_aqT6zohh3csII9u-5Tu-4Kn5zZ0V6Fy-werVCOdpNihUtxzaa7OK0CXWU1XHOq1WvD2Zs_AQAA__8i-Qm8 # We cannot use the index for this query. query T diff --git a/pkg/sql/logictest/testdata/logic_test/merge_join_dist_vec b/pkg/sql/logictest/testdata/logic_test/merge_join_dist_vec index 55dbbdbf3224..2a5b2bd09683 100644 --- a/pkg/sql/logictest/testdata/logic_test/merge_join_dist_vec +++ b/pkg/sql/logictest/testdata/logic_test/merge_join_dist_vec @@ -63,7 +63,7 @@ vectorized: true table: r@primary spans: [/2 - /2] · -Diagram: https://cockroachdb.github.io/distsqlplan/decode.html#eJzEk9GPk0AQxt_9KzbjS6t7gd3iyyaXYJRTLj04gYsmhoe9MrYkHIu7S2LT9H83gEkFe7UXo76xu_P7Zr5vwg7M1woEBJ9ul6_DiMzehmmWfljOSRosgzcZeUGukviGVGQZXGXkOg4josldGkbvyEzOycf3QRIQSS4JBwq1KjCSD2hAfAYGFDjkFBqtVmiM0t31ri8Ki28gXApl3bS2u84prJRGEDuwpa0QBGTyvsIEZYHa6bQKtLKsemntN7p8kHoLFNJG1kYQh1843HkO-Z6Cau0P2YPa_ZZspNmMdXwG-T6nYKxcIwi-p4-Md9Bpa6UL1FiMlPKO_F3JEY83qNd4rcoatbMYz5ZtGxRD6vFdFiR99kChwi925rOX80tdrjfDJ1CIWyuIz6jPqe9NUjg4XPyBwyPjR-pCNY43jeJoa2_Ump2_e3ecS_V3ds8eHe9f7J7_190fGS5B06ja4FmrdTt7WKxxiMuoVq_wVqtV32Y4xj3XJ1ugscOrNxzCun_qf7_zYXYaZlPY_RnmI5hNYX4SfjWC3Sm8eILnXzqfhtlp2HuS53z_7HsAAAD___ZW7z0= +Diagram: https://cockroachdb.github.io/distsqlplan/decode.html#eJzEk1-Pk0AUxd_9FJP71OpsYCi-TLIJRlllw8IKNJoYHmbLtSVhGZwZEpum390AJhXs1jZG96Xp_Pmde8-Zyw70two4-J_vwzdBRGbvgjRLP4Zzkvqh_zYjL8lNEt-RioT-TUZu4yAiiizTIHpPZmJOPn3wE58Ick0coFDLAiPxiBr4F2BAwYGcQqPkCrWWqtve9ZeC4jtwm0JZN63ptnMKK6kQ-A5MaSoEDpl4qDBBUaCyOq0CjSirXlp5jSofhdoChbQRtebEciz7qvuxomUYQr6nIFvzU_0g-rAlG6E3YzmPQb7PKWgj1gjc2dMnujzotLVUBSosRkp5R_7pyhGrd6jWeCvLGpW1GPeWbRvkQ_jxMvOT_gmAQoVfzcxjr-bXqlxvhr9AIW4NJx6jnkM9d5LCweHiLxweaT-SV7Kx3GkUR0u7o9Ls_BGwx7lU_3QE2JNd_o8RcJ51BI40l6BuZK3xrBe2O3tYrHGIS8tWrfBeyVVfZljGPdcnW6A2w6k7LIK6P-q_wvNhdhpmU9j-FXZGMJvCzkn49Qi2p_DiAs-_VT4Ns9Owe5HnfP_iRwAAAP__RCHy6Q== # Test that we can handle merge joins with equality columns of integers with # different widths. diff --git a/pkg/sql/logictest/testdata/logic_test/vectorize_local b/pkg/sql/logictest/testdata/logic_test/vectorize_local index 381903ba5b59..499015ab0ca5 100644 --- a/pkg/sql/logictest/testdata/logic_test/vectorize_local +++ b/pkg/sql/logictest/testdata/logic_test/vectorize_local @@ -199,12 +199,10 @@ SET tracing = on; SELECT * FROM tpar WHERE a = 0 OR a = 10; SET tracing = off # Note that table ID here is hardcoded, so if a new table is created before # tpar, this query will need an adjustment. query T -SELECT message FROM [SHOW TRACE FOR SESSION] WHERE message IN - ('querying next range at /Table/56/1/0', - 'querying next range at /Table/56/1/10') +SELECT message FROM [SHOW TRACE FOR SESSION] WHERE message LIKE 'querying next range at %' ---- -querying next range at /Table/56/1/0 -querying next range at /Table/56/1/10 +querying next range at /Table/56/1/0/0 +querying next range at /Table/56/1/10/0 # Regression test for #46123 (rowexec.TableReader not implementing # execinfra.OpNode interface). diff --git a/pkg/sql/opt/exec/execbuilder/testdata/autocommit_nonmetamorphic b/pkg/sql/opt/exec/execbuilder/testdata/autocommit_nonmetamorphic index 099b5aa839fa..4d735137293b 100644 --- a/pkg/sql/opt/exec/execbuilder/testdata/autocommit_nonmetamorphic +++ b/pkg/sql/opt/exec/execbuilder/testdata/autocommit_nonmetamorphic @@ -668,7 +668,7 @@ WHERE message LIKE '%r$rangeid: sending batch%' ---- dist sender send r37: sending batch 1 DelRng to (n1,s1):1 dist sender send r37: sending batch 2 CPut to (n1,s1):1 -dist sender send r37: sending batch 2 Scan to (n1,s1):1 +dist sender send r37: sending batch 2 Get to (n1,s1):1 dist sender send r37: sending batch 1 EndTxn to (n1,s1):1 query B @@ -717,7 +717,7 @@ WHERE message LIKE '%r$rangeid: sending batch%' AND operation NOT LIKE '%async%' ---- dist sender send r37: sending batch 1 DelRng to (n1,s1):1 -dist sender send r37: sending batch 1 Scan to (n1,s1):1 +dist sender send r37: sending batch 1 Get to (n1,s1):1 dist sender send r37: sending batch 1 Del to (n1,s1):1 dist sender send r37: sending batch 1 Scan to (n1,s1):1 dist sender send r37: sending batch 1 EndTxn to (n1,s1):1 diff --git a/pkg/sql/opt/exec/execbuilder/testdata/distsql_merge_join b/pkg/sql/opt/exec/execbuilder/testdata/distsql_merge_join index 76c8a685b9d9..2c63fd59d375 100644 --- a/pkg/sql/opt/exec/execbuilder/testdata/distsql_merge_join +++ b/pkg/sql/opt/exec/execbuilder/testdata/distsql_merge_join @@ -456,7 +456,7 @@ vectorized: true │ ordering: +pid1 │ estimated row count: 4 (missing stats) │ table: parent1@primary - │ spans: /1-/1/# /11-/11/# /21-/21/# /31-/31/# + │ spans: /1/0- /11/0- /21/0- /31/0- │ parallel │ └── • scan @@ -486,7 +486,7 @@ vectorized: true table: child2@primary spans: [/1 - /1] [/11 - /11] [/21 - /21] [/31 - /31] · -Diagram: https://cockroachdb.github.io/distsqlplan/decode.html#eJycklFv0zAQx9_5FKfbSwtGqV22h0hIARYgU9eMpAgQyoOJjzZSZgfbkUBVvzuKM2lk6oDt7Xx3_7vf_-Q9uh8txph-vlq9ytYwO8_KTflhNYcyXaVvNvAU3hb5JXTSkvYcLvJsDfWuaZWAj2W2fgezrlF8Dp_ep0UKQwzDGM6AcwaCM1jyOeTFeVrA6y-hARlqo2gtr8lh_BU5Vgw7a2pyztghtQ8NmfqJ8YJho7veD-mKYW0sYbxH3_iWMMaN_NZSQVKRjRbIUJGXTRvG3iAnnW2upf2FDMtOahdDxJ9HPDoBqRUswfgdWYfVgaHp_e0m5-WWMOYH9jgaPqUZb3YMJjqJTs9umIZI_B-YuBfslqfXxiqypCYs1aD8V8sRd5dkt3RhGk02ElN3LX33s4Q_m7-0zXY3hsgw730MCWeJYMkLlpyy5OxeP8uHHLog1xnt6K6vo5MXgxlSWxqP40xva7qypg5rxmcedCGhyPmxKsZHpkMp_IQ_xfwBYnFXLP4qXk7Ei0N1ePI7AAD__9aLKbQ= +Diagram: https://cockroachdb.github.io/distsqlplan/decode.html#eJycklFvlEAQx9_9FJPx5U63gd2zfSAxQS0qDYUK16gxPKzseEdCd3F3STSX--4G0NRrrmp9IbMz85_5_Sfs0H3tMMLkw1X2Is1hcZ5W6-pdtoQqyZJXa3gCr8viEnppSXsOF0WaQ7NtOyXgukrzN7DoW8WX8P5tUiYwxjCO4Qw4ZyA4gxVfQlGeJyW8_Dg1IENtFOXyhhxGn5BjzbC3piHnjB1Tu6khVd8wChm2uh_8mK4ZNsYSRjv0re8II1zLzx2VJBXZIESGirxsu2nsT-S4t-2NtN-RYdVL7SIIeBCejJ8gv84ykFrBCozfknVY7xmawd8udF5uCCO-Z_8HxQ-h5tMdZXocnJ4F_ORXJP4NTNwLdsszaGMVWVIHLPWo_FvLEXeXZDd0YVpNNhCH7jr64hcxf7p8btvNdg6RYTH4CGLOYsHiZyw-ZfHZvX5WDzl0Sa432tFdX0cnh6MZUhuaj-PMYBu6sqaZ1szPYtJNCUXOz1UxP1I9laY_4Xcxf4BY3BWLP4pXB-JwX-8f_QgAAP__02Qrig== # Parent-grandchild. # We add the pa1 > 0 condition so a lookup join is not considered to be a better plan. diff --git a/pkg/sql/opt/exec/execbuilder/testdata/distsql_tighten_spans b/pkg/sql/opt/exec/execbuilder/testdata/distsql_tighten_spans index 884664cff37f..0b5439105b15 100644 --- a/pkg/sql/opt/exec/execbuilder/testdata/distsql_tighten_spans +++ b/pkg/sql/opt/exec/execbuilder/testdata/distsql_tighten_spans @@ -250,7 +250,7 @@ SELECT info FROM [EXPLAIN (VERBOSE) SELECT * FROM p2@p2_id WHERE i >= 1 AND d IS query T SELECT info FROM [EXPLAIN (VERBOSE) SELECT * FROM bytes_t WHERE a = 'a'] WHERE info LIKE '%spans%' ---- - spans: /"a"-/"a"/# + spans: /"a"/0- # No tightening. @@ -262,7 +262,7 @@ SELECT info FROM [EXPLAIN (VERBOSE) SELECT * FROM bytes_t WHERE a < 'aa'] WHERE query T SELECT info FROM [EXPLAIN (VERBOSE) SELECT * FROM decimal_t WHERE a = 1.00] WHERE info LIKE '%spans%' ---- - spans: /1-/1/# + spans: /1/0- # No tightening. diff --git a/pkg/sql/opt/exec/execbuilder/testdata/interleaved b/pkg/sql/opt/exec/execbuilder/testdata/interleaved index 1fe5e52766c2..d328ee28a2e1 100644 --- a/pkg/sql/opt/exec/execbuilder/testdata/interleaved +++ b/pkg/sql/opt/exec/execbuilder/testdata/interleaved @@ -77,7 +77,7 @@ SELECT info FROM [ EXPLAIN (VERBOSE) SELECT * FROM level4 WHERE k1 = 2 AND k2 = 20 AND k3 = 200 ] WHERE info LIKE '%spans%' ---- - spans: /2/#/54/1/#/55/1/20/200/#/56/1-/2/#/54/1/#/55/1/20/200/#/56/1/# + spans: /2/#/54/1/#/55/1/20/200/#/56/1/0- # ------------------------------------------------------------------------------ # Trace of interleaved fetches from interesting interleaved hierarchy. diff --git a/pkg/sql/opt/exec/execbuilder/testdata/inverted_index b/pkg/sql/opt/exec/execbuilder/testdata/inverted_index index 6d560e310ed2..93721324c190 100644 --- a/pkg/sql/opt/exec/execbuilder/testdata/inverted_index +++ b/pkg/sql/opt/exec/execbuilder/testdata/inverted_index @@ -46,7 +46,7 @@ InitPut /Table/53/2/Arr/7/1/0 -> /BYTES/ query T kvtrace DELETE FROM d WHERE a=1 ---- -Scan /Table/53/1/1{-/#} +Scan /Table/53/1/1/0 Del /Table/53/2/Arr/0/1/0 Del /Table/53/2/Arr/7/1/0 Del /Table/53/1/1/0 @@ -77,7 +77,7 @@ CPut /Table/53/1/4/0 -> /TUPLE/ query T kvtrace UPDATE d SET b='[1]' WHERE a=4 ---- -Scan /Table/53/1/4{-/#} +Scan /Table/53/1/4/0 Put /Table/53/1/4/0 -> /TUPLE/ InitPut /Table/53/2/Arr/1/4/0 -> /BYTES/ @@ -85,7 +85,7 @@ InitPut /Table/53/2/Arr/1/4/0 -> /BYTES/ query T kvtrace UPDATE d SET b=NULL WHERE a=4 ---- -Scan /Table/53/1/4{-/#} +Scan /Table/53/1/4/0 Put /Table/53/1/4/0 -> /TUPLE/ Del /Table/53/2/Arr/1/4/0 @@ -93,7 +93,7 @@ Del /Table/53/2/Arr/1/4/0 query T kvtrace DELETE FROM d WHERE a=4 ---- -Scan /Table/53/1/4{-/#} +Scan /Table/53/1/4/0 Del /Table/53/1/4/0 # Tests for array inverted indexes. @@ -160,7 +160,7 @@ CPut /Table/55/1/2/0 -> /TUPLE/ query T kvtrace UPDATE f SET b = ARRAY[0,15,7,10] WHERE a = 0 ---- -Scan /Table/55/1/0{-/#} +Scan /Table/55/1/0/0 Put /Table/55/1/0/0 -> /TUPLE/ Del /Table/55/2/1/0/0 InitPut /Table/55/2/15/0/0 -> /BYTES/ diff --git a/pkg/sql/opt/exec/execbuilder/testdata/inverted_index_multi_column b/pkg/sql/opt/exec/execbuilder/testdata/inverted_index_multi_column index 6d39c81be4c6..27bd1c3683ee 100644 --- a/pkg/sql/opt/exec/execbuilder/testdata/inverted_index_multi_column +++ b/pkg/sql/opt/exec/execbuilder/testdata/inverted_index_multi_column @@ -39,7 +39,7 @@ query T kvtrace SELECT * FROM t WHERE i = 333 AND j @> '{"a": "b"}' ---- Scan /Table/53/2/333/"a"/"b"{-/PrefixEnd} -Scan /Table/53/1/1{-/#} +Scan /Table/53/1/1/0 # Don't insert duplicate values. query T kvtrace @@ -64,7 +64,7 @@ InitPut /Table/53/3/333/"foo"/Arr/"a"/"b"/3/0 -> /BYTES/ query T kvtrace DELETE FROM t WHERE k = 2 ---- -Scan /Table/53/1/2{-/#} +Scan /Table/53/1/2/0 Del /Table/53/2/333/Arr/0/2/0 Del /Table/53/2/333/Arr/7/2/0 Del /Table/53/3/333/"foo"/Arr/0/2/0 @@ -74,7 +74,7 @@ Del /Table/53/1/2/0 query T kvtrace DELETE FROM t WHERE k = 3 ---- -Scan /Table/53/1/3{-/#} +Scan /Table/53/1/3/0 Del /Table/53/2/333/Arr/3/3/0 Del /Table/53/2/333/Arr/"a"/"b"/3/0 Del /Table/53/3/333/"foo"/Arr/3/3/0 @@ -91,7 +91,7 @@ CPut /Table/53/1/4/0 -> /TUPLE/2:2:Int/333/1:3:Bytes/foo query T kvtrace UPDATE t SET j = '[1]' WHERE k = 4 ---- -Scan /Table/53/1/4{-/#} +Scan /Table/53/1/4/0 Put /Table/53/1/4/0 -> /TUPLE/2:2:Int/333/1:3:Bytes/foo/ InitPut /Table/53/2/333/Arr/1/4/0 -> /BYTES/ InitPut /Table/53/3/333/"foo"/Arr/1/4/0 -> /BYTES/ @@ -100,7 +100,7 @@ InitPut /Table/53/3/333/"foo"/Arr/1/4/0 -> /BYTES/ query T kvtrace UPDATE t SET j = NULL WHERE k = 4 ---- -Scan /Table/53/1/4{-/#} +Scan /Table/53/1/4/0 Put /Table/53/1/4/0 -> /TUPLE/2:2:Int/333/1:3:Bytes/foo Del /Table/53/2/333/Arr/1/4/0 Del /Table/53/3/333/"foo"/Arr/1/4/0 @@ -109,7 +109,7 @@ Del /Table/53/3/333/"foo"/Arr/1/4/0 query T kvtrace DELETE FROM t WHERE k = 4 ---- -Scan /Table/53/1/4{-/#} +Scan /Table/53/1/4/0 Del /Table/53/1/4/0 # Insert NULL non-inverted value. @@ -124,7 +124,7 @@ InitPut /Table/53/3/NULL/"foo"/"a"/"b"/5/0 -> /BYTES/ query T kvtrace UPDATE t SET i = 333 WHERE k = 5 ---- -Scan /Table/53/1/5{-/#} +Scan /Table/53/1/5/0 Put /Table/53/1/5/0 -> /TUPLE/2:2:Int/333/1:3:Bytes/foo/ Del /Table/53/2/NULL/"a"/"b"/5/0 InitPut /Table/53/2/333/"a"/"b"/5/0 -> /BYTES/ @@ -135,7 +135,7 @@ InitPut /Table/53/3/333/"foo"/"a"/"b"/5/0 -> /BYTES/ query T kvtrace UPDATE t SET i = NULL WHERE k = 5 ---- -Scan /Table/53/1/5{-/#} +Scan /Table/53/1/5/0 Put /Table/53/1/5/0 -> /TUPLE/3:3:Bytes/foo/ Del /Table/53/2/333/"a"/"b"/5/0 InitPut /Table/53/2/NULL/"a"/"b"/5/0 -> /BYTES/ @@ -146,7 +146,7 @@ InitPut /Table/53/3/NULL/"foo"/"a"/"b"/5/0 -> /BYTES/ query T kvtrace DELETE FROM t WHERE k = 5 ---- -Scan /Table/53/1/5{-/#} +Scan /Table/53/1/5/0 Del /Table/53/2/NULL/"a"/"b"/5/0 Del /Table/53/3/NULL/"foo"/"a"/"b"/5/0 Del /Table/53/1/5/0 diff --git a/pkg/sql/opt/exec/execbuilder/testdata/join b/pkg/sql/opt/exec/execbuilder/testdata/join index fec0e4188d83..bfc0c8cf3ad4 100644 --- a/pkg/sql/opt/exec/execbuilder/testdata/join +++ b/pkg/sql/opt/exec/execbuilder/testdata/join @@ -1636,13 +1636,13 @@ vectorized: true │ columns: (a, b1) │ estimated row count: 1 (missing stats) │ table: l@primary - │ spans: /3-/3/# + │ spans: /3/0- │ └── • scan columns: (a, b2) estimated row count: 1 (missing stats) table: r@primary - spans: /3-/3/# + spans: /3/0- query T EXPLAIN (VERBOSE) SELECT * FROM l LEFT OUTER JOIN r ON l.a = r.a WHERE l.a = 3; @@ -1662,13 +1662,13 @@ vectorized: true │ columns: (a, b1) │ estimated row count: 1 (missing stats) │ table: l@primary -│ spans: /3-/3/# +│ spans: /3/0- │ └── • scan columns: (a, b2) estimated row count: 1 (missing stats) table: r@primary - spans: /3-/3/# + spans: /3/0- query T EXPLAIN (VERBOSE) SELECT * FROM l RIGHT OUTER JOIN r USING(a) WHERE a = 3; @@ -1692,13 +1692,13 @@ vectorized: true │ columns: (a, b2) │ estimated row count: 1 (missing stats) │ table: r@primary - │ spans: /3-/3/# + │ spans: /3/0- │ └── • scan columns: (a, b1) estimated row count: 1 (missing stats) table: l@primary - spans: /3-/3/# + spans: /3/0- query T EXPLAIN (VERBOSE) SELECT * FROM l RIGHT OUTER JOIN r ON l.a = r.a WHERE r.a = 3; @@ -1718,13 +1718,13 @@ vectorized: true │ columns: (a, b2) │ estimated row count: 1 (missing stats) │ table: r@primary -│ spans: /3-/3/# +│ spans: /3/0- │ └── • scan columns: (a, b1) estimated row count: 1 (missing stats) table: l@primary - spans: /3-/3/# + spans: /3/0- # Regression tests for #21243 statement ok diff --git a/pkg/sql/opt/exec/execbuilder/testdata/join_order b/pkg/sql/opt/exec/execbuilder/testdata/join_order index 58e4d71f676b..6d0c93f175ca 100644 --- a/pkg/sql/opt/exec/execbuilder/testdata/join_order +++ b/pkg/sql/opt/exec/execbuilder/testdata/join_order @@ -60,7 +60,7 @@ vectorized: true columns: (a, b, c, d) estimated row count: 1 (missing stats) table: abc@primary - spans: /1-/1/# + spans: /1/0- statement ok SET reorder_joins_limit = 3 @@ -89,4 +89,4 @@ vectorized: true columns: (a, b, c, d) estimated row count: 1 (missing stats) table: abc@primary - spans: /1-/1/# + spans: /1/0- diff --git a/pkg/sql/opt/exec/execbuilder/testdata/lookup_join_nonmetamorphic b/pkg/sql/opt/exec/execbuilder/testdata/lookup_join_nonmetamorphic index f293a151cf1c..aa89ee873a80 100644 --- a/pkg/sql/opt/exec/execbuilder/testdata/lookup_join_nonmetamorphic +++ b/pkg/sql/opt/exec/execbuilder/testdata/lookup_join_nonmetamorphic @@ -76,7 +76,7 @@ query T kvtrace(Scan) SELECT family_split_2.x, family_split_2.z FROM family_split_1 INNER LOOKUP JOIN family_split_2 ON family_split_1.x = family_split_2.x; SET tracing = off ---- Scan /Table/55/{1-2} -Scan /Table/56/1/1/{0-1}, /Table/56/1/1/2/{1-2} +Scan /Table/56/1/1/0, /Table/56/1/1/2/1 statement ok CREATE TABLE family_index_join (x INT PRIMARY KEY, y INT, z INT, w INT, INDEX (y), FAMILY f1 (x), FAMILY f2 (y), FAMILY f3 (z), FAMILY f4(w)) @@ -88,7 +88,7 @@ query T kvtrace(Scan) SELECT y,w FROM family_index_join@family_index_join_y_idx WHERE y = 2 ---- Scan /Table/57/2/{2-3} -Scan /Table/57/1/1/{0-1/2}, /Table/57/1/1/3/{1-2} +Scan /Table/57/1/1/{0-1/2}, /Table/57/1/1/3/1 # Test generating tighter spans on interleaved tables. statement ok @@ -107,4 +107,4 @@ query T kvtrace(Scan) SELECT family_interleave_1.x, family_interleave_1.z FROM family_interleave_2 INNER LOOKUP JOIN family_interleave_1 ON family_interleave_1.x = family_interleave_2.x ---- Scan /Table/58/{1-2} -Scan /Table/58/1/1/{0-1}, /Table/58/1/1/2/{1-2} +Scan /Table/58/1/1/0, /Table/58/1/1/2/1 diff --git a/pkg/sql/opt/exec/execbuilder/testdata/orderby b/pkg/sql/opt/exec/execbuilder/testdata/orderby index 5f3334d35958..13b20e59f144 100644 --- a/pkg/sql/opt/exec/execbuilder/testdata/orderby +++ b/pkg/sql/opt/exec/execbuilder/testdata/orderby @@ -755,7 +755,7 @@ vectorized: true columns: (a, b) estimated row count: 1 (missing stats) table: t@primary - spans: /3-/3/# + spans: /3/0- query T EXPLAIN (VERBOSE) UPDATE t SET c = TRUE RETURNING b diff --git a/pkg/sql/opt/exec/execbuilder/testdata/partial_index_nonmetamorphic b/pkg/sql/opt/exec/execbuilder/testdata/partial_index_nonmetamorphic index e45575fce18a..9e1c4e1079dd 100644 --- a/pkg/sql/opt/exec/execbuilder/testdata/partial_index_nonmetamorphic +++ b/pkg/sql/opt/exec/execbuilder/testdata/partial_index_nonmetamorphic @@ -88,7 +88,7 @@ InitPut /Table/54/2/3/2/0 -> /BYTES/ query T kvtrace DELETE FROM t WHERE a = 5 ---- -Scan /Table/53/1/5{-/#} +Scan /Table/53/1/5/0 Del /Table/53/2/4/5/0 Del /Table/53/1/5/0 @@ -96,7 +96,7 @@ Del /Table/53/1/5/0 query T kvtrace DELETE FROM t WHERE a = 6 ---- -Scan /Table/53/1/6{-/#} +Scan /Table/53/1/6/0 Del /Table/53/2/11/6/0 Del /Table/53/3/11/6/0 Del /Table/53/1/6/0 @@ -105,7 +105,7 @@ Del /Table/53/1/6/0 query T kvtrace DELETE FROM t WHERE a = 12 ---- -Scan /Table/53/1/12{-/#} +Scan /Table/53/1/12/0 Del /Table/53/2/11/12/0 Del /Table/53/3/11/12/0 Del /Table/53/4/"foo"/12/0 @@ -116,7 +116,7 @@ Del /Table/53/1/12/0 query T kvtrace DELETE FROM u WHERE k = 1 ---- -Scan /Table/54/1/1{-/#} +Scan /Table/54/1/1/0 Del /Table/54/1/1/0 # Deleted row matches partial index with predicate column that is not @@ -124,7 +124,7 @@ Del /Table/54/1/1/0 query T kvtrace DELETE FROM u WHERE k = 2 ---- -Scan /Table/54/1/2{-/#} +Scan /Table/54/1/2/0 Del /Table/54/2/3/2/0 Del /Table/54/1/2/0 @@ -155,7 +155,7 @@ INSERT INTO t VALUES(13, 11, 'foo') query T kvtrace UPDATE t SET c = 'baz' WHERE a = 5 ---- -Scan /Table/53/1/5{-/#} +Scan /Table/53/1/5/0 Put /Table/53/1/5/0 -> /TUPLE/2:2:Int/4/1:3:Bytes/baz # Update a row that matches no partial indexes before the update, but does match @@ -163,7 +163,7 @@ Put /Table/53/1/5/0 -> /TUPLE/2:2:Int/4/1:3:Bytes/baz query T kvtrace UPDATE t SET b = 11 WHERE a = 5 ---- -Scan /Table/53/1/5{-/#} +Scan /Table/53/1/5/0 Put /Table/53/1/5/0 -> /TUPLE/2:2:Int/11/1:3:Bytes/baz Del /Table/53/2/4/5/0 CPut /Table/53/2/11/5/0 -> /BYTES/ (expecting does not exist) @@ -174,7 +174,7 @@ CPut /Table/53/3/11/5/0 -> /BYTES/ (expecting does not exist) query T kvtrace UPDATE t SET c = 'baz' WHERE a = 6 ---- -Scan /Table/53/1/6{-/#} +Scan /Table/53/1/6/0 Put /Table/53/1/6/0 -> /TUPLE/2:2:Int/11/1:3:Bytes/baz # Update a row that matches the first partial index before and after the update @@ -182,7 +182,7 @@ Put /Table/53/1/6/0 -> /TUPLE/2:2:Int/11/1:3:Bytes/baz query T kvtrace UPDATE t SET b = 12 WHERE a = 6 ---- -Scan /Table/53/1/6{-/#} +Scan /Table/53/1/6/0 Put /Table/53/1/6/0 -> /TUPLE/2:2:Int/12/1:3:Bytes/baz Del /Table/53/2/11/6/0 CPut /Table/53/2/12/6/0 -> /BYTES/ (expecting does not exist) @@ -194,7 +194,7 @@ CPut /Table/53/3/12/6/0 -> /BYTES/ (expecting does not exist) query T kvtrace UPDATE t SET b = 9 WHERE a = 6 ---- -Scan /Table/53/1/6{-/#} +Scan /Table/53/1/6/0 Put /Table/53/1/6/0 -> /TUPLE/2:2:Int/9/1:3:Bytes/baz Del /Table/53/2/12/6/0 CPut /Table/53/2/9/6/0 -> /BYTES/ (expecting does not exist) @@ -205,7 +205,7 @@ Del /Table/53/3/12/6/0 query T kvtrace UPDATE t SET c = 'baz', b = 12 WHERE a = 13 ---- -Scan /Table/53/1/13{-/#} +Scan /Table/53/1/13/0 Put /Table/53/1/13/0 -> /TUPLE/2:2:Int/12/1:3:Bytes/baz Del /Table/53/2/11/13/0 CPut /Table/53/2/12/13/0 -> /BYTES/ (expecting does not exist) @@ -217,7 +217,7 @@ Del /Table/53/4/"foo"/13/0 query T kvtrace UPDATE t SET c = 'foo', b = 11 WHERE a = 13 ---- -Scan /Table/53/1/13{-/#} +Scan /Table/53/1/13/0 Put /Table/53/1/13/0 -> /TUPLE/2:2:Int/11/1:3:Bytes/foo Del /Table/53/2/12/13/0 CPut /Table/53/2/11/13/0 -> /BYTES/ (expecting does not exist) @@ -233,7 +233,7 @@ INSERT INTO u VALUES (1, 2, 3) query T kvtrace UPDATE u SET v = 11 WHERE k = 1 ---- -Scan /Table/54/1/1{-/#} +Scan /Table/54/1/1/0 Put /Table/54/1/1/0 -> /TUPLE/2:2:Int/2/1:3:Int/11 CPut /Table/54/2/2/1/0 -> /BYTES/ (expecting does not exist) @@ -242,7 +242,7 @@ CPut /Table/54/2/2/1/0 -> /BYTES/ (expecting does not exist) query T kvtrace UPDATE u SET v = 3 WHERE k = 1 ---- -Scan /Table/54/1/1{-/#} +Scan /Table/54/1/1/0 Put /Table/54/1/1/0 -> /TUPLE/2:2:Int/2/1:3:Int/3 Del /Table/54/2/2/1/0 @@ -259,7 +259,7 @@ INSERT INTO t VALUES(20, 11, 'bar') query T kvtrace UPDATE t SET a = 21 WHERE a = 20 ---- -Scan /Table/53/1/20{-/#} +Scan /Table/53/1/20/0 Del /Table/53/2/11/20/0 Del /Table/53/3/11/20/0 Del /Table/53/1/20/0 @@ -273,7 +273,7 @@ InitPut /Table/53/3/11/21/0 -> /BYTES/ query T kvtrace UPDATE t SET a = 22, b = 9, c = 'foo' WHERE a = 21 ---- -Scan /Table/53/1/21{-/#} +Scan /Table/53/1/21/0 Del /Table/53/2/11/21/0 Del /Table/53/3/11/21/0 Del /Table/53/1/21/0 @@ -296,7 +296,7 @@ DELETE FROM u query T kvtrace INSERT INTO t VALUES (5, 4, 'bar') ON CONFLICT DO NOTHING ---- -Scan /Table/53/1/5{-/#} +Scan /Table/53/1/5/0 CPut /Table/53/1/5/0 -> /TUPLE/2:2:Int/4/1:3:Bytes/bar InitPut /Table/53/2/4/5/0 -> /BYTES/ @@ -304,13 +304,13 @@ InitPut /Table/53/2/4/5/0 -> /BYTES/ query T kvtrace INSERT INTO t VALUES (5, 4, 'bar') ON CONFLICT DO NOTHING ---- -Scan /Table/53/1/5{-/#} +Scan /Table/53/1/5/0 # Insert a row that matches the first partial index. query T kvtrace INSERT INTO t VALUES (6, 11, 'bar') ON CONFLICT DO NOTHING ---- -Scan /Table/53/1/6{-/#} +Scan /Table/53/1/6/0 CPut /Table/53/1/6/0 -> /TUPLE/2:2:Int/11/1:3:Bytes/bar InitPut /Table/53/2/11/6/0 -> /BYTES/ InitPut /Table/53/3/11/6/0 -> /BYTES/ @@ -319,13 +319,13 @@ InitPut /Table/53/3/11/6/0 -> /BYTES/ query T kvtrace INSERT INTO t VALUES (6, 11, 'bar') ON CONFLICT DO NOTHING ---- -Scan /Table/53/1/6{-/#} +Scan /Table/53/1/6/0 # Insert a row that matches both partial indexes. query T kvtrace INSERT INTO t VALUES (12, 11, 'foo') ON CONFLICT DO NOTHING ---- -Scan /Table/53/1/12{-/#} +Scan /Table/53/1/12/0 CPut /Table/53/1/12/0 -> /TUPLE/2:2:Int/11/1:3:Bytes/foo InitPut /Table/53/2/11/12/0 -> /BYTES/ InitPut /Table/53/3/11/12/0 -> /BYTES/ @@ -335,14 +335,14 @@ InitPut /Table/53/4/"foo"/12/0 -> /BYTES/ query T kvtrace INSERT INTO t VALUES (12, 11, 'foo') ON CONFLICT DO NOTHING ---- -Scan /Table/53/1/12{-/#} +Scan /Table/53/1/12/0 # Insert a non-conflicting row that does not match the partial index with # predicate column that is not indexed. query T kvtrace INSERT INTO u VALUES (1, 2, 3) ON CONFLICT DO NOTHING ---- -Scan /Table/54/1/1{-/#} +Scan /Table/54/1/1/0 CPut /Table/54/1/1/0 -> /TUPLE/2:2:Int/2/1:3:Int/3 # Insert a conflicting row that does not match the partial index with predicate @@ -350,14 +350,14 @@ CPut /Table/54/1/1/0 -> /TUPLE/2:2:Int/2/1:3:Int/3 query T kvtrace INSERT INTO u VALUES (1, 4, 6) ON CONFLICT DO NOTHING ---- -Scan /Table/54/1/1{-/#} +Scan /Table/54/1/1/0 # Insert a non-conflicting row that matches the partial index with predicate # column that is not indexed. query T kvtrace INSERT INTO u VALUES (2, 3, 11) ON CONFLICT DO NOTHING ---- -Scan /Table/54/1/2{-/#} +Scan /Table/54/1/2/0 CPut /Table/54/1/2/0 -> /TUPLE/2:2:Int/3/1:3:Int/11 InitPut /Table/54/2/3/2/0 -> /BYTES/ @@ -366,7 +366,7 @@ InitPut /Table/54/2/3/2/0 -> /BYTES/ query T kvtrace INSERT INTO u VALUES (2, 3, 11) ON CONFLICT DO NOTHING ---- -Scan /Table/54/1/2{-/#} +Scan /Table/54/1/2/0 # --------------------------------------------------------- # INSERT ON CONFLICT DO UPDATE @@ -383,7 +383,7 @@ DELETE FROM u query T kvtrace INSERT INTO t VALUES (5, 4, 'bar') ON CONFLICT (a) DO UPDATE SET b = 3 ---- -Scan /Table/53/1/5{-/#} +Scan /Table/53/1/5/0 CPut /Table/53/1/5/0 -> /TUPLE/2:2:Int/4/1:3:Bytes/bar InitPut /Table/53/2/4/5/0 -> /BYTES/ @@ -392,7 +392,7 @@ InitPut /Table/53/2/4/5/0 -> /BYTES/ query T kvtrace INSERT INTO t VALUES (5, 3, 'foo') ON CONFLICT (a) DO UPDATE SET b = 3 ---- -Scan /Table/53/1/5{-/#} +Scan /Table/53/1/5/0 Put /Table/53/1/5/0 -> /TUPLE/2:2:Int/3/1:3:Bytes/bar Del /Table/53/2/4/5/0 CPut /Table/53/2/3/5/0 -> /BYTES/ (expecting does not exist) @@ -402,7 +402,7 @@ CPut /Table/53/2/3/5/0 -> /BYTES/ (expecting does not exist) query T kvtrace INSERT INTO t VALUES (5, 7, 'foo') ON CONFLICT (a) DO UPDATE SET b = 11 ---- -Scan /Table/53/1/5{-/#} +Scan /Table/53/1/5/0 Put /Table/53/1/5/0 -> /TUPLE/2:2:Int/11/1:3:Bytes/bar Del /Table/53/2/3/5/0 CPut /Table/53/2/11/5/0 -> /BYTES/ (expecting does not exist) @@ -414,7 +414,7 @@ CPut /Table/53/3/11/5/0 -> /BYTES/ (expecting does not exist) query T kvtrace INSERT INTO t VALUES (5, 11, 'bar') ON CONFLICT (a) DO UPDATE SET b = 4, c = 'foo' ---- -Scan /Table/53/1/5{-/#} +Scan /Table/53/1/5/0 Put /Table/53/1/5/0 -> /TUPLE/2:2:Int/4/1:3:Bytes/foo Del /Table/53/2/11/5/0 CPut /Table/53/2/4/5/0 -> /BYTES/ (expecting does not exist) @@ -426,7 +426,7 @@ CPut /Table/53/4/"foo"/5/0 -> /BYTES/ (expecting does not exist) query T kvtrace INSERT INTO t VALUES (5, 11, 'bar') ON CONFLICT (a) DO UPDATE SET b = 3 ---- -Scan /Table/53/1/5{-/#} +Scan /Table/53/1/5/0 Put /Table/53/1/5/0 -> /TUPLE/2:2:Int/3/1:3:Bytes/foo Del /Table/53/2/4/5/0 CPut /Table/53/2/3/5/0 -> /BYTES/ (expecting does not exist) @@ -436,7 +436,7 @@ CPut /Table/53/2/3/5/0 -> /BYTES/ (expecting does not exist) query T kvtrace INSERT INTO t VALUES (5, 11, 'bar') ON CONFLICT (a) DO UPDATE SET c = 'foobar' ---- -Scan /Table/53/1/5{-/#} +Scan /Table/53/1/5/0 Put /Table/53/1/5/0 -> /TUPLE/2:2:Int/3/1:3:Bytes/foobar Del /Table/53/4/"foo"/5/0 CPut /Table/53/4/"foobar"/5/0 -> /BYTES/ (expecting does not exist) @@ -445,7 +445,7 @@ CPut /Table/53/4/"foobar"/5/0 -> /BYTES/ (expecting does not exist) query T kvtrace INSERT INTO t VALUES (6, 11, 'baz') ON CONFLICT (a) DO UPDATE SET b = 3 ---- -Scan /Table/53/1/6{-/#} +Scan /Table/53/1/6/0 CPut /Table/53/1/6/0 -> /TUPLE/2:2:Int/11/1:3:Bytes/baz InitPut /Table/53/2/11/6/0 -> /BYTES/ InitPut /Table/53/3/11/6/0 -> /BYTES/ @@ -455,7 +455,7 @@ InitPut /Table/53/3/11/6/0 -> /BYTES/ query T kvtrace INSERT INTO u VALUES (1, 2, 3) ON CONFLICT (k) DO UPDATE SET u = 5 ---- -Scan /Table/54/1/1{-/#} +Scan /Table/54/1/1/0 CPut /Table/54/1/1/0 -> /TUPLE/2:2:Int/2/1:3:Int/3 # Insert a conflicting row that does not match the partial index with predicate @@ -463,7 +463,7 @@ CPut /Table/54/1/1/0 -> /TUPLE/2:2:Int/2/1:3:Int/3 query T kvtrace INSERT INTO u VALUES (1, 4, 6) ON CONFLICT (k) DO UPDATE SET v = 8 ---- -Scan /Table/54/1/1{-/#} +Scan /Table/54/1/1/0 Put /Table/54/1/1/0 -> /TUPLE/2:2:Int/2/1:3:Int/8 # Insert a non-conflicting row that matches the partial index with predicate @@ -471,7 +471,7 @@ Put /Table/54/1/1/0 -> /TUPLE/2:2:Int/2/1:3:Int/8 query T kvtrace INSERT INTO u VALUES (2, 3, 11) ON CONFLICT (k) DO UPDATE SET u = 5 ---- -Scan /Table/54/1/2{-/#} +Scan /Table/54/1/2/0 CPut /Table/54/1/2/0 -> /TUPLE/2:2:Int/3/1:3:Int/11 InitPut /Table/54/2/3/2/0 -> /BYTES/ @@ -480,7 +480,7 @@ InitPut /Table/54/2/3/2/0 -> /BYTES/ query T kvtrace INSERT INTO u VALUES (2, 3, 11) ON CONFLICT (k) DO UPDATE SET u = 4, v = 12 ---- -Scan /Table/54/1/2{-/#} +Scan /Table/54/1/2/0 Put /Table/54/1/2/0 -> /TUPLE/2:2:Int/4/1:3:Int/12 Del /Table/54/2/3/2/0 CPut /Table/54/2/4/2/0 -> /BYTES/ (expecting does not exist) @@ -500,7 +500,7 @@ DELETE FROM u query T kvtrace INSERT INTO t VALUES (5, 4, 'bar') ON CONFLICT (a) DO UPDATE SET a = 5 ---- -Scan /Table/53/1/5{-/#} +Scan /Table/53/1/5/0 CPut /Table/53/1/5/0 -> /TUPLE/2:2:Int/4/1:3:Bytes/bar InitPut /Table/53/2/4/5/0 -> /BYTES/ @@ -509,7 +509,7 @@ InitPut /Table/53/2/4/5/0 -> /BYTES/ query T kvtrace INSERT INTO t VALUES (5, 3, 'baz') ON CONFLICT (a) DO UPDATE SET a = 6 ---- -Scan /Table/53/1/5{-/#} +Scan /Table/53/1/5/0 Del /Table/53/2/4/5/0 Del /Table/53/1/5/0 CPut /Table/53/1/6/0 -> /TUPLE/2:2:Int/4/1:3:Bytes/bar @@ -520,7 +520,7 @@ InitPut /Table/53/2/4/6/0 -> /BYTES/ query T kvtrace INSERT INTO t VALUES (6, 3, 'bar') ON CONFLICT (a) DO UPDATE SET a = 7, c = 'foo' ---- -Scan /Table/53/1/6{-/#} +Scan /Table/53/1/6/0 Del /Table/53/2/4/6/0 Del /Table/53/1/6/0 CPut /Table/53/1/7/0 -> /TUPLE/2:2:Int/4/1:3:Bytes/foo @@ -533,7 +533,7 @@ InitPut /Table/53/4/"foo"/7/0 -> /BYTES/ query T kvtrace INSERT INTO t VALUES (7, 3, 'bar') ON CONFLICT (a) DO UPDATE SET a = 8, b = 11 ---- -Scan /Table/53/1/7{-/#} +Scan /Table/53/1/7/0 Del /Table/53/2/4/7/0 Del /Table/53/4/"foo"/7/0 Del /Table/53/1/7/0 @@ -546,7 +546,7 @@ InitPut /Table/53/3/11/8/0 -> /BYTES/ query T kvtrace INSERT INTO t VALUES (8, 4, 'bar') ON CONFLICT (a) DO UPDATE SET a = 9, c = 'foobar' ---- -Scan /Table/53/1/8{-/#} +Scan /Table/53/1/8/0 Del /Table/53/2/11/8/0 Del /Table/53/3/11/8/0 Del /Table/53/1/8/0 @@ -569,7 +569,7 @@ DELETE FROM u query T kvtrace UPSERT INTO t VALUES (5, 4, 'bar') ---- -Scan /Table/53/1/5{-/#} +Scan /Table/53/1/5/0 CPut /Table/53/1/5/0 -> /TUPLE/2:2:Int/4/1:3:Bytes/bar InitPut /Table/53/2/4/5/0 -> /BYTES/ @@ -578,7 +578,7 @@ InitPut /Table/53/2/4/5/0 -> /BYTES/ query T kvtrace UPSERT INTO t VALUES (5, 3, 'bar') ---- -Scan /Table/53/1/5{-/#} +Scan /Table/53/1/5/0 Put /Table/53/1/5/0 -> /TUPLE/2:2:Int/3/1:3:Bytes/bar Del /Table/53/2/4/5/0 CPut /Table/53/2/3/5/0 -> /BYTES/ (expecting does not exist) @@ -588,7 +588,7 @@ CPut /Table/53/2/3/5/0 -> /BYTES/ (expecting does not exist) query T kvtrace UPSERT INTO t VALUES (5, 11, 'bar') ---- -Scan /Table/53/1/5{-/#} +Scan /Table/53/1/5/0 Put /Table/53/1/5/0 -> /TUPLE/2:2:Int/11/1:3:Bytes/bar Del /Table/53/2/3/5/0 CPut /Table/53/2/11/5/0 -> /BYTES/ (expecting does not exist) @@ -600,7 +600,7 @@ CPut /Table/53/3/11/5/0 -> /BYTES/ (expecting does not exist) query T kvtrace UPSERT INTO t VALUES (5, 3, 'foo') ---- -Scan /Table/53/1/5{-/#} +Scan /Table/53/1/5/0 Put /Table/53/1/5/0 -> /TUPLE/2:2:Int/3/1:3:Bytes/foo Del /Table/53/2/11/5/0 CPut /Table/53/2/3/5/0 -> /BYTES/ (expecting does not exist) @@ -612,7 +612,7 @@ CPut /Table/53/4/"foo"/5/0 -> /BYTES/ (expecting does not exist) query T kvtrace UPSERT INTO t VALUES (5, 4, 'foo') ---- -Scan /Table/53/1/5{-/#} +Scan /Table/53/1/5/0 Put /Table/53/1/5/0 -> /TUPLE/2:2:Int/4/1:3:Bytes/foo Del /Table/53/2/3/5/0 CPut /Table/53/2/4/5/0 -> /BYTES/ (expecting does not exist) @@ -622,7 +622,7 @@ CPut /Table/53/2/4/5/0 -> /BYTES/ (expecting does not exist) query T kvtrace UPSERT INTO t VALUES (5, 4, 'foobar') ---- -Scan /Table/53/1/5{-/#} +Scan /Table/53/1/5/0 Put /Table/53/1/5/0 -> /TUPLE/2:2:Int/4/1:3:Bytes/foobar Del /Table/53/4/"foo"/5/0 CPut /Table/53/4/"foobar"/5/0 -> /BYTES/ (expecting does not exist) @@ -631,7 +631,7 @@ CPut /Table/53/4/"foobar"/5/0 -> /BYTES/ (expecting does not exist) query T kvtrace UPSERT INTO t VALUES (9, 11, 'baz') ---- -Scan /Table/53/1/9{-/#} +Scan /Table/53/1/9/0 CPut /Table/53/1/9/0 -> /TUPLE/2:2:Int/11/1:3:Bytes/baz InitPut /Table/53/2/11/9/0 -> /BYTES/ InitPut /Table/53/3/11/9/0 -> /BYTES/ @@ -641,7 +641,7 @@ InitPut /Table/53/3/11/9/0 -> /BYTES/ query T kvtrace UPSERT INTO u VALUES (1, 2, 3) ---- -Scan /Table/54/1/1{-/#} +Scan /Table/54/1/1/0 CPut /Table/54/1/1/0 -> /TUPLE/2:2:Int/2/1:3:Int/3 # Upsert a conflicting row that does not match the partial index with predicate @@ -649,7 +649,7 @@ CPut /Table/54/1/1/0 -> /TUPLE/2:2:Int/2/1:3:Int/3 query T kvtrace UPSERT INTO u VALUES (1, 4, 6) ---- -Scan /Table/54/1/1{-/#} +Scan /Table/54/1/1/0 Put /Table/54/1/1/0 -> /TUPLE/2:2:Int/4/1:3:Int/6 # Upsert a non-conflicting row that matches the partial index with predicate @@ -657,7 +657,7 @@ Put /Table/54/1/1/0 -> /TUPLE/2:2:Int/4/1:3:Int/6 query T kvtrace UPSERT INTO u VALUES (2, 3, 11) ---- -Scan /Table/54/1/2{-/#} +Scan /Table/54/1/2/0 CPut /Table/54/1/2/0 -> /TUPLE/2:2:Int/3/1:3:Int/11 InitPut /Table/54/2/3/2/0 -> /BYTES/ @@ -666,7 +666,7 @@ InitPut /Table/54/2/3/2/0 -> /BYTES/ query T kvtrace UPSERT INTO u VALUES (2, 4, 12) ---- -Scan /Table/54/1/2{-/#} +Scan /Table/54/1/2/0 Put /Table/54/1/2/0 -> /TUPLE/2:2:Int/4/1:3:Int/12 Del /Table/54/2/3/2/0 CPut /Table/54/2/4/2/0 -> /BYTES/ (expecting does not exist) @@ -722,7 +722,7 @@ CPut /Table/55/1/2/0 -> /TUPLE/ query T kvtrace DELETE FROM inv WHERE a = 1 ---- -Scan /Table/55/1/1{-/#} +Scan /Table/55/1/1/0 Del /Table/55/2/"num"/1/1/0 Del /Table/55/2/"x"/"y"/1/0 Del /Table/55/1/1/0 @@ -730,7 +730,7 @@ Del /Table/55/1/1/0 query T kvtrace DELETE FROM inv WHERE a = 2 ---- -Scan /Table/55/1/2{-/#} +Scan /Table/55/1/2/0 Del /Table/55/1/2/0 # --------------------------------------------------------- @@ -745,14 +745,14 @@ INSERT INTO inv VALUES (2, '{"x": "y", "num": 2}', 'baz'); query T kvtrace UPDATE inv SET c = 'bar' WHERE a = 1 ---- -Scan /Table/55/1/1{-/#} +Scan /Table/55/1/1/0 Put /Table/55/1/1/0 -> /TUPLE/ # Update the JSON of a row in the partial index. query T kvtrace UPDATE inv SET b = '{"x": "y", "num": 3}' WHERE a = 1 ---- -Scan /Table/55/1/1{-/#} +Scan /Table/55/1/1/0 Put /Table/55/1/1/0 -> /TUPLE/ Del /Table/55/2/"num"/1/1/0 InitPut /Table/55/2/"num"/3/1/0 -> /BYTES/ @@ -761,7 +761,7 @@ InitPut /Table/55/2/"num"/3/1/0 -> /BYTES/ query T kvtrace UPDATE inv SET c = 'fud' WHERE a = 1 ---- -Scan /Table/55/1/1{-/#} +Scan /Table/55/1/1/0 Put /Table/55/1/1/0 -> /TUPLE/ Del /Table/55/2/"num"/3/1/0 Del /Table/55/2/"x"/"y"/1/0 @@ -770,21 +770,21 @@ Del /Table/55/2/"x"/"y"/1/0 query T kvtrace UPDATE inv SET c = 'boo' WHERE a = 2 ---- -Scan /Table/55/1/2{-/#} +Scan /Table/55/1/2/0 Put /Table/55/1/2/0 -> /TUPLE/ # Update the JSON of a row not in the partial index. query T kvtrace UPDATE inv SET b = '{"x": "y", "num": 4}' WHERE a = 2 ---- -Scan /Table/55/1/2{-/#} +Scan /Table/55/1/2/0 Put /Table/55/1/2/0 -> /TUPLE/ # Update a non-JSON column so that the row is added to the partial index. query T kvtrace UPDATE inv SET c = 'bar' WHERE a = 2 ---- -Scan /Table/55/1/2{-/#} +Scan /Table/55/1/2/0 Put /Table/55/1/2/0 -> /TUPLE/ InitPut /Table/55/2/"num"/4/2/0 -> /BYTES/ InitPut /Table/55/2/"x"/"y"/2/0 -> /BYTES/ @@ -793,7 +793,7 @@ InitPut /Table/55/2/"x"/"y"/2/0 -> /BYTES/ query T kvtrace UPDATE inv SET a = 4 WHERE a = 2 ---- -Scan /Table/55/1/2{-/#} +Scan /Table/55/1/2/0 Del /Table/55/2/"num"/4/2/0 Del /Table/55/2/"x"/"y"/2/0 Del /Table/55/1/2/0 @@ -805,7 +805,7 @@ InitPut /Table/55/2/"x"/"y"/4/0 -> /BYTES/ query T kvtrace UPDATE inv SET a = 3 WHERE a = 1 ---- -Scan /Table/55/1/1{-/#} +Scan /Table/55/1/1/0 Del /Table/55/1/1/0 CPut /Table/55/1/3/0 -> /TUPLE/ @@ -844,7 +844,7 @@ Put /Table/55/1/13/0 -> /TUPLE/ query T kvtrace UPSERT INTO inv VALUES (4, '{"x": "y", "num": 4}', 'foo') ---- -Scan /Table/55/1/4{-/#} +Scan /Table/55/1/4/0 Put /Table/55/1/4/0 -> /TUPLE/ # Upsert a conflicting row with different JSON from the existing row in the @@ -852,7 +852,7 @@ Put /Table/55/1/4/0 -> /TUPLE/ query T kvtrace UPSERT INTO inv VALUES (4, '{"x": "y", "num": 6}', 'foo') ---- -Scan /Table/55/1/4{-/#} +Scan /Table/55/1/4/0 Put /Table/55/1/4/0 -> /TUPLE/ Del /Table/55/2/"num"/4/4/0 InitPut /Table/55/2/"num"/6/4/0 -> /BYTES/ @@ -861,7 +861,7 @@ InitPut /Table/55/2/"num"/6/4/0 -> /BYTES/ query T kvtrace UPSERT INTO inv VALUES (4, '{"x": "y", "num": 6}', 'fud') ---- -Scan /Table/55/1/4{-/#} +Scan /Table/55/1/4/0 Put /Table/55/1/4/0 -> /TUPLE/ Del /Table/55/2/"num"/6/4/0 Del /Table/55/2/"x"/"y"/4/0 @@ -870,7 +870,7 @@ Del /Table/55/2/"x"/"y"/4/0 query T kvtrace UPSERT INTO inv VALUES (5, '{"x": "y", "num": 7}', 'bar') ---- -Scan /Table/55/1/5{-/#} +Scan /Table/55/1/5/0 CPut /Table/55/1/5/0 -> /TUPLE/ InitPut /Table/55/2/"num"/7/5/0 -> /BYTES/ InitPut /Table/55/2/"x"/"y"/5/0 -> /BYTES/ @@ -879,7 +879,7 @@ InitPut /Table/55/2/"x"/"y"/5/0 -> /BYTES/ query T kvtrace UPSERT INTO inv VALUES (6, '{"x": "y", "num": 8}', 'baz') ---- -Scan /Table/55/1/6{-/#} +Scan /Table/55/1/6/0 CPut /Table/55/1/6/0 -> /TUPLE/ # Regression test for #57085. Cascading DELETEs should not issue DEL operations diff --git a/pkg/sql/opt/exec/execbuilder/testdata/secondary_index_column_families_nonmetamorphic b/pkg/sql/opt/exec/execbuilder/testdata/secondary_index_column_families_nonmetamorphic index a023840b648c..19469c125120 100644 --- a/pkg/sql/opt/exec/execbuilder/testdata/secondary_index_column_families_nonmetamorphic +++ b/pkg/sql/opt/exec/execbuilder/testdata/secondary_index_column_families_nonmetamorphic @@ -253,7 +253,7 @@ SELECT y, z, v FROM t@i WHERE y = 2.01 AND z = 3.001 query T kvtrace(Scan,prefix=/Table/55/2/) SELECT y, z, v FROM t@i WHERE y = 2.01 AND z = 3.001 ---- -Scan /Table/55/2/2.01/3.001/{0-1}, /Table/55/2/2.01/3.001/2/{1-2} +Scan /Table/55/2/2.01/3.001/0, /Table/55/2/2.01/3.001/2/1 query T EXPLAIN SELECT y, z, v FROM t@i WHERE y = 2.01 AND z = 3.001 @@ -287,7 +287,7 @@ SELECT y FROM t@i WHERE y = 2 query T kvtrace(Scan,prefix=/Table/56/2/) SELECT y FROM t@i WHERE y = 2 ---- -Scan /Table/56/2/2/{0-1} +Scan /Table/56/2/2/0 # Ensure that when backfilling an index we only insert the needed k/vs. statement ok diff --git a/pkg/sql/opt/exec/execbuilder/testdata/select b/pkg/sql/opt/exec/execbuilder/testdata/select index e778cab380ca..50473d3653ca 100644 --- a/pkg/sql/opt/exec/execbuilder/testdata/select +++ b/pkg/sql/opt/exec/execbuilder/testdata/select @@ -357,7 +357,7 @@ vectorized: true columns: (x, y) estimated row count: 1 (missing stats) table: a@primary - spans: /2-/2/# + spans: /2/0- query T EXPLAIN (VERBOSE) SELECT * FROM a WHERE x > 1 AND y < 30 @@ -862,7 +862,7 @@ DROP TABLE dt # Ensure that decimal values result in correct scan spans. # ------------------------------------------------------------------------------ statement ok -CREATE TABLE dec (d decimal, v decimal(3, 1), primary key (d, v)) +CREATE TABLE dec (d decimal, v decimal(3, 1), primary key (d, v), family(d, v)) query T EXPLAIN (TYPES) SELECT * FROM dec WHERE d IS NaN and v IS NaN @@ -874,6 +874,23 @@ vectorized: true columns: (d decimal, v decimal) estimated row count: 1 (missing stats) table: dec@primary + spans: /NaN/NaN/0- + +# Test again with separate column families. + +statement ok +CREATE TABLE decfam (d decimal, v decimal(3, 1), primary key (d, v), family(d), family(v)) + +query T +EXPLAIN (TYPES) SELECT * FROM decfam WHERE d IS NaN and v IS NaN +---- +distribution: local +vectorized: true +· +• scan + columns: (d decimal, v decimal) + estimated row count: 1 (missing stats) + table: decfam@primary spans: /NaN/NaN-/NaN/NaN/# # The NaN suffix is decimalNaNDesc, not decimalNaN(Asc). @@ -887,7 +904,7 @@ vectorized: true columns: (d decimal, v decimal) estimated row count: 1 (missing stats) table: dec@primary - spans: /Infinity/Infinity-/Infinity/Infinity/# + spans: /Infinity/Infinity/0- query T EXPLAIN (TYPES) SELECT * FROM dec WHERE d = '-Infinity' and v = '-Infinity' @@ -899,7 +916,7 @@ vectorized: true columns: (d decimal, v decimal) estimated row count: 1 (missing stats) table: dec@primary - spans: /-Infinity/-Infinity-/-Infinity/-Infinity/# + spans: /-Infinity/-Infinity/0- statement ok DROP TABLE dec @@ -1751,14 +1768,11 @@ SET tracing = on; SELECT * FROM a WHERE a = 0 OR a = 10; SET tracing = off # See #30943 for more details. query T SELECT message FROM [SHOW TRACE FOR SESSION] -WHERE message IN - ('querying next range at /Table/73/1/0', - 'querying next range at /Table/73/1/10', - '=== SPAN START: kv.DistSender: sending partial batch ===' - ) ----- -querying next range at /Table/73/1/0 -querying next range at /Table/73/1/10 +WHERE message LIKE 'querying next range at /Table/74/1%' OR + message = '=== SPAN START: kv.DistSender: sending partial batch ===' +---- +querying next range at /Table/74/1/0/0 +querying next range at /Table/74/1/10/0 # Test for 42202 -- ensure filters can get pushed down through project-set. statement ok diff --git a/pkg/sql/opt/exec/execbuilder/testdata/select_for_update b/pkg/sql/opt/exec/execbuilder/testdata/select_for_update index 12c4479f208c..d4bdbc5e3c51 100644 --- a/pkg/sql/opt/exec/execbuilder/testdata/select_for_update +++ b/pkg/sql/opt/exec/execbuilder/testdata/select_for_update @@ -148,7 +148,7 @@ vectorized: true columns: (a, b) estimated row count: 1 (missing stats) table: t@primary - spans: /1-/1/# + spans: /1/0- locking strength: for update query T @@ -161,7 +161,7 @@ vectorized: true columns: (a, b) estimated row count: 1 (missing stats) table: t@primary - spans: /1-/1/# + spans: /1/0- locking strength: for no key update query T @@ -174,7 +174,7 @@ vectorized: true columns: (a, b) estimated row count: 1 (missing stats) table: t@primary - spans: /1-/1/# + spans: /1/0- locking strength: for share query T @@ -187,7 +187,7 @@ vectorized: true columns: (a, b) estimated row count: 1 (missing stats) table: t@primary - spans: /1-/1/# + spans: /1/0- locking strength: for key share query T @@ -200,7 +200,7 @@ vectorized: true columns: (a, b) estimated row count: 1 (missing stats) table: t@primary - spans: /1-/1/# + spans: /1/0- locking strength: for share query T @@ -213,7 +213,7 @@ vectorized: true columns: (a, b) estimated row count: 1 (missing stats) table: t@primary - spans: /1-/1/# + spans: /1/0- locking strength: for no key update query T @@ -226,7 +226,7 @@ vectorized: true columns: (a, b) estimated row count: 1 (missing stats) table: t@primary - spans: /1-/1/# + spans: /1/0- locking strength: for update query T @@ -239,7 +239,7 @@ vectorized: true columns: (a, b) estimated row count: 1 (missing stats) table: t@primary - spans: /1-/1/# + spans: /1/0- locking strength: for update query error pgcode 42P01 relation "t2" in FOR UPDATE clause not found in FROM clause @@ -260,7 +260,7 @@ vectorized: true columns: (a) estimated row count: 1 (missing stats) table: t@primary - spans: /1-/1/# + spans: /1/0- locking strength: for update # ------------------------------------------------------------------------------ @@ -1769,7 +1769,7 @@ vectorized: true columns: (a, b) estimated row count: 1 (missing stats) table: t@primary - spans: /1-/1/# + spans: /1/0- locking strength: for update locking wait policy: nowait @@ -1783,7 +1783,7 @@ vectorized: true columns: (a, b) estimated row count: 1 (missing stats) table: t@primary - spans: /1-/1/# + spans: /1/0- locking strength: for no key update locking wait policy: nowait @@ -1797,7 +1797,7 @@ vectorized: true columns: (a, b) estimated row count: 1 (missing stats) table: t@primary - spans: /1-/1/# + spans: /1/0- locking strength: for share locking wait policy: nowait @@ -1811,7 +1811,7 @@ vectorized: true columns: (a, b) estimated row count: 1 (missing stats) table: t@primary - spans: /1-/1/# + spans: /1/0- locking strength: for key share locking wait policy: nowait @@ -1825,7 +1825,7 @@ vectorized: true columns: (a, b) estimated row count: 1 (missing stats) table: t@primary - spans: /1-/1/# + spans: /1/0- locking strength: for share locking wait policy: nowait @@ -1839,7 +1839,7 @@ vectorized: true columns: (a, b) estimated row count: 1 (missing stats) table: t@primary - spans: /1-/1/# + spans: /1/0- locking strength: for no key update locking wait policy: nowait @@ -1853,7 +1853,7 @@ vectorized: true columns: (a, b) estimated row count: 1 (missing stats) table: t@primary - spans: /1-/1/# + spans: /1/0- locking strength: for update locking wait policy: nowait @@ -1867,7 +1867,7 @@ vectorized: true columns: (a, b) estimated row count: 1 (missing stats) table: t@primary - spans: /1-/1/# + spans: /1/0- locking strength: for update locking wait policy: nowait @@ -1889,6 +1889,6 @@ vectorized: true columns: (a) estimated row count: 1 (missing stats) table: t@primary - spans: /1-/1/# + spans: /1/0- locking strength: for update locking wait policy: nowait diff --git a/pkg/sql/opt/exec/execbuilder/testdata/unique b/pkg/sql/opt/exec/execbuilder/testdata/unique index e104f2e861a8..728d3a25e436 100644 --- a/pkg/sql/opt/exec/execbuilder/testdata/unique +++ b/pkg/sql/opt/exec/execbuilder/testdata/unique @@ -348,7 +348,7 @@ vectorized: true │ columns: (k) │ estimated row count: 1 (missing stats) │ table: uniq@primary - │ spans: /1/0-/1/1 + │ spans: /1/0- │ └── • hash join (right anti) │ columns: (column1, column2, column3, column4, column5) @@ -1170,7 +1170,7 @@ vectorized: true columns: (k) estimated row count: 1 (missing stats) table: uniq_partial@primary - spans: /1/0-/1/1 + spans: /1/0- # Insert with non-constant input. query T @@ -2507,7 +2507,7 @@ vectorized: true │ columns: (r, a, b, c) │ estimated row count: 1 (0.10% of the table; stats collected ago) │ table: uniq_partial_enum@primary -│ spans: /"@"/2/0-/"@"/2/1 /"@"/2/2/1-/"@"/2/3/2 /"\x80"/2/0-/"\x80"/2/1 /"\x80"/2/2/1-/"\x80"/2/3/2 /"\xc0"/2/0-/"\xc0"/2/1 /"\xc0"/2/2/1-/"\xc0"/2/3/2 +│ spans: /"@"/2/0- /"@"/2/2/1-/"@"/2/3/2 /"\x80"/2/0- /"\x80"/2/2/1-/"\x80"/2/3/2 /"\xc0"/2/0- /"\xc0"/2/2/1-/"\xc0"/2/3/2 │ parallel │ locking strength: for update │ diff --git a/pkg/sql/opt/exec/execbuilder/testdata/upsert b/pkg/sql/opt/exec/execbuilder/testdata/upsert index 5093eb479876..e3b9e21cc826 100644 --- a/pkg/sql/opt/exec/execbuilder/testdata/upsert +++ b/pkg/sql/opt/exec/execbuilder/testdata/upsert @@ -215,7 +215,7 @@ vectorized: true columns: (a, b, c, d) estimated row count: 1 (missing stats) table: indexed@primary - spans: /1-/1/# + spans: /1/0- locking strength: for update query T @@ -479,7 +479,7 @@ vectorized: true columns: (a, b) estimated row count: 1 (missing stats) table: table38627@primary - spans: /1-/1/# + spans: /1/0- statement ok COMMIT diff --git a/pkg/sql/opt/exec/execbuilder/testdata/upsert_nonmetamorphic b/pkg/sql/opt/exec/execbuilder/testdata/upsert_nonmetamorphic index fb470616c054..6c3b842e936f 100644 --- a/pkg/sql/opt/exec/execbuilder/testdata/upsert_nonmetamorphic +++ b/pkg/sql/opt/exec/execbuilder/testdata/upsert_nonmetamorphic @@ -38,7 +38,7 @@ query TT SELECT operation, message FROM [SHOW KV TRACE FOR SESSION] WHERE operation != 'dist sender send' ---- -colbatchscan Scan /Table/55/1/2{-/#} +colbatchscan Scan /Table/55/1/2/0 flow CPut /Table/55/1/2/0 -> /TUPLE/2:2:Int/3 flow InitPut /Table/55/2/3/0 -> /BYTES/0x8a flow fast path completed @@ -51,7 +51,7 @@ query TT SELECT operation, message FROM [SHOW KV TRACE FOR SESSION] WHERE operation != 'dist sender send' ---- -colbatchscan Scan /Table/55/1/1{-/#} +colbatchscan Scan /Table/55/1/1/0 flow CPut /Table/55/1/1/0 -> /TUPLE/2:2:Int/2 flow InitPut /Table/55/2/2/0 -> /BYTES/0x89 flow fast path completed @@ -65,7 +65,7 @@ set tracing=off; SELECT operation, message FROM [SHOW KV TRACE FOR SESSION] WHERE operation != 'dist sender send' ---- -colbatchscan Scan /Table/55/1/2{-/#} +colbatchscan Scan /Table/55/1/2/0 colbatchscan fetched: /kv/primary/2/v -> /3 flow Put /Table/55/1/2/0 -> /TUPLE/2:2:Int/2 flow Del /Table/55/2/3/0 diff --git a/pkg/sql/opt/exec/execbuilder/testdata/virtual_columns b/pkg/sql/opt/exec/execbuilder/testdata/virtual_columns index 9fd5b963ce86..1a24d9244879 100644 --- a/pkg/sql/opt/exec/execbuilder/testdata/virtual_columns +++ b/pkg/sql/opt/exec/execbuilder/testdata/virtual_columns @@ -621,7 +621,7 @@ vectorized: true columns: (a, c) estimated row count: 1 (missing stats) table: t_idx@primary - spans: /2/0-/2/1 /2/2/1-/2/2/2 + spans: /2/0- /2/2/1- locking strength: for update query T diff --git a/pkg/sql/row/fk_spans.go b/pkg/sql/row/fk_spans.go index 05410ab5b0a3..afbd150f86b2 100644 --- a/pkg/sql/row/fk_spans.go +++ b/pkg/sql/row/fk_spans.go @@ -28,7 +28,7 @@ func FKCheckSpan( } // If it is safe to split this lookup into multiple families, generate a point lookup for // family 0. Because we are just checking for existence, we only need family 0. - if s.CanSplitSpanIntoSeparateFamilies(1 /* numNeededFamilies */, numCols, containsNull) { + if s.CanSplitSpanIntoFamilySpans(1 /* numNeededFamilies */, numCols, containsNull) { return s.SpanToPointSpan(span, 0), nil } return span, nil diff --git a/pkg/sql/row/kv_batch_fetcher.go b/pkg/sql/row/kv_batch_fetcher.go index ecfcfded2782..6197c2d7469c 100644 --- a/pkg/sql/row/kv_batch_fetcher.go +++ b/pkg/sql/row/kv_batch_fetcher.go @@ -67,7 +67,10 @@ type sendFunc func( type txnKVFetcher struct { // "Constant" fields, provided by the caller. sendFn sendFunc - spans roachpb.Spans + // spans is the list of Spans that will be read by this KV Fetcher. If an + // individual Span has only a start key, it will be interpreted as a + // single-key fetch and may use a GetRequest under the hood. + spans roachpb.Spans // If useBatchLimit is true, batches are limited to kvBatchSize. If // firstBatchLimit is also set, the first batch is limited to that value. // Subsequent batches are larger, up to kvBatchSize. @@ -247,7 +250,12 @@ func makeKVBatchFetcherWithSendFunc( if useBatchLimit { // Verify the spans are ordered if a batch limit is used. for i := 1; i < len(spans); i++ { - if spans[i].Key.Compare(spans[i-1].EndKey) < 0 { + prevKey := spans[i-1].EndKey + if prevKey == nil { + // This is the case of a GetRequest. + prevKey = spans[i-1].Key + } + if spans[i].Key.Compare(prevKey) < 0 { return txnKVFetcher{}, errors.Errorf("unordered spans (%s %s)", spans[i-1], spans[i]) } } @@ -255,11 +263,19 @@ func makeKVBatchFetcherWithSendFunc( // Otherwise, just verify the spans don't contain consecutive overlapping // spans. for i := 1; i < len(spans); i++ { - if spans[i].Key.Compare(spans[i-1].EndKey) >= 0 { + prevEndKey := spans[i-1].EndKey + if prevEndKey == nil { + prevEndKey = spans[i-1].Key + } + curEndKey := spans[i].EndKey + if curEndKey == nil { + curEndKey = spans[i].Key + } + if spans[i].Key.Compare(prevEndKey) >= 0 { // Current span's start key is greater than or equal to the last span's // end key - we're good. continue - } else if spans[i].EndKey.Compare(spans[i-1].Key) < 0 { + } else if curEndKey.Compare(spans[i-1].Key) < 0 { // Current span's end key is less than or equal to the last span's start // key - also good. continue @@ -317,29 +333,67 @@ func (f *txnKVFetcher) fetch(ctx context.Context) error { } ba.Requests = make([]roachpb.RequestUnion, len(f.spans)) keyLocking := f.getKeyLockingStrength() + + // Detect the number of gets vs scans, so we can batch allocate all of the + // requests precisely. + nGets := 0 + for i := range f.spans { + if f.spans[i].EndKey == nil { + nGets++ + } + } + gets := make([]struct { + req roachpb.GetRequest + union roachpb.RequestUnion_Get + }, nGets) + + // curGet is incremented each time we fill in a GetRequest. + curGet := 0 if f.reverse { scans := make([]struct { req roachpb.ReverseScanRequest union roachpb.RequestUnion_ReverseScan - }, len(f.spans)) + }, len(f.spans)-nGets) for i := range f.spans { - scans[i].req.SetSpan(f.spans[i]) - scans[i].req.ScanFormat = roachpb.BATCH_RESPONSE - scans[i].req.KeyLocking = keyLocking - scans[i].union.ReverseScan = &scans[i].req - ba.Requests[i].Value = &scans[i].union + if f.spans[i].EndKey == nil { + // A span without an EndKey indicates that the caller is requesting a + // single key fetch, which can be served using a GetRequest. + gets[curGet].req.Key = f.spans[i].Key + gets[curGet].req.KeyLocking = keyLocking + gets[curGet].union.Get = &gets[curGet].req + ba.Requests[i].Value = &gets[curGet].union + curGet++ + continue + } + curScan := i - curGet + scans[curScan].req.SetSpan(f.spans[i]) + scans[curScan].req.ScanFormat = roachpb.BATCH_RESPONSE + scans[curScan].req.KeyLocking = keyLocking + scans[curScan].union.ReverseScan = &scans[curScan].req + ba.Requests[i].Value = &scans[curScan].union } } else { scans := make([]struct { req roachpb.ScanRequest union roachpb.RequestUnion_Scan - }, len(f.spans)) + }, len(f.spans)-nGets) for i := range f.spans { - scans[i].req.SetSpan(f.spans[i]) - scans[i].req.ScanFormat = roachpb.BATCH_RESPONSE - scans[i].req.KeyLocking = keyLocking - scans[i].union.Scan = &scans[i].req - ba.Requests[i].Value = &scans[i].union + if f.spans[i].EndKey == nil { + // A span without an EndKey indicates that the caller is requesting a + // single key fetch, which can be served using a GetRequest. + gets[curGet].req.Key = f.spans[i].Key + gets[curGet].req.KeyLocking = keyLocking + gets[curGet].union.Get = &gets[curGet].req + ba.Requests[i].Value = &gets[curGet].union + curGet++ + continue + } + curScan := i - curGet + scans[curScan].req.SetSpan(f.spans[i]) + scans[curScan].req.ScanFormat = roachpb.BATCH_RESPONSE + scans[curScan].req.KeyLocking = keyLocking + scans[curScan].union.Scan = &scans[curScan].req + ba.Requests[i].Value = &scans[curScan].union } } if cap(f.requestSpans) < len(f.spans) { @@ -453,7 +507,7 @@ func (f *txnKVFetcher) nextBatch( f.remainingBatches = f.remainingBatches[1:] return true, nil, batch, f.origSpan, nil } - if len(f.responses) > 0 { + for len(f.responses) > 0 { reply := f.responses[0].GetInner() f.responses = f.responses[1:] origSpan := f.requestSpans[0] @@ -472,6 +526,17 @@ func (f *txnKVFetcher) nextBatch( f.remainingBatches = t.BatchResponses[1:] } return true, t.Rows, batchResp, origSpan, nil + case *roachpb.GetResponse: + if t.IntentValue != nil { + return false, nil, nil, origSpan, + errors.AssertionFailedf("unexpectedly got an IntentValue back from a SQL GetRequest %v", *t.IntentValue) + } + if t.Value == nil { + // Nothing found in this particular response, let's continue to the next + // one. + continue + } + return true, []roachpb.KeyValue{{Key: origSpan.Key, Value: *t.Value}}, nil, origSpan, nil } } if f.fetchEnd { diff --git a/pkg/sql/rowenc/index_encoding.go b/pkg/sql/rowenc/index_encoding.go index c626c72e3074..76c9b15d067f 100644 --- a/pkg/sql/rowenc/index_encoding.go +++ b/pkg/sql/rowenc/index_encoding.go @@ -375,25 +375,30 @@ func NeededColumnFamilyIDs( return neededFamilyIDs } -// SplitSpanIntoSeparateFamilies splits a span representing a single row point +// SplitSpanIntoFamilySpans splits a span representing a single row point // lookup into separate disjoint spans that request only the particular column // families from neededFamilies instead of requesting all the families. It is up // to the client to ensure the requested span represents a single row lookup and -// that the span splitting is appropriate (see CanSplitSpanIntoSeparateFamilies). +// that the span splitting is appropriate (see CanSplitSpanIntoFamilySpans). +// +// Note that this function will still return a family-specific span even if the +// input span is for a table that has just a single column family, so that the +// caller can have a precise key to send via a GetRequest if desired. // // The function accepts a slice of spans to append to. -func SplitSpanIntoSeparateFamilies( +func SplitSpanIntoFamilySpans( appendTo roachpb.Spans, span roachpb.Span, neededFamilies []descpb.FamilyID, ) roachpb.Spans { span.Key = span.Key[:len(span.Key):len(span.Key)] // avoid mutation and aliasing for i, familyID := range neededFamilies { var famSpan roachpb.Span famSpan.Key = keys.MakeFamilyKey(span.Key, uint32(familyID)) - famSpan.EndKey = famSpan.Key.PrefixEnd() + // Don't set the EndKey yet, because a column family on its own can be + // fetched using a GetRequest. if i > 0 && familyID == neededFamilies[i-1]+1 { // This column family is adjacent to the previous one. We can merge // the two spans into one. - appendTo[len(appendTo)-1].EndKey = famSpan.EndKey + appendTo[len(appendTo)-1].EndKey = famSpan.Key.PrefixEnd() } else { appendTo = append(appendTo, famSpan) } diff --git a/pkg/sql/span/span_builder.go b/pkg/sql/span/span_builder.go index 7c7bfa371559..2d47275fcc75 100644 --- a/pkg/sql/span/span_builder.go +++ b/pkg/sql/span/span_builder.go @@ -136,7 +136,7 @@ func (s *Builder) UnsetNeededFamilies() { // ID. SpanFromEncDatums assumes that the EncDatums in values are in the order // of the index columns. It also returns whether or not the input values contain // a null value or not, which can be used as input for -// CanSplitSpanIntoSeparateFamilies. +// CanSplitSpanIntoFamilySpans. func (s *Builder) SpanFromEncDatums( values rowenc.EncDatumRow, prefixLen int, ) (_ roachpb.Span, containsNull bool, _ error) { @@ -147,7 +147,7 @@ func (s *Builder) SpanFromEncDatums( // SpanFromDatumRow generates an index span with prefixLen constraint columns from the index. // SpanFromDatumRow assumes that values is a valid table row for the Builder's table. // It also returns whether or not the input values contain a null value or not, which can be -// used as input for CanSplitSpanIntoSeparateFamilies. +// used as input for CanSplitSpanIntoFamilySpans. func (s *Builder) SpanFromDatumRow( values tree.Datums, prefixLen int, colMap catalog.TableColMap, ) (_ roachpb.Span, containsNull bool, _ error) { @@ -156,7 +156,7 @@ func (s *Builder) SpanFromDatumRow( // SpanToPointSpan converts a span into a span that represents a point lookup on a // specific family. It is up to the caller to ensure that this is a safe operation, -// by calling CanSplitSpanIntoSeparateFamilies before using it. +// by calling CanSplitSpanIntoFamilySpans before using it. func (s *Builder) SpanToPointSpan(span roachpb.Span, family descpb.FamilyID) roachpb.Span { key := keys.MakeFamilyKey(span.Key, uint32(family)) return roachpb.Span{Key: key, EndKey: roachpb.Key(key).PrefixEnd()} @@ -170,41 +170,70 @@ func (s *Builder) SpanToPointSpan(span roachpb.Span, family descpb.FamilyID) roa func (s *Builder) MaybeSplitSpanIntoSeparateFamilies( appendTo roachpb.Spans, span roachpb.Span, prefixLen int, containsNull bool, ) roachpb.Spans { - if s.neededFamilies != nil && s.CanSplitSpanIntoSeparateFamilies(len(s.neededFamilies), prefixLen, containsNull) { - return rowenc.SplitSpanIntoSeparateFamilies(appendTo, span, s.neededFamilies) + if s.neededFamilies != nil && s.CanSplitSpanIntoFamilySpans(len(s.neededFamilies), prefixLen, containsNull) { + return rowenc.SplitSpanIntoFamilySpans(appendTo, span, s.neededFamilies) } return append(appendTo, span) } -// CanSplitSpanIntoSeparateFamilies returns whether a span encoded with prefixLen keys and numNeededFamilies -// needed families can be safely split into multiple family specific spans. -func (s *Builder) CanSplitSpanIntoSeparateFamilies( +// CanSplitSpanIntoFamilySpans returns whether a span encoded with prefixLen keys and numNeededFamilies +// needed families can be safely split into 1 or more family specific spans. +func (s *Builder) CanSplitSpanIntoFamilySpans( numNeededFamilies, prefixLen int, containsNull bool, ) bool { // We can only split a span into separate family specific point lookups if: - // * We have a unique index. - // * The index we are generating spans for actually has multiple families: - // - In the case of the primary index, that means the table itself has - // multiple families. - // - In the case of a secondary index, the table must have multiple families - // and the index must store some columns. - // * If we have a secondary index, then containsNull must be false - // and it cannot be an inverted index. - // * We have all of the lookup columns of the index. - // * We don't need all of the families. + // * The table is not a special system table. (System tables claim to have // column families, but actually do not, since they're written to with // raw KV puts in a "legacy" way.) - isSystemTable := s.table.GetID() > 0 && s.table.GetID() < keys.MaxReservedDescID - return !isSystemTable && s.index.Unique && len(s.table.GetFamilies()) > 1 && - (s.index.ID == s.table.GetPrimaryIndexID() || - // Secondary index specific checks. - (s.index.Version >= descpb.SecondaryIndexFamilyFormatVersion && - !containsNull && - len(s.index.StoreColumnIDs) > 0 && - s.index.Type == descpb.IndexDescriptor_FORWARD)) && - prefixLen == len(s.index.ColumnIDs) && - numNeededFamilies < len(s.table.GetFamilies()) + if s.table.GetID() > 0 && s.table.GetID() < keys.MaxReservedDescID { + return false + } + + // * The index is unique. + if !s.index.Unique { + return false + } + + // * The index is fully constrained. + if prefixLen != len(s.index.ColumnIDs) { + return false + } + + // * The index either has just 1 family (so we'll make a GetRequest) or we + // need fewer than every column family in the table (otherwise we'd just + // make a big ScanRequest). + numFamilies := len(s.table.GetFamilies()) + if numFamilies > 1 && numNeededFamilies == numFamilies { + return false + } + + // If we're looking at a secondary index... + if s.index.ID != s.table.GetPrimaryIndexID() { + // * The index constraint must not contain null, since that would cause the + // index key to not be completely knowable. + if containsNull { + return false + } + // * The index cannot be inverted. + if s.index.Type != descpb.IndexDescriptor_FORWARD { + return false + } + + // * The index must store some columns. + if len(s.index.StoreColumnIDs) == 0 { + return false + } + + // * The index is a new enough version. + if s.index.Version < descpb.SecondaryIndexFamilyFormatVersion { + return false + } + } + + // We've passed all the conditions, and should be able to safely split this + // span into multiple column-family-specific spans. + return true } // Functions for optimizer related span generation are below. @@ -271,13 +300,16 @@ func (s *Builder) appendSpansFromConstraintSpan( } span.EndKey = append(span.EndKey, s.interstices[cs.EndKey().Length()]...) - // Optimization: for single row lookups on a table with multiple column - // families, only scan the relevant column families. This is disabled for - // deletions to ensure that the entire row is deleted. - if !forDelete && needed.Len() > 0 && span.Key.Equal(span.EndKey) { + // Optimization: for single row lookups on a table with one or more column + // families, only scan the relevant column families, and use GetRequests + // instead of ScanRequests when doing the column family fetches. This is + // disabled for deletions on tables with multiple column families to ensure + // that the entire row (all of its column families) is deleted. + + if needed.Len() > 0 && span.Key.Equal(span.EndKey) && !forDelete { neededFamilyIDs := rowenc.NeededColumnFamilyIDs(needed, s.table, s.index) - if s.CanSplitSpanIntoSeparateFamilies(len(neededFamilyIDs), cs.StartKey().Length(), containsNull) { - return rowenc.SplitSpanIntoSeparateFamilies(appendTo, span, neededFamilyIDs), nil + if s.CanSplitSpanIntoFamilySpans(len(neededFamilyIDs), cs.StartKey().Length(), containsNull) { + return rowenc.SplitSpanIntoFamilySpans(appendTo, span, neededFamilyIDs), nil } } diff --git a/pkg/sql/span/span_builder_test.go b/pkg/sql/span/span_builder_test.go index 5d99a13ed92c..926202318d4c 100644 --- a/pkg/sql/span/span_builder_test.go +++ b/pkg/sql/span/span_builder_test.go @@ -25,7 +25,7 @@ func TestSpanBuilderDoesNotSplitSystemTableFamilySpans(t *testing.T) { builder := MakeBuilder(&evalCtx, keys.SystemSQLCodec, systemschema.DescriptorTable, systemschema.DescriptorTable.GetPrimaryIndex().IndexDesc()) - if res := builder.CanSplitSpanIntoSeparateFamilies( + if res := builder.CanSplitSpanIntoFamilySpans( 1, 1, false); res { t.Errorf("expected the system table to not be splittable") } diff --git a/pkg/sql/span_builder_test.go b/pkg/sql/span_builder_test.go index cddec253abe1..49e3621b7d67 100644 --- a/pkg/sql/span_builder_test.go +++ b/pkg/sql/span_builder_test.go @@ -64,7 +64,7 @@ func TestSpanBuilderCanSplitSpan(t *testing.T) { index: "primary", prefixLen: 2, numNeededFamilies: 1, - canSplit: false, + canSplit: true, }, { sql: "a INT, b INT, c INT, INDEX i (b) STORING (a, c), FAMILY (a), FAMILY (b), FAMILY (c)", @@ -108,7 +108,7 @@ func TestSpanBuilderCanSplitSpan(t *testing.T) { t.Fatal(err) } builder := span.MakeBuilder(evalCtx, execCfg.Codec, desc, idx.IndexDesc()) - if res := builder.CanSplitSpanIntoSeparateFamilies( + if res := builder.CanSplitSpanIntoFamilySpans( tc.numNeededFamilies, tc.prefixLen, tc.containsNull); res != tc.canSplit { t.Errorf("expected result to be %v, but found %v", tc.canSplit, res) } diff --git a/pkg/sql/testdata/explain_tree b/pkg/sql/testdata/explain_tree index 253040f233ac..637ce7a4c688 100644 --- a/pkg/sql/testdata/explain_tree +++ b/pkg/sql/testdata/explain_tree @@ -18,7 +18,7 @@ network usage: 0 B (0 messages) columns: (oid int) estimated row count: 1 (missing stats) table: orders@primary - spans: /123-/123/# + spans: /123/0- ---- ---- diff --git a/pkg/sql/txn_restart_test.go b/pkg/sql/txn_restart_test.go index 3d0ae4d3b296..4a51754078e6 100644 --- a/pkg/sql/txn_restart_test.go +++ b/pkg/sql/txn_restart_test.go @@ -1104,7 +1104,7 @@ func TestNonRetryableError(t *testing.T) { hitError := false cleanupFilter := cmdFilters.AppendFilter( func(args kvserverbase.FilterArgs) *roachpb.Error { - if req, ok := args.Req.(*roachpb.ScanRequest); ok { + if req, ok := args.Req.(*roachpb.GetRequest); ok { if bytes.Contains(req.Key, testKey) && !kv.TestingIsRangeLookupRequest(req) { hitError = true return roachpb.NewErrorWithTxn(fmt.Errorf("testError"), args.Hdr.Txn) @@ -1167,7 +1167,7 @@ func TestReacquireLeaseOnRestart(t *testing.T) { var clockUpdate, restartDone int32 cleanupFilter := cmdFilters.AppendFilter( func(args kvserverbase.FilterArgs) *roachpb.Error { - if req, ok := args.Req.(*roachpb.ScanRequest); ok { + if req, ok := args.Req.(*roachpb.GetRequest); ok { if bytes.Contains(req.Key, testKey) && !kv.TestingIsRangeLookupRequest(req) { if atomic.LoadInt32(&clockUpdate) == 0 { atomic.AddInt32(&clockUpdate, 1) @@ -1252,7 +1252,7 @@ func TestFlushUncommitedDescriptorCacheOnRestart(t *testing.T) { return nil } - if req, ok := args.Req.(*roachpb.ScanRequest); ok { + if req, ok := args.Req.(*roachpb.GetRequest); ok { if bytes.Contains(req.Key, testKey) && !kv.TestingIsRangeLookupRequest(req) { atomic.AddInt32(&restartDone, 1) // Return ReadWithinUncertaintyIntervalError. diff --git a/pkg/sql/upsert_test.go b/pkg/sql/upsert_test.go index a15bc5f89bd3..3b61f1c54812 100644 --- a/pkg/sql/upsert_test.go +++ b/pkg/sql/upsert_test.go @@ -42,6 +42,7 @@ func TestUpsertFastPath(t *testing.T) { // This filter increments scans and endTxn for every ScanRequest and // EndTxnRequest that hits user table data. + var gets uint64 var scans uint64 var endTxn uint64 filter := func(filterArgs kvserverbase.FilterArgs) *roachpb.Error { @@ -49,6 +50,8 @@ func TestUpsertFastPath(t *testing.T) { switch filterArgs.Req.Method() { case roachpb.Scan: atomic.AddUint64(&scans, 1) + case roachpb.Get: + atomic.AddUint64(&gets, 1) case roachpb.EndTxn: if filterArgs.Hdr.Txn.Status == roachpb.STAGING { // Ignore async explicit commits. @@ -73,6 +76,7 @@ func TestUpsertFastPath(t *testing.T) { sqlDB.Exec(t, `CREATE TABLE d.kv (k INT PRIMARY KEY, v INT)`) // This should hit the fast path. + atomic.StoreUint64(&gets, 0) atomic.StoreUint64(&scans, 0) atomic.StoreUint64(&endTxn, 0) sqlDB.Exec(t, `UPSERT INTO d.kv VALUES (1, 1)`) @@ -84,22 +88,30 @@ func TestUpsertFastPath(t *testing.T) { } // This could hit the fast path, but doesn't right now because of #14482. + atomic.StoreUint64(&gets, 0) atomic.StoreUint64(&scans, 0) atomic.StoreUint64(&endTxn, 0) sqlDB.Exec(t, `INSERT INTO d.kv VALUES (1, 1) ON CONFLICT (k) DO UPDATE SET v=excluded.v`) - if s := atomic.LoadUint64(&scans); s != 1 { - t.Errorf("expected 1 scans (no upsert fast path) but got %d", s) + if s := atomic.LoadUint64(&gets); s != 1 { + t.Errorf("expected 1 get (no upsert fast path) but got %d", s) + } + if s := atomic.LoadUint64(&scans); s != 0 { + t.Errorf("expected 0 scans but got %d", s) } if s := atomic.LoadUint64(&endTxn); s != 0 { t.Errorf("expected no end-txn (1PC) but got %d", s) } // This should not hit the fast path because it doesn't set every column. + atomic.StoreUint64(&gets, 0) atomic.StoreUint64(&scans, 0) atomic.StoreUint64(&endTxn, 0) sqlDB.Exec(t, `UPSERT INTO d.kv (k) VALUES (1)`) - if s := atomic.LoadUint64(&scans); s != 1 { - t.Errorf("expected 1 scans (no upsert fast path) but got %d", s) + if s := atomic.LoadUint64(&gets); s != 1 { + t.Errorf("expected 1 get (no upsert fast path) but got %d", s) + } + if s := atomic.LoadUint64(&scans); s != 0 { + t.Errorf("expected 0 scans but got %d", s) } if s := atomic.LoadUint64(&endTxn); s != 0 { t.Errorf("expected no end-txn (1PC) but got %d", s) @@ -107,6 +119,7 @@ func TestUpsertFastPath(t *testing.T) { // This should hit the fast path, but won't be a 1PC because of the explicit // transaction. + atomic.StoreUint64(&gets, 0) atomic.StoreUint64(&scans, 0) atomic.StoreUint64(&endTxn, 0) tx, err := conn.Begin() @@ -119,6 +132,9 @@ func TestUpsertFastPath(t *testing.T) { if err := tx.Commit(); err != nil { t.Fatal(err) } + if s := atomic.LoadUint64(&gets); s != 0 { + t.Errorf("expected no gets (the upsert fast path) but got %d", s) + } if s := atomic.LoadUint64(&scans); s != 0 { t.Errorf("expected no scans (the upsert fast path) but got %d", s) } @@ -128,11 +144,15 @@ func TestUpsertFastPath(t *testing.T) { // This should not hit the fast path because kv has a secondary index. sqlDB.Exec(t, `CREATE INDEX vidx ON d.kv (v)`) + atomic.StoreUint64(&gets, 0) atomic.StoreUint64(&scans, 0) atomic.StoreUint64(&endTxn, 0) sqlDB.Exec(t, `UPSERT INTO d.kv VALUES (1, 1)`) - if s := atomic.LoadUint64(&scans); s != 1 { - t.Errorf("expected 1 scans (no upsert fast path) but got %d", s) + if s := atomic.LoadUint64(&gets); s != 1 { + t.Errorf("expected 1 get (no upsert fast path) but got %d", s) + } + if s := atomic.LoadUint64(&scans); s != 0 { + t.Errorf("expected 0 scans (no upsert fast path) but got %d", s) } if s := atomic.LoadUint64(&endTxn); s != 0 { t.Errorf("expected no end-txn (1PC) but got %d", s)