Example #1
0
File: idl.c Project: MPlatform/mdb
/* 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;
}
Example #2
0
File: idl.c Project: 1ack/Impala
/*
 * 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;
}
Example #3
0
File: idl.c Project: 1ack/Impala
/*
 * 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;
}
Example #4
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;
}
Example #5
0
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;
}