This is an automated email from the ASF dual-hosted git repository.

reshke pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudberry.git

commit 7d0ea5944ecb60ddf13080e7bf9784b610bd5ef9
Author: David Kimura <[email protected]>
AuthorDate: Thu Sep 7 13:34:21 2023 -0700

    [ORCA] Add fallback on relations with 'hnsw' index type (#16384)
    
    Extension of commit 26c3382759b3 that falls back to planner for queries
    using 'ivfflat' indexes from pgvector. However, there is another similar
    index 'hnsw' added in pgvector 0.5.0. Add 'hnsw' to the list of indexes
    ORCA will fall back when it encounters.
    
    An alternative approach was considered to fallback for any unsupported
    index. However, the downside of that is that it will lead to many more
    fallbacks when a table has an unsupported index. That could severely
    limit ORCA's ability to operate on that table.
    
    NB: This is intended as a temporary hack to avoid ORCA from picking bad
    plans until ORCA is able to support these indexes.
    
    Following test falls back to PLANNER:
      ```
      CREATE EXTENSION embedding;
      CREATE TABLE documents(id INTEGER, embedding REAL[]);
      CREATE INDEX ON documents USING hnsw(embedding) WITH (maxelements=1000, 
dims=3, m=8);
    
      EXPLAIN SELECT id FROM documents ORDER BY embedding <-> array[1.1, 2.2, 
3.3] LIMIT 1;
      ```
---
 .../gpopt/translate/CTranslatorRelcacheToDXL.cpp       | 18 ++++++++++++------
 .../gporca/libgpos/include/gpos/string/CWStringBase.h  |  3 +++
 .../server/src/unittest/gpos/string/CWStringTest.cpp   |  2 ++
 src/backend/gporca/libgpos/src/string/CWStringBase.cpp | 16 ++++++++++++++++
 .../gporca/libgpos/src/string/CWStringConst.cpp        |  1 -
 5 files changed, 33 insertions(+), 7 deletions(-)

diff --git a/src/backend/gpopt/translate/CTranslatorRelcacheToDXL.cpp 
b/src/backend/gpopt/translate/CTranslatorRelcacheToDXL.cpp
index 478972dc54..bca58a4c2d 100644
--- a/src/backend/gpopt/translate/CTranslatorRelcacheToDXL.cpp
+++ b/src/backend/gpopt/translate/CTranslatorRelcacheToDXL.cpp
@@ -2805,22 +2805,28 @@ CTranslatorRelcacheToDXL::IsIndexSupported(Relation 
index_rel)
                return true;
        }
 
-       // Fall back if query is on a relation with a pgvector index (ivfflat)
-       // Orca currently does not generate index scan alternatives here
-       // Fall back to ensure users can get better performing index plans 
using planner
+       // Fall back if query is on a relation with a pgvector index (ivfflat) 
or
+       // pg_embedding index (hnsw). Orca currently does not generate index 
scan
+       // alternatives here. Fall back to ensure users can get better 
performing
+       // index plans using planner.
+       //
+       // An alternative approach was considered to fall back for any 
unsupported
+       // index. However, the downside of that is that it will lead to many 
more
+       // fall backs when a table has an unsupported index. That could severely
+       // limit ORCA's ability to operate on that table.
        CAutoMemoryPool amp;
        CMemoryPool *mp = amp.Pmp();
        CWStringDynamic *am_name_str = 
CDXLUtils::CreateDynamicStringFromCharArray(
                mp, gpdb::GetRelAmName(index_rel->rd_rel->relam));
 
