/* Append sorted list b to sorted list a. The result is unsorted but * a[1] is the min of the result and a[a[0]] is the max. */ int bdb_idl_append( ID *a, ID *b ) { ID ida, idb, tmp, swap = 0; if ( BDB_IDL_IS_ZERO( b ) ) { return 0; } if ( BDB_IDL_IS_ZERO( a ) ) { BDB_IDL_CPY( a, b ); return 0; } if ( b[0] == 1 ) { return bdb_idl_append_one( a, BDB_IDL_FIRST( b )); } ida = BDB_IDL_LAST( a ); idb = BDB_IDL_LAST( b ); if ( BDB_IDL_IS_RANGE( a ) || BDB_IDL_IS_RANGE(b) || a[0] + b[0] >= BDB_IDL_UM_MAX ) { a[2] = IDL_MAX( ida, idb ); a[1] = IDL_MIN( a[1], b[1] ); a[0] = NOID; return 0; } if ( ida > idb ) { swap = idb; a[a[0]] = idb; b[b[0]] = ida; } if ( b[1] < a[1] ) { tmp = a[1]; a[1] = b[1]; } else { tmp = b[1]; } a[0]++; a[a[0]] = tmp; { int i = b[0] - 1; AC_MEMCPY(a+a[0]+1, b+2, i * sizeof(ID)); a[0] += i; } if ( swap ) { b[b[0]] = swap; } return 0; }
/* * idl_union - return a = a union b */ int bdb_idl_union( ID *a, ID *b ) { ID ida, idb; ID cursora = 0, cursorb = 0, cursorc; if ( BDB_IDL_IS_ZERO( b ) ) { return 0; } if ( BDB_IDL_IS_ZERO( a ) ) { BDB_IDL_CPY( a, b ); return 0; } if ( BDB_IDL_IS_RANGE( a ) || BDB_IDL_IS_RANGE(b) ) { over: ida = IDL_MIN( BDB_IDL_FIRST(a), BDB_IDL_FIRST(b) ); idb = IDL_MAX( BDB_IDL_LAST(a), BDB_IDL_LAST(b) ); a[0] = NOID; a[1] = ida; a[2] = idb; return 0; } ida = bdb_idl_first( a, &cursora ); idb = bdb_idl_first( b, &cursorb ); cursorc = b[0]; /* The distinct elements of a are cat'd to b */ while( ida != NOID || idb != NOID ) { if ( ida < idb ) { if( ++cursorc > BDB_IDL_UM_MAX ) { goto over; } b[cursorc] = ida; ida = bdb_idl_next( a, &cursora ); } else { if ( ida == idb ) ida = bdb_idl_next( a, &cursora ); idb = bdb_idl_next( b, &cursorb ); } } /* b is copied back to a in sorted order */ a[0] = cursorc; cursora = 1; cursorb = 1; cursorc = b[0]+1; while (cursorb <= b[0] || cursorc <= a[0]) { if (cursorc > a[0]) idb = NOID; else idb = b[cursorc]; if (cursorb <= b[0] && b[cursorb] < idb) a[cursora++] = b[cursorb++]; else { a[cursora++] = idb; cursorc++; } } return 0; }
/* * idl_intersection - return a = a intersection b */ int bdb_idl_intersection( ID *a, ID *b ) { ID ida, idb; ID idmax, idmin; ID cursora = 0, cursorb = 0, cursorc; int swap = 0; if ( BDB_IDL_IS_ZERO( a ) || BDB_IDL_IS_ZERO( b ) ) { a[0] = 0; return 0; } idmin = IDL_MAX( BDB_IDL_FIRST(a), BDB_IDL_FIRST(b) ); idmax = IDL_MIN( BDB_IDL_LAST(a), BDB_IDL_LAST(b) ); if ( idmin > idmax ) { a[0] = 0; return 0; } else if ( idmin == idmax ) { a[0] = 1; a[1] = idmin; return 0; } if ( BDB_IDL_IS_RANGE( a ) ) { if ( BDB_IDL_IS_RANGE(b) ) { /* If both are ranges, just shrink the boundaries */ a[1] = idmin; a[2] = idmax; return 0; } else { /* Else swap so that b is the range, a is a list */ ID *tmp = a; a = b; b = tmp; swap = 1; } } /* If a range completely covers the list, the result is * just the list. If idmin to idmax is contiguous, just * turn it into a range. */ if ( BDB_IDL_IS_RANGE( b ) && BDB_IDL_FIRST( b ) <= BDB_IDL_FIRST( a ) && BDB_IDL_LAST( b ) >= BDB_IDL_LAST( a ) ) { if (idmax - idmin + 1 == a[0]) { a[0] = NOID; a[1] = idmin; a[2] = idmax; } goto done; } /* Fine, do the intersection one element at a time. * First advance to idmin in both IDLs. */ cursora = cursorb = idmin; ida = bdb_idl_first( a, &cursora ); idb = bdb_idl_first( b, &cursorb ); cursorc = 0; while( ida <= idmax || idb <= idmax ) { if( ida == idb ) { a[++cursorc] = ida; ida = bdb_idl_next( a, &cursora ); idb = bdb_idl_next( b, &cursorb ); } else if ( ida < idb ) { ida = bdb_idl_next( a, &cursora ); } else { idb = bdb_idl_next( b, &cursorb ); } } a[0] = cursorc; done: if (swap) BDB_IDL_CPY( b, a ); return 0; }
IDE_RC mtfInlistTokenize( const mtdModule * aModule, mtcColumn * /* aValueColumn */, const void * aValue, mtcInlistInfo * aInlistInfo, mtcTemplate * /* aTemplate */, mtkRangeInfo * aInfo ) { const mtdCharType * sSrcValue; UInt sIndex; UInt sCommaCount; UInt sOffset; void * sTokenValue; UInt sTokenLength; UInt sTokenIdx; UInt sTokenMaxLength; UInt sValueOffset; mtdValueInfo sValueInfo1; mtdValueInfo sValueInfo2; idBool sIsDuplicate; SInt sCompare; UInt i; UInt j; sSrcValue = (const mtdCharType *)aValue; /* comma 개수를 세고 가장 큰 토큰의 길이를 얻는다.*/ sIndex = 0; sCommaCount = 0; sTokenLength = 0; sTokenMaxLength = 0; while ( sIndex < sSrcValue->length ) { if ( sSrcValue->value[sIndex] == ',' ) { sCommaCount++; sTokenMaxLength = IDL_MAX( sTokenMaxLength, sTokenLength ); sTokenLength = 0; } else { sTokenLength++; } sIndex++; } sTokenMaxLength = IDL_MAX( sTokenMaxLength, sTokenLength ); IDE_TEST_RAISE( sTokenLength > MTC_INLIST_ELEMRNT_LENGTH_MAX, ERR_INVALID_LENGTH ); aInlistInfo->count = sCommaCount + 1; IDE_TEST_RAISE( aInlistInfo->count > MTC_INLIST_ELEMENT_COUNT_MAX, ERR_INVALID_VALUE ); /* clolumn init */ if ( ( aModule == &mtdFloat ) || ( aModule == &mtdNumeric ) ) { IDE_TEST( mtc::initializeColumn( &aInlistInfo->valueDesc, & mtdFloat, 0, 0, 0 ) != IDE_SUCCESS ); } else if ( aModule == &mtdChar ) { IDE_TEST( mtc::initializeColumn( &aInlistInfo->valueDesc, & mtdChar, 1, sTokenMaxLength, 0 ) != IDE_SUCCESS ); /* space padding */ idlOS::memset( (void *)aInlistInfo->valueBuf, ' ', ID_SIZEOF(aInlistInfo->valueBuf) ); } else if ( aModule == &mtdVarchar ) { IDE_TEST( mtc::initializeColumn( &aInlistInfo->valueDesc, & mtdVarchar, 1, sTokenMaxLength, 0 ) != IDE_SUCCESS ); } else { IDE_RAISE( ERR_CONVERSION_NOT_APPLICABLE ); } sOffset = 0; sTokenLength = 0; sTokenIdx = 0; sIndex = 0; sValueOffset = 0; while ( sIndex < sSrcValue->length ) { if ( sSrcValue->value[sIndex] != ',' ) { sTokenLength++; } else { if ( ( aModule == &mtdFloat ) || ( aModule == &mtdNumeric ) ) { sTokenValue = (mtdNumericType*)( (UChar *)aInlistInfo->valueBuf + sValueOffset ); IDE_TEST( mtc::makeNumeric( (mtdNumericType*) sTokenValue, MTD_FLOAT_MANTISSA_MAXIMUM, (const UChar*)sSrcValue->value + sOffset, sTokenLength ) != IDE_SUCCESS ); } else { /* char, varchar */ sTokenValue = (mtdCharType *)( (UChar *)aInlistInfo->valueBuf + sValueOffset ); idlOS::memcpy( ((mtdCharType *)sTokenValue)->value, (const UChar*)sSrcValue->value + sOffset, sTokenLength ); if( aModule == &mtdChar) { ((mtdCharType *)sTokenValue)->length = sTokenMaxLength; /* space padding */ } else { ((mtdCharType *)sTokenValue)->length = sTokenLength; } } sOffset = sIndex + 1; sTokenLength = 0; /* BUG-43803 중복제거와 정렬 */ sIsDuplicate = ID_FALSE; for ( i = 0; i < sTokenIdx; i++ ) { sValueInfo1.column = &aInlistInfo->valueDesc; sValueInfo1.value = aInlistInfo->valueArray[i]; sValueInfo1.flag = MTD_OFFSET_USELESS; sValueInfo2.column = &aInlistInfo->valueDesc; sValueInfo2.value = sTokenValue; sValueInfo2.flag = MTD_OFFSET_USELESS; sCompare = aModule->logicalCompare[aInfo->direction]( &sValueInfo1, &sValueInfo2 ); if ( sCompare == 0 ) { sIsDuplicate = ID_TRUE; break; } else if ( sCompare > 0 ) { /* 여기에 삽입 */ break; } else { /* nothing to do */ } } if ( sIsDuplicate == ID_FALSE ) { /* i번째에 삽입한다 */ for ( j = sTokenIdx; j > i; j-- ) { aInlistInfo->valueArray[j] = aInlistInfo->valueArray[j - 1]; } aInlistInfo->valueArray[j] = sTokenValue; sTokenIdx++; if ( ( aModule == &mtdFloat ) || ( aModule == &mtdNumeric ) ) { sValueOffset += idlOS::align( ((mtdNumericType*)sTokenValue)->length + mtdFloat.headerSize(), mtdFloat.align ); } else { /* char, varchar align은 같다 */ sValueOffset += idlOS::align( ((mtdCharType*)sTokenValue)->length + mtdChar.headerSize(), mtdChar.align ); } } else { /* nothing to do */ } } sIndex++; } /* 마지막 , 또는 ','가 없는 경우 */ if ( ( aModule == &mtdFloat ) || ( aModule == &mtdNumeric ) ) { sTokenValue = (mtdNumericType*)( (UChar *)aInlistInfo->valueBuf + sValueOffset ); IDE_TEST( mtc::makeNumeric( (mtdNumericType*) sTokenValue, MTD_FLOAT_MANTISSA_MAXIMUM, (const UChar*)sSrcValue->value + sOffset, sTokenLength ) != IDE_SUCCESS ); } else { /* char, varchar */ sTokenValue = (mtdCharType *)( (UChar *)aInlistInfo->valueBuf + sValueOffset ); idlOS::memcpy( ((mtdCharType *)sTokenValue)->value, (const UChar*)sSrcValue->value + sOffset, sTokenLength); if ( aModule == &mtdChar ) { ((mtdCharType *)sTokenValue)->length = sTokenMaxLength; /* space padding */ } else { ((mtdCharType *)sTokenValue)->length = sTokenLength; } } sIsDuplicate = ID_FALSE; for ( i = 0; i < sTokenIdx; i++ ) { sValueInfo1.column = &aInlistInfo->valueDesc; sValueInfo1.value = aInlistInfo->valueArray[i]; sValueInfo1.flag = MTD_OFFSET_USELESS; sValueInfo2.column = &aInlistInfo->valueDesc; sValueInfo2.value = sTokenValue; sValueInfo2.flag = MTD_OFFSET_USELESS; sCompare = aModule->logicalCompare[aInfo->direction]( &sValueInfo1, &sValueInfo2 ); if ( sCompare == 0 ) { sIsDuplicate = ID_TRUE; break; } else if ( sCompare > 0 ) { /* 여기에 삽입 */ break; } else { /* nothing to do */ } } if ( sIsDuplicate == ID_FALSE ) { /* i번째에 삽입한다 */ for ( j = sTokenIdx; j > i; j-- ) { aInlistInfo->valueArray[j] = aInlistInfo->valueArray[j - 1]; } aInlistInfo->valueArray[j] = sTokenValue; aInlistInfo->count = sTokenIdx + 1; } else { aInlistInfo->count = sTokenIdx; } return IDE_SUCCESS; IDE_EXCEPTION( ERR_CONVERSION_NOT_APPLICABLE ); { IDE_SET( ideSetErrorCode( mtERR_ABORT_CONVERSION_NOT_APPLICABLE ) ); } IDE_EXCEPTION( ERR_INVALID_LENGTH ); { IDE_SET( ideSetErrorCode( mtERR_ABORT_VALIDATE_INVALID_LENGTH ) ); } IDE_EXCEPTION( ERR_INVALID_VALUE ); { IDE_SET( ideSetErrorCode( mtERR_ABORT_VALIDATE_INVALID_VALUE ) ); } IDE_EXCEPTION_END; return IDE_FAILURE; }
IDE_RC mtfInlistCalculate( mtcNode* aNode, mtcStack* aStack, SInt aRemain, void* aInfo, mtcTemplate* aTemplate ) { const mtdModule * sModule; mtdValueInfo sValueInfo1; mtdValueInfo sValueInfo2; mtdBooleanType sValue; mtcColumn sTokenValueColumn; ULong sTokenValueBuf[MTC_INLIST_ELEMRNT_LENGTH_MAX / 8 + 1]; void * sTokenValue; const mtdCharType * sSrcValue; UInt sIndex; UInt sTokenLength; UInt sOffset; UInt sTokenMaxLength; IDE_TEST( mtf::postfixCalculate( aNode, aStack, aRemain, aInfo, aTemplate ) != IDE_SUCCESS ); /* list type is not supported */ IDE_TEST_RAISE( ( aStack[1].column->module == &mtdList ) || ( aStack[2].column->module == &mtdList ), ERR_INVALID_FUNCTION_ARGUMENT ); sValue = MTD_BOOLEAN_FALSE; sTokenValue = (void *)sTokenValueBuf; sSrcValue = (const mtdCharType *)aStack[2].value; /* get max token length */ sIndex = 0; sTokenLength = 0; sTokenMaxLength = 0; while ( sIndex < sSrcValue->length ) { if ( sSrcValue->value[sIndex] == ',' ) { sTokenMaxLength = IDL_MAX( sTokenMaxLength, sTokenLength ); sTokenLength = 0; } else { sTokenLength++; } sIndex++; } sTokenMaxLength = IDL_MAX( sTokenMaxLength, sTokenLength ); IDE_TEST_RAISE( sTokenLength > MTC_INLIST_ELEMRNT_LENGTH_MAX, ERR_INVALID_LENGTH ); /* clolumn init */ sModule = aStack[1].column->module; if ( ( sModule == &mtdFloat ) || ( sModule == &mtdNumeric ) ) { IDE_TEST( mtc::initializeColumn( &sTokenValueColumn, & mtdFloat, 0, 0, 0 ) != IDE_SUCCESS ); } else if ( sModule == &mtdChar ) { IDE_TEST( mtc::initializeColumn( &sTokenValueColumn, & mtdChar, 1, sTokenMaxLength, 0 ) != IDE_SUCCESS ); } else if ( sModule == &mtdVarchar ) { IDE_TEST( mtc::initializeColumn( &sTokenValueColumn, & mtdVarchar, 1, sTokenMaxLength, 0 ) != IDE_SUCCESS ); } else { IDE_RAISE( ERR_CONVERSION_NOT_APPLICABLE ); } sIndex = 0; sTokenLength = 0; sOffset = 0; while ( sIndex < sSrcValue->length ) { if ( sSrcValue->value[sIndex] != ',' ) { sTokenLength++; } else { if ( ( sModule == &mtdFloat ) || ( sModule == &mtdNumeric ) ) { IDE_TEST( mtc::makeNumeric( (mtdNumericType*) sTokenValue, MTD_FLOAT_MANTISSA_MAXIMUM, (const UChar*)sSrcValue->value + sOffset, sTokenLength ) != IDE_SUCCESS ); } else { /* space padding */ idlOS::memcpy( ((mtdCharType *)sTokenValue)->value, (const UChar*)sSrcValue->value + sOffset, sTokenLength ); if ( sModule == &mtdChar ) { idlOS::memset( ((mtdCharType *)sTokenValue)->value + sTokenLength , ' ', sTokenMaxLength - sTokenLength ); ((mtdCharType *)sTokenValue)->length = sTokenMaxLength; /* space padding */ } else { ((mtdCharType *)sTokenValue)->length = sTokenLength; } } /* logical compare toeknized value and aStack[1] */ if ( ( sModule->isNull( aStack[1].column, aStack[1].value ) == ID_TRUE ) || ( sModule->isNull( &sTokenValueColumn, sTokenValue ) == ID_TRUE ) ) { sValue = MTD_BOOLEAN_NULL; } else { sValueInfo1.column = aStack[1].column; sValueInfo1.value = aStack[1].value; sValueInfo1.flag = MTD_OFFSET_USELESS; sValueInfo2.column = &sTokenValueColumn; sValueInfo2.value = sTokenValue; sValueInfo2.flag = MTD_OFFSET_USELESS; if ( sModule->logicalCompare[MTD_COMPARE_ASCENDING]( &sValueInfo1, &sValueInfo2 ) == 0 ) { sValue = MTD_BOOLEAN_TRUE; break; } else { sValue = MTD_BOOLEAN_FALSE; } } sOffset = sIndex + 1; sTokenLength = 0; } sIndex++; } /* while */ /* 마지막 , 또는 ','가 없는 경우 */ if ( ( sIndex == sSrcValue->length ) && ( sValue != MTD_BOOLEAN_TRUE ) ) { if ( ( sModule == &mtdFloat ) || ( sModule == &mtdNumeric ) ) { IDE_TEST( mtc::makeNumeric( (mtdNumericType*) sTokenValue, MTD_FLOAT_MANTISSA_MAXIMUM, (const UChar*)sSrcValue->value + sOffset, sTokenLength ) != IDE_SUCCESS ); } else { idlOS::memcpy( ((mtdCharType *)sTokenValue)->value, (const UChar*)sSrcValue->value + sOffset, sTokenLength ); if ( sModule == &mtdChar) { idlOS::memset( ((mtdCharType *)sTokenValue)->value + sTokenLength , ' ', sTokenMaxLength - sTokenLength ); ((mtdCharType *)sTokenValue)->length = sTokenMaxLength; /* space padding */ } else { ((mtdCharType *)sTokenValue)->length = sTokenLength; } } /* logical compare toeknized value and aStack[1] */ if ( ( sModule->isNull( aStack[1].column, aStack[1].value ) == ID_TRUE ) || ( sModule->isNull( &sTokenValueColumn, sTokenValue ) == ID_TRUE ) ) { sValue = MTD_BOOLEAN_NULL; } else { sValueInfo1.column = aStack[1].column; sValueInfo1.value = aStack[1].value; sValueInfo1.flag = MTD_OFFSET_USELESS; sValueInfo2.column = &sTokenValueColumn; sValueInfo2.value = sTokenValue; sValueInfo2.flag = MTD_OFFSET_USELESS; if ( sModule->logicalCompare[MTD_COMPARE_ASCENDING]( &sValueInfo1, &sValueInfo2 ) == 0 ) { sValue = MTD_BOOLEAN_TRUE; } else { sValue = MTD_BOOLEAN_FALSE; } } } *(mtdBooleanType*)aStack[0].value = sValue; return IDE_SUCCESS; IDE_EXCEPTION( ERR_INVALID_FUNCTION_ARGUMENT ); { IDE_SET( ideSetErrorCode( mtERR_ABORT_INVALID_FUNCTION_ARGUMENT ) ); } IDE_EXCEPTION( ERR_CONVERSION_NOT_APPLICABLE ); { IDE_SET( ideSetErrorCode( mtERR_ABORT_CONVERSION_NOT_APPLICABLE ) ); } IDE_EXCEPTION( ERR_INVALID_LENGTH ); { IDE_SET( ideSetErrorCode( mtERR_ABORT_VALIDATE_INVALID_LENGTH ) ); } IDE_EXCEPTION_END; return IDE_FAILURE; }