2008-09-19 12:21 UTC+0100 Miguel Angel Marchuet <miguelangel@marchuet.net>
* contrib/hbbmcdx/bmdbfcdx.c
* source/rdd/dbfcdx/dbfcdx1.c
! fixed return value after rt error.
* Added rt error as in clipper when OrdkeyVal is greater than 240, with default
capabilities as in clipper.
code to test it:
FUNCTION MAIN()
LOCAL i
LOCAL nSec := SECONDS()
REQUEST DBFCDX
RddSetDefault( "DBFCDX" )
DBCREATE( "__MYTEST", { { "test", "C", 241, 0 } } )
USE __MYTEST
INDEX ON FIELD->Test TO __MYTEST
FOR i := 1 TO 10
APPEND BLANK
FIELD->test := Replicate( "1", 240 ) + Str( 10 - i, 1 )
NEXT
DbGoTop()
? &(OrdKey())
? "Length of &(OrdKey()) :" + Str( Len( &(OrdKey()) ) )
? OrdKeyVal()
? "Length of OrdKeyVal() :" + Str( Len(OrdKeyVal()) )
WHILE ! EOF()
? Right( FIELD->Test, 1 )
DbSkip()
ENDDO
USE
FERASE( "__MYTEST.DBF" )
FERASE( "__MYTEST.CDX" )
RETURN NIL
This commit is contained in:
@@ -8,6 +8,47 @@
|
||||
2008-12-31 13:59 UTC+0100 Foo Bar (foo.bar foobar.org)
|
||||
*/
|
||||
|
||||
2008-09-19 12:21 UTC+0100 Miguel Angel Marchuet <miguelangel@marchuet.net>
|
||||
* contrib/hbbmcdx/bmdbfcdx.c
|
||||
* source/rdd/dbfcdx/dbfcdx1.c
|
||||
! fixed return value after rt error.
|
||||
* Added rt error as in clipper when OrdkeyVal is greater than 240, with default
|
||||
capabilities as in clipper.
|
||||
code to test it:
|
||||
FUNCTION MAIN()
|
||||
|
||||
LOCAL i
|
||||
LOCAL nSec := SECONDS()
|
||||
|
||||
REQUEST DBFCDX
|
||||
RddSetDefault( "DBFCDX" )
|
||||
|
||||
DBCREATE( "__MYTEST", { { "test", "C", 241, 0 } } )
|
||||
|
||||
USE __MYTEST
|
||||
INDEX ON FIELD->Test TO __MYTEST
|
||||
|
||||
FOR i := 1 TO 10
|
||||
APPEND BLANK
|
||||
FIELD->test := Replicate( "1", 240 ) + Str( 10 - i, 1 )
|
||||
NEXT
|
||||
|
||||
DbGoTop()
|
||||
? &(OrdKey())
|
||||
? "Length of &(OrdKey()) :" + Str( Len( &(OrdKey()) ) )
|
||||
? OrdKeyVal()
|
||||
? "Length of OrdKeyVal() :" + Str( Len(OrdKeyVal()) )
|
||||
WHILE ! EOF()
|
||||
? Right( FIELD->Test, 1 )
|
||||
DbSkip()
|
||||
ENDDO
|
||||
|
||||
USE
|
||||
FERASE( "__MYTEST.DBF" )
|
||||
FERASE( "__MYTEST.CDX" )
|
||||
|
||||
RETURN NIL
|
||||
|
||||
2008-09-19 11:00 UTC+0200 Viktor Szakats (harbour.01 syenar hu)
|
||||
* contrib/hbct/fcopy.prg
|
||||
* contrib/hbnf/dfile.prg
|
||||
|
||||
@@ -3490,17 +3490,24 @@ static void hb_cdxTagHeaderStore( LPCDXTAG pTag )
|
||||
uiKeyLen = pTag->KeyExpr == NULL ? 0 : strlen( pTag->KeyExpr );
|
||||
uiForLen = pTag->ForExpr == NULL ? 0 : strlen( pTag->ForExpr );
|
||||
|
||||
HB_PUT_LE_UINT16( tagHeader.keyExpPos, 0 );
|
||||
HB_PUT_LE_UINT16( tagHeader.keyExpLen, uiKeyLen + 1 );
|
||||
HB_PUT_LE_UINT16( tagHeader.forExpPos, uiKeyLen + 1 );
|
||||
HB_PUT_LE_UINT16( tagHeader.forExpLen, uiForLen + 1 );
|
||||
if ( uiKeyLen > 0 )
|
||||
if( uiKeyLen + uiForLen > CDX_HEADEREXPLEN - 2 )
|
||||
{
|
||||
memcpy( tagHeader.keyExpPool, pTag->KeyExpr, uiKeyLen + 1 );
|
||||
hb_cdxErrorRT( pTag->pIndex->pArea, EG_DATAWIDTH, EDBF_KEYLENGTH, NULL, 0, 0 );
|
||||
}
|
||||
if ( uiForLen > 0 )
|
||||
else
|
||||
{
|
||||
memcpy( tagHeader.keyExpPool + uiKeyLen + 1, pTag->ForExpr, uiForLen + 1 );
|
||||
HB_PUT_LE_UINT16( tagHeader.keyExpPos, 0 );
|
||||
HB_PUT_LE_UINT16( tagHeader.keyExpLen, uiKeyLen + 1 );
|
||||
HB_PUT_LE_UINT16( tagHeader.forExpPos, uiKeyLen + 1 );
|
||||
HB_PUT_LE_UINT16( tagHeader.forExpLen, uiForLen + 1 );
|
||||
if( uiKeyLen > 0 )
|
||||
{
|
||||
memcpy( tagHeader.keyExpPool, pTag->KeyExpr, uiKeyLen );
|
||||
}
|
||||
if( uiForLen > 0 )
|
||||
{
|
||||
memcpy( tagHeader.keyExpPool + uiKeyLen + 1, pTag->ForExpr, uiForLen );
|
||||
}
|
||||
}
|
||||
hb_cdxIndexPageWrite( pTag->pIndex, pTag->TagBlock, (BYTE *) &tagHeader, sizeof( CDXTAGHEADER ) );
|
||||
}
|
||||
@@ -3529,17 +3536,26 @@ static void hb_cdxTagLoad( LPCDXTAG pTag )
|
||||
* invalid root page offset (position inside an index file)
|
||||
* invalid key value length
|
||||
*/
|
||||
if ( pTag->RootBlock == 0 || pTag->RootBlock % CDX_PAGELEN != 0 ||
|
||||
( HB_FOFFSET ) pTag->RootBlock >= hb_fsSeekLarge( pTag->pIndex->hFile, 0, FS_END ) ||
|
||||
HB_GET_LE_UINT16( tagHeader.keySize ) > CDX_MAXKEY ||
|
||||
uiForPos + uiForLen > CDX_HEADEREXPLEN ||
|
||||
uiKeyPos + uiKeyLen > CDX_HEADEREXPLEN )
|
||||
if( pTag->RootBlock == 0 || pTag->RootBlock % CDX_PAGELEN != 0 ||
|
||||
( HB_FOFFSET ) pTag->RootBlock >= hb_fsSeekLarge( pTag->pIndex->hFile, 0, FS_END ) ||
|
||||
HB_GET_LE_UINT16( tagHeader.keySize ) > CDX_MAXKEY ||
|
||||
uiForPos + uiForLen > CDX_HEADEREXPLEN ||
|
||||
uiKeyPos + uiKeyLen > CDX_HEADEREXPLEN ||
|
||||
( uiKeyPos < uiForPos ? ( uiKeyPos + uiKeyLen > uiForPos ) :
|
||||
( uiForPos + uiForLen > uiKeyPos ) ) )
|
||||
{
|
||||
pTag->RootBlock = 0; /* To force RT error - index corrupted */
|
||||
return;
|
||||
}
|
||||
pTag->KeyExpr = ( char * ) hb_xgrab( CDX_MAXEXP + 1 );
|
||||
hb_strncpyTrim( pTag->KeyExpr, ( const char * ) tagHeader.keyExpPool, CDX_MAXEXP );
|
||||
|
||||
/* some wrong RDDs do not set expression length this is workaround for them */
|
||||
if( !uiKeyLen )
|
||||
uiKeyLen = ( uiForPos >= uiKeyPos ? uiForPos : CDX_HEADEREXPLEN ) - uiKeyPos;
|
||||
if( !uiForLen )
|
||||
uiForLen = ( uiForPos <= uiKeyPos ? uiKeyPos : CDX_HEADEREXPLEN ) - uiForPos;
|
||||
|
||||
pTag->KeyExpr = ( char * ) hb_xgrab( uiKeyLen + 1 );
|
||||
hb_strncpyTrim( pTag->KeyExpr, ( const char * ) tagHeader.keyExpPool, uiKeyLen );
|
||||
|
||||
pTag->uiLen = HB_GET_LE_UINT16( tagHeader.keySize );
|
||||
pTag->MaxKeys = CDX_INT_FREESPACE / ( pTag->uiLen + 8 );
|
||||
@@ -3600,9 +3616,9 @@ static void hb_cdxTagLoad( LPCDXTAG pTag )
|
||||
/* Check if there is a FOR expression: pTag->OptFlags & CDX_TYPE_FORFILTER */
|
||||
if ( tagHeader.keyExpPool[ uiForPos ] != 0 )
|
||||
{
|
||||
pTag->ForExpr = ( char * ) hb_xgrab( CDX_MAXEXP + 1 );
|
||||
pTag->ForExpr = ( char * ) hb_xgrab( uiForLen + 1 );
|
||||
hb_strncpyTrim( pTag->ForExpr, ( const char * ) tagHeader.keyExpPool +
|
||||
uiForPos, CDX_MAXEXP );
|
||||
uiForPos, uiForLen );
|
||||
if ( SELF_COMPILE( ( AREAP ) pTag->pIndex->pArea, ( BYTE * ) pTag->ForExpr ) == FAILURE )
|
||||
pTag->RootBlock = 0; /* To force RT error - index corrupted */
|
||||
else
|
||||
@@ -4564,19 +4580,17 @@ static LPCDXTAG hb_cdxIndexCreateTag( BOOL fStruct, LPCDXINDEX pIndex,
|
||||
|
||||
if ( bType == 'C' )
|
||||
hb_cdxMakeSortTab( pTag->pIndex->pArea );
|
||||
|
||||
if ( KeyExp != NULL )
|
||||
{
|
||||
pTag->KeyExpr = ( char * ) hb_xgrab( CDX_MAXEXP + 1 );
|
||||
hb_strncpyTrim( pTag->KeyExpr, KeyExp, CDX_MAXEXP );
|
||||
pTag->KeyExpr = hb_strduptrim( KeyExp );
|
||||
pTag->nField = hb_rddFieldExpIndex( ( AREAP ) pTag->pIndex->pArea,
|
||||
pTag->KeyExpr );
|
||||
}
|
||||
pTag->pKeyItem = pKeyItem;
|
||||
if ( ForExp != NULL )
|
||||
{
|
||||
pTag->ForExpr = ( char * ) hb_xgrab( CDX_MAXEXP + 1 );
|
||||
hb_strncpyTrim( pTag->ForExpr, ForExp, CDX_MAXEXP );
|
||||
}
|
||||
pTag->ForExpr = hb_strduptrim( ForExp );
|
||||
|
||||
pTag->pForItem = pForItem;
|
||||
pTag->AscendKey = pTag->UsrAscend = fAscnd;
|
||||
pTag->UniqueKey = fUniq;
|
||||
@@ -7948,30 +7962,37 @@ static ERRCODE hb_cdxOrderCreate( CDXAREAP pArea, LPDBORDERCREATEINFO pOrderInfo
|
||||
|
||||
HB_TRACE(HB_TR_DEBUG, ("hb_cdxOrderCreate(%p, %p)", pArea, pOrderInfo));
|
||||
|
||||
if ( FAST_GOCOLD( ( AREAP ) pArea ) == FAILURE )
|
||||
if( SELF_GOCOLD( ( AREAP ) pArea ) == FAILURE )
|
||||
return FAILURE;
|
||||
|
||||
if( pArea->lpdbPendingRel )
|
||||
SELF_FORCEREL( ( AREAP ) pArea );
|
||||
|
||||
if( hb_itemGetCLen( pOrderInfo->abExpr ) > CDX_MAXKEY )
|
||||
return hb_cdxErrorRT( pArea, EG_DATAWIDTH, EDBF_KEYLENGTH, NULL, 0, 0 );
|
||||
|
||||
/* If we have a codeblock for the expression, use it */
|
||||
if ( pOrderInfo->itmCobExpr )
|
||||
pKeyExp = hb_itemNew( pOrderInfo->itmCobExpr );
|
||||
else /* Otherwise, try compiling the key expression string */
|
||||
if( hb_strlentrim( hb_itemGetCPtr( pOrderInfo->abExpr ) ) +
|
||||
( pArea->lpdbOrdCondInfo && pArea->lpdbOrdCondInfo->abFor ?
|
||||
hb_strlentrim( ( const char * ) pArea->lpdbOrdCondInfo->abFor ) : 0 ) >
|
||||
CDX_HEADEREXPLEN - 2 )
|
||||
{
|
||||
if( SELF_COMPILE( (AREAP) pArea, ( BYTE * ) hb_itemGetCPtr( pOrderInfo->abExpr ) ) == FAILURE )
|
||||
return FAILURE;
|
||||
pKeyExp = pArea->valResult;
|
||||
pArea->valResult = NULL;
|
||||
hb_cdxErrorRT( pArea, EG_DATAWIDTH, EDBF_KEYLENGTH, NULL, 0, 0 );
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
if( SELF_COMPILE( (AREAP) pArea, ( BYTE * ) hb_itemGetCPtr( pOrderInfo->abExpr ) ) == FAILURE )
|
||||
return FAILURE;
|
||||
|
||||
pKeyExp = pArea->valResult;
|
||||
pArea->valResult = NULL;
|
||||
/* If we have a codeblock for the expression, use it */
|
||||
if( pOrderInfo->itmCobExpr )
|
||||
{
|
||||
hb_vmDestroyBlockOrMacro( pKeyExp );
|
||||
pKeyExp = hb_itemNew( pOrderInfo->itmCobExpr );
|
||||
}
|
||||
|
||||
/* Get a blank record before testing expression */
|
||||
ulRecNo = pArea->ulRecNo;
|
||||
SELF_GOTO( ( AREAP ) pArea, 0 );
|
||||
if ( SELF_EVALBLOCK( ( AREAP ) pArea, pKeyExp ) == FAILURE )
|
||||
if( SELF_EVALBLOCK( ( AREAP ) pArea, pKeyExp ) == FAILURE )
|
||||
{
|
||||
hb_vmDestroyBlockOrMacro( pKeyExp );
|
||||
SELF_GOTO( ( AREAP ) pArea, ulRecNo );
|
||||
@@ -7992,8 +8013,6 @@ static ERRCODE hb_cdxOrderCreate( CDXAREAP pArea, LPDBORDERCREATEINFO pOrderInfo
|
||||
break;
|
||||
case 'C':
|
||||
uiLen = ( USHORT ) hb_itemGetCLen( pResult );
|
||||
if( uiLen > CDX_MAXKEY )
|
||||
uiLen = CDX_MAXKEY;
|
||||
break;
|
||||
default:
|
||||
bType = 'U';
|
||||
@@ -8001,16 +8020,27 @@ static ERRCODE hb_cdxOrderCreate( CDXAREAP pArea, LPDBORDERCREATEINFO pOrderInfo
|
||||
}
|
||||
hb_itemRelease( pResult );
|
||||
|
||||
/* Make sure KEY has proper type and iLen lower than 240 */
|
||||
if ( bType == 'C' && uiLen > CDX_MAXKEY )
|
||||
{
|
||||
if( hb_cdxErrorRT( pArea, EG_DATAWIDTH, EDBF_INVALIDKEY, NULL, 0, EF_CANDEFAULT ) == E_DEFAULT )
|
||||
uiLen = CDX_MAXKEY;
|
||||
else
|
||||
{
|
||||
hb_vmDestroyBlockOrMacro( pKeyExp );
|
||||
SELF_GOTO( ( AREAP ) pArea, ulRecNo );
|
||||
return FAILURE;
|
||||
}
|
||||
}
|
||||
/* Make sure KEY has proper type and iLen is not 0 */
|
||||
if ( bType == 'U' || uiLen == 0 )
|
||||
else if ( bType == 'U' || uiLen == 0 )
|
||||
{
|
||||
hb_vmDestroyBlockOrMacro( pKeyExp );
|
||||
SELF_GOTO( ( AREAP ) pArea, ulRecNo );
|
||||
hb_cdxErrorRT( pArea, bType == 'U' ? EG_DATATYPE : EG_DATAWIDTH,
|
||||
EDBF_INVALIDKEY, NULL, 0, 0 );
|
||||
hb_cdxErrorRT( pArea, bType == 'U' ? EG_DATATYPE : EG_DATAWIDTH, EDBF_INVALIDKEY, NULL, 0, 0 );
|
||||
return FAILURE;
|
||||
}
|
||||
if ( pArea->lpdbOrdCondInfo )
|
||||
if( pArea->lpdbOrdCondInfo )
|
||||
{
|
||||
fAscend = !pArea->lpdbOrdCondInfo->fDescending;
|
||||
fCustom = pArea->lpdbOrdCondInfo->fCustom;
|
||||
@@ -8019,13 +8049,9 @@ static ERRCODE hb_cdxOrderCreate( CDXAREAP pArea, LPDBORDERCREATEINFO pOrderInfo
|
||||
|
||||
/* Check conditional expression */
|
||||
szFor = ( char * ) pArea->lpdbOrdCondInfo->abFor;
|
||||
if ( pArea->lpdbOrdCondInfo->itmCobFor )
|
||||
/* If we have a codeblock for the conditional expression, use it */
|
||||
pForExp = hb_itemNew( pArea->lpdbOrdCondInfo->itmCobFor );
|
||||
else if ( szFor )
|
||||
if( szFor )
|
||||
{
|
||||
/* Otherwise, try compiling the conditional expression string */
|
||||
if ( SELF_COMPILE( (AREAP) pArea, ( BYTE * ) szFor ) == FAILURE )
|
||||
if( SELF_COMPILE( (AREAP) pArea, ( BYTE * ) szFor ) == FAILURE )
|
||||
{
|
||||
hb_vmDestroyBlockOrMacro( pKeyExp );
|
||||
SELF_GOTO( ( AREAP ) pArea, ulRecNo );
|
||||
@@ -8034,6 +8060,13 @@ static ERRCODE hb_cdxOrderCreate( CDXAREAP pArea, LPDBORDERCREATEINFO pOrderInfo
|
||||
pForExp = pArea->valResult;
|
||||
pArea->valResult = NULL;
|
||||
}
|
||||
/* If we have a codeblock for the conditional expression, use it */
|
||||
if( pArea->lpdbOrdCondInfo->itmCobFor )
|
||||
{
|
||||
if( pForExp )
|
||||
hb_vmDestroyBlockOrMacro( pForExp );
|
||||
pForExp = hb_itemNew( pArea->lpdbOrdCondInfo->itmCobFor );
|
||||
}
|
||||
}
|
||||
/* Test conditional expression */
|
||||
if ( pForExp )
|
||||
@@ -8200,8 +8233,8 @@ static ERRCODE hb_cdxOrderCreate( CDXAREAP pArea, LPDBORDERCREATEINFO pOrderInfo
|
||||
}
|
||||
|
||||
pTag = hb_cdxIndexAddTag( pIndex, szTagName, hb_itemGetCPtr( pOrderInfo->abExpr ),
|
||||
pKeyExp, bType, uiLen, szFor, pForExp,
|
||||
fAscend , pOrderInfo->fUnique, fCustom, FALSE );
|
||||
pKeyExp, bType, uiLen, szFor, pForExp,
|
||||
fAscend , pOrderInfo->fUnique, fCustom, FALSE );
|
||||
|
||||
if ( pArea->lpdbOrdCondInfo && ( !pArea->lpdbOrdCondInfo->fAll &&
|
||||
!pArea->lpdbOrdCondInfo->fAdditive ) )
|
||||
|
||||
@@ -7387,7 +7387,10 @@ static ERRCODE hb_cdxOrderCreate( CDXAREAP pArea, LPDBORDERCREATEINFO pOrderInfo
|
||||
( pArea->lpdbOrdCondInfo && pArea->lpdbOrdCondInfo->abFor ?
|
||||
hb_strlentrim( ( const char * ) pArea->lpdbOrdCondInfo->abFor ) : 0 ) >
|
||||
CDX_HEADEREXPLEN - 2 )
|
||||
return hb_cdxErrorRT( pArea, EG_DATAWIDTH, EDBF_KEYLENGTH, NULL, 0, 0 );
|
||||
{
|
||||
hb_cdxErrorRT( pArea, EG_DATAWIDTH, EDBF_KEYLENGTH, NULL, 0, 0 );
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
if( SELF_COMPILE( (AREAP) pArea, ( BYTE * ) hb_itemGetCPtr( pOrderInfo->abExpr ) ) == FAILURE )
|
||||
return FAILURE;
|
||||
@@ -7425,8 +7428,6 @@ static ERRCODE hb_cdxOrderCreate( CDXAREAP pArea, LPDBORDERCREATEINFO pOrderInfo
|
||||
break;
|
||||
case 'C':
|
||||
uiLen = ( USHORT ) hb_itemGetCLen( pResult );
|
||||
if( uiLen > CDX_MAXKEY )
|
||||
uiLen = CDX_MAXKEY;
|
||||
break;
|
||||
default:
|
||||
bType = 'U';
|
||||
@@ -7434,13 +7435,24 @@ static ERRCODE hb_cdxOrderCreate( CDXAREAP pArea, LPDBORDERCREATEINFO pOrderInfo
|
||||
}
|
||||
hb_itemRelease( pResult );
|
||||
|
||||
/* Make sure KEY has proper type and iLen lower than 240 */
|
||||
if ( bType == 'C' && uiLen > CDX_MAXKEY )
|
||||
{
|
||||
if( hb_cdxErrorRT( pArea, EG_DATAWIDTH, EDBF_INVALIDKEY, NULL, 0, EF_CANDEFAULT ) == E_DEFAULT )
|
||||
uiLen = CDX_MAXKEY;
|
||||
else
|
||||
{
|
||||
hb_vmDestroyBlockOrMacro( pKeyExp );
|
||||
SELF_GOTO( ( AREAP ) pArea, ulRecNo );
|
||||
return FAILURE;
|
||||
}
|
||||
}
|
||||
/* Make sure KEY has proper type and iLen is not 0 */
|
||||
if ( bType == 'U' || uiLen == 0 )
|
||||
else if ( bType == 'U' || uiLen == 0 )
|
||||
{
|
||||
hb_vmDestroyBlockOrMacro( pKeyExp );
|
||||
SELF_GOTO( ( AREAP ) pArea, ulRecNo );
|
||||
hb_cdxErrorRT( pArea, bType == 'U' ? EG_DATATYPE : EG_DATAWIDTH,
|
||||
EDBF_INVALIDKEY, NULL, 0, 0 );
|
||||
hb_cdxErrorRT( pArea, bType == 'U' ? EG_DATATYPE : EG_DATAWIDTH, EDBF_INVALIDKEY, NULL, 0, 0 );
|
||||
return FAILURE;
|
||||
}
|
||||
if( pArea->lpdbOrdCondInfo )
|
||||
|
||||
Reference in New Issue
Block a user