-       CWStringConst str_pgvector_am(GPOS_WSZ_LIT("ivfflat"));
-       if (am_name_str->Equals(&str_pgvector_am))
+       if (am_name_str->Equals(GPOS_WSZ_LIT("ivfflat")) ||
+               am_name_str->Equals(GPOS_WSZ_LIT("hnsw")))
        {
                GPOS_DELETE(am_name_str);
                GPOS_RAISE(
                        gpdxl::ExmaMD, gpdxl::ExmiMDObjUnsupported,
                        GPOS_WSZ_LIT(
-                               "Queries on relations with pgvector indexes 
(ivfflat) are not supported"));
+                               "Queries on relations with pgvector indexes 
(ivfflat) or pg_embedding indexes (hnsw) are not supported"));
        }
        GPOS_DELETE(am_name_str);
        return false;
diff --git a/src/backend/gporca/libgpos/include/gpos/string/CWStringBase.h 
b/src/backend/gporca/libgpos/include/gpos/string/CWStringBase.h
index b532c44eb2..56738a379c 100644
--- a/src/backend/gporca/libgpos/include/gpos/string/CWStringBase.h
+++ b/src/backend/gporca/libgpos/include/gpos/string/CWStringBase.h
@@ -74,6 +74,9 @@ public:
        // checks whether the string is byte-wise equal to another string
        virtual BOOL Equals(const CWStringBase *str) const;
 
+       // checks whether the string is equal to a string literal
+       virtual BOOL Equals(const WCHAR *str) const;
+
        // checks whether the string contains any characters
        virtual BOOL IsEmpty() const;
 
diff --git 
a/src/backend/gporca/libgpos/server/src/unittest/gpos/string/CWStringTest.cpp 
b/src/backend/gporca/libgpos/server/src/unittest/gpos/string/CWStringTest.cpp
index 321ca9bca7..e561a937f0 100644
--- 
a/src/backend/gporca/libgpos/server/src/unittest/gpos/string/CWStringTest.cpp
+++ 
b/src/backend/gporca/libgpos/server/src/unittest/gpos/string/CWStringTest.cpp
@@ -376,6 +376,8 @@ CWStringTest::EresUnittest_Equals()
        GPOS_ASSERT(str1->Equals(str2));
        GPOS_ASSERT(!str1->Equals(str3));
        GPOS_ASSERT(!str3->Equals(str1));
+       GPOS_ASSERT(str3->Equals(GPOS_WSZ_LIT("12")));
+       GPOS_ASSERT(!str3->Equals(GPOS_WSZ_LIT("123")));
 
        // static strings
        WCHAR buffer1[8];
diff --git a/src/backend/gporca/libgpos/src/string/CWStringBase.cpp 
b/src/backend/gporca/libgpos/src/string/CWStringBase.cpp
index 210f204fe3..126f17a691 100644
--- a/src/backend/gporca/libgpos/src/string/CWStringBase.cpp
+++ b/src/backend/gporca/libgpos/src/string/CWStringBase.cpp
@@ -93,6 +93,22 @@ CWStringBase::Equals(const CWStringBase *str) const
                   0 == clib::Wcsncmp(GetBuffer(), str->GetBuffer(), Length());
 }
 
+//---------------------------------------------------------------------------
+//     @function:
+//             CWStringBase::Equals
+//
+//     @doc:
+//             Checks whether the string is equal to a string literal
+//
+//---------------------------------------------------------------------------
+BOOL
+CWStringBase::Equals(const WCHAR *str) const
+{
+       GPOS_ASSERT(nullptr != str);
+       return Length() == GPOS_WSZ_LENGTH(str) &&
+                  0 == clib::Wcsncmp(GetBuffer(), str, Length());
+}
+
 //---------------------------------------------------------------------------
 //     @function:
 //             CWStringBase::IsEmpty
diff --git a/src/backend/gporca/libgpos/src/string/CWStringConst.cpp 
b/src/backend/gporca/libgpos/src/string/CWStringConst.cpp
index 9f30302d02..31f0be1546 100644
--- a/src/backend/gporca/libgpos/src/string/CWStringConst.cpp
+++ b/src/backend/gporca/libgpos/src/string/CWStringConst.cpp
@@ -142,7 +142,6 @@ CWStringConst::HashValue(const CWStringConst *string)
 BOOL
 CWStringConst::Equals(const CWStringBase *str) const
 {
-       GPOS_ASSERT(nullptr != str);
        GPOS_ASSERT(nullptr != str);
        return Length() == str->Length() &&
                   0 == clib::Wcsncmp(GetBuffer(), str->GetBuffer(), Length());


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to