diff --git a/pkg/sql/logictest/testdata/logic_test/inverted_filter_geospatial_dist b/pkg/sql/logictest/testdata/logic_test/inverted_filter_geospatial_dist index db12b25a7353..59bc5b6ef46f 100644 --- a/pkg/sql/logictest/testdata/logic_test/inverted_filter_geospatial_dist +++ b/pkg/sql/logictest/testdata/logic_test/inverted_filter_geospatial_dist @@ -35,7 +35,7 @@ query T SELECT url FROM [EXPLAIN (DISTSQL) SELECT k FROM geo_table WHERE ST_Intersects('MULTIPOINT((2.2 2.2), (3.0 3.0))'::geometry, geom) ORDER BY k] ---- -https://cockroachdb.github.io/distsqlplan/decode.html#eJyUU19P2zAQf9-nsO6FVvNa2-m04afCCFumQlmaaUM4QllzYxHBzmx3yoT63ackDGhRC70HJ_fnd3e_O90tuN8lSJiFk_BDQha2JMfx9IRchN_PJgfRKekdRbNk9mXSJ3ch113AFZpLn_0okXz7FMYhcf6y0B6tw7l3vb2Tr5MkOptGp0mvJwaCiIHoU9ILBowEA9bv70n5MZyehEl8TptcN30yjY_CmByek-sUKGiT42l2gw7kBXBIKVTWzNE5YxvTbRsQ5TVIRqHQ1cI35pTC3FgEeQu-8CWChKRpMsYsRztkQCFHnxVlm_aew7jp4LLQOdZAYVZl2kkyVHCoVP0zV6rmTKmaPffAm10xXAHJdE4CRoz_hdZBuqRgFv6Bj_PZFYLkS_pyzpH-g9ZjflyUHi3aIV8l_t8f1pUlRpMxl8Q1rInzmfWyZRG8e6sUE0wpxp57gKDOd4U15NfYU5guvCRjvnEOYpc5fDaFvlu92LT6yhY3mf37UJqOxcbqwS7VZ8Z6tMNgtfKYvwYK3Wbk-tkwzkasE3H35Yx3P_sH-_fC-OiJ_hC5Iu9HT_Q9-fj6xqL_grmPdmEeo6uMdrjCfFNmtkwpYH6F3V07s7BzPLNm3pbp1GmLaw05Ot95eadEunM1DT4G861gsR0stoKD7eBgK3i0Bk6Xr_4FAAD__2cps3E= +https://cockroachdb.github.io/distsqlplan/decode.html#eJyUU11P2zAUfd-vsO4Ljea1dtJpw0-FEbZMhbA004ZwhLLmjkUEO7PdKRPqf5-SMKBFLdQPTu7HObnnOL4F-7sCAbNwGn5IycJU5DiJT8hF-P1sehCdksFRNEtnX6YeuWu57huuUF-6_EeF5NunMAmJdZelcmgszp0d7J18nabRWRydpoOBP_SJP_Q9SgbBkJFgyDxvT4iPYXwSpsk5bbluPBInR2FCDs_JdQYUlC7wNL9BC-ICOGQUaqPnaK02beq2a4iKBgSjUKp64dp0RmGuDYK4BVe6CkFA2g6ZYF6gGTGgUKDLy6qjvdcwaSe4LFWBDVCY1bmygowkHErZ_CykbDiTsmHPbfBmVwyXQHJVkIAR7X6hsZAtKeiFe9BjXX6FIPiSvlxzpP6gcVgcl5VDg2bEV4X_r4dNbYhWZMIFsa1qYl1unOhUBO_eSsl8JiVjz21AUBW7wlrxa-opxAsnyIRv9MHfxYfPulR3R-9vOvralDe5-QsUerfE-q_MOBuzfvl3T854_7J_sH-_GB8_iR86V9b78ZN4Tzy-ERPfe4EXwS5ezLRxaEbBqg8T_noj_XgX-gRtrZXFFfpNzGyZUcDiCvurbPXCzPHM6Hn3mT6MO1yXKNC6vsr7IFJ9qR3wMZhvBfvbwf5WcLAdHGwFj9fA2fLVvwAAAP__ks-wYA== # The inverted filterer handles five inverted index rows with decoded # datums, where the first column is the PK (k) and the second is the cellid @@ -65,7 +65,7 @@ query T SELECT url FROM [EXPLAIN (DISTSQL) SELECT k FROM geo_table WHERE ST_Intersects('MULTIPOINT((2.2 2.2), (3.0 3.0))'::geometry, geom) ORDER BY k] ---- -https://cockroachdb.github.io/distsqlplan/decode.html#eJyUU19P2zAQf9-nsO6FVvNa2-m04afCCFumQlmaaUM4QllzYxHBzmx3yoT63ackDGhRC70HJ_fnd3e_O90tuN8lSJiFk_BDQha2JMfx9IRchN_PJgfRKekdRbNk9mXSJ3ch113AFZpLn_0okXz7FMYhcf6y0B6tw7l3vb2Tr5MkOptGp0mvJwaCiIHoU9ILBowEA9bv70n5MZyehEl8TptcN30yjY_CmByek-sUKGiT42l2gw7kBXBIKVTWzNE5YxvTbRsQ5TVIRqHQ1cI35pTC3FgEeQu-8CWChKRpMsYsRztkQCFHnxVlm_aew7jp4LLQOdZAYVZl2kkyVHCoVP0zV6rmTKmaPffAm10xXAHJdE4CRoz_hdZBuqRgFv6Bj_PZFYLkS_pyzpH-g9ZjflyUHi3aIV8l_t8f1pUlRpMxl8Q1rInzmfWyZRG8e6sUE0wpxp57gKDOd4U15NfYU5guvCRjvnEOYpc5fDaFvlu92LT6yhY3mf37UJqOxcbqwS7VZ8Z6tMNgtfKYvwYK3Wbk-tkwzkasE3H35Yx3P_sH-_fC-OiJ_hC5Iu9HT_Q9-fj6xqL_grmPdmEeo6uMdrjCfFNmtkwpYH6F3V07s7BzPLNm3pbp1GmLaw05Ot95eadEunM1DT4G861gsR0stoKD7eBgK3i0Bk6Xr_4FAAD__2cps3E= +https://cockroachdb.github.io/distsqlplan/decode.html#eJyUU11P2zAUfd-vsO4Ljea1dtJpw0-FEbZMhbA004ZwhLLmjkUEO7PdKRPqf5-SMKBFLdQPTu7HObnnOL4F-7sCAbNwGn5IycJU5DiJT8hF-P1sehCdksFRNEtnX6YeuWu57huuUF-6_EeF5NunMAmJdZelcmgszp0d7J18nabRWRydpoOBP_SJP_Q9SgbBkJFgyDxvT4iPYXwSpsk5bbluPBInR2FCDs_JdQYUlC7wNL9BC-ICOGQUaqPnaK02beq2a4iKBgSjUKp64dp0RmGuDYK4BVe6CkFA2g6ZYF6gGTGgUKDLy6qjvdcwaSe4LFWBDVCY1bmygowkHErZ_CykbDiTsmHPbfBmVwyXQHJVkIAR7X6hsZAtKeiFe9BjXX6FIPiSvlxzpP6gcVgcl5VDg2bEV4X_r4dNbYhWZMIFsa1qYl1unOhUBO_eSsl8JiVjz21AUBW7wlrxa-opxAsnyIRv9MHfxYfPulR3R-9vOvralDe5-QsUerfE-q_MOBuzfvl3T854_7J_sH-_GB8_iR86V9b78ZN4Tzy-ERPfe4EXwS5ezLRxaEbBqg8T_noj_XgX-gRtrZXFFfpNzGyZUcDiCvurbPXCzPHM6Hn3mT6MO1yXKNC6vsr7IFJ9qR3wMZhvBfvbwf5WcLAdHGwFj9fA2fLVvwAAAP__ks-wYA== statement ok ALTER INDEX geo_table@geom_index EXPERIMENTAL_RELOCATE VALUES (ARRAY[2], 1152921574000000000) @@ -89,7 +89,7 @@ query T SELECT url FROM [EXPLAIN (DISTSQL) SELECT k FROM geo_table WHERE ST_Intersects('MULTIPOINT((2.2 2.2), (3.0 3.0))'::geometry, geom) ORDER BY k] ---- -https://cockroachdb.github.io/distsqlplan/decode.html#eJyUU19P2zAQf9-nsO6FVvNa2-m04afCCFumQlmaaUM4QllzYxHBzmx3yoT63ackDGhRC70HJ_fnd3e_O90tuN8lSJiFk_BDQha2JMfx9IRchN_PJgfRKekdRbNk9mXSJ3ch113AFZpLn_0okXz7FMYhcf6y0B6tw7l3vb2Tr5MkOptGp0mvJwaCiIHoU9ILBowEA9bv70n5MZyehEl8TptcN30yjY_CmByek-sUKGiT42l2gw7kBXBIKVTWzNE5YxvTbRsQ5TVIRqHQ1cI35pTC3FgEeQu-8CWChKRpMsYsRztkQCFHnxVlm_aew7jp4LLQOdZAYVZl2kkyVHCoVP0zV6rmTKmaPffAm10xXAHJdE4CRoz_hdZBuqRgFv6Bj_PZFYLkS_pyzpH-g9ZjflyUHi3aIV8l_t8f1pUlRpMxl8Q1rInzmfWyZRG8e6sUE0wpxp57gKDOd4U15NfYU5guvCRjvnEOYpc5fDaFvlu92LT6yhY3mf37UJqOxcbqwS7VZ8Z6tMNgtfKYvwYK3Wbk-tkwzkasE3H35Yx3P_sH-_fC-OiJ_hC5Iu9HT_Q9-fj6xqL_grmPdmEeo6uMdrjCfFNmtkwpYH6F3V07s7BzPLNm3pbp1GmLaw05Ot95eadEunM1DT4G861gsR0stoKD7eBgK3i0Bk6Xr_4FAAD__2cps3E= +https://cockroachdb.github.io/distsqlplan/decode.html#eJyUU11P2zAUfd-vsO4Ljea1dtJpw0-FEbZMhbA004ZwhLLmjkUEO7PdKRPqf5-SMKBFLdQPTu7HObnnOL4F-7sCAbNwGn5IycJU5DiJT8hF-P1sehCdksFRNEtnX6YeuWu57huuUF-6_EeF5NunMAmJdZelcmgszp0d7J18nabRWRydpoOBP_SJP_Q9SgbBkJFgyDxvT4iPYXwSpsk5bbluPBInR2FCDs_JdQYUlC7wNL9BC-ICOGQUaqPnaK02beq2a4iKBgSjUKp64dp0RmGuDYK4BVe6CkFA2g6ZYF6gGTGgUKDLy6qjvdcwaSe4LFWBDVCY1bmygowkHErZ_CykbDiTsmHPbfBmVwyXQHJVkIAR7X6hsZAtKeiFe9BjXX6FIPiSvlxzpP6gcVgcl5VDg2bEV4X_r4dNbYhWZMIFsa1qYl1unOhUBO_eSsl8JiVjz21AUBW7wlrxa-opxAsnyIRv9MHfxYfPulR3R-9vOvralDe5-QsUerfE-q_MOBuzfvl3T854_7J_sH-_GB8_iR86V9b78ZN4Tzy-ERPfe4EXwS5ezLRxaEbBqg8T_noj_XgX-gRtrZXFFfpNzGyZUcDiCvurbPXCzPHM6Hn3mT6MO1yXKNC6vsr7IFJ9qR3wMZhvBfvbwf5WcLAdHGwFj9fA2fLVvwAAAP__ks-wYA== # Data is distributed, but the filterer can't be distributed since it is not a union. query I @@ -102,7 +102,7 @@ query T SELECT url FROM [EXPLAIN (DISTSQL) SELECT k FROM geo_table WHERE ST_CoveredBy('MULTIPOINT((2.2 2.2), (3.0 3.0))'::geometry, geom) ORDER BY k] ---- -https://cockroachdb.github.io/distsqlplan/decode.html#eJyUU99P2z4Qf__-Fda90OrrtbbTacNPhRG2TIWyNNOGcIRCfWMRIc5sFwWh_u9TEgYU1ELvwcn9-Nzd5053B-5PARJm4ST8lJCFLchhPD0iZ-HPk8ledEx6B9EsmX2b9Ml9yFUXcInm3GcXBZIfX8I4JM6fz80NWtQXt72do--TJDqZRsdJrycGgoiB6FPSCwaMBAPW7-9I-TmcHoVJfEqbVNd9Mo0Pwpjsn5KrFCiURuNxdo0O5BlwSClU1szROWMb010bEOkaJKOQl9XCN-aUwtxYBHkHPvcFgoSk6THGTKMdMqCg0Wd50aZ9oDBuOjjPS401UJhVWekkGSrYV6r-pZWqOVOqZq898G5bDFdAslKTgBHjf6N1kC4pmIV_5ON8dokg-ZK-nXNU3qD1qA_zwqNFO-SrxP_5w7qyxJRkzCVxDWvifGa9bFkEH94rxQRTirHXHiBY6m1hDfln7ClMF16SMV87B7HNHL6avLxfvVi3-srm15m9fSxNx2Jt9WCb6jNjPdphsFp5zP8HCt1m5LOrYZyNWCfi_ssZ735293YfhPHRC_0xckU-jl7oO_Lp8Y1F_w1jH21DPEZXmdLhCvF1mdkypYD6EruzdmZh53hizbwt06nTFtcaNDrfeXmnRGXnahp8CuYbwWIzWGwEB5vBwUbw6Bk4Xf73NwAA__-VlLJv +https://cockroachdb.github.io/distsqlplan/decode.html#eJyUU19P2z4Uff99Cuu-0OjntXbSacNPhRG2TIWwNNOGcIRCfcciQpzZLgpC_e5TEgYU1EL94OT-OSf3HMd3YP-UIGAWTsNPKVmYkhwm8RE5C3-eTPeiYzI4iGbp7NvUI_ctV33DJepzl1-USH58CZOQWHc-1zdoUF3cDnaOvk_T6CSOjtPBwB_6xB_6HiWDYMhIMGSetyPE5zA-CtPklLZU1x6Jk4MwIfun5CoDCpVWeJxfowVxBhwyCrXRc7RWmzZ11zVEqgHBKBRVvXBtOqMw1wZB3IErXIkgIG1nTDBXaEYMKCh0eVF2tA8SJu0E50WlsAEKszqvrCAjCftSNr-UlA1nUjbstQ3ebYvhEkheKRIwot1vNBayJQW9cI96rMsvEQRf0rdrjqobNA7VYVE6NGhGfFX4v3rY1Iboiky4ILZVTazLjROdiuDDeymZz6Rk7LUNCFZqW1gr_pl6CvHCCTLha33wt_Hhqy6q-6P31x19bYrr3NwChd4t8exPZpyNWb_8-ydnvH_Z3dt9WIyPX8SPnSvr4_hFvCOeXoiJ773BimAbK2baODSjYNWGCf9_Lf14G_oEba0riyv065jZMqOA6hL7m2z1wszxxOh595k-jDtcl1BoXV_lfRBVfakd8CmYbwT7m8H-RnCwGRxsBI-fgbPlf38DAAD__7lKr14= # Move all the index data that will be read to node 2 while the query executes # at node 1. The filtering moves to node 2 when it is distributable. @@ -129,7 +129,7 @@ query T SELECT url FROM [EXPLAIN (DISTSQL) SELECT k FROM geo_table WHERE ST_Intersects('MULTIPOINT((2.2 2.2), (3.0 3.0))'::geometry, geom) ORDER BY k] ---- -https://cockroachdb.github.io/distsqlplan/decode.html#eJyUlFFP2zAQx9_3Kax7odVMaztBG34qjLBlKi1LO20IVyhrbiyi2JntTplQv_uUhAEFNaV-cHL2_e7yv9PlDtzvBUiYRMPow5Qs7YKcJuMzchl9Px8exSPSOYkn08mXYZfcu9w0Dtdornz6Y4Hk26coiYjzV7n2aB3OvevsnX0dTuPzcTyadjqiJ4joiS4lnaDHSNBj3e6elB-j8Vk0TS5oFeu2S8bJSZSQ4wtyMwMK2mQ4Sm_RgbwEDhQEzCgU1szROWOr47vaKc5KkIxCroulr45nFObGIsg78LlfIEgYmX1T9EOgkKFP80XttqJglv4Rcj69RpAHK_okMG8PPK0qkGCaoe2ztfDwUKBBJe8q1xmWQGFSpNpJ0ldwrFT5M1Oq5Eypkm3bYH9Xhisgqc5IwIjxv9A62KSZ76I51n_QesxO84VHi7bP14X_v4_KwhKjyYBL4irVxPnUelmrCN4dKMUEU4qxbRsQ1NmuWCX-mXoK46WXZMA31kHsUofPJtf3rRebWl_Y_Da1fx9T04HYmD3YJfvEWI-2H6xnHvC3QKHpjHw-k4yzkDVL3D85483L4dHhw2I8fGE_eq6t9-ELe08-He2B6L6i7uGa8i3DnKArjHb4qmlmqxkFzK6x-WE4s7RzPLdmXqdpzHHN1QcZOt_cHjRGrJur6gOfwrwVFu2waIWDdjhohcN2OGyF2TN4tnrzLwAA__-ZiOWI +https://cockroachdb.github.io/distsqlplan/decode.html#eJyUlFFP2zAQx9_3Kax7odVMaztBG34qjLBlKi1LO20IVyhrbiyi2JntTplQv_uUhAEFNaV-cHu--13y_1uXO3C_FyBhEg2jD1OytAtymozPyGX0_Xx4FI9I5ySeTCdfhl1yX3LTFFyjufLpjwWSb5-iJCLOX-Xao3U4966zd_Z1OI3Px_Fo2umIniCiJ7qUdIIeI0GPdbt7Un6MxmfRNLmgVa_bLhknJ1FCji_IzQwoaJPhKL1FB_ISOFAQMKNQWDNH54ytju_qojgrQTIKuS6WvjqeUZgbiyDvwOd-gSBhZPZN0Q-BQoY-zRd12YqCWfpHyPn0GkEerOiTxry98bRyIME0Q9tna-3hwaBBJe8q1xmWQGFSpNpJ0ldwrFT5M1Oq5Eypkm3bYH9Xhisgqc5IwIjxv9A62KSZ76I51n_QesxO84VHi7bP14X_z0dlYYnRZMAlcZVq4nxqvaxVBO8OlGKCKcXYtg0I6mxXrBL_TD2F8dJLMuAbfRC7-PDZ5Pr-6sWmqy9sfpvav0ChcUs-nxPGWciaJe5_OePNn8Ojw4fFePgifqxcW-_DF_GefDpuA9F9hRfBLl5MjPVo-8G6DwP-dmP7cK39lvlN0BVGO3zVALPVjAJm19h8I5xZ2jmeWzOvH9OE45qrDzJ0vskeNEGsm1T1gk9h3gqLdli0wkE7HLTCYTsctsLsGTxbvfkXAAD__4th4nc= query I SELECT k FROM geo_table WHERE ST_CoveredBy('MULTIPOINT((2.2 2.2), (3.0 3.0))'::geometry, geom) ORDER BY k @@ -142,7 +142,7 @@ query T SELECT url FROM [EXPLAIN (DISTSQL) SELECT k FROM geo_table WHERE ST_CoveredBy('MULTIPOINT((2.2 2.2), (3.0 3.0))'::geometry, geom) ORDER BY k] ---- -https://cockroachdb.github.io/distsqlplan/decode.html#eJyUlNFP2z4Qx99_f4V1L7T6mdZ2gjb8VBhhy1RalnbaEK5QqG8sosSZ7aIg1P99SsKAghqoH5ycfZ-7fO90uQf3ZwESJtEw-jQlS7sgx8n4hJxHP0-HB_GIdI7iyXTybdglDy7XjcMVmgufXi6Q_PgSJRFx_mJubtGivrzr7Jx8H07j03E8mnY6oieI6IkuJZ2gx0jQY93ujpSfo_FJNE3OaBXqpkvGyVGUkMMzcj0DCrnROEpv0IE8Bw4UBMwoFNbM0Tljq-P72inWJUhGIcuLpa-OZxTmxiLIe_CZXyBIGJldU_RDoKDRp9midltRMEv_BDmfXiHIvRV9Fpi3B55WBUgw1Wj7bC08PNZnUMm7yHKNJVCYFGnuJOkrOFSq_KWVKjlTqmRvbbC7LcMVkDTXJGDE-N9oHWzSzLfRHOe3aD3q42zh0aLt83Xh_-6jsrDE5GTAJXGVauJ8ar2sVQQf9pRiginF2FsbEMz1tlgl_oV6CuOll2TAN9ZBbFOHrybLH1ovNrW-sNlNau-eUtOB2Jg92Cb7xFiPth-sZx7w_4FC0xn5YiQZZyFrlnh4csabl_2D_cfFePjKfvJcWx_DV_aOfD7ZA9F9R9nDNeFvzHKCrjC5w3cNM1vNKKC-wuZ_4czSzvHUmnmdpjHHNVcfaHS-ud1rjDhvrqoPfA7zVli0w6IVDtrhoBUO2-GwFWYv4Nnqv78BAAD__z445IY= +https://cockroachdb.github.io/distsqlplan/decode.html#eJyUlNFP2z4Qx99_f4V1L7T6mdZ2gjb8VBhhy1RalnbaEK5QqG8sosSZ7aIg1P99SsKAghqoH9ye7z6XfL_W5R7cnwVImETD6NOULO2CHCfjE3Ie_TwdHsQj0jmKJ9PJt2GXPJRcNwVXaC58erlA8uNLlETE-Yu5uUWL-vKus3PyfTiNT8fxaNrpiJ4goie6lHSCHiNBj3W7O1J-jsYn0TQ5o1Wrmy4ZJ0dRQg7PyPUMKORG4yi9QQfyHDhQEDCjUFgzR-eMrY7v66JYlyAZhSwvlr46nlGYG4sg78FnfoEgYWR2TdEPgYJGn2aLumxFwSz9E-R8eoUg91b0WWPe3nhaGZBgqtH22Vp7ePRnUMm7yHKNJVCYFGnuJOkrOFSq_KWVKjlTqmRvbbC7LcMVkDTXJGDE-N9oHWzSzLfRHOe3aD3q42zh0aLt83Xh__JRWVhicjLgkrhKNXE-tV7WKoIPe0oxwZRi7K0NCOZ6W6wS_0I9hfHSSzLgG30Q2_jw1WT5w9WLTVdf2OwmtXdAoXFLvhgTxlnImiUefjnjzZ_9g_3HxXj4Kn6qXFsfw1fxjnw-bQPRfYcVwTZWTIz1aPvBug0D_v_G9uFa-zfGN0FXmNzhu-aXrWYUUF9h84lwZmnneGrNvH5ME45rrj7Q6HyT3WuCOG9S1Qs-h3krLNph0QoH7XDQCoftcNgKsxfwbPXf3wAAAP__KCLhdQ== # Bounding box operations. statement ok diff --git a/pkg/sql/logictest/testdata/logic_test/inverted_index_geospatial b/pkg/sql/logictest/testdata/logic_test/inverted_index_geospatial index f213ad03d27d..c2cdb2833a9d 100644 --- a/pkg/sql/logictest/testdata/logic_test/inverted_index_geospatial +++ b/pkg/sql/logictest/testdata/logic_test/inverted_index_geospatial @@ -28,7 +28,7 @@ SELECT k FROM geo_table WHERE ST_Intersects('SRID=26918;POINT(400003 4000003)':: query T SELECT url FROM [EXPLAIN ANALYZE SELECT k FROM geo_table WHERE ST_Intersects('SRID=26918;POINT(400003 4000003)'::geometry, geom) ORDER BY k] ---- -https://cockroachdb.github.io/distsqlplan/decode.html#eJyUVGFP2zAQ_b5fcbovUM1T7STriqdJLRC2bqVlaaWNkQqF5sYikriz3S0I9b9PSWDQQgvtB1e-u-e89-7sGzS_U5Q48vv-wRjmOoWjYHgMZ_73k363N4DuoNs__eHD7mFvNB597TfgtvSqLrwkdW6ji5Tg2yc_8MHY8yS3pA1NrdndGQW9ww9Oa0-0358Me4Pxrsc55y5Uf9xt7Ej50R8e--PglJVnZQ0YBod-APuncDVBhrmKaRBlZFCeocAJw5lWUzJG6TJ0UxX04gIlZ5jks7ktwxOGU6UJ5Q3axKaEEsclyYCimHSTI8OYbJSk1bH_NXRKBudJHlOBDEezKDcSmiHuh2HxMw7DQvAwLPhzC77ZFiNChCiPweWg7C_SBhlq9deApiiW4CFDY6M0BZtkJIGX-YtrS3cFjteGfZwsGKq5vffA2OiSUIoFe7lPvfwPaUvxUZJa0qSbYtmsu7xfzDSoHDpCgimdAmMjbWWl3H33Ngy5w8OQ8-cWBMrjbWGlYY8cG86thI54gXdZVEBGmdLXMDdUGsjhS7LeQWcbBz-rJL8dNGfdoM10kkX6-p406zjLvJ2neFejCStVdXCldp0SdxslI6Ut6aa7rKIjXiPDej7k6oXngovyajvcabX2-MPfQasr2p6oN23eFm3P8z2xIx--AR2nsa6TTzryqJNicye9bfQHZGYqN7Skf93JfDFhSPEl1e-SUXM9pROtptVn6u2wwlWBmIyts6Le9PI6VRJ8CBYbwc5msLMR7G4GuxvB3gp4snj1LwAA__8OjPdQ +https://cockroachdb.github.io/distsqlplan/decode.html#eJyUlFFv0zAQx9_5FKd72SqMaiehdEZI7bYMAl070kowlmrKmmNES-Jiu5Bp6ndHSTbYOtqteXDku_s7f__syw2anxlKHPsD_2ACC53BUTg6hjP_68mgHwyhP-wPTr_5sHsYjCfjz4MW3JZeNYWXpM5tfJERfPnghz4Ye54WlrShmTW7O-MwOHzndPZE9-3JKBhOdj3OOXehfnG3tSPle3907E_CU1atlbdgFB76IeyfwtUUGRYqoWGck0F5hgKnDOdazcgYpavQTV0QJCVKzjAt5gtbhacMZ0oTyhu0qc0IJU4qkyHFCek2R4YJ2TjN6mX_7qFXOThPi4RKZDiex4WR0I5wP4rK70kUlYJHUcmfGvDVthoRIcRFAi4HZX-QNshQq98GNMWJBA8ZGhtnGdg0Jwm8yl9cW7orcLwu7ON0yVAt7D8GxsaXhFIs2fM5BcUv0paSozSzpEm3xUNYd3m_nGtQBfSEBFORAmNjbWW9c_fN6yjiDo8izp8aEKhItpVVwB4RGy2shJ54Brs8LiGnXOlrWBiqAHL4lK4n6GxD8KNKi9uL5qy7aHOd5rG-RoYNZ7naOFxwUbWIw51OZ4_ffw46fdH1RDPp8q7oep7viR15v5d6TmsdEed_ROpLDytVTXCldh0jdxtGY6Ut6bb7kE9PvHyG1UeHJzYfnreNsZDMXBWGHhhbtzJfThlScknNr8iohZ7RiVaz-jPNdFTr6kBCxjZZ0UyCoklVBu-LxUaxs1nsbBS7m8XuRrG3Ip4uX_wJAAD__58c9D8= statement ok DROP TABLE geo_table @@ -64,7 +64,7 @@ SELECT k FROM geo_table WHERE ST_Intersects('SRID=26918;POINT(400003 4000003)':: query T SELECT url FROM [EXPLAIN ANALYZE SELECT k FROM geo_table WHERE ST_Intersects('SRID=26918;POINT(400003 4000003)'::geometry, geom) ORDER BY k] ---- -https://cockroachdb.github.io/distsqlplan/decode.html#eJykVGFP2zoU_f5-xdX9AtXzU-0kr6_4aVILhK1baVlaaWOkQqG5YxFJ3NnuVoT63ycnMKBTM6r1gyvfe87NPcfXvkPzNUeJk3AYHk1hqXM4icancBF-PBv2ByPoj_rD808h7B8PJtPJ-2EL7qE3NfCa1KVNrnKCD2_CKARjL7PSkjY0t2Z_bxINjl95nQPR_f9sPBhN9wPOOfeh-uN-a0_K1-H4NJxG58zVKlowjo7DCA7P4WaGDEuV0igpyKC8QIEzhgut5mSM0i50VwEG6QolZ5iVi6V14RnDudKE8g5tZnNCiVPXZERJSrrNkWFKNsnyquxPDT3XwWVWprRChpNFUhoJ7RgP43j1OY3jFffdwn-z4D-7ckSMkJQp-ByU_ULaIEOtvhvQlKQSPGRobJLnYLOCJHCXv7q19AAQXgCHOFszVEv76IGxyTWhFGv2cp8G5TfSltKTLLekSbfFc7Me8uFqoUGV0BMSjHMKjE20lZVy_79_45g75dwJbFwQqEx3pTnDfnFsvLQSeuIF3hXJCgoqlL6FpSGH4vAu2-6gt4uDb1VW3g-at23QFjorEn372DTreS_ouxpN2EDVwQ3sNiX-LkomSlvSbf-5ip74GxnW8yE3LzwXXLir7XGv0zngT39Hnb7oBqLedHlXdIMgDMSefPoG9LzWn52kaD7JYBf9EZmFKg0907-tMl_PGFJ6TfW7ZNRSz-lMq3n1mXo7rnhVICVj66yoN4OyTrkGn5JFI9lrJnuNZL-Z7DeSgw3ybP3XjwAAAP__-mH3Sw== +https://cockroachdb.github.io/distsqlplan/decode.html#eJyclFFv0zAQx9_5FKd72SqCaiehdEZI7bYMAl070kowlmrKmmNES-Jiu9Bp6ndHTjZYixpW8uDId_-_c_eznTvU33MUOA4GwdEEFiqHk2h0ChfB57NBPxxCf9gfnH8JYP84HE_GHwctuJfe1MJrkpcmucoJPr0LogC0ucxKQ0rTzOj9vXEUHr9xOwe8-_psFA4n-z5jjHlQvZjX2hPibTA6DSbRuWPXKlowio6DCA7P4WaKDpYypWFSkEZxgRynDs6VnJHWUtnQXSUI0yUK5mBWzhfGhqcOzqQiFHdoMpMTCpzYIiNKUlJthg6mZJIsr5b93UPPVnCZlSkt0cHxPCm1gHaMh3G8_JrG8ZJ5dmD_GPDFrh4eIyRlCh4Dab6R0uigkj81KEpSAS46qE2S52CyggQwm7-6NfQg4K4PhzhdOSgX5g8DbZJrQsFXztM5heUPUobSkyw3pEi1-Tqsh3ywnCuQJfS4AG1JgTaJMqLq3Hv1Mo6Z7ZzZBhsHBCrTXW0W2F_ERgsjoMefwK5IllBQIdUtLDRZFYMP2XaC7i4E38usvD9o7raDNldZkahbdLDmLDYvDuOM2yviMrfTOWCPn6NOn3d9Xk-6rMu7vh_4fE88vks9t7UTkerQw4aqDm5otzHydmE0lsqQanvrfHr8-f9sHm_ePH-XwiLSc1lqWits28psNXWQ0muqf0VaLtSMzpScVZ-pp6PKVwVS0qbO8noSlnXKFvjYzBvNbrPZbTR7zWav0exvmKerZ78CAAD__4tB9Do= # Also works when creating an index. statement ok @@ -76,4 +76,4 @@ CREATE INVERTED INDEX geom_index ON geo_table(geom) query T SELECT url FROM [EXPLAIN ANALYZE SELECT k FROM geo_table WHERE ST_Intersects('SRID=26918;POINT(400003 4000003)'::geometry, geom) ORDER BY k] ---- -https://cockroachdb.github.io/distsqlplan/decode.html#eJykVGFP2zoU_f5-xdX9AtXzU-0kr6_4aVILhK1baVlaaWOkQqG5YxFJ3NnuVoT63ycnMKBTM6r1gyvfe87NPcfXvkPzNUeJk3AYHk1hqXM4icancBF-PBv2ByPoj_rD808h7B8PJtPJ-2EL7qE3NfCa1KVNrnKCD2_CKARjL7PSkjY0t2Z_bxINjl95nQPR_f9sPBhN9wPOOfeh-uN-a0_K1-H4NJxG58zVKlowjo7DCA7P4WaGDEuV0igpyKC8QIEzhgut5mSM0i50VwEG6QolZ5iVi6V14RnDudKE8g5tZnNCiVPXZERJSrrNkWFKNsnyquxPDT3XwWVWprRChpNFUhoJ7RgP43j1OY3jFffdwn-z4D-7ckSMkJQp-ByU_ULaIEOtvhvQlKQSPGRobJLnYLOCJHCXv7q19AAQXgCHOFszVEv76IGxyTWhFGv2cp8G5TfSltKTLLekSbfFc7Me8uFqoUGV0BMSjHMKjE20lZVy_79_45g75dwJbFwQqEx3pTnDfnFsvLQSeuIF3hXJCgoqlL6FpSGH4vAu2-6gt4uDb1VW3g-at23QFjorEn372DTreS_ouxpN2EDVwQ3sNiX-LkomSlvSbf-5ip74GxnW8yE3LzwXXLir7XGv0zngT39Hnb7oBqLedHlXdIMgDMSefPoG9LzWn52kaD7JYBf9EZmFKg0907-tMl_PGFJ6TfW7ZNRSz-lMq3n1mXo7rnhVICVj66yoN4OyTrkGn5JFI9lrJnuNZL-Z7DeSgw3ybP3XjwAAAP__-mH3Sw== +https://cockroachdb.github.io/distsqlplan/decode.html#eJyclFFv0zAQx9_5FKd72SqCaiehdEZI7bYMAl070kowlmrKmmNES-Jiu9Bp6ndHTjZYixpW8uDId_-_c_eznTvU33MUOA4GwdEEFiqHk2h0ChfB57NBPxxCf9gfnH8JYP84HE_GHwctuJfe1MJrkpcmucoJPr0LogC0ucxKQ0rTzOj9vXEUHr9xOwe8-_psFA4n-z5jjHlQvZjX2hPibTA6DSbRuWPXKlowio6DCA7P4WaKDpYypWFSkEZxgRynDs6VnJHWUtnQXSUI0yUK5mBWzhfGhqcOzqQiFHdoMpMTCpzYIiNKUlJthg6mZJIsr5b93UPPVnCZlSkt0cHxPCm1gHaMh3G8_JrG8ZJ5dmD_GPDFrh4eIyRlCh4Dab6R0uigkj81KEpSAS46qE2S52CyggQwm7-6NfQg4K4PhzhdOSgX5g8DbZJrQsFXztM5heUPUobSkyw3pEi1-Tqsh3ywnCuQJfS4AG1JgTaJMqLq3Hv1Mo6Z7ZzZBhsHBCrTXW0W2F_ERgsjoMefwK5IllBQIdUtLDRZFYMP2XaC7i4E38usvD9o7raDNldZkahbdLDmLDYvDuOM2yviMrfTOWCPn6NOn3d9Xk-6rMu7vh_4fE88vks9t7UTkerQw4aqDm5otzHydmE0lsqQanvrfHr8-f9sHm_ePH-XwiLSc1lqWits28psNXWQ0muqf0VaLtSMzpScVZ-pp6PKVwVS0qbO8noSlnXKFvjYzBvNbrPZbTR7zWav0exvmKerZ78CAAD__4tB9Do= diff --git a/pkg/sql/opt/exec/execbuilder/testdata/inverted_index b/pkg/sql/opt/exec/execbuilder/testdata/inverted_index index 2109fd9dafea..e52d4fd204ee 100644 --- a/pkg/sql/opt/exec/execbuilder/testdata/inverted_index +++ b/pkg/sql/opt/exec/execbuilder/testdata/inverted_index @@ -644,9 +644,9 @@ EXPLAIN (VERBOSE) SELECT k FROM geo_table WHERE ST_Intersects('POINT(3.0 3.0)':: · distribution local · · · vectorized false · · project · · (k) · - │ estimated row count 330 (missing stats) · · + │ estimated row count 110 (missing stats) · · └── filter · · (k, geom) · - │ estimated row count 330 (missing stats) · · + │ estimated row count 110 (missing stats) · · │ filter st_intersects('010100000000000000000008400000000000000840', geom) · · └── index join · · (k, geom) · │ estimated row count 111 (missing stats) · · diff --git a/pkg/sql/opt/memo/statistics_builder.go b/pkg/sql/opt/memo/statistics_builder.go index f0ec88938280..1c2a4b3fe75b 100644 --- a/pkg/sql/opt/memo/statistics_builder.go +++ b/pkg/sql/opt/memo/statistics_builder.go @@ -656,8 +656,7 @@ func (sb *statisticsBuilder) buildScan(scan *ScanExpr, relProps *props.Relationa // the constraint selectivity and the partial index predicate (if it exists) // to the underlying table stats. if scan.InvertedConstraint != nil { - // TODO(mjibson): support partial index predicates for inverted constraints. - sb.invertedConstrainScan(scan, relProps) + sb.invertedConstrainScan(scan, pred, relProps) sb.finalizeFromCardinality(relProps) return } @@ -789,7 +788,9 @@ func (sb *statisticsBuilder) constrainScan( // invertedConstrainScan is called from buildScan to calculate the stats for // the scan based on the given inverted constraint. -func (sb *statisticsBuilder) invertedConstrainScan(scan *ScanExpr, relProps *props.Relational) { +func (sb *statisticsBuilder) invertedConstrainScan( + scan *ScanExpr, pred FiltersExpr, relProps *props.Relational, +) { s := &relProps.Stats // Calculate distinct counts and histograms for constrained columns @@ -831,14 +832,41 @@ func (sb *statisticsBuilder) invertedConstrainScan(scan *ScanExpr, relProps *pro numUnappliedConjuncts += 2 } - // Inverted indexes don't contain NULLs, so we do not need to have - // updateNullCountsFromNotNullCols or selectivityFromNullsRemoved here. + // Set null counts to 0 for non-nullable columns + // --------------------------------------------- + // Inverted indexes don't contain NULLs, so there is no need to try to + // determine not-null columns from the constraint. However, the partial + // index predicate may guarantee that non-indexed columns are not-null. + notNullCols := relProps.NotNullCols.Copy() + if pred != nil { + // Add any not-null columns from the predicate constraints. + for i := range pred { + if c := pred[i].ScalarProps().Constraints; c != nil { + cols := c.ExtractNotNullCols(sb.evalCtx) + const distinctCount = math.MaxFloat64 + sb.ensureColStat(cols, distinctCount, scan, s) + notNullCols.UnionWith(cols) + } + } + } + sb.updateNullCountsFromNotNullCols(notNullCols, s) + + // Calculate distinct counts and histograms for the partial index predicate + // ------------------------------------------------------------------------ + if pred != nil { + predUnappliedConjucts, predConstrainedCols, predHistCols := sb.applyFilter(pred, scan, relProps) + numUnappliedConjuncts += predUnappliedConjucts + constrainedCols.UnionWith(predConstrainedCols) + constrainedCols = sb.tryReduceCols(constrainedCols, s, &scan.Relational().FuncDeps) + histCols.UnionWith(predHistCols) + } // Calculate row count and selectivity // ----------------------------------- s.ApplySelectivity(sb.selectivityFromHistograms(histCols, scan, s)) s.ApplySelectivity(sb.selectivityFromMultiColDistinctCounts(constrainedCols, scan, s)) s.ApplySelectivity(sb.selectivityFromUnappliedConjuncts(numUnappliedConjuncts)) + s.ApplySelectivity(sb.selectivityFromNullsRemoved(scan, notNullCols, constrainedCols)) // Adjust the selectivity so we don't double-count the histogram columns. s.ApplySelectivity(1.0 / sb.selectivityFromSingleColDistinctCounts(histCols, scan, s)) @@ -2995,6 +3023,12 @@ func (sb *statisticsBuilder) applyFilter( histCols.UnionWith(histColsLocal) if !scalarProps.TightConstraints { numUnappliedConjuncts++ + // Mimic invertedConstrainScan in the case of no histogram + // information that assumes a geo function is a single closed + // span that corresponds to two "conjuncts". + if isGeoIndexScanCond(conjunct.Condition) { + numUnappliedConjuncts++ + } } } else { numUnappliedConjuncts++ @@ -3942,6 +3976,19 @@ func isGeoIndexJoinCond(cond opt.ScalarExpr) bool { return false } +// isGeoIndexScanCond returns true if the given condition is an +// index-accelerated geospatial function with one variable argument. +func isGeoIndexScanCond(cond opt.ScalarExpr) bool { + if fn, ok := cond.(*FunctionExpr); ok { + if _, ok := geoindex.RelationshipMap[fn.Name]; ok && len(fn.Args) >= 2 { + firstIsVar := fn.Args[0].Op() == opt.VariableOp + secondIsVar := fn.Args[1].Op() == opt.VariableOp + return (firstIsVar && !secondIsVar) || (!firstIsVar && secondIsVar) + } + } + return false +} + func hasGeoIndexJoinCond(filters FiltersExpr) bool { for i := range filters { if isGeoIndexJoinCond(filters[i].Condition) { diff --git a/pkg/sql/opt/memo/testdata/stats/inverted-geo b/pkg/sql/opt/memo/testdata/stats/inverted-geo index 01378940495a..9b0befe7dad4 100644 --- a/pkg/sql/opt/memo/testdata/stats/inverted-geo +++ b/pkg/sql/opt/memo/testdata/stats/inverted-geo @@ -73,13 +73,13 @@ project ├── sort │ ├── columns: i:1(int) g:2(geometry!null) │ ├── immutable - │ ├── stats: [rows=666.666667, distinct(2)=7, null(2)=0] + │ ├── stats: [rows=222.222222, distinct(2)=7, null(2)=0] │ ├── ordering: +1 │ ├── limit hint: 1.00 │ └── select │ ├── columns: i:1(int) g:2(geometry!null) │ ├── immutable - │ ├── stats: [rows=666.666667, distinct(2)=7, null(2)=0] + │ ├── stats: [rows=222.222222, distinct(2)=7, null(2)=0] │ ├── scan t │ │ ├── columns: i:1(int) g:2(geometry) │ │ └── stats: [rows=2000, distinct(2)=7, null(2)=0] @@ -94,22 +94,22 @@ memo (optimized, ~11KB, required=[presentation: i:1]) ├── G1: (project G2 G3 i) │ └── [presentation: i:1] │ ├── best: (project G2 G3 i) - │ └── cost: 4262.50 + │ └── cost: 4163.18 ├── G2: (limit G4 G5 ordering=+1) │ └── [] │ ├── best: (limit G4="[ordering: +1] [limit hint: 1.00]" G5 ordering=+1) - │ └── cost: 4262.48 + │ └── cost: 4163.16 ├── G3: (projections) ├── G4: (select G6 G7) (select G8 G7) │ ├── [ordering: +1] [limit hint: 1.00] │ │ ├── best: (sort G4) - │ │ └── cost: 4262.46 + │ │ └── cost: 4163.14 │ └── [] │ ├── best: (select G6 G7) │ └── cost: 4124.04 ├── G5: (const 1) ├── G6: (scan t,cols=(1,2)) - │ ├── [ordering: +1] [limit hint: 3.00] + │ ├── [ordering: +1] [limit hint: 9.00] │ │ ├── best: (sort G6) │ │ └── cost: 2582.66 │ └── [] @@ -117,7 +117,7 @@ memo (optimized, ~11KB, required=[presentation: i:1]) │ └── cost: 2104.02 ├── G7: (filters G9) ├── G8: (index-join G10 t,cols=(1,2)) - │ ├── [ordering: +1] [limit hint: 4.50] + │ ├── [ordering: +1] [limit hint: 13.50] │ │ ├── best: (sort G8) │ │ └── cost: 22095.08 │ └── [] @@ -159,7 +159,7 @@ project ├── select │ ├── columns: i:1(int) g:2(geometry!null) │ ├── immutable - │ ├── stats: [rows=666.666667, distinct(2)=7, null(2)=0] + │ ├── stats: [rows=222.222222, distinct(2)=7, null(2)=0] │ ├── ordering: +1 │ ├── limit hint: 1.00 │ ├── sort @@ -213,7 +213,7 @@ memo (optimized, ~11KB, required=[presentation: i:1]) │ └── cost: 4.05 ├── G5: (const 1) ├── G6: (scan t,cols=(1,2)) - │ ├── [ordering: +1] [limit hint: 3.00] + │ ├── [ordering: +1] [limit hint: 9.00] │ │ ├── best: (sort G6) │ │ └── cost: 2582.66 │ └── [] @@ -328,7 +328,7 @@ project ├── columns: i:1(int) ├── cardinality: [0 - 1] ├── immutable - ├── stats: [rows=1, distinct(1)=0.999851422, null(1)=0.025, distinct(2)=0.932539762, null(2)=0] + ├── stats: [rows=1, distinct(1)=0.999867838, null(1)=0.025, distinct(2)=0.933913991, null(2)=0] ├── key: () ├── fd: ()-->(1) └── limit @@ -336,19 +336,19 @@ project ├── internal-ordering: +1 ├── cardinality: [0 - 1] ├── immutable - ├── stats: [rows=1, distinct(1)=0.999851422, null(1)=0.025, distinct(2)=0.932539762, null(2)=0] + ├── stats: [rows=1, distinct(1)=0.999867838, null(1)=0.025, distinct(2)=0.933913991, null(2)=0] ├── key: () ├── fd: ()-->(1,2) ├── sort │ ├── columns: i:1(int) g:2(geometry!null) │ ├── immutable - │ ├── stats: [rows=633.333333, distinct(1)=533.055556, null(1)=15.8333333, distinct(2)=7, null(2)=0] + │ ├── stats: [rows=211.111111, distinct(1)=199.969136, null(1)=5.27777778, distinct(2)=7, null(2)=0] │ ├── ordering: +1 │ ├── limit hint: 1.00 │ └── select │ ├── columns: i:1(int) g:2(geometry!null) │ ├── immutable - │ ├── stats: [rows=633.333333, distinct(1)=533.055556, null(1)=15.8333333, distinct(2)=7, null(2)=0] + │ ├── stats: [rows=211.111111, distinct(1)=199.969136, null(1)=5.27777778, distinct(2)=7, null(2)=0] │ ├── scan t │ │ ├── columns: i:1(int) g:2(geometry) │ │ └── stats: [rows=2000, distinct(1)=1000, null(1)=50, distinct(2)=7, null(2)=100] @@ -364,7 +364,7 @@ project ├── columns: i:1(int) ├── cardinality: [0 - 1] ├── immutable - ├── stats: [rows=1, distinct(1)=0.999851422, null(1)=0.025, distinct(2)=0.932539762, null(2)=0] + ├── stats: [rows=1, distinct(1)=0.999867838, null(1)=0.025, distinct(2)=0.933913991, null(2)=0] ├── key: () ├── fd: ()-->(1) └── limit @@ -372,13 +372,13 @@ project ├── internal-ordering: +1 ├── cardinality: [0 - 1] ├── immutable - ├── stats: [rows=1, distinct(1)=0.999851422, null(1)=0.025, distinct(2)=0.932539762, null(2)=0] + ├── stats: [rows=1, distinct(1)=0.999867838, null(1)=0.025, distinct(2)=0.933913991, null(2)=0] ├── key: () ├── fd: ()-->(1,2) ├── select │ ├── columns: i:1(int) g:2(geometry!null) │ ├── immutable - │ ├── stats: [rows=633.333333, distinct(1)=533.055556, null(1)=15.8333333, distinct(2)=7, null(2)=0] + │ ├── stats: [rows=211.111111, distinct(1)=199.969136, null(1)=5.27777778, distinct(2)=7, null(2)=0] │ ├── ordering: +1 │ ├── limit hint: 1.00 │ ├── sort @@ -461,7 +461,7 @@ SELECT * FROM t WHERE st_intersects('LINESTRING(.5 .5, .7 .7)', g) select ├── columns: i:1(int) g:2(geometry!null) ├── immutable - ├── stats: [rows=33.3333333, distinct(1)=28.7528606, null(1)=30, distinct(2)=4, null(2)=0] + ├── stats: [rows=11.1111111, distinct(1)=10.5717006, null(1)=10, distinct(2)=4, null(2)=0] ├── index-join t │ ├── columns: i:1(int) g:2(geometry) │ ├── stats: [rows=100] @@ -499,11 +499,11 @@ SELECT i FROM t@secondary WHERE st_intersects('LINESTRING(.5 .5, .7 .7)', g) project ├── columns: i:1(int) ├── immutable - ├── stats: [rows=33.3333333] + ├── stats: [rows=11.1111111] └── select ├── columns: i:1(int) g:2(geometry!null) ├── immutable - ├── stats: [rows=33.3333333, distinct(2)=4, null(2)=0] + ├── stats: [rows=11.1111111, distinct(2)=4, null(2)=0] ├── index-join t │ ├── columns: i:1(int) g:2(geometry) │ ├── stats: [rows=100] diff --git a/pkg/sql/opt/memo/testdata/stats/partial-index-scan b/pkg/sql/opt/memo/testdata/stats/partial-index-scan index 4c848a250836..fbabee6fa3c1 100644 --- a/pkg/sql/opt/memo/testdata/stats/partial-index-scan +++ b/pkg/sql/opt/memo/testdata/stats/partial-index-scan @@ -1113,3 +1113,518 @@ select │ └── key: (1) └── filters └── (i:2 > 0) AND (i:2 <= 100) [type=bool, outer=(2), constraints=(/2: [/1 - /100]; tight)] + +# ---------------------------------------------------------- +# Tests for partial inverted spatial indexes +# ---------------------------------------------------------- + +exec-ddl +CREATE TABLE spatial ( + k INT PRIMARY KEY, + g GEOMETRY, + s STRING, + INVERTED INDEX i (g), + INVERTED INDEX p (g) WHERE s IN ('apple', 'banana', 'cherry') +) +---- + +# Add non-histogram stats. +exec-ddl +ALTER TABLE spatial INJECT STATISTICS '[ + { + "columns": ["g"], + "created_at": "2018-01-01 1:00:00.00000+00:00", + "row_count": 2000, + "distinct_count": 7, + "null_count": 0 + }, + { + "columns": ["s"], + "created_at": "2018-01-01 1:00:00.00000+00:00", + "row_count": 2000, + "distinct_count": 40, + "null_count": 0 + } +]' +---- + +# The partial index should be preferred over the non-partial index or PK. +opt +SELECT k FROM spatial WHERE st_intersects('LINESTRING(0.5 0.5, 0.7 0.7)', g) AND s IN ('apple', 'banana', 'cherry') +---- +project + ├── columns: k:1(int!null) + ├── immutable + ├── stats: [rows=16.6666667] + ├── key: (1) + └── select + ├── columns: k:1(int!null) g:2(geometry!null) s:3(string!null) + ├── immutable + ├── stats: [rows=16.6666667, distinct(2)=7, null(2)=0, distinct(3)=3, null(3)=0] + ├── key: (1) + ├── fd: (1)-->(2,3) + ├── index-join spatial + │ ├── columns: k:1(int!null) g:2(geometry) s:3(string) + │ ├── stats: [rows=16.6666667] + │ ├── key: (1) + │ ├── fd: (1)-->(2,3) + │ └── inverted-filter + │ ├── columns: k:1(int!null) + │ ├── inverted expression: /6 + │ │ ├── tight: false + │ │ └── union spans + │ │ ├── ["B\xfd\x10\x00\x00\x00\x00\x00\x00\x00", "B\xfd\x10\x00\x00\x00\x00\x00\x00\x00"] + │ │ ├── ["B\xfd\x10\x00\x00\x00\x00\x00\x00\x01", "B\xfd\x12\x00\x00\x00\x00\x00\x00\x00") + │ │ └── ["B\xfd\x14\x00\x00\x00\x00\x00\x00\x00", "B\xfd\x14\x00\x00\x00\x00\x00\x00\x00"] + │ ├── pre-filterer expression + │ │ └── st_intersects('010200000002000000000000000000E03F000000000000E03F666666666666E63F666666666666E63F', g:2) [type=bool] + │ ├── stats: [rows=16.6666667] + │ ├── key: (1) + │ └── scan spatial@p,partial + │ ├── columns: k:1(int!null) g_inverted_key:6(geometry!null) + │ ├── inverted constraint: /6/1 + │ │ └── spans + │ │ ├── ["B\xfd\x10\x00\x00\x00\x00\x00\x00\x00", "B\xfd\x10\x00\x00\x00\x00\x00\x00\x00"] + │ │ ├── ["B\xfd\x10\x00\x00\x00\x00\x00\x00\x01", "B\xfd\x12\x00\x00\x00\x00\x00\x00\x00") + │ │ └── ["B\xfd\x14\x00\x00\x00\x00\x00\x00\x00", "B\xfd\x14\x00\x00\x00\x00\x00\x00\x00"] + │ ├── stats: [rows=16.6666667, distinct(1)=16.6666667, null(1)=0, distinct(3)=3, null(3)=0, distinct(6)=16.6666667, null(6)=0] + │ ├── key: (1) + │ └── fd: (1)-->(6) + └── filters + └── st_intersects('010200000002000000000000000000E03F000000000000E03F666666666666E63F666666666666E63F', g:2) [type=bool, outer=(2), immutable, constraints=(/2: (/NULL - ])] + +# The partial index should be preferred over the non-partial index or PK when +# there is an additional filter to apply on s. +opt +SELECT k FROM spatial WHERE st_intersects('LINESTRING(0.5 0.5, 0.7 0.7)', g) AND s = 'banana' +---- +project + ├── columns: k:1(int!null) + ├── immutable + ├── stats: [rows=5.55555556] + ├── key: (1) + └── select + ├── columns: k:1(int!null) g:2(geometry!null) s:3(string!null) + ├── immutable + ├── stats: [rows=5.55555556, distinct(2)=5.55555556, null(2)=0, distinct(3)=1, null(3)=0] + ├── key: (1) + ├── fd: ()-->(3), (1)-->(2) + ├── index-join spatial + │ ├── columns: k:1(int!null) g:2(geometry) s:3(string) + │ ├── stats: [rows=16.6666667] + │ ├── key: (1) + │ ├── fd: (1)-->(2,3) + │ └── inverted-filter + │ ├── columns: k:1(int!null) + │ ├── inverted expression: /6 + │ │ ├── tight: false + │ │ └── union spans + │ │ ├── ["B\xfd\x10\x00\x00\x00\x00\x00\x00\x00", "B\xfd\x10\x00\x00\x00\x00\x00\x00\x00"] + │ │ ├── ["B\xfd\x10\x00\x00\x00\x00\x00\x00\x01", "B\xfd\x12\x00\x00\x00\x00\x00\x00\x00") + │ │ └── ["B\xfd\x14\x00\x00\x00\x00\x00\x00\x00", "B\xfd\x14\x00\x00\x00\x00\x00\x00\x00"] + │ ├── pre-filterer expression + │ │ └── st_intersects('010200000002000000000000000000E03F000000000000E03F666666666666E63F666666666666E63F', g:2) [type=bool] + │ ├── stats: [rows=16.6666667] + │ ├── key: (1) + │ └── scan spatial@p,partial + │ ├── columns: k:1(int!null) g_inverted_key:6(geometry!null) + │ ├── inverted constraint: /6/1 + │ │ └── spans + │ │ ├── ["B\xfd\x10\x00\x00\x00\x00\x00\x00\x00", "B\xfd\x10\x00\x00\x00\x00\x00\x00\x00"] + │ │ ├── ["B\xfd\x10\x00\x00\x00\x00\x00\x00\x01", "B\xfd\x12\x00\x00\x00\x00\x00\x00\x00") + │ │ └── ["B\xfd\x14\x00\x00\x00\x00\x00\x00\x00", "B\xfd\x14\x00\x00\x00\x00\x00\x00\x00"] + │ ├── stats: [rows=16.6666667, distinct(1)=16.6666667, null(1)=0, distinct(3)=3, null(3)=0, distinct(6)=16.6666667, null(6)=0] + │ ├── key: (1) + │ └── fd: (1)-->(6) + └── filters + ├── st_intersects('010200000002000000000000000000E03F000000000000E03F666666666666E63F666666666666E63F', g:2) [type=bool, outer=(2), immutable, constraints=(/2: (/NULL - ])] + └── s:3 = 'banana' [type=bool, outer=(3), constraints=(/3: [/'banana' - /'banana']; tight), fd=()-->(3)] + +# Add null values for s. +exec-ddl +ALTER TABLE spatial INJECT STATISTICS '[ + { + "columns": ["g"], + "created_at": "2018-01-01 1:00:00.00000+00:00", + "row_count": 2000, + "distinct_count": 7, + "null_count": 0 + }, + { + "columns": ["s"], + "created_at": "2018-01-01 1:00:00.00000+00:00", + "row_count": 2000, + "distinct_count": 40, + "null_count": 1000 + } +]' +---- + +opt +SELECT k FROM spatial WHERE st_intersects('LINESTRING(0.5 0.5, 0.7 0.7)', g) AND s IN ('apple', 'banana', 'cherry') +---- +project + ├── columns: k:1(int!null) + ├── immutable + ├── stats: [rows=8.54700855] + ├── key: (1) + └── select + ├── columns: k:1(int!null) g:2(geometry!null) s:3(string!null) + ├── immutable + ├── stats: [rows=8.54700855, distinct(2)=7, null(2)=0, distinct(3)=3, null(3)=0] + ├── key: (1) + ├── fd: (1)-->(2,3) + ├── index-join spatial + │ ├── columns: k:1(int!null) g:2(geometry) s:3(string) + │ ├── stats: [rows=8.54700855] + │ ├── key: (1) + │ ├── fd: (1)-->(2,3) + │ └── inverted-filter + │ ├── columns: k:1(int!null) + │ ├── inverted expression: /6 + │ │ ├── tight: false + │ │ └── union spans + │ │ ├── ["B\xfd\x10\x00\x00\x00\x00\x00\x00\x00", "B\xfd\x10\x00\x00\x00\x00\x00\x00\x00"] + │ │ ├── ["B\xfd\x10\x00\x00\x00\x00\x00\x00\x01", "B\xfd\x12\x00\x00\x00\x00\x00\x00\x00") + │ │ └── ["B\xfd\x14\x00\x00\x00\x00\x00\x00\x00", "B\xfd\x14\x00\x00\x00\x00\x00\x00\x00"] + │ ├── pre-filterer expression + │ │ └── st_intersects('010200000002000000000000000000E03F000000000000E03F666666666666E63F666666666666E63F', g:2) [type=bool] + │ ├── stats: [rows=8.54700855] + │ ├── key: (1) + │ └── scan spatial@p,partial + │ ├── columns: k:1(int!null) g_inverted_key:6(geometry!null) + │ ├── inverted constraint: /6/1 + │ │ └── spans + │ │ ├── ["B\xfd\x10\x00\x00\x00\x00\x00\x00\x00", "B\xfd\x10\x00\x00\x00\x00\x00\x00\x00"] + │ │ ├── ["B\xfd\x10\x00\x00\x00\x00\x00\x00\x01", "B\xfd\x12\x00\x00\x00\x00\x00\x00\x00") + │ │ └── ["B\xfd\x14\x00\x00\x00\x00\x00\x00\x00", "B\xfd\x14\x00\x00\x00\x00\x00\x00\x00"] + │ ├── stats: [rows=8.54700855, distinct(1)=8.54700855, null(1)=0, distinct(3)=3, null(3)=0, distinct(6)=8.54700855, null(6)=0] + │ ├── key: (1) + │ └── fd: (1)-->(6) + └── filters + └── st_intersects('010200000002000000000000000000E03F000000000000E03F666666666666E63F666666666666E63F', g:2) [type=bool, outer=(2), immutable, constraints=(/2: (/NULL - ])] + +opt +SELECT k FROM spatial WHERE st_intersects('LINESTRING(0.5 0.5, 0.7 0.7)', g) AND s = 'banana' +---- +project + ├── columns: k:1(int!null) + ├── immutable + ├── stats: [rows=2.84900285] + ├── key: (1) + └── select + ├── columns: k:1(int!null) g:2(geometry!null) s:3(string!null) + ├── immutable + ├── stats: [rows=2.84900285, distinct(2)=2.84900285, null(2)=0, distinct(3)=1, null(3)=0] + ├── key: (1) + ├── fd: ()-->(3), (1)-->(2) + ├── index-join spatial + │ ├── columns: k:1(int!null) g:2(geometry) s:3(string) + │ ├── stats: [rows=8.54700855] + │ ├── key: (1) + │ ├── fd: (1)-->(2,3) + │ └── inverted-filter + │ ├── columns: k:1(int!null) + │ ├── inverted expression: /6 + │ │ ├── tight: false + │ │ └── union spans + │ │ ├── ["B\xfd\x10\x00\x00\x00\x00\x00\x00\x00", "B\xfd\x10\x00\x00\x00\x00\x00\x00\x00"] + │ │ ├── ["B\xfd\x10\x00\x00\x00\x00\x00\x00\x01", "B\xfd\x12\x00\x00\x00\x00\x00\x00\x00") + │ │ └── ["B\xfd\x14\x00\x00\x00\x00\x00\x00\x00", "B\xfd\x14\x00\x00\x00\x00\x00\x00\x00"] + │ ├── pre-filterer expression + │ │ └── st_intersects('010200000002000000000000000000E03F000000000000E03F666666666666E63F666666666666E63F', g:2) [type=bool] + │ ├── stats: [rows=8.54700855] + │ ├── key: (1) + │ └── scan spatial@p,partial + │ ├── columns: k:1(int!null) g_inverted_key:6(geometry!null) + │ ├── inverted constraint: /6/1 + │ │ └── spans + │ │ ├── ["B\xfd\x10\x00\x00\x00\x00\x00\x00\x00", "B\xfd\x10\x00\x00\x00\x00\x00\x00\x00"] + │ │ ├── ["B\xfd\x10\x00\x00\x00\x00\x00\x00\x01", "B\xfd\x12\x00\x00\x00\x00\x00\x00\x00") + │ │ └── ["B\xfd\x14\x00\x00\x00\x00\x00\x00\x00", "B\xfd\x14\x00\x00\x00\x00\x00\x00\x00"] + │ ├── stats: [rows=8.54700855, distinct(1)=8.54700855, null(1)=0, distinct(3)=3, null(3)=0, distinct(6)=8.54700855, null(6)=0] + │ ├── key: (1) + │ └── fd: (1)-->(6) + └── filters + ├── st_intersects('010200000002000000000000000000E03F000000000000E03F666666666666E63F666666666666E63F', g:2) [type=bool, outer=(2), immutable, constraints=(/2: (/NULL - ])] + └── s:3 = 'banana' [type=bool, outer=(3), constraints=(/3: [/'banana' - /'banana']; tight), fd=()-->(3)] + +# Add histogram statistics. +# +# Histogram boundaries are from a `POLYGON((0.0 0.0, 1.0 0.0, 1.0 1.0, +# 0.0 1.0, 0.0 0.0))` row. The row_count is lower than the sum of the +# histogram's num_eq and num_range because there are more entries in +# the inverted index than rows in the table. +exec-ddl +ALTER TABLE spatial INJECT STATISTICS '[ + { + "columns": ["g"], + "created_at": "2018-01-01 1:00:00.00000+00:00", + "row_count": 2000, + "distinct_count": 7, + "null_count": 0, + "histo_col_type":"BYTES", + "histo_buckets":[ + {"num_eq": 1000, "num_range": 0, "distinct_range": 0, "upper_bound": "\\x42fd0555555555555555"}, + {"num_eq": 1000, "num_range": 1000, "distinct_range": 1, "upper_bound": "\\x42fd0fffffff00000000"}, + {"num_eq": 1000, "num_range": 1000, "distinct_range": 1, "upper_bound": "\\x42fd1000000100000000"}, + {"num_eq": 1000, "num_range": 1000, "distinct_range": 1, "upper_bound": "\\x42fd1aaaaaab00000000"} + ] + }, + { + "columns": ["s"], + "created_at": "2018-01-01 1:00:00.00000+00:00", + "row_count": 2000, + "distinct_count": 40, + "null_count": 0, + "histo_col_type": "string", + "histo_buckets": [ + {"num_eq": 0, "num_range": 0, "distinct_range": 0, "upper_bound": "apple"}, + {"num_eq": 100, "num_range": 300, "distinct_range": 9, "upper_bound": "banana"}, + {"num_eq": 100, "num_range": 300, "distinct_range": 9, "upper_bound": "cherry"}, + {"num_eq": 200, "num_range": 400, "distinct_range": 9, "upper_bound": "mango"}, + {"num_eq": 200, "num_range": 400, "distinct_range": 9, "upper_bound": "pineapple"} + ] + } +]' +---- + +# The partial index should be preferred over the non-partial index or PK. +opt +SELECT k FROM spatial WHERE st_intersects('LINESTRING(0.5 0.5, 0.7 0.7)', g) AND s IN ('apple', 'banana', 'cherry') +---- +project + ├── columns: k:1(int!null) + ├── immutable + ├── stats: [rows=22.2222222] + ├── key: (1) + └── select + ├── columns: k:1(int!null) g:2(geometry!null) s:3(string!null) + ├── immutable + ├── stats: [rows=22.2222222, distinct(2)=7, null(2)=0, distinct(3)=2, null(3)=0] + │ histogram(3)= 0 11.111 0 11.111 + │ <--- 'banana' --- 'cherry' + ├── key: (1) + ├── fd: (1)-->(2,3) + ├── index-join spatial + │ ├── columns: k:1(int!null) g:2(geometry) s:3(string) + │ ├── stats: [rows=300] + │ ├── key: (1) + │ ├── fd: (1)-->(2,3) + │ └── inverted-filter + │ ├── columns: k:1(int!null) + │ ├── inverted expression: /6 + │ │ ├── tight: false + │ │ └── union spans + │ │ ├── ["B\xfd\x10\x00\x00\x00\x00\x00\x00\x00", "B\xfd\x10\x00\x00\x00\x00\x00\x00\x00"] + │ │ ├── ["B\xfd\x10\x00\x00\x00\x00\x00\x00\x01", "B\xfd\x12\x00\x00\x00\x00\x00\x00\x00") + │ │ └── ["B\xfd\x14\x00\x00\x00\x00\x00\x00\x00", "B\xfd\x14\x00\x00\x00\x00\x00\x00\x00"] + │ ├── pre-filterer expression + │ │ └── st_intersects('010200000002000000000000000000E03F000000000000E03F666666666666E63F666666666666E63F', g:2) [type=bool] + │ ├── stats: [rows=300] + │ ├── key: (1) + │ └── scan spatial@p,partial + │ ├── columns: k:1(int!null) g_inverted_key:6(geometry!null) + │ ├── inverted constraint: /6/1 + │ │ └── spans + │ │ ├── ["B\xfd\x10\x00\x00\x00\x00\x00\x00\x00", "B\xfd\x10\x00\x00\x00\x00\x00\x00\x00"] + │ │ ├── ["B\xfd\x10\x00\x00\x00\x00\x00\x00\x01", "B\xfd\x12\x00\x00\x00\x00\x00\x00\x00") + │ │ └── ["B\xfd\x14\x00\x00\x00\x00\x00\x00\x00", "B\xfd\x14\x00\x00\x00\x00\x00\x00\x00"] + │ ├── stats: [rows=300, distinct(1)=85.7142857, null(1)=0, distinct(3)=2, null(3)=0, distinct(6)=3, null(6)=0, distinct(3,6)=6, null(3,6)=0] + │ │ histogram(3)= 0 100 0 100 + │ │ <--- 'banana' --- 'cherry' + │ │ histogram(6)= 0 0 50 0 50 100 50 0 0 0 50 0 + │ │ <--- '\x42fd1000000000000000' ---- '\x42fd1000000000000001' ---- '\x42fd1000000100000000' ---- '\x42fd1200000000000000' --- '\x42fd1400000000000000' ---- '\x42fd1400000000000001' + │ ├── key: (1) + │ └── fd: (1)-->(6) + └── filters + └── st_intersects('010200000002000000000000000000E03F000000000000E03F666666666666E63F666666666666E63F', g:2) [type=bool, outer=(2), immutable, constraints=(/2: (/NULL - ])] + +# The partial index should be preferred over the non-partial index or PK when +# there is an additional filter to apply on s. +opt +SELECT k FROM spatial WHERE st_intersects('LINESTRING(0.5 0.5, 0.7 0.7)', g) AND s = 'banana' +---- +project + ├── columns: k:1(int!null) + ├── immutable + ├── stats: [rows=11.1111111] + ├── key: (1) + └── select + ├── columns: k:1(int!null) g:2(geometry!null) s:3(string!null) + ├── immutable + ├── stats: [rows=11.1111111, distinct(2)=7, null(2)=0, distinct(3)=1, null(3)=0] + │ histogram(3)= 0 11.111 + │ <--- 'banana' + ├── key: (1) + ├── fd: ()-->(3), (1)-->(2) + ├── index-join spatial + │ ├── columns: k:1(int!null) g:2(geometry) s:3(string) + │ ├── stats: [rows=300] + │ ├── key: (1) + │ ├── fd: (1)-->(2,3) + │ └── inverted-filter + │ ├── columns: k:1(int!null) + │ ├── inverted expression: /6 + │ │ ├── tight: false + │ │ └── union spans + │ │ ├── ["B\xfd\x10\x00\x00\x00\x00\x00\x00\x00", "B\xfd\x10\x00\x00\x00\x00\x00\x00\x00"] + │ │ ├── ["B\xfd\x10\x00\x00\x00\x00\x00\x00\x01", "B\xfd\x12\x00\x00\x00\x00\x00\x00\x00") + │ │ └── ["B\xfd\x14\x00\x00\x00\x00\x00\x00\x00", "B\xfd\x14\x00\x00\x00\x00\x00\x00\x00"] + │ ├── pre-filterer expression + │ │ └── st_intersects('010200000002000000000000000000E03F000000000000E03F666666666666E63F666666666666E63F', g:2) [type=bool] + │ ├── stats: [rows=300] + │ ├── key: (1) + │ └── scan spatial@p,partial + │ ├── columns: k:1(int!null) g_inverted_key:6(geometry!null) + │ ├── inverted constraint: /6/1 + │ │ └── spans + │ │ ├── ["B\xfd\x10\x00\x00\x00\x00\x00\x00\x00", "B\xfd\x10\x00\x00\x00\x00\x00\x00\x00"] + │ │ ├── ["B\xfd\x10\x00\x00\x00\x00\x00\x00\x01", "B\xfd\x12\x00\x00\x00\x00\x00\x00\x00") + │ │ └── ["B\xfd\x14\x00\x00\x00\x00\x00\x00\x00", "B\xfd\x14\x00\x00\x00\x00\x00\x00\x00"] + │ ├── stats: [rows=300, distinct(1)=85.7142857, null(1)=0, distinct(3)=2, null(3)=0, distinct(6)=3, null(6)=0, distinct(3,6)=6, null(3,6)=0] + │ │ histogram(3)= 0 100 0 100 + │ │ <--- 'banana' --- 'cherry' + │ │ histogram(6)= 0 0 50 0 50 100 50 0 0 0 50 0 + │ │ <--- '\x42fd1000000000000000' ---- '\x42fd1000000000000001' ---- '\x42fd1000000100000000' ---- '\x42fd1200000000000000' --- '\x42fd1400000000000000' ---- '\x42fd1400000000000001' + │ ├── key: (1) + │ └── fd: (1)-->(6) + └── filters + ├── st_intersects('010200000002000000000000000000E03F000000000000E03F666666666666E63F666666666666E63F', g:2) [type=bool, outer=(2), immutable, constraints=(/2: (/NULL - ])] + └── s:3 = 'banana' [type=bool, outer=(3), constraints=(/3: [/'banana' - /'banana']; tight), fd=()-->(3)] + +# Add null values for s. +exec-ddl +ALTER TABLE spatial INJECT STATISTICS '[ + { + "columns": ["g"], + "created_at": "2018-01-01 1:00:00.00000+00:00", + "row_count": 2000, + "distinct_count": 7, + "null_count": 0, + "histo_col_type":"BYTES", + "histo_buckets":[ + {"num_eq": 1000, "num_range": 0, "distinct_range": 0, "upper_bound": "\\x42fd0555555555555555"}, + {"num_eq": 1000, "num_range": 1000, "distinct_range": 1, "upper_bound": "\\x42fd0fffffff00000000"}, + {"num_eq": 1000, "num_range": 1000, "distinct_range": 1, "upper_bound": "\\x42fd1000000100000000"}, + {"num_eq": 1000, "num_range": 1000, "distinct_range": 1, "upper_bound": "\\x42fd1aaaaaab00000000"} + ] + }, + { + "columns": ["s"], + "created_at": "2018-01-01 1:00:00.00000+00:00", + "row_count": 2000, + "distinct_count": 40, + "null_count": 100, + "histo_col_type": "string", + "histo_buckets": [ + {"num_eq": 0, "num_range": 0, "distinct_range": 0, "upper_bound": "apple"}, + {"num_eq": 100, "num_range": 200, "distinct_range": 9, "upper_bound": "banana"}, + {"num_eq": 100, "num_range": 300, "distinct_range": 9, "upper_bound": "cherry"}, + {"num_eq": 200, "num_range": 400, "distinct_range": 9, "upper_bound": "mango"}, + {"num_eq": 200, "num_range": 400, "distinct_range": 9, "upper_bound": "pineapple"} + ] + } +]' +---- + +opt +SELECT k FROM spatial WHERE st_intersects('LINESTRING(0.5 0.5, 0.7 0.7)', g) AND s IN ('apple', 'banana', 'cherry') +---- +project + ├── columns: k:1(int!null) + ├── immutable + ├── stats: [rows=22.2222222] + ├── key: (1) + └── select + ├── columns: k:1(int!null) g:2(geometry!null) s:3(string!null) + ├── immutable + ├── stats: [rows=22.2222222, distinct(2)=7, null(2)=0, distinct(3)=3, null(3)=0] + │ histogram(3)= 0 11.111 0 11.111 + │ <--- 'banana' --- 'cherry' + ├── key: (1) + ├── fd: (1)-->(2,3) + ├── index-join spatial + │ ├── columns: k:1(int!null) g:2(geometry) s:3(string) + │ ├── stats: [rows=307.105263] + │ ├── key: (1) + │ ├── fd: (1)-->(2,3) + │ └── inverted-filter + │ ├── columns: k:1(int!null) + │ ├── inverted expression: /6 + │ │ ├── tight: false + │ │ └── union spans + │ │ ├── ["B\xfd\x10\x00\x00\x00\x00\x00\x00\x00", "B\xfd\x10\x00\x00\x00\x00\x00\x00\x00"] + │ │ ├── ["B\xfd\x10\x00\x00\x00\x00\x00\x00\x01", "B\xfd\x12\x00\x00\x00\x00\x00\x00\x00") + │ │ └── ["B\xfd\x14\x00\x00\x00\x00\x00\x00\x00", "B\xfd\x14\x00\x00\x00\x00\x00\x00\x00"] + │ ├── pre-filterer expression + │ │ └── st_intersects('010200000002000000000000000000E03F000000000000E03F666666666666E63F666666666666E63F', g:2) [type=bool] + │ ├── stats: [rows=307.105263] + │ ├── key: (1) + │ └── scan spatial@p,partial + │ ├── columns: k:1(int!null) g_inverted_key:6(geometry!null) + │ ├── inverted constraint: /6/1 + │ │ └── spans + │ │ ├── ["B\xfd\x10\x00\x00\x00\x00\x00\x00\x00", "B\xfd\x10\x00\x00\x00\x00\x00\x00\x00"] + │ │ ├── ["B\xfd\x10\x00\x00\x00\x00\x00\x00\x01", "B\xfd\x12\x00\x00\x00\x00\x00\x00\x00") + │ │ └── ["B\xfd\x14\x00\x00\x00\x00\x00\x00\x00", "B\xfd\x14\x00\x00\x00\x00\x00\x00\x00"] + │ ├── stats: [rows=307.105263, distinct(1)=87.7443609, null(1)=0, distinct(3)=2, null(3)=0, distinct(6)=3, null(6)=0, distinct(3,6)=6, null(3,6)=0] + │ │ histogram(3)= 0 100 0 100 + │ │ <--- 'banana' --- 'cherry' + │ │ histogram(6)= 0 0 51.184 0 51.184 102.37 51.184 0 0 0 51.184 0 + │ │ <--- '\x42fd1000000000000000' -------- '\x42fd1000000000000001' -------- '\x42fd1000000100000000' -------- '\x42fd1200000000000000' --- '\x42fd1400000000000000' -------- '\x42fd1400000000000001' + │ ├── key: (1) + │ └── fd: (1)-->(6) + └── filters + └── st_intersects('010200000002000000000000000000E03F000000000000E03F666666666666E63F666666666666E63F', g:2) [type=bool, outer=(2), immutable, constraints=(/2: (/NULL - ])] + +opt +SELECT k FROM spatial WHERE st_intersects('LINESTRING(0.5 0.5, 0.7 0.7)', g) AND s = 'banana' +---- +project + ├── columns: k:1(int!null) + ├── immutable + ├── stats: [rows=11.1111111] + ├── key: (1) + └── select + ├── columns: k:1(int!null) g:2(geometry!null) s:3(string!null) + ├── immutable + ├── stats: [rows=11.1111111, distinct(2)=7, null(2)=0, distinct(3)=2, null(3)=0] + │ histogram(3)= 0 11.111 + │ <--- 'banana' + ├── key: (1) + ├── fd: ()-->(3), (1)-->(2) + ├── index-join spatial + │ ├── columns: k:1(int!null) g:2(geometry) s:3(string) + │ ├── stats: [rows=307.105263] + │ ├── key: (1) + │ ├── fd: (1)-->(2,3) + │ └── inverted-filter + │ ├── columns: k:1(int!null) + │ ├── inverted expression: /6 + │ │ ├── tight: false + │ │ └── union spans + │ │ ├── ["B\xfd\x10\x00\x00\x00\x00\x00\x00\x00", "B\xfd\x10\x00\x00\x00\x00\x00\x00\x00"] + │ │ ├── ["B\xfd\x10\x00\x00\x00\x00\x00\x00\x01", "B\xfd\x12\x00\x00\x00\x00\x00\x00\x00") + │ │ └── ["B\xfd\x14\x00\x00\x00\x00\x00\x00\x00", "B\xfd\x14\x00\x00\x00\x00\x00\x00\x00"] + │ ├── pre-filterer expression + │ │ └── st_intersects('010200000002000000000000000000E03F000000000000E03F666666666666E63F666666666666E63F', g:2) [type=bool] + │ ├── stats: [rows=307.105263] + │ ├── key: (1) + │ └── scan spatial@p,partial + │ ├── columns: k:1(int!null) g_inverted_key:6(geometry!null) + │ ├── inverted constraint: /6/1 + │ │ └── spans + │ │ ├── ["B\xfd\x10\x00\x00\x00\x00\x00\x00\x00", "B\xfd\x10\x00\x00\x00\x00\x00\x00\x00"] + │ │ ├── ["B\xfd\x10\x00\x00\x00\x00\x00\x00\x01", "B\xfd\x12\x00\x00\x00\x00\x00\x00\x00") + │ │ └── ["B\xfd\x14\x00\x00\x00\x00\x00\x00\x00", "B\xfd\x14\x00\x00\x00\x00\x00\x00\x00"] + │ ├── stats: [rows=307.105263, distinct(1)=87.7443609, null(1)=0, distinct(3)=2, null(3)=0, distinct(6)=3, null(6)=0, distinct(3,6)=6, null(3,6)=0] + │ │ histogram(3)= 0 100 0 100 + │ │ <--- 'banana' --- 'cherry' + │ │ histogram(6)= 0 0 51.184 0 51.184 102.37 51.184 0 0 0 51.184 0 + │ │ <--- '\x42fd1000000000000000' -------- '\x42fd1000000000000001' -------- '\x42fd1000000100000000' -------- '\x42fd1200000000000000' --- '\x42fd1400000000000000' -------- '\x42fd1400000000000001' + │ ├── key: (1) + │ └── fd: (1)-->(6) + └── filters + ├── st_intersects('010200000002000000000000000000E03F000000000000E03F666666666666E63F666666666666E63F', g:2) [type=bool, outer=(2), immutable, constraints=(/2: (/NULL - ])] + └── s:3 = 'banana' [type=bool, outer=(3), constraints=(/3: [/'banana' - /'banana']; tight), fd=()-->(3)] diff --git a/pkg/sql/opt/xform/testdata/external/postgis-tutorial-idx b/pkg/sql/opt/xform/testdata/external/postgis-tutorial-idx index e49cc8277ca9..455fd8e4ed71 100644 --- a/pkg/sql/opt/xform/testdata/external/postgis-tutorial-idx +++ b/pkg/sql/opt/xform/testdata/external/postgis-tutorial-idx @@ -22,35 +22,34 @@ WHERE ORDER BY name, boroname ---- -project +sort ├── columns: name:3 boroname:2 ├── immutable ├── ordering: +3,+2 - └── select - ├── columns: boroname:2 name:3 geom:4!null + └── project + ├── columns: boroname:2 name:3 ├── immutable - ├── ordering: +3,+2 - ├── sort - │ ├── columns: boroname:2 name:3 geom:4 - │ ├── ordering: +3,+2 - │ └── index-join nyc_neighborhoods - │ ├── columns: boroname:2 name:3 geom:4 - │ └── inverted-filter - │ ├── columns: gid:1!null - │ ├── inverted expression: /6 - │ │ ├── tight: false - │ │ └── union spans: ["B\xfd\xff\xff\xff\xff\xff\xff\xff\xff", "B\xfd\xff\xff\xff\xff\xff\xff\xff\xff"] - │ ├── pre-filterer expression - │ │ └── st_intersects('0101000020266900000000000026CF21410000008016315141', geom:4) - │ ├── key: (1) - │ └── scan nyc_neighborhoods@nyc_neighborhoods_geom_idx - │ ├── columns: gid:1!null geom_inverted_key:6!null - │ ├── inverted constraint: /6/1 - │ │ └── spans: ["B\xfd\xff\xff\xff\xff\xff\xff\xff\xff", "B\xfd\xff\xff\xff\xff\xff\xff\xff\xff"] - │ ├── key: (1) - │ └── fd: (1)-->(6) - └── filters - └── st_intersects(geom:4, '0101000020266900000000000026CF21410000008016315141') [outer=(4), immutable, constraints=(/4: (/NULL - ])] + └── select + ├── columns: boroname:2 name:3 geom:4!null + ├── immutable + ├── index-join nyc_neighborhoods + │ ├── columns: boroname:2 name:3 geom:4 + │ └── inverted-filter + │ ├── columns: gid:1!null + │ ├── inverted expression: /6 + │ │ ├── tight: false + │ │ └── union spans: ["B\xfd\xff\xff\xff\xff\xff\xff\xff\xff", "B\xfd\xff\xff\xff\xff\xff\xff\xff\xff"] + │ ├── pre-filterer expression + │ │ └── st_intersects('0101000020266900000000000026CF21410000008016315141', geom:4) + │ ├── key: (1) + │ └── scan nyc_neighborhoods@nyc_neighborhoods_geom_idx + │ ├── columns: gid:1!null geom_inverted_key:6!null + │ ├── inverted constraint: /6/1 + │ │ └── spans: ["B\xfd\xff\xff\xff\xff\xff\xff\xff\xff", "B\xfd\xff\xff\xff\xff\xff\xff\xff\xff"] + │ ├── key: (1) + │ └── fd: (1)-->(6) + └── filters + └── st_intersects(geom:4, '0101000020266900000000000026CF21410000008016315141') [outer=(4), immutable, constraints=(/4: (/NULL - ])] # 11.6 opt @@ -67,35 +66,34 @@ WHERE ORDER BY name ASC ---- -project +sort ├── columns: name:3 ├── immutable ├── ordering: +3 - └── select - ├── columns: name:3 geom:6!null + └── project + ├── columns: name:3 ├── immutable - ├── ordering: +3 - ├── sort - │ ├── columns: name:3 geom:6 - │ ├── ordering: +3 - │ └── index-join nyc_streets - │ ├── columns: name:3 geom:6 - │ └── inverted-filter - │ ├── columns: gid:1!null - │ ├── inverted expression: /8 - │ │ ├── tight: false - │ │ └── union spans: ["B\xfd\xff\xff\xff\xff\xff\xff\xff\xff", "B\xfd\xff\xff\xff\xff\xff\xff\xff\xff"] - │ ├── pre-filterer expression - │ │ └── st_dwithin('0101000020266900000000000026CF21410000008016315141', geom:6, 10.0) - │ ├── key: (1) - │ └── scan nyc_streets@nyc_streets_geom_idx - │ ├── columns: gid:1!null geom_inverted_key:8!null - │ ├── inverted constraint: /8/1 - │ │ └── spans: ["B\xfd\xff\xff\xff\xff\xff\xff\xff\xff", "B\xfd\xff\xff\xff\xff\xff\xff\xff\xff"] - │ ├── key: (1) - │ └── fd: (1)-->(8) - └── filters - └── st_dwithin(geom:6, '0101000020266900000000000026CF21410000008016315141', 10.0) [outer=(6), immutable, constraints=(/6: (/NULL - ])] + └── select + ├── columns: name:3 geom:6!null + ├── immutable + ├── index-join nyc_streets + │ ├── columns: name:3 geom:6 + │ └── inverted-filter + │ ├── columns: gid:1!null + │ ├── inverted expression: /8 + │ │ ├── tight: false + │ │ └── union spans: ["B\xfd\xff\xff\xff\xff\xff\xff\xff\xff", "B\xfd\xff\xff\xff\xff\xff\xff\xff\xff"] + │ ├── pre-filterer expression + │ │ └── st_dwithin('0101000020266900000000000026CF21410000008016315141', geom:6, 10.0) + │ ├── key: (1) + │ └── scan nyc_streets@nyc_streets_geom_idx + │ ├── columns: gid:1!null geom_inverted_key:8!null + │ ├── inverted constraint: /8/1 + │ │ └── spans: ["B\xfd\xff\xff\xff\xff\xff\xff\xff\xff", "B\xfd\xff\xff\xff\xff\xff\xff\xff\xff"] + │ ├── key: (1) + │ └── fd: (1)-->(8) + └── filters + └── st_dwithin(geom:6, '0101000020266900000000000026CF21410000008016315141', 10.0) [outer=(6), immutable, constraints=(/6: (/NULL - ])] # 12.1.2 opt @@ -114,35 +112,34 @@ WHERE ORDER BY name, boroname ---- -project +sort ├── columns: name:3 boroname:2 ├── immutable ├── ordering: +3,+2 - └── select - ├── columns: boroname:2 name:3 geom:4!null + └── project + ├── columns: boroname:2 name:3 ├── immutable - ├── ordering: +3,+2 - ├── sort - │ ├── columns: boroname:2 name:3 geom:4 - │ ├── ordering: +3,+2 - │ └── index-join nyc_neighborhoods - │ ├── columns: boroname:2 name:3 geom:4 - │ └── inverted-filter - │ ├── columns: gid:1!null - │ ├── inverted expression: /6 - │ │ ├── tight: false - │ │ └── union spans: ["B\xfd\xff\xff\xff\xff\xff\xff\xff\xff", "B\xfd\xff\xff\xff\xff\xff\xff\xff\xff"] - │ ├── pre-filterer expression - │ │ └── st_intersects('01020000202669000002000000000000003CE8214100000080A22E514100000000E0E8214100000000A62E5141', geom:4) - │ ├── key: (1) - │ └── scan nyc_neighborhoods@nyc_neighborhoods_geom_idx - │ ├── columns: gid:1!null geom_inverted_key:6!null - │ ├── inverted constraint: /6/1 - │ │ └── spans: ["B\xfd\xff\xff\xff\xff\xff\xff\xff\xff", "B\xfd\xff\xff\xff\xff\xff\xff\xff\xff"] - │ ├── key: (1) - │ └── fd: (1)-->(6) - └── filters - └── st_intersects(geom:4, '01020000202669000002000000000000003CE8214100000080A22E514100000000E0E8214100000000A62E5141') [outer=(4), immutable, constraints=(/4: (/NULL - ])] + └── select + ├── columns: boroname:2 name:3 geom:4!null + ├── immutable + ├── index-join nyc_neighborhoods + │ ├── columns: boroname:2 name:3 geom:4 + │ └── inverted-filter + │ ├── columns: gid:1!null + │ ├── inverted expression: /6 + │ │ ├── tight: false + │ │ └── union spans: ["B\xfd\xff\xff\xff\xff\xff\xff\xff\xff", "B\xfd\xff\xff\xff\xff\xff\xff\xff\xff"] + │ ├── pre-filterer expression + │ │ └── st_intersects('01020000202669000002000000000000003CE8214100000080A22E514100000000E0E8214100000000A62E5141', geom:4) + │ ├── key: (1) + │ └── scan nyc_neighborhoods@nyc_neighborhoods_geom_idx + │ ├── columns: gid:1!null geom_inverted_key:6!null + │ ├── inverted constraint: /6/1 + │ │ └── spans: ["B\xfd\xff\xff\xff\xff\xff\xff\xff\xff", "B\xfd\xff\xff\xff\xff\xff\xff\xff\xff"] + │ ├── key: (1) + │ └── fd: (1)-->(6) + └── filters + └── st_intersects(geom:4, '01020000202669000002000000000000003CE8214100000080A22E514100000000E0E8214100000000A62E5141') [outer=(4), immutable, constraints=(/4: (/NULL - ])] # 12.2.3 opt @@ -162,35 +159,34 @@ WHERE ORDER BY name ---- -project +sort ├── columns: name:3 ├── immutable ├── ordering: +3 - └── select - ├── columns: name:3 geom:6!null + └── project + ├── columns: name:3 ├── immutable - ├── ordering: +3 - ├── sort - │ ├── columns: name:3 geom:6 - │ ├── ordering: +3 - │ └── index-join nyc_streets - │ ├── columns: name:3 geom:6 - │ └── inverted-filter - │ ├── columns: gid:1!null - │ ├── inverted expression: /8 - │ │ ├── tight: false - │ │ └── union spans: ["B\xfd\xff\xff\xff\xff\xff\xff\xff\xff", "B\xfd\xff\xff\xff\xff\xff\xff\xff\xff"] - │ ├── pre-filterer expression - │ │ └── st_dwithin('01020000202669000002000000000000003CE8214100000080A22E514100000000E0E8214100000000A62E5141', geom:6, 0.1) - │ ├── key: (1) - │ └── scan nyc_streets@nyc_streets_geom_idx - │ ├── columns: gid:1!null geom_inverted_key:8!null - │ ├── inverted constraint: /8/1 - │ │ └── spans: ["B\xfd\xff\xff\xff\xff\xff\xff\xff\xff", "B\xfd\xff\xff\xff\xff\xff\xff\xff\xff"] - │ ├── key: (1) - │ └── fd: (1)-->(8) - └── filters - └── st_dwithin(geom:6, '01020000202669000002000000000000003CE8214100000080A22E514100000000E0E8214100000000A62E5141', 0.1) [outer=(6), immutable, constraints=(/6: (/NULL - ])] + └── select + ├── columns: name:3 geom:6!null + ├── immutable + ├── index-join nyc_streets + │ ├── columns: name:3 geom:6 + │ └── inverted-filter + │ ├── columns: gid:1!null + │ ├── inverted expression: /8 + │ │ ├── tight: false + │ │ └── union spans: ["B\xfd\xff\xff\xff\xff\xff\xff\xff\xff", "B\xfd\xff\xff\xff\xff\xff\xff\xff\xff"] + │ ├── pre-filterer expression + │ │ └── st_dwithin('01020000202669000002000000000000003CE8214100000080A22E514100000000E0E8214100000000A62E5141', geom:6, 0.1) + │ ├── key: (1) + │ └── scan nyc_streets@nyc_streets_geom_idx + │ ├── columns: gid:1!null geom_inverted_key:8!null + │ ├── inverted constraint: /8/1 + │ │ └── spans: ["B\xfd\xff\xff\xff\xff\xff\xff\xff\xff", "B\xfd\xff\xff\xff\xff\xff\xff\xff\xff"] + │ ├── key: (1) + │ └── fd: (1)-->(8) + └── filters + └── st_dwithin(geom:6, '01020000202669000002000000000000003CE8214100000080A22E514100000000E0E8214100000000A62E5141', 0.1) [outer=(6), immutable, constraints=(/6: (/NULL - ])] # 12.2.4 opt