Beispiel #1
0
DB_STATUS
adu_hash(
ADF_CB          *adf_scb,
DB_DATA_VALUE   *dv1,
DB_DATA_VALUE   *rdv)
{
    i4 		    in_len;
    i4 		    res_len;
    char	    *tmp;
    u_i4	    *out_p = ((u_i4 *)rdv->db_data);
    DB_STATUS	    db_stat;

    /* Don't support long data types */
    if ( Adf_globs->Adi_dtptrs[ADI_DT_MAP_MACRO(dv1->db_datatype)]->
		adi_dtstat_bits & AD_PERIPHERAL )
        return (adu_error(adf_scb, E_AD2090_BAD_DT_FOR_STRFUNC, 0));

    switch (dv1->db_datatype)
    {
	/* call lenaddr for the stringish types - it gets varying length
	** lengths, among other things. */
        case DB_CHA_TYPE:
        case DB_CHR_TYPE:
        case DB_BYTE_TYPE:
        case DB_VCH_TYPE:
        case DB_TXT_TYPE:
        case DB_LTXT_TYPE:
	case DB_VBYTE_TYPE:
	case DB_NCHR_TYPE:
	case DB_NVCHR_TYPE:
	 if (db_stat = adu_lenaddr(adf_scb, dv1, &in_len, &tmp))
	 return(db_stat);
	 break;
	default:	/* all the others */
	 in_len = dv1->db_length;	/* fixed length */
	 tmp = dv1->db_data;
	 break;
    }

    *out_p = -1;
    HSH_CRC32(tmp, in_len, out_p);

    return(E_DB_OK);
}
Beispiel #2
0
DB_STATUS
adu_uuid_from_char(
ADF_CB          *adf_scb,
DB_DATA_VALUE   *dv1,
DB_DATA_VALUE   *rdv)
{
    UUID    		d;
    i4			lensrc;
    char		e[100];
    char		*srcptr;
    DB_STATUS		db_stat;

    /* Verify the result is 16 byte binary UUID */
    if ((rdv->db_datatype != DB_BYTE_TYPE) ||
        (rdv->db_length != sizeof(UUID)) ) 
    {
       db_stat = adu_error(adf_scb, E_AD9998_INTERNAL_ERROR, 2, 0, "uuid_from_char wrong type/len");
       return(db_stat);
    }

    if (db_stat = adu_lenaddr(adf_scb, dv1, &lensrc, &srcptr))
	return (db_stat);
    if(lensrc > sizeof(e)-1)
    {
       db_stat = adu_error(adf_scb, E_AD50A0_BAD_UUID_PARM, 0);
       return(db_stat);
    }
    /* Make a string */
    MEcopy(srcptr, lensrc, &e);
    e[lensrc] = 0x00;

    if((db_stat = IDuuid_from_string(&e[0], &d)) != OK)
    {
       db_stat = adu_error(adf_scb, E_AD50A0_BAD_UUID_PARM, 0);
       return(db_stat);
    }

    /* Copy the UUID into the result area */
    MEcopy(&d, rdv->db_length, rdv->db_data);

    return(E_DB_OK);
}
Beispiel #3
0
DB_STATUS
adu_like_all(
	ADF_CB		*adf_scb,
	DB_DATA_VALUE	*src_dv,
	DB_DATA_VALUE	*pat_dv,
	DB_DATA_VALUE	*esc_dv,
	u_i4		pat_flags,
	i4		*rcmp)
{
    DB_STATUS db_stat = E_DB_OK;
    AD_PAT_SEA_CTX _sea_ctx;
    AD_PAT_SEA_CTX *sea_ctx = &_sea_ctx;
    AD_PATDATA _patdata;
    AD_PATDATA *patdata;
    AD_PAT_DA_CTX da_ctx;
    DB_DATA_VALUE dv_tmp1;
    DB_DATA_VALUE dv_tmp2;
    DB_DATA_VALUE *s1 = src_dv, *p1 = pat_dv;
    i4 rcmp1 = 0;
    i4 long_seen = 0;
    DB_STATUS db_stat1 = E_DB_OK;
    char tmp[2000];
    i2 saved_uninorm_flag = adf_scb->adf_uninorm_flag;
    static struct {
	ADU_PATCOMP_FUNC *compile;
	ADU_PATEXEC_FUNC *execute;
    } rtns[] = {
	{adu_patcomp_like,     adu_pat_execute},
	{adu_patcomp_like,     adu_pat_execute_col},
	{adu_patcomp_like_uni, adu_pat_execute_uni},
    };
    enum rtns_idx {
	LIKE, LIKE_COLLATION, LIKE_UNICODE 
    } form = LIKE;
    
    if (pat_dv->db_datatype == DB_PAT_TYPE)
    {
	patdata = (AD_PATDATA*)pat_dv->db_data;
	if (ME_ALIGN_MACRO(patdata, sizeof(i2)) != (PTR)patdata)
	{
	    if ((i2)sizeof(_patdata) >= pat_dv->db_length)
		patdata = &_patdata;
	    else
	    {
		patdata = (AD_PATDATA*)MEreqmem(0, pat_dv->db_length,
			    FALSE, &db_stat);
		if (!patdata || db_stat)
		    return db_stat;
	    }
	    MEcopy(pat_dv->db_data, pat_dv->db_length, patdata);
	}
	pat_flags = patdata->patdata.flags|
		    (patdata->patdata.flags2<<16);
	/* Pre-compiled pattern */
	{
	    i4 i;
	    /* ->patdata is passed in preset with a valid [PATDATA_LENGTH] -
	    ** save it now as we will clear the lot */
	    MEfill(sizeof(*sea_ctx), 0, (PTR)sea_ctx);
	    sea_ctx->patdata = patdata;
	    /*sea_ctx->buffer = NULL;*/
	    /*sea_ctx->bufend = NULL;*/
	    /*sea_ctx->buftrueend = NULL;*/
	    /*sea_ctx->seg_offset = 0;*/
	    /*sea_ctx->buflen = 0;*/
	    /*sea_ctx->at_bof = FALSE;*/
	    /*sea_ctx->at_eof = FALSE;*/
	    /*sea_ctx->trace = FALSE;*/
	    /*sea_ctx->force_fail = FALSE;*/
	    /*sea_ctx->cmplx_lim_exc = FALSE;*/
	    /*sea_ctx->stalled = NULL;*/
	    /*sea_ctx->pending = NULL;*/
	    /*sea_ctx->free = NULL;*/
	    /*sea_ctx->setbuf = NULL;*/
#if PAT_DBG_TRACE>0
	    /*sea_ctx->nid = 0;*/
	    /*sea_ctx->infile = NULL;*/
	    /*sea_ctx->outfile = NULL;*/
#endif
	    /*sea_ctx->nctxs_extra = 0;*/
	    sea_ctx->nctxs = DEF_THD;
	    for (i = DEF_THD-1; i >= 0; i--)
	    {
		sea_ctx->ctxs[i].next = sea_ctx->free;
		sea_ctx->free = &sea_ctx->ctxs[i];
	    }
	}
	db_stat = adu_patcomp_set_pats(sea_ctx);

	/* If prior patcomp flagged force_fail - obey it */
	if (patdata->patdata.flags2 & AD_PAT2_FORCE_FAIL)
	    sea_ctx->force_fail = TRUE;
    }
    else
    {
	patdata = &_patdata;
	/* Tell compiler size we are prepared for */
	patdata->patdata.length = sizeof(_patdata)/sizeof(_patdata.vec[0]);
	sea_ctx->patdata = patdata;
	/*
	** To allow for default processing we have the user specified
	** case flags to deal with. If AD_PAT_WITH_CASE or AD_PAT_WO_CASE
	** is set then we use that setting to override any collation
	** case request. If neither are set we obey the collation.
	*/
	if (pat_flags & AD_PAT_WITH_CASE)
	{
	    pat_flags &= ~AD_PAT_WO_CASE;
	}
	else if (!(pat_flags & AD_PAT_WO_CASE) &&
		(src_dv->db_collID == DB_UNICODE_CASEINSENSITIVE_COLL ||
		pat_dv->db_collID == DB_UNICODE_CASEINSENSITIVE_COLL))
	{
	    pat_flags |= AD_PAT_WO_CASE;
	}
	/*
	** From this point on, the AD_PAT_WITH_CASE flag is ignored as
	** its state has been folded into the AD_PAT_WO_CASE flag.
	*/
    }

    if (ADU_pat_legacy == -1)
	pat_flags &= ~AD_PAT_WO_CASE;
    else if (ADU_pat_legacy == -2)
	pat_flags |= AD_PAT_WO_CASE;

    dv_tmp1.db_data = NULL;
    dv_tmp2.db_data = NULL;

    switch (abs(src_dv->db_datatype))
    {
    case DB_LNVCHR_TYPE:
    case DB_LNLOC_TYPE:
	long_seen = 1;
    case DB_NVCHR_TYPE:
    case DB_NCHR_TYPE:
    case DB_UTF8_TYPE:
    case DB_NQTXT_TYPE:
	form = LIKE_UNICODE;
	/* All handled directly by DA */
	break;
    case DB_LVCH_TYPE:
    case DB_LCLOC_TYPE:
	if (adf_scb->adf_utf8_flag & AD_UTF8_ENABLED)
	    form = LIKE_UNICODE;
    case DB_LBYTE_TYPE:
    case DB_LBLOC_TYPE:
	long_seen = 1;
    case DB_BYTE_TYPE:
    case DB_VBYTE_TYPE:
	/* All handled directly by DA */
	break;
    case DB_CHR_TYPE:
	pat_flags |= AD_PAT_BIGNORE;	/* Ignore blanks */
	/*FALLTHROUGH*/
    case DB_CHA_TYPE:
    case DB_VCH_TYPE:
    case DB_TXT_TYPE:
    case DB_LTXT_TYPE:
	if (adf_scb->adf_utf8_flag & AD_UTF8_ENABLED)
	{
	    form = LIKE_UNICODE;
	    dv_tmp1.db_datatype = DB_NVCHR_TYPE;
	    dv_tmp1.db_length = src_dv->db_length * 4 + DB_CNTSIZE;
	    dv_tmp1.db_prec = 0;
	    dv_tmp1.db_collID = -1;
	    if (dv_tmp1.db_length < (i2)sizeof(tmp))
		dv_tmp1.db_data = tmp;
	    else
	    {
		dv_tmp1.db_data = (char *) MEreqmem (0, dv_tmp1.db_length, TRUE, &db_stat);
		if (db_stat)
		    return db_stat;
	    }
            adf_scb->adf_uninorm_flag = AD_UNINORM_NFC;
	    db_stat = adu_nvchr_fromutf8(adf_scb, src_dv, &dv_tmp1);
            adf_scb->adf_uninorm_flag = saved_uninorm_flag;
	    src_dv = &dv_tmp1;
	}
	break;
    default:
	return(adu_error(adf_scb, E_AD9999_INTERNAL_ERROR, 0));
    }

    /*
    ** See how the pattern looks and coerce appropriatly
    */
    switch (abs(pat_dv->db_datatype))
    {
    case DB_LNVCHR_TYPE:
    case DB_LNLOC_TYPE:
	long_seen = 1;
    case DB_NVCHR_TYPE:
    case DB_NCHR_TYPE:
    case DB_UTF8_TYPE:
    case DB_NQTXT_TYPE:
	if (form != LIKE_UNICODE)
	{
	    DB_DATA_VALUE dv_tmp3;
	    form = LIKE_UNICODE;
	    dv_tmp1.db_datatype = DB_NVCHR_TYPE;
	    dv_tmp1.db_length = src_dv->db_length * 3 + DB_CNTSIZE;
	    dv_tmp1.db_prec = 0;
	    dv_tmp1.db_collID = -1;
	    dv_tmp3.db_datatype = DB_NVCHR_TYPE;
	    dv_tmp3.db_length = src_dv->db_length * 3 + DB_CNTSIZE;
	    dv_tmp3.db_prec = 0;
	    dv_tmp3.db_collID = -1;
	    if (dv_tmp1.db_length < (i2)sizeof(tmp))
		dv_tmp1.db_data = tmp;
	    else
	    {
		dv_tmp1.db_data = (char *) MEreqmem (0, dv_tmp1.db_length, TRUE, &db_stat);
		if (db_stat)
		    return db_stat;
	    }
	    dv_tmp3.db_data = (char *) MEreqmem (0, dv_tmp3.db_length, TRUE, &db_stat);
	    if (db_stat)
		return db_stat;
	    if (db_stat = adu_nvchr_coerce(adf_scb, src_dv, &dv_tmp3))
	    {
		if (dv_tmp1.db_data && dv_tmp1.db_data != tmp)
		    MEfree((char *)dv_tmp1.db_data);
		return db_stat;
	    }

            adf_scb->adf_uninorm_flag = AD_UNINORM_NFC;
	    db_stat = adu_unorm(adf_scb, &dv_tmp3, &dv_tmp1);
            adf_scb->adf_uninorm_flag = saved_uninorm_flag;
	    MEfree((char *)dv_tmp3.db_data);
	    if (db_stat)
	    {
		if (dv_tmp1.db_data && dv_tmp1.db_data != tmp)
		    MEfree((char *)dv_tmp1.db_data);
		return db_stat;
	    }
	    src_dv = &dv_tmp1;
	}
	break;
    case DB_CHR_TYPE:
	pat_flags |= AD_PAT_BIGNORE;	/* Ignore blanks */
	/*FALLTHROUGH*/
    case DB_LVCH_TYPE:
    case DB_LCLOC_TYPE:
    case DB_LBYTE_TYPE:
    case DB_LBLOC_TYPE:
    case DB_BYTE_TYPE:
    case DB_VBYTE_TYPE:
    case DB_CHA_TYPE:
    case DB_VCH_TYPE:
    case DB_TXT_TYPE:
    case DB_LTXT_TYPE:
	if (form == LIKE_UNICODE)
	{
	    DB_DATA_VALUE dv_tmp3;
	    dv_tmp2.db_datatype = DB_NVCHR_TYPE;
	    dv_tmp2.db_length = pat_dv->db_length * 4 + DB_CNTSIZE;
	    dv_tmp2.db_prec = 0;
	    dv_tmp2.db_collID = -1;
	    dv_tmp3.db_datatype = DB_NVCHR_TYPE;
	    dv_tmp3.db_length = pat_dv->db_length * 3 + DB_CNTSIZE;
	    dv_tmp3.db_prec = 0;
	    dv_tmp3.db_collID = -1;
	    if (dv_tmp2.db_length < (i2)sizeof(tmp) && dv_tmp1.db_data != tmp)
		dv_tmp2.db_data = tmp;
	    else
	    {
		dv_tmp2.db_data = (char *) MEreqmem (0, dv_tmp2.db_length, TRUE, &db_stat);
		if (db_stat)
		    return db_stat;
	    }
	    if (adf_scb->adf_utf8_flag & AD_UTF8_ENABLED)
            {
                adf_scb->adf_uninorm_flag = AD_UNINORM_NFC;
		db_stat = adu_nvchr_fromutf8(adf_scb, pat_dv, &dv_tmp2);
                adf_scb->adf_uninorm_flag = saved_uninorm_flag;
            }
	    else
	    {
		dv_tmp3.db_data = (char *) MEreqmem (0, dv_tmp3.db_length, TRUE, &db_stat);
		if (db_stat)
		    return db_stat;
		if (db_stat = adu_nvchr_coerce(adf_scb, pat_dv, &dv_tmp3))
		{
		    if (dv_tmp2.db_data && dv_tmp2.db_data != tmp)
			MEfree((char *)dv_tmp2.db_data);
		    return db_stat;
		}
                adf_scb->adf_uninorm_flag = AD_UNINORM_NFC;
		db_stat = adu_unorm(adf_scb, &dv_tmp3, &dv_tmp2);
                adf_scb->adf_uninorm_flag = saved_uninorm_flag;
		MEfree((char *)dv_tmp3.db_data);
		if (db_stat)
		{
		    if (dv_tmp2.db_data && dv_tmp2.db_data != tmp)
			MEfree((char *)dv_tmp2.db_data);
		    return db_stat;
		}
	    }
	    pat_dv = &dv_tmp2;
	}
	break;
    case DB_PAT_TYPE:
	if (patdata->patdata.flags2 & AD_PAT2_UNICODE)
	    form = LIKE_UNICODE;
	else if (patdata->patdata.flags2 & AD_PAT2_COLLATE)
	    form = LIKE_COLLATION;
	break;
    default:
	return(adu_error(adf_scb, E_AD9999_INTERNAL_ERROR, 0));
    }

    if (abs(pat_dv->db_datatype) != DB_PAT_TYPE)
    {
	if (form == LIKE && adf_scb->adf_collation)
	{
	    form = LIKE_COLLATION;
	    pat_flags |= (AD_PAT2_COLLATE<<16);
	}
	else if (form == LIKE_UNICODE)
	    pat_flags |= (AD_PAT2_UNICODE<<16);

	if (ADU_pat_legacy > 0 &&
		    !long_seen &&
		    (pat_flags & AD_PAT_FORM_MASK) == AD_PAT_FORM_LIKE)
	{
	    if (form == LIKE_UNICODE)
		db_stat1 = adu_ulike(adf_scb, s1, p1,
			(UCS2*)(esc_dv?esc_dv->db_data:0), &rcmp1);
	    else
		db_stat1 = adu_like(adf_scb, s1, p1,
			(u_char*)(esc_dv?esc_dv->db_data:0), &rcmp1);
	    if (ADU_pat_legacy == 3)
	    {
		/* Look no further */
		*rcmp = rcmp1;
		if (dv_tmp1.db_data && dv_tmp1.db_data != tmp)
		    MEfree((char *)dv_tmp1.db_data);
		if (dv_tmp2.db_data && dv_tmp2.db_data != tmp)
		    MEfree((char *)dv_tmp2.db_data);
		return db_stat1;
	    }
	}

	/* Compile the input pattern */
	db_stat = (rtns[form].compile)(adf_scb, pat_dv, esc_dv, pat_flags, sea_ctx);
    }
    if (!db_stat && sea_ctx)
    {
	if (sea_ctx->force_fail)
	    *rcmp = 1;
	else
	{
	    /* Init the data access */
	    if (!(db_stat = adu_patda_init(adf_scb, src_dv, sea_ctx, &da_ctx)))
	    {
		/* Do the search */
		db_stat = (rtns[form].execute)(sea_ctx, &da_ctx, rcmp);
	    }
	    /* Cleanup the data access */
	    (VOID)adu_patda_term(&da_ctx);
	    if (!db_stat && sea_ctx->cmplx_lim_exc)
		db_stat = adu_error(adf_scb, E_AD1026_PAT_TOO_CPLX, 0);
        }
    }
    adu_patcomp_free(sea_ctx);

    if (dv_tmp1.db_data && dv_tmp1.db_data != tmp)
	MEfree((char *)dv_tmp1.db_data);
    if (dv_tmp2.db_data && dv_tmp2.db_data != tmp)
	MEfree((char *)dv_tmp2.db_data);
    if (patdata != &_patdata && (PTR)patdata != pat_dv->db_data)
	MEfree((PTR)patdata);

    if (ADU_pat_legacy > 0 &&
		!long_seen &&
		(pat_flags & AD_PAT_FORM_MASK) == AD_PAT_FORM_LIKE)
    {
	if (db_stat1 && db_stat)
	{
	    /* Old unsupported? - just report */
	    TRdisplay("%s old fail - %d %d osts=%d nsts=%d\n",
		pat_flags & AD_PAT_WO_CASE?"ILIKE":"LIKE",
		s1->db_datatype, p1->db_datatype,
		db_stat1, db_stat);
	}
	else if (db_stat1 && !db_stat)
	{
	    /* NEW SOLUTION - */
	    TRdisplay("%s new support - %d %d osts=%d\n",
		pat_flags & AD_PAT_WO_CASE?"ILIKE":"LIKE",
		s1->db_datatype, p1->db_datatype,
		db_stat1);
	}
	else if (!db_stat1 && db_stat)
	{
	    i4 sl, pl;
	    char *s, *p;
	    /*NEW PROB - report & fixup */
	    adu_lenaddr(adf_scb, s1, &sl, &s);
	    adu_lenaddr(adf_scb, p1, &pl, &p);
	    TRdisplay("%s new problem - %d %d nsts=%d ores=%d nres=%d '%.#s' '%.#s'\n",
		pat_flags & AD_PAT_WO_CASE?"ILIKE":"LIKE",
		s1->db_datatype, p1->db_datatype,
		db_stat,
		rcmp1, *rcmp,
		sl,s,pl,p);
	    if (ADU_pat_legacy > 1)
	    {
		*rcmp = rcmp1;
		db_stat = db_stat1;
	    }
	}
	else if (*rcmp != rcmp1)
	{
	    i4 sl, pl;
	    char *s, *p;
	    /*NEW PROB - report & fixup */
	    adu_lenaddr(adf_scb, s1, &sl, &s);
	    adu_lenaddr(adf_scb, p1, &pl, &p);
	    TRdisplay("%s bad? %d %d ores=%d nres=%d '%.#s' '%.#s'\n",
		pat_flags & AD_PAT_WO_CASE?"ILIKE":"LIKE",
		s1->db_datatype, p1->db_datatype,
		rcmp1, *rcmp,
		sl,s,pl,p);
	    if (ADU_pat_legacy > 1)
	    {
		*rcmp = rcmp1;
		db_stat = db_stat1;
	    }
	}
    }
    return db_stat;
}