Skip to content

Commit f996bdd

Browse files
committed
fix: sorting by string with OPTION scroll
Related issue #3928
1 parent 9f06c49 commit f996bdd

File tree

4 files changed

+189
-36
lines changed

4 files changed

+189
-36
lines changed

src/sorterscroll.cpp

Lines changed: 48 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ class ScrollSorter_T : public ISphMatchSorter
6464
CSphVector<CSphRowitem> m_dStatic;
6565
CSphMatchComparatorState m_tState;
6666
ScrollSettings_t m_tScroll;
67+
CSphVector<BYTE*> m_dAllocatedPtrs; // Track allocated pointer values directly
6768

6869
FORCE_INLINE bool PushMatch ( const CSphMatch & tEntry );
6970
void SetupRefMatch();
@@ -122,8 +123,10 @@ void ScrollSorter_T<COMP>::SetupRefMatch()
122123
const ISphSchema * pSchema = m_pSorter->GetSchema();
123124
assert(pSchema);
124125

126+
// Free old data pointer attributes before resetting
125127
FreeDataPtrAttrs();
126-
m_tRefMatch.Reset ( pSchema->GetRowSize() );
128+
129+
m_tRefMatch.Reset ( pSchema->GetDynamicSize() );
127130
m_dStatic.Resize ( pSchema->GetStaticSize() );
128131
m_tRefMatch.m_pStatic = m_dStatic.Begin();
129132

@@ -137,11 +140,32 @@ void ScrollSorter_T<COMP>::SetupRefMatch()
137140
}
138141

139142
auto pAttr = pSchema->GetAttr ( i.m_sSortAttr.cstr() );
143+
if ( !pAttr )
144+
continue;
145+
146+
// If the scroll token has a string type and the schema attribute is SPH_ATTR_STRING,
147+
// use the remapped STRINGPTR version (used for sorting)
148+
if ( i.m_eType==SPH_ATTR_STRINGPTR && pAttr->m_eAttrType==SPH_ATTR_STRING )
149+
{
150+
CSphString sRemappedName;
151+
sRemappedName.SetSprintf ( "@int_attr_%s", i.m_sSortAttr.cstr() );
152+
auto pRemapped = pSchema->GetAttr ( sRemappedName.cstr() );
153+
if ( pRemapped && pRemapped->m_eAttrType==SPH_ATTR_STRINGPTR )
154+
pAttr = pRemapped;
155+
}
156+
140157
auto pRowData = pAttr->m_tLocator.m_bDynamic ? m_tRefMatch.m_pDynamic : m_dStatic.Begin();
141158
switch ( i.m_eType )
142159
{
143160
case SPH_ATTR_STRINGPTR:
144-
sphSetRowAttr ( pRowData, pAttr->m_tLocator, (SphAttr_t)sphPackPtrAttr ( { (const BYTE*)i.m_sValue.cstr(), i.m_sValue.Length() } ) );
161+
// After remapping, pAttr should be SPH_ATTR_STRINGPTR, but check to be safe
162+
if ( pAttr->m_eAttrType==SPH_ATTR_STRINGPTR )
163+
{
164+
BYTE * pPacked = sphPackPtrAttr ( { (const BYTE*)i.m_sValue.cstr(), i.m_sValue.Length() } );
165+
sphSetRowAttr ( pRowData, pAttr->m_tLocator, (SphAttr_t)pPacked );
166+
// Track the allocated pointer value directly
167+
m_dAllocatedPtrs.Add(pPacked);
168+
}
145169
break;
146170

147171
case SPH_ATTR_FLOAT:
@@ -158,25 +182,16 @@ void ScrollSorter_T<COMP>::SetupRefMatch()
158182
template <typename COMP>
159183
void ScrollSorter_T<COMP>::FreeDataPtrAttrs()
160184
{
161-
if ( !m_tRefMatch.m_pDynamic )
162-
return;
163-
164-
const ISphSchema * pSchema = m_pSorter->GetSchema();
165-
assert(pSchema);
166-
167-
for ( auto & i : m_tScroll.m_dAttrs )
185+
// Free all pointers we allocated directly
186+
// We store the pointer values themselves, not the attributes, so we don't need
187+
// to access m_tRefMatch which might have been reset
188+
for ( auto pPacked : m_dAllocatedPtrs )
168189
{
169-
if ( i.m_sSortAttr=="weight()" )
170-
continue;
171-
172-
const CSphColumnInfo * pAttr = pSchema->GetAttr ( i.m_sSortAttr.cstr() );
173-
assert(pAttr);
174-
if ( sphIsDataPtrAttr ( pAttr->m_eAttrType ) )
175-
{
176-
auto pData = (BYTE *)m_tRefMatch.GetAttr ( pAttr->m_tLocator );
177-
sphDeallocatePacked(pData);
178-
}
190+
if ( pPacked )
191+
sphDeallocatePacked(pPacked);
179192
}
193+
194+
m_dAllocatedPtrs.Resize(0);
180195
}
181196

182197
/////////////////////////////////////////////////////////////////////
@@ -218,9 +233,22 @@ static bool CanCreateScrollSorter ( bool bMulti, const ISphSchema & tSchema, con
218233
if ( !pAttr )
219234
return false;
220235

236+
ESphAttr eCheckType = pAttr->m_eAttrType;
237+
238+
// If the scroll token has a string type and the schema attribute is SPH_ATTR_STRING,
239+
// check if there's a remapped STRINGPTR version (used for sorting)
240+
if ( i.m_eType==SPH_ATTR_STRINGPTR && eCheckType==SPH_ATTR_STRING )
241+
{
242+
CSphString sRemappedName;
243+
sRemappedName.SetSprintf ( "@int_attr_%s", i.m_sSortAttr.cstr() );
244+
auto pRemapped = tSchema.GetAttr ( sRemappedName.cstr() );
245+
if ( pRemapped && pRemapped->m_eAttrType==SPH_ATTR_STRINGPTR )
246+
eCheckType = SPH_ATTR_STRINGPTR;
247+
}
248+
221249
bool bSupported = false;
222250
for ( auto eType : dSupportedTypes )
223-
if ( pAttr->m_eAttrType==eType )
251+
if ( eCheckType==eType )
224252
{
225253
bSupported = true;
226254
break;

0 commit comments

Comments
 (0)