/*{ ** Name: OPU_GSMEMORY_CLOSE - Get memory from the stack ULM memory stream ** ** Description: ** This routine allocates memory from the ULM memory stream that is used ** for the stack style memory usage. [@comment_line@]... ** ** Inputs: ** global - ** State info for the current query. ** global->ops_mstate.ops_ulmrcb - ** The ULM control block. ** global->ops_mstate.ops_sstreamid - ** The stream id. ** size - ** size of the piece of memory to allocate. ** ** Outputs: ** ** Returns: ** The address of the allocated memory. ** Exceptions: ** none ** ** Side Effects: ** none ** ** History: ** 19-July-87 (eric) ** written ** 21-feb-91 (seputis) ** make non-zero initialization of memory an xDEBUG feature ** 16-sep-93 (smc) ** Moved <cs.h> for CS_SID. ** 11-oct-2006 (hayke02) ** Send E_OP0002_NOMEMORY to errlog.log. This change fixes bug 116309. [@history_line@]... [@history_template@]... */ PTR opu_Gsmemory_get( OPS_STATE *global, i4 size) { DB_STATUS ulmstatus; /* return status from ULM */ /* store the stream id */ global->ops_mstate.ops_ulmrcb.ulm_streamid_p = &global->ops_mstate.ops_sstreamid; /* store the size to be allocate */ global->ops_mstate.ops_ulmrcb.ulm_psize = size; if ( (ulmstatus = ulm_palloc( &global->ops_mstate.ops_ulmrcb )) != E_DB_OK ) { if (global->ops_mstate.ops_ulmrcb.ulm_error.err_code == E_UL0005_NOMEM) { opx_lerror(E_OP0002_NOMEMORY, 0, 0, 0, 0, 0); opx_error( E_OP0002_NOMEMORY); /* out of memory */ } #ifdef E_OP0093_ULM_ERROR else opx_verror( ulmstatus, E_OP0093_ULM_ERROR, global->ops_mstate.ops_ulmrcb.ulm_error.err_code); /* check for error */ #endif } #ifdef xDEBUG MEfill( size, (u_char)127, (PTR)global->ops_mstate.ops_ulmrcb.ulm_pptr); /*FIXME ** remove this initialization after ** test for uninitialized memory ** is not required any more */ #endif /* return the allocated memory */ return( global->ops_mstate.ops_ulmrcb.ulm_pptr ); }
/*{ ** Name: psq_tinsert - Add a piece of query text to a chain in front ** of some piece. ** ** Description: ** This function inserts a piece of query text to an existing chain. ** New text is added in front of the existing piece specified by the ** caller . ** A need for the routine arises from the fact that the owner names need ** to qualify database object names in case of database procedures. ** Another use for the function is when synonym_name has to be ** replaced with owner.actual_table_name in the text stored for views, ** integrities, and permits. ** These names become known when the scanner has already 'seen' the ** object name (and therefore has already added it to the text chain). ** ** Inputs: ** header Pointer to chain header ** piece Pointer to piece of text ** size Size of piece ** result Place to put pointer to new piece ** oldpiece Piece in front of which the new piece ** will be inserted (should not be NULL). ** err_blk Filled in if an error happens ** ** Outputs: ** result Filled in with pointer to chain element ** err_blk Filled in if an error happens ** Returns: ** E_DB_OK Success ** E_DB_ERROR Non-catastrophic failure ** E_DB_FATAL Catastrophic failure ** Exceptions: ** none ** ** Side Effects: ** Allocates memory ** ** History: ** 02-jun-88 (stec) ** written ** 04-jun-90 (andre) ** renamed from psq_tb1add() to psq_tinsert(); ** changed the description to describe use of this function in ** conjunction with synonyms. */ DB_STATUS psq_tinsert( PTR header, u_char *piece, i4 size, PTR *result, PTR oldpiece, DB_ERROR *err_blk) { PSQ_THEAD *hp = (PSQ_THEAD *) header; PSQ_TEXT *tp, *op = (PSQ_TEXT *) oldpiece; i4 err_code; DB_STATUS status; if (op == (PSQ_TEXT *) NULL) { /* Should not be reached */ return (E_DB_ERROR); } /* Allocate enough space for PSQ_TEXT structure containing piece */ hp->psq_tmem.ulm_psize = size + sizeof(PSQ_TEXT) - 1; status = ulm_palloc(&hp->psq_tmem); if (DB_FAILURE_MACRO(status)) { if (hp->psq_tmem.ulm_error.err_code == E_UL0005_NOMEM) { psf_error(E_PS0F02_MEMORY_FULL, 0L, PSF_CALLERR, &err_code, err_blk, 0); } else (VOID) psf_error(E_PS0371_ALLOC_TEXT_CHAIN, hp->psq_tmem.ulm_error.err_code, PSF_INTERR, &err_code,err_blk, 0); return (status); } *result = hp->psq_tmem.ulm_pptr; tp = (PSQ_TEXT*) *result; /* Fill in text piece */ MEcopy((char *) piece, size, (char *) tp->psq_tval); tp->psq_psize = size; /* Hook it up to the chain */ if (tp->psq_prev = op->psq_prev) tp->psq_prev->psq_next = tp; tp->psq_next = op; op->psq_prev = tp; if (hp->psq_first == op) hp->psq_first = tp; /* Add in the length to the total for the chain */ hp->psq_tsize += size; return (E_DB_OK); }
/*{ ** Name: psq_tadd - Add a piece of query text to a chain ** ** Description: ** This function adds a piece of query text to an existing chain. ** ** Inputs: ** header Pointer to chain header ** piece Pointer to piece of text ** size Size of piece ** result Place to put pointer to new piece ** err_blk Filled in if an error happens ** ** Outputs: ** result Filled in with pointer to chain element ** err_blk Filled in if an error happens ** Returns: ** E_DB_OK Success ** E_DB_ERROR Non-catastrophic failure ** E_DB_FATAL Catastrophic failure ** Exceptions: ** none ** ** Side Effects: ** Allocates memory ** ** History: ** 18-jul-86 (jeff) ** written */ DB_STATUS psq_tadd( PTR header, u_char *piece, i4 size, PTR *result, DB_ERROR *err_blk) { PSQ_THEAD *hp = (PSQ_THEAD *) header; PSQ_TEXT *tp; i4 err_code; DB_STATUS status; /* Allocate enough space for PSQ_TEXT structure containing piece */ hp->psq_tmem.ulm_psize = size + sizeof(PSQ_TEXT) - 1; status = ulm_palloc(&hp->psq_tmem); if (status != E_DB_OK) { if (hp->psq_tmem.ulm_error.err_code == E_UL0005_NOMEM) { psf_error(E_PS0F02_MEMORY_FULL, 0L, PSF_CALLERR, &err_code, err_blk, 0); } else (VOID) psf_error(E_PS0371_ALLOC_TEXT_CHAIN, hp->psq_tmem.ulm_error.err_code, PSF_INTERR, &err_code,err_blk, 0); return (status); } *result = hp->psq_tmem.ulm_pptr; tp = (PSQ_TEXT*) *result; /* Fill in text piece */ MEcopy((char *) piece, size, (char *) tp->psq_tval); tp->psq_psize = size; /* Hook it up to the chain */ tp->psq_next = (PSQ_TEXT *) NULL; if (hp->psq_last != (PSQ_TEXT *) NULL) { hp->psq_last->psq_next = tp; tp->psq_prev = hp->psq_last; } else { tp->psq_prev = NULL; } hp->psq_last = tp; if (hp->psq_first == (PSQ_TEXT *) NULL) hp->psq_first = tp; /* Add in the length to the total for the chain */ hp->psq_tsize += size; return (E_DB_OK); }
/*{ ** Name: psf_symall Allocates memory for a symbol block. ** ** Description: ** Symbol blocks are used mainly by scanners to pass additional data ** to parsers. They also hold emmitted text. This routine allocates ** a new block and takes care of initializing appropriate fields in the ** session control block. ** ** Inputs: ** pss_cb session control block pointer. ** psq_cb query control block. ** size amount of memory to be allocated. ** ** Outputs: ** pss_cb session control block with ** appropriate fields initialized. ** psq_cb query control block with psq_error ** field initialized, if error. ** Returns: ** E_DB_OK ** status return by ULM ** ** Exceptions: ** none ** ** Side Effects: ** Allocates memory. ** ** History: ** 25-nov-87 (stec) ** written ** 31-jan-97 (pchang) ** psf_symall(), when allocating memory for a symbol table block, ** failed to take into account the space needed for the next block ** pointer 'pss_sbnext' which later caused memory overrun in the data ** area 'pss_symdata'. In some cases, the corruption is neutralized ** when the user of the violated adjacent memory space overlays it ** with new data. Whereas, if the violated memory space is occupied ** by a less volatile entity such as a pointer for a linked list, ** what follows could be a random SEGV. (B75105?) */ DB_STATUS psf_symall( PSS_SESBLK *pss_cb, PSQ_CB *psq_cb, i4 size) { DB_STATUS status = E_DB_OK; ULM_RCB ulm_rcb; i4 err_code; /* If no more blocks, allocate another */ if (pss_cb->pss_symblk->pss_sbnext==(PSS_SYMBLK *) NULL) { /* If out of room, allocate some more */ ulm_rcb.ulm_facility = DB_PSF_ID; ulm_rcb.ulm_streamid_p = &pss_cb->pss_symstr; ulm_rcb.ulm_psize = size + sizeof(PTR); /* add space for fwd ptr */ ulm_rcb.ulm_memleft = &pss_cb->pss_memleft; status = ulm_palloc(&ulm_rcb); if (DB_FAILURE_MACRO(status)) { if (ulm_rcb.ulm_error.err_code == E_UL0005_NOMEM) { psf_error(E_PS0F02_MEMORY_FULL, 0L, PSF_CALLERR, &err_code, &psq_cb->psq_error, 0); } else { psf_error(2704L, 0L, PSF_USERERR, &err_code, &psq_cb->psq_error, 0); } return (status); } pss_cb->pss_symblk->pss_sbnext = (PSS_SYMBLK*) ulm_rcb.ulm_pptr; pss_cb->pss_symblk->pss_sbnext->pss_sbnext = NULL; } /* Set current block and next character pointer */ pss_cb->pss_symblk = pss_cb->pss_symblk->pss_sbnext; pss_cb->pss_symnext = pss_cb->pss_symblk->pss_symdata; return (E_DB_OK); }
/*{ ** Name: psf_umalloc - Allocate memory from ULM. ** ** Description: ** General purpose interface into allocating from ULM for the current ** session. ** ** Inputs: ** sess_cb Session control block pointer. ** mstream ULM stream id. ** msize Size of memory. ** ** Outputs: ** sess_cb Session control block: ** .pss_memleft Memory left in current session. ** mresult Pointer to result object. ** err_blk.err_code Error returned ** E_PS0F02_MEMORY_FULL No more memory for session ** E_PS0A02_BADALLOC Some other ULM error ** ** Returns: ** status return by ULM ** E_DB_FATAL If memory corrupted. ** ** Exceptions: ** none ** ** Side Effects: ** Allocates memory. ** ** History: ** 19-apr-89 (neil) ** Written */ DB_STATUS psf_umalloc( PSS_SESBLK *sess_cb, PTR mstream, i4 msize, PTR *mresult, DB_ERROR *err_blk) { DB_STATUS status; ULM_RCB ulm_rcb; i4 err_code; ulm_rcb.ulm_facility = DB_PSF_ID; ulm_rcb.ulm_streamid_p = &mstream; ulm_rcb.ulm_psize = msize; ulm_rcb.ulm_memleft = &sess_cb->pss_memleft; status = ulm_palloc(&ulm_rcb); if (status != E_DB_OK) { if (ulm_rcb.ulm_error.err_code == E_UL0005_NOMEM) { _VOID_ psf_error(E_PS0F02_MEMORY_FULL, 0L, PSF_CALLERR, &err_code, err_blk, 0); } else { _VOID_ psf_error(E_PS0A02_BADALLOC, 0L, PSF_INTERR, &err_code, err_blk, 0); } if (ulm_rcb.ulm_error.err_code == E_UL0004_CORRUPT) status = E_DB_FATAL; *mresult = NULL; } else { *mresult = ulm_rcb.ulm_pptr; } return (status); } /* psf_umalloc */
/*{ ** Name: opu_memory - get joinop memory ** ** Description: ** This routine will allocate the requested size of memory from the ** joinop memory stream. Memory in this stream is not deallocated ** until the optimization has completed. The allocated memory will ** be aligned for any datatype. ** ** Inputs: ** global ptr to global state variable ** size size of memory block requested. ** ** Outputs: ** Returns: ** PTR to aligned memory of "size" bytes ** Exceptions: ** none ** ** Side Effects: ** none ** ** History: ** 16-jun-86 (seputis) ** initial creation ** 4-mar-91 (seputis) ** make initialization of memory an xDEBUG feature ** 11-oct-2006 (hayke02) ** Send E_OP0002_NOMEMORY to errlog.log. This change fixes bug 116309. ** 5-oct-2007 (dougi) ** Accumulate memory acquisition stats. */ PTR opu_memory( OPS_STATE *global, i4 size) { DB_STATUS ulmstatus; /* return status from ULM */ global->ops_mstate.ops_countalloc++; if (size >= 2048) global->ops_mstate.ops_count2kalloc++; global->ops_mstate.ops_totalloc += size; global->ops_mstate.ops_ulmrcb.ulm_streamid_p = &global->ops_mstate.ops_streamid; /* allocate memory ** from the global stream */ global->ops_mstate.ops_ulmrcb.ulm_psize = size; /* size of request */ ulmstatus = ulm_palloc( &global->ops_mstate.ops_ulmrcb ); if (DB_FAILURE_MACRO(ulmstatus)) { if (global->ops_mstate.ops_ulmrcb.ulm_error.err_code == E_UL0005_NOMEM) { opx_lerror(E_OP0002_NOMEMORY, 0, 0, 0, 0, 0); opx_error( E_OP0002_NOMEMORY); /* out of memory */ } #ifdef E_OP0093_ULM_ERROR else opx_verror( ulmstatus, E_OP0093_ULM_ERROR, global->ops_mstate.ops_ulmrcb.ulm_error.err_code); /* check for error */ #endif } #ifdef xDEBUG MEfill( size, (u_char)247, (PTR)global->ops_mstate.ops_ulmrcb.ulm_pptr); /*FIXME ** remove this initialization after ** test for uninitialized memory ** is not required any more */ #endif return( global->ops_mstate.ops_ulmrcb.ulm_pptr ); /* return the allocated ** memory */ }
/* ** Name: sxapo_bgn_ses - register a session with the auditing system ** ** Description: ** This routine is called at session startup time to initialize the ** audit specific data structures associated with a session. It should ** be called only once for each session. ** ** The only session specific data structure need for the operating system ** audit log version of auditing is the record identifier that keeps ** count of the number of records written since the last flush for this ** session. ** ** Inputs: ** scb SXF session control block ** ** Outputs: ** err_code Error code returned to the caller ** ** Returns: ** DB_STATUS ** ** History: ** 1-dec-93 (stephenb) ** Initial creation. ** */ DB_STATUS sxapo_bgn_ses ( SXF_SCB *scb, i4 *err_code) { ULM_RCB ulm_rcb; DB_STATUS status; i4 local_err; *err_code = E_SX0000_OK; ulm_rcb.ulm_facility = DB_SXF_ID; ulm_rcb.ulm_streamid_p = &scb->sxf_scb_mem; ulm_rcb.ulm_psize = sizeof (SXAPO_RECID); ulm_rcb.ulm_memleft = &Sxf_svcb->sxf_pool_sz; status = ulm_palloc(&ulm_rcb); if (status != E_DB_OK) { if (ulm_rcb.ulm_error.err_code == E_UL0005_NOMEM) *err_code = E_SX106B_MEMORY_ERROR; else *err_code = E_SX106B_MEMORY_ERROR; _VOID_ ule_format(ulm_rcb.ulm_error.err_code, NULL, ULE_LOG, NULL, NULL, 0L, NULL, &local_err, 0); } else scb->sxf_sxap_scb = ulm_rcb.ulm_pptr; /* handle errors */ if (*err_code != E_SX0000_OK) { _VOID_ ule_format(*err_code, NULL, ULE_LOG, NULL, NULL, 0L, NULL, &local_err, 0); *err_code = E_SX101D_SXAP_BGN_SESSION; status = E_DB_ERROR; } return(status); }
/* ** Name: sxapo_startup - startup the low level auditing system ** ** Description: ** ** This routine initializes the operating system audit log version of ** the SXAP auditing system. It should ** be called once at SXF startup time. Its purpose is to allocate ** and initialize the resources needed for the running of the low level ** auditing system. ** ** This routine also initializes the vector used to access all other ** SXAP routines, all these routines must be called using this vector. ** ** Inputs: ** None. ** ** Outputs: ** rscb RSCB for the current write audit file. ** err_code Error code returned to the caller. ** ** Returns: ** DB_STATUS ** ** History: ** 2-dec-93 (stephenb) ** first written. ** 4-jan-94 (stephenb) ** Add sxapo_alter entry point to the sxap vector. */ DB_STATUS sxapo_startup( SXF_RSCB *rscb, i4 *err_code) { DB_STATUS status = E_DB_OK; i4 local_err; SXAPO_RSCB *rs; ULM_RCB ulm_rcb; SXAP_VECTOR *v; bool file_open = FALSE; *err_code = E_SX0000_OK; for (;;) { /* Build the SXAP main control block */ ulm_rcb.ulm_facility = DB_SXF_ID; ulm_rcb.ulm_streamid_p = &Sxf_svcb->sxf_svcb_mem; ulm_rcb.ulm_psize = sizeof (SXAPO_CB); ulm_rcb.ulm_memleft = &Sxf_svcb->sxf_pool_sz; status = ulm_palloc(&ulm_rcb); if (status != E_DB_OK) { if (ulm_rcb.ulm_error.err_code == E_UL0005_NOMEM) *err_code = E_SX1002_NO_MEMORY; else *err_code = E_SX106B_MEMORY_ERROR; _VOID_ ule_format(ulm_rcb.ulm_error.err_code, NULL, ULE_LOG, NULL, NULL, 0L, NULL, &local_err, 0); break; } Sxapo_cb = (SXAPO_CB *) ulm_rcb.ulm_pptr; Sxapo_cb->sxapo_curr_rscb = NULL; /* Build and initialize the SXAP call vector */ ulm_rcb.ulm_psize = sizeof (SXAP_VECTOR); status = ulm_palloc(&ulm_rcb); if (status != E_DB_OK) { if (ulm_rcb.ulm_error.err_code == E_UL0005_NOMEM) *err_code = E_SX1002_NO_MEMORY; else *err_code = E_SX106B_MEMORY_ERROR; _VOID_ ule_format(ulm_rcb.ulm_error.err_code, NULL, ULE_LOG, NULL, NULL, 0L, NULL, &local_err, 0); _VOID_ ule_format(*err_code, NULL, ULE_LOG, NULL, NULL, 0L, NULL, &local_err, 0); break; } Sxap_vector = (SXAP_VECTOR *) ulm_rcb.ulm_pptr; v = Sxap_vector; v->sxap_init = sxapo_startup; v->sxap_term = sxapo_shutdown; v->sxap_begin = sxapo_bgn_ses; v->sxap_end = sxapo_end_ses; v->sxap_open = sxapo_open; v->sxap_close = sxapo_close; v->sxap_pos = sxapo_position; v->sxap_read = sxapo_read; v->sxap_write = sxapo_write; v->sxap_flush = sxapo_flush; v->sxap_show = sxapo_show; v->sxap_alter = sxapo_alter; /* Initialize the audit file configuration data */ status = sxapo_init_cnf(&local_err); if (status != E_DB_OK) { *err_code = local_err; _VOID_ ule_format(*err_code, NULL, ULE_LOG, NULL, NULL, 0L, NULL, &local_err, 0); break; } /* ** Open the audit file for writing. */ status = sxapo_open( NULL, SXF_WRITE, rscb, NULL, NULL, &local_err); if (status != E_DB_OK) { *err_code = local_err; _VOID_ ule_format(*err_code, NULL, ULE_LOG, NULL, NULL, 0L, NULL, &local_err, 0); break; } file_open = TRUE; rs = (SXAPO_RSCB *) rscb->sxf_sxap; Sxapo_cb->sxapo_curr_rscb = rs; Sxapo_cb->sxapo_status |= SXAPO_ACTIVE; break; } /* Cleanup after any errors */ if (*err_code != E_SX0000_OK) { if (file_open) _VOID_ sxapo_close(rscb, &local_err); *err_code = E_SX101A_SXAP_STARTUP; /* ** Errors during startup of the auditing system are ** considered to be severe errors. */ status = E_DB_SEVERE; } return (status); }
/*{ ** Name: PSQ_TCNVT - convert db_data_value to text form ** ** Description: ** This routine takes any user supplied db_data_value and converts ** it to the value's textual representation. This is required for the ** iiqrytext catalog. It is assumed that all datavalues can be written ** into a character representation. ** ** Inputs: ** sess_cb session control block ** .pss_adfcb adf session control block for output ** arguments. ** header Pointer to chain header ** dbval db_data_value ** result Place to put pointer to new piece ** err_blk Filled in if an error happens ** ** Outputs: ** result Filled in with pointer to chain element ** err_blk Filled in if an error happens ** Returns: ** E_DB_OK Success ** E_DB_ERROR Non-catastrophic failure ** E_DB_FATAL Catastrophic failure ** Exceptions: ** none ** ** Side Effects: ** Allocates memory ** ** History: ** 29-jun-87 (daved) ** written ** 28-jan-91 (andre) ** fix bug 35446: size of a new piece should include quotes, if they ** were added. ** 18-nov-91 (rog) ** Fixed bug 40869, et alia: the above fix missed adding the quotes ** to the total size and not just the piece size. ** 23-Sep-2009 (kiria01) b122578 ** Initialise the ADF_FN_BLK .adf_fi_desc and adf_dv_n members. ** 19-Aug-2010 (kschendel) b124282 ** Make sure fi-desc is always set to something. */ DB_STATUS psq_tcnvt( PSS_SESBLK *sess_cb, PTR header, DB_DATA_VALUE *dbval, PTR *result, DB_ERROR *err_blk) { PSQ_THEAD *hp; PSQ_TEXT *tp; i4 err_code; DB_STATUS status; ADF_CB *adf_cb; ADF_FN_BLK adffn; i4 dv_size; i4 count; char *cptr; char *quote_char; DB_TEXT_STRING *string; ADI_DT_NAME dt_fname; ADI_DT_NAME dt_tname; char f4_style; char f8_style; i4 f4_width; i4 f8_width; i4 f4_prec; i4 f8_prec; i4 totype; i4 is_string; hp = (PSQ_THEAD *) header; adf_cb = (ADF_CB *) sess_cb->pss_adfcb; status = E_DB_OK; totype = (DB_DT_ID) DB_LTXT_TYPE; adffn.adf_r_dv.db_datatype = totype; if (dbval->db_datatype == totype) dv_size = dbval->db_length; else dv_size = 0; /* JRBCMT -- PSF is not allowed to know this!! First of all, date is */ /* missing from the list below and decimal will soon need to be on it. */ /* But also, we need to fix this code so that it doesn't make */ /* assumptions about what types exist. I think the proper approach is */ /* to quote all non-intrinsic types, but this should be investigated. */ /* are we dealing with a string type (incoming). */ if (abs(dbval->db_datatype) == DB_INT_TYPE || abs(dbval->db_datatype) == DB_FLT_TYPE || abs(dbval->db_datatype) == DB_MNY_TYPE || abs(dbval->db_datatype) == DB_BOO_TYPE) { is_string = FALSE; quote_char = (char *) NULL; } else { is_string = TRUE; quote_char = (sess_cb->pss_lang == DB_SQL) ? "\'" : "\""; } /* set the floating point conversion display */ f4_style = adf_cb->adf_outarg.ad_f4style; f8_style = adf_cb->adf_outarg.ad_f8style; f4_width = adf_cb->adf_outarg.ad_f4width; f8_width = adf_cb->adf_outarg.ad_f8width; f4_prec = adf_cb->adf_outarg.ad_f4prec; f8_prec = adf_cb->adf_outarg.ad_f8prec; adf_cb->adf_outarg.ad_f4style = 'n'; adf_cb->adf_outarg.ad_f8style = 'n'; adf_cb->adf_outarg.ad_f4width = 20; adf_cb->adf_outarg.ad_f8width = 20; adf_cb->adf_outarg.ad_f4prec = 10; adf_cb->adf_outarg.ad_f8prec = 10; /* get the function instance id for this conversion */ status = adi_ficoerce(adf_cb, dbval->db_datatype, totype, &adffn.adf_fi_id); if (status != E_DB_OK) { goto exit; } /* determine the result size. */ status = adi_fidesc(adf_cb, adffn.adf_fi_id, &adffn.adf_fi_desc); if (status != E_DB_OK) { goto exit; } if (!dv_size) { /* Now lets fill in the datatype length info and allocate space for the ** data. */ status = adi_0calclen(adf_cb, &adffn.adf_fi_desc->adi_lenspec, 1, &dbval, &adffn.adf_r_dv); dv_size = adffn.adf_r_dv.db_length; if (status != E_DB_OK) { goto exit; } } /* if string, add room for quotes */ if (is_string) dv_size += 2 * CMbytecnt(quote_char); /* Allocate enough space for PSQ_TEXT structure containing piece */ hp->psq_tmem.ulm_psize = dv_size + sizeof(PSQ_TEXT) - 1; status = ulm_palloc(&hp->psq_tmem); if (status != E_DB_OK) { if (hp->psq_tmem.ulm_error.err_code == E_UL0005_NOMEM) { psf_error(E_PS0F02_MEMORY_FULL, 0L, PSF_CALLERR, &err_code, err_blk, 0); } else (VOID) psf_error(E_PS0371_ALLOC_TEXT_CHAIN, hp->psq_tmem.ulm_error.err_code, PSF_INTERR, &err_code, err_blk, 0); return (status); } *result = hp->psq_tmem.ulm_pptr; tp = (PSQ_TEXT*) *result; string = (DB_TEXT_STRING*) tp->psq_tval; /* Fill in text piece */ adffn.adf_r_dv.db_length = dv_size; adffn.adf_r_dv.db_data = (PTR) string; adffn.adf_dv_n = 1; STRUCT_ASSIGN_MACRO(*dbval, adffn.adf_1_dv); adffn.adf_pat_flags = AD_PAT_DOESNT_APPLY; if ((status = adf_func(adf_cb, &adffn)) != E_DB_OK) { goto exit; } /* CAUTION: entering tricky code. ** string is a variable containing a text datatype. We want to convert ** to a C datatype. We also want to add quote characters if the datatype ** was a string type. We grab the count from the string variable first. ** we can then use the 2 byte count for character data. */ count = string->db_t_count; cptr = (char *) string; if (is_string) { /* ** for strings, copy the opening quote (" or ', depending on language) */ CMcpychar(quote_char, cptr); cptr += CMbytecnt(quote_char); } MEcopy((PTR) string->db_t_text, count, (PTR) cptr); cptr += count; if (is_string) { /* ** for strings, copy the closing quote (" or ', depending on language) */ CMcpychar(quote_char, cptr); } /* if storing a string, do not forget to account for quotes (bug 35446) */ tp->psq_psize = (is_string) ? count + 2 * CMbytecnt(quote_char) : count; /* Hook it up to the chain */ tp->psq_next = (PSQ_TEXT *) NULL; if (hp->psq_last != (PSQ_TEXT *) NULL) { hp->psq_last->psq_next = tp; tp->psq_prev = hp->psq_last; } else { tp->psq_prev = NULL; } hp->psq_last = tp; if (hp->psq_first == (PSQ_TEXT *) NULL) hp->psq_first = tp; /* Add in the length to the total for the chain */ hp->psq_tsize += tp->psq_psize; exit: /* set the floating point conversion display */ adf_cb->adf_outarg.ad_f4style = f4_style; adf_cb->adf_outarg.ad_f8style = f8_style; adf_cb->adf_outarg.ad_f4width = f4_width; adf_cb->adf_outarg.ad_f8width = f8_width; adf_cb->adf_outarg.ad_f4prec = f4_prec; adf_cb->adf_outarg.ad_f8prec = f8_prec; if (status != E_DB_OK) { (VOID) adi_tyname(adf_cb, dbval->db_datatype, &dt_fname); (VOID) adi_tyname(adf_cb, totype, &dt_tname); (VOID) psf_error(2911L, 0L, PSF_USERERR, &err_code, err_blk, 3, sizeof (sess_cb->pss_lineno), &sess_cb->pss_lineno, psf_trmwhite(sizeof(dt_fname), (char *) &dt_fname), &dt_fname, psf_trmwhite(sizeof (dt_tname), (char *) &dt_tname), &dt_tname); return (E_DB_ERROR); } return (status); }
/*{ ** Name: psq_tsubs - Substitute one piece of text for another ** ** Description: ** This function substitutes one piece of query text for another in the ** given text chain. It will try to re-use the current piece before ** allocating another. ** ** Inputs: ** header Pointer to header ** piece Piece we want to substitute for ** newtext Pointer to new piece of text ** size Size of new piece ** newpiece Place to put pointer to new piece ** err_blk Filled in if an error happens ** ** Outputs: ** newpiece Filled in with pointer to new piece ** err_blk Filled in if an error happened ** Returns: ** E_DB_OK Success ** E_DB_ERROR Non-catastrophic error ** E_DB_FATAL Catastrophic error ** Exceptions: ** none ** ** Side Effects: ** Can allocate memory ** ** History: ** 18-jul-86 (jeff) ** written */ DB_STATUS psq_tsubs( PTR header, PTR piece, u_char *newtext, i4 size, PTR *newpiece, DB_ERROR *err_blk) { PSQ_THEAD *hp = (PSQ_THEAD *) header; PSQ_TEXT *tp = (PSQ_TEXT *) piece; PSQ_TEXT *np; DB_STATUS status; i4 err_code; i4 oldsize; /* Remember the size of the original piece */ oldsize = tp->psq_psize; /* If there isn't enough room in the current piece, allocate another one */ if (tp->psq_psize < size) { /* Allocate enough for PSQ_TEXT struct with size bytes of text */ hp->psq_tmem.ulm_psize = size + sizeof(PSQ_TEXT) - 1; status = ulm_palloc(&hp->psq_tmem); if (status != E_DB_OK) { if (hp->psq_tmem.ulm_error.err_code == E_UL0005_NOMEM) { psf_error(E_PS0F02_MEMORY_FULL, 0L, PSF_CALLERR, &err_code, err_blk, 0); } else (VOID) psf_error(E_PS0371_ALLOC_TEXT_CHAIN, hp->psq_tmem.ulm_error.err_code, PSF_INTERR,&err_code, err_blk, 0); return (status); } np = (PSQ_TEXT*) hp->psq_tmem.ulm_pptr; /* Hook up the new piece into the chain */ if (np->psq_prev = tp->psq_prev) { np->psq_prev->psq_next = np; } if (np->psq_next = tp->psq_next) { np->psq_next->psq_prev = np; } if (hp->psq_first == tp) hp->psq_first = np; if (hp->psq_last == tp) hp->psq_last = np; tp = np; } /* Copy the new text into the piece and set the size */ MEcopy((char *) newtext, size, (char *) tp->psq_tval); tp->psq_psize = size; /* Adjust the total size of the chain */ hp->psq_tsize -= oldsize - size; /* Give the caller a pointer to the new piece */ *newpiece = (PTR) tp; return (E_DB_OK); }
/*{ ** Name: psq_rptqry_text - add a piece of text to the text chain for a repeat ** query ** ** Description: Add a piece of text to the text chain for a repeat query. It is ** imperative that text of all repeat queries be stored in a ** uniform fashion so that comparing two stored query texts would ** serve as a reliable indicator of their sameness. Each piece ** will be preceeded with a blank except for a PERIOD. Neither the ** piece consisting of PERIOD nor the following piece will be ** preceeded with a blank. ** ** Inputs: ** header Pointer to chain header ** piece Pointer to piece of text ** size Size of piece ** result Place to put pointer to new piece ** err_blk Filled in if an error happens ** ** Outputs: ** result Filled in with pointer to chain element ** err_blk Filled in if an error happens ** Returns: ** E_DB_OK Success ** E_DB_ERROR Non-catastrophic failure ** E_DB_FATAL Catastrophic failure ** Exceptions: ** none ** ** Side Effects: ** Allocates memory ** ** History: ** 24-jan-90 (andre) ** Plagiarized from psq_tadd(). ** 28-jan-91 (andre) ** Do not insert a space if a piece is immediately following a piece ** consisting of a $. */ DB_STATUS psq_rptqry_text( PTR header, u_char *piece, i4 size, PTR *result, DB_ERROR *err_blk) { PSQ_THEAD *hp = (PSQ_THEAD *) header; PSQ_TEXT *tp; i4 err_code; bool leading_blank; char *txt; DB_STATUS status; /* ** Allocate enough space for PSQ_TEXT structure containing piece: ** all pieces will be preceeded with a blank with the following exceptions: ** - piece consisting of PERIOD will not be preceeeded with a blank; ** - piece which immediately follows a piece consisting of PERIOD; ** - piece starting with a "white" character will not be preceeded with a ** blank; ** - piece which immediately follows a piece consisting of $ (preceeded by ** a blank which was inserted by this function) */ if ( size == CMbytecnt(".") && !CMcmpcase(piece, ".") || CMwhite(piece)) { /* ** piece consists of a period or starts with a "white" character - no ** leading blanks will be added */ leading_blank = FALSE; } else if ( hp->psq_last != (PSQ_TEXT *) NULL && (( hp->psq_last->psq_psize == CMbytecnt(".") && !CMcmpcase(hp->psq_last->psq_tval, ".") ) || ( hp->psq_last->psq_psize == CMbytecnt(" ") + CMbytecnt("$") && !CMcmpcase(hp->psq_last->psq_tval, " ") && !CMcmpcase((hp->psq_last->psq_tval + CMbytecnt(" ")), "$") ) ) ) { /* ** previous piece consists of a period or of a $ preceeded by a blank ** inserted by this function - no leading blanks will be added */ leading_blank = FALSE; } else { /* insert a blank before the piece */ leading_blank = TRUE; } hp->psq_tmem.ulm_psize = (leading_blank) ? size + sizeof(PSQ_TEXT) - 1 + CMbytecnt(" ") : size + sizeof(PSQ_TEXT) - 1; if ((status = ulm_palloc(&hp->psq_tmem)) != E_DB_OK) { if (hp->psq_tmem.ulm_error.err_code == E_UL0005_NOMEM) { (VOID) psf_error(E_PS0F02_MEMORY_FULL, 0L, PSF_CALLERR, &err_code, err_blk, 0); } else { (VOID) psf_error(E_PS0371_ALLOC_TEXT_CHAIN, hp->psq_tmem.ulm_error.err_code, PSF_INTERR, &err_code, err_blk, 0); } return (status); } *result = hp->psq_tmem.ulm_pptr; tp = (PSQ_TEXT*) *result; /* Fill in text piece */ txt = (char *) tp->psq_tval; /* insert a leading blank if necessary */ if (leading_blank) { CMcpychar(" ", txt); txt += CMbytecnt(" "); } MEcopy((char *) piece, size, txt); tp->psq_psize = (leading_blank) ? size + CMbytecnt(" ") : size; /* Hook it up to the chain */ tp->psq_next = (PSQ_TEXT *) NULL; if (hp->psq_last != (PSQ_TEXT *) NULL) { hp->psq_last->psq_next = tp; tp->psq_prev = hp->psq_last; } else { tp->psq_prev = NULL; } hp->psq_last = tp; if (hp->psq_first == (PSQ_TEXT *) NULL) hp->psq_first = tp; /* Add in the length to the total for the chain */ hp->psq_tsize += tp->psq_psize; return (E_DB_OK); }
/*{ ** Name: gwi_map_idx_rel - create a tuple entry in the iigwX_relation ** table for this gateway secondary index ** ** Description: ** This function creates a tuple in the extended relation catalog for this ** gateway secondary index. The tuple is identical to that for its base ** table, except that it has a non-zero xreltidx field. ** ** Inputs: ** gw_rcb-> gateway request control block ** gwr_tab_id table id for this secondary index ** dmt_cb DMF table request control block, passed in from ** parent routine to avoid re-allocating ** dmr_cb DMF record request control block passed in from ** parent routine to avoid re-allocating ** ulm_rcb memory request control block, passed in from ** parent routine as it is in the same stream, we ** want to deallocate all related memory from there ** ** Output: ** gw_rcb-> ** error.err_code One of the following error numbers. ** E_GW0600_NO_MEM ** ** Returns: ** E_DB_OK Function completed normally. ** E_DB_ERROR Function completed abnormally with ** error.err_code. ** History: ** 24-sep-90 (linda) ** Created. ** 07-oct-92 (robf) ** If we can't find the base tuple, don't try to save an (incorrect) ** index tuple. ** Look up the base tuple, not index tuple, from relation (the ** index tuple doesn't exist yet, so we wouldn't expect to find it) ** If opening the iigwXX_relation catalog fails, break rather ** than trying to access an unopened table. ** Save errors on return so higher level knows what happened. ** (symptom was spurious ULEFORMAT errors on error #0) ** 8-oct-92 (daveb) ** prototyped. Cast db_id arg to gwu_copen. It's a PTR. ** removed dead var gwx. */ static DB_STATUS gwi_map_idx_rel( GW_RCB *gw_rcb, DMT_CB *dmt, DMR_CB *dmr, ULM_RCB *ulm_rcb ) { GW_SESSION *session = (GW_SESSION *)gw_rcb->gwr_session_id; DB_TAB_ID base_tab_id; DB_TAB_ID *tab_id; i4 gw_id = gw_rcb->gwr_gw_id; i4 xrel_sz = Gwf_facility->gwf_gw_info[gw_id].gwf_xrel_sz; DB_STATUS status = E_DB_OK; DB_STATUS ret_code=E_DB_OK; DMR_ATTR_ENTRY attkey[2]; DMR_ATTR_ENTRY *attkey_ptr[2]; DB_ERROR err; for (;;) /* just to break out of on error... */ { /* ** First create the iigwXX_relation row buffer */ ulm_rcb->ulm_psize = xrel_sz; if ((status = ulm_palloc(ulm_rcb)) != E_DB_OK) { gwf_error(ulm_rcb->ulm_error.err_code, GWF_INTERR, 0); gwf_error(E_GW0314_ULM_PALLOC_ERROR, GWF_INTERR, 4, sizeof(*ulm_rcb->ulm_memleft), ulm_rcb->ulm_memleft, sizeof(ulm_rcb->ulm_sizepool), &ulm_rcb->ulm_sizepool, sizeof(ulm_rcb->ulm_blocksize), &ulm_rcb->ulm_blocksize, sizeof(ulm_rcb->ulm_psize), &ulm_rcb->ulm_psize); if (ulm_rcb->ulm_error.err_code == E_UL0005_NOMEM) gw_rcb->gwr_error.err_code = E_GW0600_NO_MEM; else gw_rcb->gwr_error.err_code = E_GW021D_GWU_MAP_IDX_REL_ERROR; break; } dmr->dmr_data.data_in_size = xrel_sz; dmr->dmr_data.data_address = ulm_rcb->ulm_pptr; /* ** NOTE we are looking for the base table entry. */ STRUCT_ASSIGN_MACRO(gw_rcb->gwr_tab_id, base_tab_id); base_tab_id.db_tab_index = 0; /* position to get if this is a DMT_A_READ */ attkey[0].attr_number = 1; attkey[0].attr_operator = DMR_OP_EQ; attkey[0].attr_value = (char *)&gw_rcb->gwr_tab_id.db_tab_base; attkey[1].attr_number = 2; attkey[1].attr_operator = DMR_OP_EQ; /* attkey[1].attr_value = (char *)&gw_rcb->gwr_tab_id.db_tab_index; */ attkey[1].attr_value = (char*) &base_tab_id.db_tab_index; attkey_ptr[0] = &attkey[0]; attkey_ptr[1] = &attkey[1]; dmr->type = DMR_RECORD_CB; dmr->length = sizeof(DMR_CB); dmr->dmr_flags_mask = 0; dmr->dmr_position_type = DMR_QUAL; dmr->dmr_attr_desc.ptr_in_count = 2; dmr->dmr_attr_desc.ptr_size = sizeof(DMR_ATTR_ENTRY); dmr->dmr_attr_desc.ptr_address = (PTR)&attkey_ptr[0]; dmr->dmr_access_id = dmt->dmt_record_access_id; dmr->dmr_q_fcn = NULL; /* get extended relation catalog info - iigwX_relation */ if ((status = gwu_copen(dmt, dmr, session->gws_scf_session_id, (PTR)gw_rcb->gwr_database_id, gw_id, gw_rcb->gwr_xact_id, &gw_rcb->gwr_tab_id, &session->gws_gw_info[gw_id].gws_xrel_tab_name, DMT_A_WRITE, TRUE, &err)) != E_DB_OK) { switch (dmt->error.err_code) { case E_DM0042_DEADLOCK: gw_rcb->gwr_error.err_code = E_GW0327_DMF_DEADLOCK; break; default: (VOID) gwf_error(err.err_code, GWF_INTERR, 0); gw_rcb->gwr_error.err_code = E_GW021D_GWU_MAP_IDX_REL_ERROR; break; } break; } dmr->dmr_flags_mask = DMR_NEXT; tab_id = (DB_TAB_ID *)dmr->dmr_data.data_address; STRUCT_ASSIGN_MACRO(base_tab_id, *tab_id); dmr->dmr_char_array.data_address = 0; /* search for the right tuple */ do { status = (*Dmf_cptr)(DMR_GET, dmr); } while (status == E_DB_OK && MEcmp((PTR)dmr->dmr_data.data_address, (PTR)&base_tab_id, sizeof(DB_TAB_ID))); if (status != E_DB_OK) /* cannot get table info */ { switch (dmt->error.err_code) { case E_DM0042_DEADLOCK: err.err_code = E_GW0327_DMF_DEADLOCK; break; default: (VOID) gwf_error(dmr->error.err_code, GWF_INTERR, 0); (VOID) gwf_error(E_GW0321_DMR_GET_ERROR, GWF_INTERR, 2, (i4)4, (PTR)&gw_rcb->gwr_tab_id.db_tab_base, (i4)4, (PTR)&gw_rcb->gwr_tab_id.db_tab_index); gw_rcb->gwr_error.err_code = E_GW021D_GWU_MAP_IDX_REL_ERROR; break; } } /* ** Only save the index tuple if we found base tuple */ if (status == E_DB_OK) { /* ** Now that we've found the tuple for the base table, ** update it to be that of the index. This code assumes that ** the tab_id fields are the first fields in the extended ** relation catalog. */ tab_id = (DB_TAB_ID *)dmr->dmr_data.data_address; STRUCT_ASSIGN_MACRO(gw_rcb->gwr_tab_id, *tab_id); /* put the iigwX_relation tuple */ /* ** Initialize the DMR control block with the information ** required for an insert. */ dmr->type = DMR_RECORD_CB; dmr->length = sizeof(*dmr); dmr->dmr_data.data_in_size = xrel_sz; if ((status = (*Dmf_cptr)(DMR_PUT, dmr)) != E_DB_OK) { switch (dmt->error.err_code) { case E_DM0042_DEADLOCK: err.err_code = E_GW0327_DMF_DEADLOCK; break; default: /***note need args here to specify which catalog***/ gwf_error(dmr->error.err_code, GWF_INTERR, 0); gwf_error(E_GW0320_DMR_PUT_ERROR, GWF_INTERR, 2, sizeof(gw_rcb->gwr_tab_id.db_tab_base), &gw_rcb->gwr_tab_id.db_tab_base, sizeof(gw_rcb->gwr_tab_id.db_tab_index), &gw_rcb->gwr_tab_id.db_tab_index); gwf_error(E_GW0623_XCAT_PUT_FAILED, GWF_INTERR, 0); gw_rcb->gwr_error.err_code = E_GW021D_GWU_MAP_IDX_REL_ERROR; break; } } } /* ** Preserve previous status in case of earlier error and ** OK close loosing error status. */ ret_code=status; if ((status = (*Dmf_cptr)(DMT_CLOSE, dmt)) != E_DB_OK) { switch (dmt->error.err_code) { case E_DM0042_DEADLOCK: err.err_code = E_GW0327_DMF_DEADLOCK; break; default: (VOID) gwf_error(dmt->error.err_code, GWF_INTERR, 0); (VOID) gwf_error(E_GW0325_DMT_CLOSE_ERROR, GWF_INTERR, 2, sizeof(dmt->dmt_id.db_tab_base), &dmt->dmt_id.db_tab_base, sizeof(dmt->dmt_id.db_tab_index), &dmt->dmt_id.db_tab_index); gw_rcb->gwr_error.err_code = E_GW021D_GWU_MAP_IDX_REL_ERROR; break; } } /* ** Restore any failure from before */ if (status==E_DB_OK) status=ret_code; break; } return(status); }
/*{ ** Name: gwi_remove - remove a gateway index ** ** Description: ** This function removes extended gateway index catalog information. A ** DMF external interface is used to update, namely delete, the extended ** gateway index catalog, iigwX_index. This request must be made before ** gateway index removal can be considered complete. ** ** The GWF tcb cache for the base table is discarded since it is no longer ** current. ** ** Inputs: ** gw_rcb-> gateway request control block ** session_id an established session id ** dmu-> ** dmu_db_id database id ** dmu_tran_id transaction id ** dmu_tbl_id base table id ** dmu_idx_id INGRES index id ** gw_id gateway id, derived from DBMS type ** ** Output: ** gw_rcb-> ** error.err_code One of the following error numbers. ** E_GW0600_NO_MEM ** E_GW0400_BAD_GWID ** E_GW0006_XIDX_OPEN_FAILED ** Returns: ** E_DB_OK Function completed normally. ** E_DB_ERROR Function completed abnormally with ** error.err_code. ** History: ** 28-Apr-1989 (alexh) ** Created. ** 2-apr-90 (bryanp) ** If this gateway has no extended system catalogs, nothing to do. ** 09-apr-90 (linda) ** Added error handling, single return point. ** 18-apr-90 (bryanp) ** Return E_GW0600_NO_MEM when out of ULM memory. ** 28-mar-91 (linda) ** Fixed 2 problems: (a) error on tuple delete from dmf was logged ** but did not cause this routine to return a bad status; (b) call to ** DMR_DELETE required DMR_CURRENT_POS in flags mask. ** 7-oct-92 (daveb) ** prototyped. Cast arg to gwu_copen (db_id is PTR). */ DB_STATUS gwi_remove(GW_RCB *gw_rcb) { GW_SESSION *session = (GW_SESSION *)gw_rcb->gwr_session_id; DMT_CB dmt; DMR_CB dmr; ULM_RCB ulm_rcb; DM_DATA xidx_buff; i4 gw_id = gw_rcb->gwr_gw_id; i4 xidx_sz = Gwf_facility->gwf_gw_info[gw_id].gwf_xidx_sz; DMR_ATTR_ENTRY attkey[2]; DMR_ATTR_ENTRY *attkey_ptr[2]; DB_TAB_ID sav_idx_id; DB_ERROR err; DB_STATUS status; DB_STATUS sav_status; for (;;) { if ((gw_id <= 0) || (gw_id >= GW_GW_COUNT) || (Gwf_facility->gwf_gw_info[gw_id].gwf_gw_exist == 0)) { (VOID) gwf_error(E_GW0400_BAD_GWID, (i4)0, GWF_INTERR, 1, sizeof(gw_rcb->gwr_gw_id), &gw_rcb->gwr_gw_id); gw_rcb->gwr_error.err_code = E_GW0208_GWI_REGISTER_ERROR; status = E_DB_ERROR; break; } if (xidx_sz == 0) { status = E_DB_OK; break; } /* copy ulm_rcb */ STRUCT_ASSIGN_MACRO(session->gws_ulm_rcb, ulm_rcb); xidx_buff.data_in_size = xidx_sz; ulm_rcb.ulm_blocksize = xidx_buff.data_in_size; /* allocate a iigwX_index buffer from a temporary memory stream */ if ((status = ulm_openstream(&ulm_rcb)) != E_DB_OK) { (VOID) gwf_error(ulm_rcb.ulm_error.err_code, GWF_INTERR, 0); (VOID) gwf_error(E_GW0312_ULM_OPENSTREAM_ERROR, GWF_INTERR, 3, sizeof(*ulm_rcb.ulm_memleft), ulm_rcb.ulm_memleft, sizeof(ulm_rcb.ulm_sizepool), &ulm_rcb.ulm_sizepool, sizeof(ulm_rcb.ulm_blocksize), &ulm_rcb.ulm_blocksize); if (ulm_rcb.ulm_error.err_code == E_UL0005_NOMEM) gw_rcb->gwr_error.err_code = E_GW0600_NO_MEM; else gw_rcb->gwr_error.err_code = E_GW0209_GWI_REMOVE_ERROR; break; } ulm_rcb.ulm_psize = ulm_rcb.ulm_blocksize; if ((status = ulm_palloc(&ulm_rcb)) != E_DB_OK) { (VOID) gwf_error(ulm_rcb.ulm_error.err_code, GWF_INTERR, 0); (VOID) gwf_error(E_GW0314_ULM_PALLOC_ERROR, GWF_INTERR, 4, sizeof(*ulm_rcb.ulm_memleft), ulm_rcb.ulm_memleft, sizeof(ulm_rcb.ulm_sizepool), &ulm_rcb.ulm_sizepool, sizeof(ulm_rcb.ulm_blocksize), &ulm_rcb.ulm_blocksize, sizeof(ulm_rcb.ulm_psize), &ulm_rcb.ulm_psize); if (ulm_rcb.ulm_error.err_code == E_UL0005_NOMEM) gw_rcb->gwr_error.err_code = E_GW0600_NO_MEM; else gw_rcb->gwr_error.err_code = E_GW0209_GWI_REMOVE_ERROR; if ((status = ulm_closestream(&ulm_rcb)) != E_DB_OK) { (VOID) gwf_error(ulm_rcb.ulm_error.err_code, GWF_INTERR, 0); (VOID) gwf_error(E_GW0313_ULM_CLOSESTREAM_ERROR, GWF_INTERR, 1, sizeof(*ulm_rcb.ulm_memleft), ulm_rcb.ulm_memleft); } status = E_DB_ERROR; /* reset after closestream call */ break; } xidx_buff.data_address = ulm_rcb.ulm_pptr; /* initialize dmt_sequence */ dmt.dmt_sequence = gw_rcb->gwr_gw_sequence; /* set up position for iigwXX_index catalog*/ attkey[0].attr_number = 1; attkey[0].attr_operator = DMR_OP_EQ; attkey[0].attr_value = (char *)&gw_rcb->gwr_tab_id.db_tab_base; attkey[1].attr_number = 2; attkey[1].attr_operator = DMR_OP_EQ; attkey[1].attr_value = (char *)&gw_rcb->gwr_tab_id.db_tab_index; attkey_ptr[0] = &attkey[0]; attkey_ptr[1] = &attkey[1]; dmr.type = DMR_RECORD_CB; dmr.length = sizeof(DMR_CB); dmr.dmr_flags_mask = 0; dmr.dmr_position_type = DMR_QUAL; dmr.dmr_attr_desc.ptr_in_count = 2; dmr.dmr_attr_desc.ptr_size = sizeof(DMR_ATTR_ENTRY); dmr.dmr_attr_desc.ptr_address = (PTR)&attkey_ptr[0]; dmr.dmr_access_id = dmt.dmt_record_access_id; dmr.dmr_q_fcn = NULL; /* open the iigwX_index catalog */ if ((status = gwu_copen(&dmt, &dmr, session->gws_scf_session_id, (PTR)gw_rcb->gwr_database_id, gw_id, gw_rcb->gwr_xact_id, &gw_rcb->gwr_tab_id, &session->gws_gw_info[gw_id].gws_xidx_tab_name, DMT_A_WRITE, TRUE, &err)) != E_DB_OK) { switch (dmt.error.err_code) { case E_DM0042_DEADLOCK: gw_rcb->gwr_error.err_code = E_GW0327_DMF_DEADLOCK; break; default: (VOID) gwf_error(err.err_code, GWF_INTERR, 0); gw_rcb->gwr_error.err_code = E_GW0209_GWI_REMOVE_ERROR; break; } if ((status = ulm_closestream(&ulm_rcb)) != E_DB_OK) { (VOID) gwf_error(ulm_rcb.ulm_error.err_code, GWF_INTERR, 0); (VOID) gwf_error(E_GW0313_ULM_CLOSESTREAM_ERROR, GWF_INTERR, 1, sizeof(*ulm_rcb.ulm_memleft), ulm_rcb.ulm_memleft); gw_rcb->gwr_error.err_code = E_GW0209_GWI_REMOVE_ERROR; } break; } dmr.dmr_flags_mask = DMR_NEXT; STRUCT_ASSIGN_MACRO(xidx_buff, dmr.dmr_data); dmr.dmr_char_array.data_address = 0; /* ** Delete the index entry with index and base table id */ do { status = (*Dmf_cptr)(DMR_GET, &dmr); } while (status == E_DB_OK && MEcmp((PTR)dmr.dmr_data.data_address, (PTR)&gw_rcb->gwr_tab_id, sizeof(DB_TAB_ID)) ); if (status == E_DB_OK) { dmr.dmr_flags_mask |= DMR_CURRENT_POS; if ((status = (*Dmf_cptr)(DMR_DELETE, &dmr)) != E_DB_OK) { switch (dmt.error.err_code) { case E_DM0042_DEADLOCK: gw_rcb->gwr_error.err_code = E_GW0327_DMF_DEADLOCK; break; default: (VOID) gwf_error(dmr.error.err_code, GWF_INTERR, 0); (VOID) gwf_error(E_GW0322_DMR_DELETE_ERROR, GWF_INTERR, 2, sizeof(gw_rcb->gwr_tab_id.db_tab_base), &gw_rcb->gwr_tab_id.db_tab_base, sizeof(gw_rcb->gwr_tab_id.db_tab_index), &gw_rcb->gwr_tab_id.db_tab_index); gw_rcb->gwr_error.err_code = E_GW0209_GWI_REMOVE_ERROR; break; } if (dmt.error.err_code == E_DM0042_DEADLOCK) break; /* (Else no break; we still want to close index catalog.) */ } } else /* status != E_DB_OK */ { switch (dmt.error.err_code) { case E_DM0042_DEADLOCK: gw_rcb->gwr_error.err_code = E_GW0327_DMF_DEADLOCK; break; default: (VOID) gwf_error(dmr.error.err_code, GWF_INTERR, 0); (VOID) gwf_error(E_GW0321_DMR_GET_ERROR, GWF_INTERR, 2, sizeof(gw_rcb->gwr_tab_id.db_tab_base), &gw_rcb->gwr_tab_id.db_tab_base, sizeof(gw_rcb->gwr_tab_id.db_tab_index), &gw_rcb->gwr_tab_id.db_tab_index); gw_rcb->gwr_error.err_code = E_GW0209_GWI_REMOVE_ERROR; break; } if (dmt.error.err_code == E_DM0042_DEADLOCK) break; /* (Else no break; we still want to close index catalog.) */ } sav_status = status; /* in case of non-deadlock error above */ if ((status = (*Dmf_cptr)(DMT_CLOSE, &dmt)) != E_DB_OK) { switch (dmt.error.err_code) { case E_DM0042_DEADLOCK: gw_rcb->gwr_error.err_code = E_GW0327_DMF_DEADLOCK; break; default: (VOID) gwf_error(dmt.error.err_code, GWF_INTERR, 0); (VOID) gwf_error(E_GW0325_DMT_CLOSE_ERROR, GWF_INTERR, 2, sizeof(dmt.dmt_id.db_tab_base), &dmt.dmt_id.db_tab_base, sizeof(dmt.dmt_id.db_tab_index), &dmt.dmt_id.db_tab_index); gw_rcb->gwr_error.err_code = E_GW0209_GWI_REMOVE_ERROR; break; } } /* ** delete tcb from GWF cache since its index info cannot be current. */ /* ** First save index's tab_id, set base to 0 for call. */ _VOID_ MEcopy((PTR)&gw_rcb->gwr_tab_id, sizeof(DB_TAB_ID), (PTR)&sav_idx_id); gw_rcb->gwr_tab_id.db_tab_index = 0; if ((status = gwu_deltcb(gw_rcb, GWU_TCB_OPTIONAL, &err)) != E_DB_OK) { (VOID) gwf_error(err.err_code, GWF_INTERR, 0); gw_rcb->gwr_error.err_code = E_GW0209_GWI_REMOVE_ERROR; _VOID_ MEcopy((PTR)&sav_idx_id, sizeof(DB_TAB_ID), (PTR)&gw_rcb->gwr_tab_id); break; } _VOID_ MEcopy((PTR)&sav_idx_id, sizeof(DB_TAB_ID), (PTR)&gw_rcb->gwr_tab_id); if ((status = ulm_closestream(&ulm_rcb)) != E_DB_OK) { (VOID) gwf_error(ulm_rcb.ulm_error.err_code, GWF_INTERR, 0); (VOID) gwf_error(E_GW0313_ULM_CLOSESTREAM_ERROR, GWF_INTERR, 1, sizeof(ulm_rcb.ulm_error.err_code), &ulm_rcb.ulm_error.err_code); gw_rcb->gwr_error.err_code = E_GW0209_GWI_REMOVE_ERROR; break; } /* ** If we get here, things went okay after the tuple delete. Recheck ** status from that call. */ if (sav_status == E_DB_OK) { gw_rcb->gwr_error.err_code = E_DB_OK; } else { status = sav_status; gw_rcb->gwr_error.err_code = E_GW0209_GWI_REMOVE_ERROR; } break; } return(status); }
/* ** Name: gwi_register - register a gateway index ** ** Description: ** This function registers extended gateway index catalog information. A ** DMF external interface is used to update, namely put, the extended ** gateway catalog, iigwX_index. This request must be made before ** gateway index registration can be considered complete. ** ** The GWF tcb cache for the base table is discarded since it is no longer ** current. ** ** Inputs: ** gw_rcb-> gateway request control block ** session_id an established session id ** dmu-> ** dmu_db_id database id ** dmu_tran_id transaction id ** dmu_tbl_id base table id ** dmu_idx_id INGRES index id ** gw_id gateway id, derived from DBMS type ** in_vdata2 source of the gateway index. ** ** Output: ** gw_rcb-> ** error.err_code One of the following error numbers. ** E_GW0600_NO_MEM ** E_GW0400_BAD_GWID ** E_GW0208_GWI_REGISTER_ERROR ** E_GW0006_XIDX_OPEN_FAILED ** Returns: ** E_DB_OK Function completed normally. ** E_DB_ERROR Function completed abnormally with ** error.err_code. ** History: ** 28-Apr-1989 (alexh) ** Created. ** 2-apr-90 (bryanp) ** If gateway has no extended system catalog, nothing to do. ** 09-apr-90 (linda) ** Add error handling and single return point. ** 18-apr-90 (bryanp) ** Return E_GW0600_NO_MEM when out of ULM memory. ** 1-jul-91 (rickh) ** If the gateway exit returns an error, don't clobber the status ** word when we close the stream! Also, if the exit has already ** reported the problem, spare us the uninformative yet alarming ** error-babble of higher facilities. ** 7-oct-92 (robf) ** Still create Xrelation & Xattribute entries even if no Xindex ** table - a gateway may need rel/attr entires but not the ** index one ** 7-oct-92 (daveb) ** Hand the exit the session pointer, in case it wants to add ** an exit-private SCB. Prototyped. Removed dead vars xrel_sz ** and sav_idx_id. Cast db_id arg to gwu_copen; it's a PTR. ** 17-nov-92 (robf) ** Changed calls to gwf_display() to use array rather than ** arg list. */ DB_STATUS gwi_register(GW_RCB *gw_rcb) { GWX_RCB gwx; ULM_RCB ulm_rcb; GW_SESSION *session = (GW_SESSION *)gw_rcb->gwr_session_id; DMT_CB dmt; DMR_CB dmr; i4 gw_id = gw_rcb->gwr_gw_id; i4 xidx_sz = Gwf_facility->gwf_gw_info[gw_id].gwf_xidx_sz; DB_STATUS status; DB_STATUS ulm_status; DB_ERROR err; char trbuf[GWF_MAX_MSGLEN + 1]; /* last char for `\n' */ if(GWF_MAIN_MACRO(12)) { gwf_display(gwf_scctalk, 0, trbuf, sizeof(trbuf) - 1, "GWI_REGISTER: REGISTER INDEX entry\n"); } for (;;) { if ((gw_id <= 0) || (gw_id >= GW_GW_COUNT) || (Gwf_facility->gwf_gw_info[gw_id].gwf_gw_exist == 0)) { (VOID) gwf_error(E_GW0400_BAD_GWID, (i4)0, GWF_INTERR, 1, sizeof(gw_id), &gw_id); gw_rcb->gwr_error.err_code = E_GW0208_GWI_REGISTER_ERROR; status = E_DB_ERROR; break; } /* ** Allocate a memory stream for the life of this operation. Used as ** storage for temporary structures. Note that it is allocated from ** the session's GWF memory stream. */ STRUCT_ASSIGN_MACRO(session->gws_ulm_rcb, ulm_rcb); ulm_rcb.ulm_blocksize = xidx_sz; if ((status = ulm_openstream(&ulm_rcb)) != E_DB_OK) { (VOID) gwf_error(ulm_rcb.ulm_error.err_code, GWF_INTERR, 0); (VOID) gwf_error(E_GW0312_ULM_OPENSTREAM_ERROR, GWF_INTERR, 3, sizeof(*ulm_rcb.ulm_memleft), ulm_rcb.ulm_memleft, sizeof(ulm_rcb.ulm_sizepool), &ulm_rcb.ulm_sizepool, sizeof(ulm_rcb.ulm_blocksize), &ulm_rcb.ulm_blocksize); if (ulm_rcb.ulm_error.err_code == E_UL0005_NOMEM) gw_rcb->gwr_error.err_code = E_GW0600_NO_MEM; else gw_rcb->gwr_error.err_code = E_GW0208_GWI_REGISTER_ERROR; break; } /* ** Only process extended index info if this gateway has an ** extended index catalog */ if (Gwf_facility->gwf_gw_info[gw_id].gwf_xidx_sz > 0) { gwx.xrcb_tab_id = &gw_rcb->gwr_tab_id; /* STRUCT_ASSIGN_MACRO(gw_rcb->gwr_tab_id, gwx.xrcb_tab_id); */ gwx.xrcb_gw_id = gw_id; STRUCT_ASSIGN_MACRO(gw_rcb->gwr_in_vdata2, gwx.xrcb_var_data2); /* allocate iigwX_index tuple buffer */ gwx.xrcb_var_data1.data_in_size = ulm_rcb.ulm_psize = ulm_rcb.ulm_blocksize; if ((status = ulm_palloc(&ulm_rcb)) != E_DB_OK) { (VOID) gwf_error(ulm_rcb.ulm_error.err_code, GWF_INTERR, 0); (VOID) gwf_error(E_GW0314_ULM_PALLOC_ERROR, GWF_INTERR, 4, sizeof(*ulm_rcb.ulm_memleft), ulm_rcb.ulm_memleft, sizeof(ulm_rcb.ulm_sizepool), &ulm_rcb.ulm_sizepool, sizeof(ulm_rcb.ulm_blocksize), &ulm_rcb.ulm_blocksize, sizeof(ulm_rcb.ulm_psize), &ulm_rcb.ulm_psize); if (ulm_rcb.ulm_error.err_code == E_UL0005_NOMEM) gw_rcb->gwr_error.err_code = E_GW0600_NO_MEM; else gw_rcb->gwr_error.err_code = E_GW0208_GWI_REGISTER_ERROR; break; } gwx.xrcb_var_data1.data_address = ulm_rcb.ulm_pptr; /* request exit format */ if ((status = (*Gwf_facility->gwf_gw_info[gw_id].gwf_gw_exits [GWX_VIDXF]) (&gwx)) != E_DB_OK) { if ( gwx.xrcb_error.err_code == E_GW050E_ALREADY_REPORTED ) { gw_rcb->gwr_error.err_code = E_GW050E_ALREADY_REPORTED; } else { (VOID) gwf_error(gwx.xrcb_error.err_code, GWF_INTERR, 0); gw_rcb->gwr_error.err_code = E_GW0208_GWI_REGISTER_ERROR; } if ((ulm_status = ulm_closestream(&ulm_rcb)) != E_DB_OK) { (VOID) gwf_error(ulm_rcb.ulm_error.err_code, GWF_INTERR, 0); (VOID) gwf_error(E_GW0313_ULM_CLOSESTREAM_ERROR, GWF_INTERR, 1, sizeof(*ulm_rcb.ulm_memleft), ulm_rcb.ulm_memleft); break; } break; } else { /* initialize dmt_sequence */ dmt.dmt_sequence = gw_rcb->gwr_gw_sequence; /* request DMF to append tuples */ status = gwu_copen(&dmt, &dmr, session->gws_scf_session_id, (PTR) gw_rcb->gwr_database_id, gw_id, gw_rcb->gwr_xact_id, &gw_rcb->gwr_tab_id, &session->gws_gw_info[gw_id].gws_xidx_tab_name, DMT_A_WRITE, FALSE, &err); /* put the iigwX_index tuple */ if ( status == E_DB_OK) { STRUCT_ASSIGN_MACRO(gwx.xrcb_var_data1, dmr.dmr_data); if ((status = (*Dmf_cptr)(DMR_PUT, &dmr)) == E_DB_OK) { status = (*Dmf_cptr)(DMT_CLOSE, &dmt); if (status != E_DB_OK) { /* Handle error from close */ (VOID) gwf_error(dmt.error.err_code, GWF_INTERR, 0); gw_rcb->gwr_error.err_code = E_GW0208_GWI_REGISTER_ERROR; break; } } else { /* Handle error from put */ switch (dmt.error.err_code) { case E_DM0042_DEADLOCK: gw_rcb->gwr_error.err_code = E_GW0327_DMF_DEADLOCK; break; default: (VOID) gwf_error(dmt.error.err_code, GWF_INTERR, 0); gw_rcb->gwr_error.err_code = E_GW0208_GWI_REGISTER_ERROR; break; } break; } } else { /* Handle error from gwu_copen() */ (VOID) gwf_error(err.err_code, GWF_INTERR, 0); gw_rcb->gwr_error.err_code = E_GW0208_GWI_REGISTER_ERROR; break; } /* ** delete tcb from GWF cache since its index info cannot be ** current. ** **** Not clear that we care about this. We probably can't remove **** an index if it is being used and it is only referenced in its **** own tcb. */ #if 0 /* ** Save the index's table id, set db_tab_index to 0 for the call. */ _VOID_ MEcopy((PTR)&gw_rcb->gwr_tab_id, sizeof(DB_TAB_ID), (PTR)&sav_idx_id); gw_rcb->gwr_tab_id.db_tab_index = 0; if ((status = gwu_deltcb(gw_rcb, GWU_TCB_OPTIONAL, &err)) != E_DB_OK) { (VOID) gwf_error(err.err_code, GWF_INTERR, 0); gw_rcb->gwr_error.err_code = E_GW0208_GWI_REGISTER_ERROR; _VOID_ MEcopy((PTR)&sav_idx_id, sizeof(DB_TAB_ID), (PTR)&gw_rcb->gwr_tab_id); break; } _VOID_ MEcopy((PTR)&sav_idx_id, sizeof(DB_TAB_ID), (PTR)&gw_rcb->gwr_tab_id); #endif /* 0 */ } } /* End if Xindex processing */ /* ** Append a tuple to iigwX_relation catalog for this index. */ if ((status = gwi_map_idx_rel(gw_rcb, &dmt, &dmr, &ulm_rcb)) != E_DB_OK) { _VOID_ gwf_error(gw_rcb->gwr_error.err_code, GWF_INTERR, 0); gw_rcb->gwr_error.err_code = E_GW0208_GWI_REGISTER_ERROR; break; } /* ** Now append iigwX_attribute tuples. */ if ((status = gwi_map_idx_att(gw_rcb, &ulm_rcb)) != E_DB_OK) { _VOID_ gwf_error(gw_rcb->gwr_error.err_code, GWF_INTERR, 0); gw_rcb->gwr_error.err_code = E_GW0208_GWI_REGISTER_ERROR; break; } /* close the temporary stream */ if ((status = ulm_closestream(&ulm_rcb)) != E_DB_OK) { (VOID) gwf_error(ulm_rcb.ulm_error.err_code, GWF_INTERR, 0); (VOID) gwf_error(E_GW0313_ULM_CLOSESTREAM_ERROR, GWF_INTERR, 1, sizeof(*ulm_rcb.ulm_memleft), ulm_rcb.ulm_memleft); gw_rcb->gwr_error.err_code = E_GW0208_GWI_REGISTER_ERROR; break; } /* If we get here everything is okay. */ break; } if (status == E_DB_OK) gw_rcb->gwr_error.err_code = E_DB_OK; return(status); }
/*{ ** Name: gwi_map_idx_att - create tuple entries in the iigwX_attribute ** table for this gateway secondary index ** ** Description: ** This function creates tuples in the extended attribute catalog for this ** gateway secondary index. The tuples are those defined for the index, ** plus a tidp column. ** ** In order to create the tuple entries, the following steps are performed: ** ** (1) select all rows from iiattribute for this index, and save them. ** (2) For each row saved: ** (a) if it's 'tidp', drop down to (3). ** (b) select the row from iiattribute for the base table which has ** the same name and save its attid; we will use this to get ** extended attribute info. ** (c) now select the appropriate row from iigwX_attribute. ** (d) update the xrelidx and xattid fields -- xrelidx is non-zero for ** this index, xattid is that for the index not the base table. ** (e) append the row. ** (3) finished with "real" attributes. Check that we found 1 or more ** other attributes -- else error. Now create the row for the tidp ** domain and append it. Use integer gw datatype, length 4, offset 0; ** we don't really use this attribute and it doesn't exist in the ** gateway record. Need to have a gateway-specific static definition ** for this row. ** ** Inputs: ** gw_rcb-> gateway request control block ** gwr_tab_id table id for this secondary index ** ulm_rcb memory request control block, passed in from ** parent routine as it is in the same stream, we ** want to deallocate all related memory from there ** ** Output: ** gw_rcb-> ** error.err_code One of the following error numbers. ** E_GW0600_NO_MEM ** ** Returns: ** E_DB_OK Function completed normally. ** E_DB_ERROR Function completed abnormally with ** error.err_code. ** History: ** 24-sep-90 (linda) ** Created. ** 07-oct-92 (robf) ** If open of iiattribute fails, don't try to continue processing. ** 8-oct-92 (daveb) ** cast an assignment. ** 8-oct-92 (daveb) ** prototyped. Cast db_id arg to gwu_copen; it's a PTR. ** 30-May-2006 (jenjo02) ** Max attributes in an index is now DB_MAXIXATTS, not DB_MAXKEYS. */ static DB_STATUS gwi_map_idx_att(GW_RCB *gw_rcb, ULM_RCB *ulm_rcb ) { GW_SESSION *session = (GW_SESSION *)gw_rcb->gwr_session_id; DMT_CB dmt; DMR_CB dmr; char *dmp_atts[DB_MAXIXATTS+1]; GW_DMP_ATTR *dmp_att1; GW_DMP_ATTR *dmp_att2; GW_DMP_ATTR iiatt_buf; DB_TAB_ID base_tab_id; DB_TAB_ID *tab_id; i4 i; i4 j; i2 *attid_ptr; DMR_ATTR_ENTRY attkey[2]; DMR_ATTR_ENTRY *attkey_ptr[2]; i4 gw_id = gw_rcb->gwr_gw_id; i4 xatt_sz = Gwf_facility->gwf_gw_info[gw_id].gwf_xatt_sz; char stage_buf[DB_MAXTUP]; char *xatt_rows[DB_MAXIXATTS+1]; DB_STATUS status = E_DB_OK; /* ** Set up the base table id for later use. */ STRUCT_ASSIGN_MACRO(gw_rcb->gwr_tab_id, base_tab_id); base_tab_id.db_tab_index = 0; for (;;) /* just to break out of on error... */ { /* ** First set up dmt and open iiattribute table. */ dmt.type = DMT_TABLE_CB; dmt.length = sizeof(DMT_CB); dmt.dmt_id.db_tab_base = 3; /* tab_id for iiattribute */ dmt.dmt_id.db_tab_index = 0; /* " " " " " " */ /** *** gwr_gw_sequence == 0, which causes dmt_open to fail. For now set it to 1. *** dmt.dmt_sequence = gw_rcb->gwr_gw_sequence; **/ dmt.dmt_sequence = 1; dmt.dmt_db_id = (PTR)gw_rcb->gwr_database_id; dmt.dmt_tran_id = gw_rcb->gwr_xact_id; dmt.dmt_flags_mask = 0; dmt.dmt_access_mode = DMT_A_READ; dmt.dmt_lock_mode = DMT_IS; dmt.dmt_update_mode = DMT_U_DEFERRED; dmt.dmt_char_array.data_address = NULL; dmt.dmt_char_array.data_in_size = 0; if ((status = (*Dmf_cptr)(DMT_OPEN, &dmt)) != E_DB_OK) { switch (dmt.error.err_code) { case E_DM0042_DEADLOCK: gw_rcb->gwr_error.err_code = E_GW0327_DMF_DEADLOCK; break; default: (VOID) gwf_error(dmt.error.err_code, GWF_INTERR, 0); (VOID) gwf_error(E_GW0324_DMT_OPEN_ERROR, GWF_INTERR, 2, (i4)4, (PTR)&dmt.dmt_id.db_tab_base, (i4)4, (PTR)&dmt.dmt_id.db_tab_index); gw_rcb->gwr_error.err_code = E_GW021E_GWU_MAP_IDX_ATT_ERROR; break; } break; } /* position to get if this is a DMT_A_READ */ attkey[0].attr_number = 1; attkey[0].attr_operator = DMR_OP_EQ; attkey[0].attr_value = (char *)&gw_rcb->gwr_tab_id.db_tab_base; attkey[1].attr_number = 2; attkey[1].attr_operator = DMR_OP_EQ; attkey[1].attr_value = (char *)&gw_rcb->gwr_tab_id.db_tab_index; attkey_ptr[0] = &attkey[0]; attkey_ptr[1] = &attkey[1]; dmr.type = DMR_RECORD_CB; dmr.length = sizeof(DMR_CB); dmr.dmr_flags_mask = 0; dmr.dmr_position_type = DMR_QUAL; dmr.dmr_attr_desc.ptr_in_count = 2; dmr.dmr_attr_desc.ptr_size = sizeof(DMR_ATTR_ENTRY); dmr.dmr_attr_desc.ptr_address = (PTR)&attkey_ptr[0]; dmr.dmr_access_id = dmt.dmt_record_access_id; dmr.dmr_q_fcn = NULL; if ((status = (*Dmf_cptr)(DMR_POSITION, &dmr)) != E_DB_OK) { switch (dmt.error.err_code) { case E_DM0042_DEADLOCK: gw_rcb->gwr_error.err_code = E_GW0327_DMF_DEADLOCK; break; default: (VOID) gwf_error(dmr.error.err_code, GWF_INTERR, 0); (VOID) gwf_error(E_GW0323_DMR_POSITION_ERROR, GWF_INTERR, 2, (i4)4, (PTR)&dmt.dmt_id.db_tab_base, (i4)4, (PTR)&dmt.dmt_id.db_tab_index); gw_rcb->gwr_error.err_code = E_GW0213_GWU_COPEN_ERROR; break; } } /* ** We'll allocate room for a GW_DMP_ATTR struct plus an extra 2 ** bytes for the column's base table attid, which we'll use to get ** the right row from iigwX_attribute. */ ulm_rcb->ulm_psize = sizeof(GW_DMP_ATTR) + 2; dmr.dmr_data.data_in_size = sizeof(GW_DMP_ATTR) + 2; dmr.dmr_flags_mask = DMR_NEXT; dmr.dmr_data.data_address = &stage_buf[0]; dmr.dmr_char_array.data_address = 0; for (i=0; i < gw_rcb->gwr_column_cnt; i++) { do { status = (*Dmf_cptr)(DMR_GET, &dmr); } while ((status == E_DB_OK) && (MEcmp((PTR)dmr.dmr_data.data_address, (PTR)&gw_rcb->gwr_tab_id, sizeof(DB_TAB_ID))) ); if (status == E_DB_OK) { if ((status = ulm_palloc(ulm_rcb)) != E_DB_OK) { gwf_error(ulm_rcb->ulm_error.err_code, GWF_INTERR, 0); gwf_error(E_GW0314_ULM_PALLOC_ERROR, GWF_INTERR, 4, sizeof(*ulm_rcb->ulm_memleft), ulm_rcb->ulm_memleft, sizeof(ulm_rcb->ulm_sizepool), &ulm_rcb->ulm_sizepool, sizeof(ulm_rcb->ulm_blocksize), &ulm_rcb->ulm_blocksize, sizeof(ulm_rcb->ulm_psize), &ulm_rcb->ulm_psize); if (ulm_rcb->ulm_error.err_code == E_UL0005_NOMEM) gw_rcb->gwr_error.err_code = E_GW0600_NO_MEM; else { switch (dmt.error.err_code) { case E_DM0042_DEADLOCK: gw_rcb->gwr_error.err_code = E_GW0327_DMF_DEADLOCK; break; default: gw_rcb->gwr_error.err_code = E_GW021E_GWU_MAP_IDX_ATT_ERROR; break; } } break; } MEcopy((PTR)&stage_buf[0], sizeof(GW_DMP_ATTR)+2, ulm_rcb->ulm_pptr); dmp_atts[i] = (char *)ulm_rcb->ulm_pptr; continue; /* get next attribute for the index */ } else if (dmr.error.err_code == E_DM0055_NONEXT) { /***FIXME*** -- at this point we've allocated an extra buffer? look at -- ***/ status = E_DB_OK; dmr.error.err_code = E_DB_OK; break; /* no more attributes for this index */ } else { switch (dmt.error.err_code) { case E_DM0042_DEADLOCK: gw_rcb->gwr_error.err_code = E_GW0327_DMF_DEADLOCK; break; default: (VOID) gwf_error(dmr.error.err_code, GWF_INTERR, 0); (VOID) gwf_error(E_GW0323_DMR_POSITION_ERROR, GWF_INTERR, 2, (i4)4, (PTR)&dmt.dmt_id.db_tab_base, (i4)4, (PTR)&dmt.dmt_id.db_tab_index); gw_rcb->gwr_error.err_code = E_GW021E_GWU_MAP_IDX_ATT_ERROR; break; } } break; } if (status != E_DB_OK) break; /* error already reported. */ /* ** Now we get the base table rows from iiattribute, so we can store the ** attid from the base to get the proper base table row from ** iigwX_attribute. */ attkey[0].attr_value = (char *)&base_tab_id.db_tab_base; attkey[1].attr_value = (char *)&base_tab_id.db_tab_index; if ((status = (*Dmf_cptr)(DMR_POSITION, &dmr)) != E_DB_OK) { switch (dmt.error.err_code) { case E_DM0042_DEADLOCK: gw_rcb->gwr_error.err_code = E_GW0327_DMF_DEADLOCK; break; default: (VOID) gwf_error(dmr.error.err_code, GWF_INTERR, 0); (VOID) gwf_error(E_GW0323_DMR_POSITION_ERROR, GWF_INTERR, 2, (i4)4, (PTR)&dmt.dmt_id.db_tab_base, (i4)4, (PTR)&dmt.dmt_id.db_tab_index); gw_rcb->gwr_error.err_code = E_GW021E_GWU_MAP_IDX_ATT_ERROR; break; } break; } /* ** We don't know how many columns are in the base table; just need to ** find matches for those in the index table. The tidp column will be ** handled separately. Only need one buffer here, we store base table ** attid with previously-allocated rows for index table. */ dmr.dmr_data.data_in_size = sizeof(GW_DMP_ATTR); dmr.dmr_data.data_address = (PTR)&iiatt_buf; dmr.dmr_char_array.data_address = 0; i = 0; /* keep a count of matches found */ for (;;) /* this gives us a place to continue to. */ { do { status = (*Dmf_cptr)(DMR_GET, &dmr); } while ((status == E_DB_OK) && (MEcmp((PTR)dmr.dmr_data.data_address, (PTR)&base_tab_id, sizeof(DB_TAB_ID))) ); if (status == E_DB_OK) { dmp_att1 = (GW_DMP_ATTR *)dmr.dmr_data.data_address; for (j=0; j < gw_rcb->gwr_column_cnt; j++) { dmp_att2 = (GW_DMP_ATTR *)dmp_atts[j]; if (!MEcmp((PTR)&dmp_att1->attname, (PTR)&dmp_att2->attname, sizeof(DB_ATT_NAME))) { attid_ptr = (i2 *)(dmp_atts[j] + sizeof(GW_DMP_ATTR)); *attid_ptr = dmp_att1->attid; i++; break; /* out of inner loop */ } } } else if (dmr.error.err_code == E_DM0055_NONEXT) { status = E_DB_OK; dmr.error.err_code = E_DB_OK; break; /* no more attributes for this index */ } else { switch (dmt.error.err_code) { case E_DM0042_DEADLOCK: gw_rcb->gwr_error.err_code = E_GW0327_DMF_DEADLOCK; break; default: (VOID) gwf_error(dmr.error.err_code, GWF_INTERR, 0); (VOID) gwf_error(E_GW0323_DMR_POSITION_ERROR, GWF_INTERR, 2, (i4)4, (PTR)&dmt.dmt_id.db_tab_base, (i4)4, (PTR)&dmt.dmt_id.db_tab_index); gw_rcb->gwr_error.err_code = E_GW021E_GWU_MAP_IDX_ATT_ERROR; break; } break; } if (i == gw_rcb->gwr_column_cnt - 1) break; /* we've found all the matching rows */ } /* Always close iiattribute table. */ if ((status = (*Dmf_cptr)(DMT_CLOSE, &dmt)) != E_DB_OK) { switch (dmt.error.err_code) { case E_DM0042_DEADLOCK: gw_rcb->gwr_error.err_code = E_GW0327_DMF_DEADLOCK; break; default: gwf_error(dmt.error.err_code, GWF_INTERR, 0); gwf_error(E_GW0325_DMT_CLOSE_ERROR, GWF_INTERR, 2, sizeof(dmt.dmt_id.db_tab_base), &dmt.dmt_id.db_tab_base, sizeof(dmt.dmt_id.db_tab_index), &dmt.dmt_id.db_tab_index); gwf_error(E_GW062C_XREL_CLOSE_FAILED, GWF_INTERR, 0); gw_rcb->gwr_error.err_code = E_GW021E_GWU_MAP_IDX_ATT_ERROR; break; } break; } if (status != E_DB_OK) /* whether from previous code, or close */ break; /* error already reported */ /* ** We should have found matches for all but one index column (tidp). */ if (i != gw_rcb->gwr_column_cnt - 1) { /***generate error here***/ gw_rcb->gwr_error.err_code = E_GW021E_GWU_MAP_IDX_ATT_ERROR; break; } /* position on base table id */ dmr.dmr_position_type = DMR_QUAL; dmr.dmr_attr_desc.ptr_in_count = 2; dmr.dmr_attr_desc.ptr_size = sizeof(DMR_ATTR_ENTRY); dmr.dmr_attr_desc.ptr_address = (PTR)&attkey_ptr[0]; /* now we get the rows from the extended attribute catalog */ if ((status = gwu_copen(&dmt, &dmr, session->gws_scf_session_id, (PTR)gw_rcb->gwr_database_id, gw_id, gw_rcb->gwr_xact_id, &gw_rcb->gwr_tab_id, &session->gws_gw_info[gw_id].gws_xatt_tab_name, DMT_A_WRITE, TRUE, &gw_rcb->gwr_error)) != E_DB_OK) { switch (dmt.error.err_code) { case E_DM0042_DEADLOCK: gw_rcb->gwr_error.err_code = E_GW0327_DMF_DEADLOCK; break; default: (VOID) gwf_error(gw_rcb->gwr_error.err_code, GWF_INTERR, 0); gw_rcb->gwr_error.err_code = E_GW021E_GWU_MAP_IDX_ATT_ERROR; break; } } /* ** Set up staging area for tuples returned from extended attribute ** catalog. We'll allocate space when we find a match, so we can ** insert them later. */ dmr.dmr_flags_mask = DMR_NEXT; dmr.dmr_data.data_in_size = xatt_sz; dmr.dmr_data.data_address = (PTR)&stage_buf[0]; dmr.dmr_char_array.data_address = 0; /* ** Size to be allocated is one extended attribute row. */ ulm_rcb->ulm_psize = xatt_sz; i = 0; /* search for the right tuples */ for (;;) { do { status = (*Dmf_cptr)(DMR_GET, &dmr); } while (status == E_DB_OK && MEcmp((PTR)dmr.dmr_data.data_address, (PTR)&base_tab_id, sizeof(DB_TAB_ID))); if (status == E_DB_OK) { /* ** When we find a tuple from iigwX_attribute which matches one ** of the index tuples, update the values to represent the ** index and then store the tuple. NOTE that we assume that ** tab_id and attid fields are the first fields in the extended ** catalog. We can't know the internal structure of extended ** attribute catalogs for particular gateways beyond the 1st ** three cols. */ dmp_att1 = (GW_DMP_ATTR *)dmr.dmr_data.data_address; for (j=0; j < gw_rcb->gwr_column_cnt - 1; j++) { if (dmp_att1->attid == *(i2 *)(dmp_atts[j] + sizeof(GW_DMP_ATTR))) { if ((status = ulm_palloc(ulm_rcb)) != E_DB_OK) { gwf_error(ulm_rcb->ulm_error.err_code, GWF_INTERR, 0); gwf_error(E_GW0314_ULM_PALLOC_ERROR, GWF_INTERR, 4, sizeof(*ulm_rcb->ulm_memleft), ulm_rcb->ulm_memleft, sizeof(ulm_rcb->ulm_sizepool), &ulm_rcb->ulm_sizepool, sizeof(ulm_rcb->ulm_blocksize), &ulm_rcb->ulm_blocksize, sizeof(ulm_rcb->ulm_psize), &ulm_rcb->ulm_psize); if (ulm_rcb->ulm_error.err_code == E_UL0005_NOMEM) gw_rcb->gwr_error.err_code = E_GW0600_NO_MEM; else gw_rcb->gwr_error.err_code = E_GW021E_GWU_MAP_IDX_ATT_ERROR; break; } dmp_att1->attid = i + 1; xatt_rows[i] = ulm_rcb->ulm_pptr; MEcopy(dmr.dmr_data.data_address, xatt_sz, xatt_rows[i]); tab_id = (DB_TAB_ID *)xatt_rows[i]; STRUCT_ASSIGN_MACRO(gw_rcb->gwr_tab_id, *tab_id); i++; break; } } if (i == gw_rcb->gwr_column_cnt - 1) break; } else /* cannot get table info */ { if (dmr.error.err_code == E_DM0055_NONEXT) { status = E_DB_OK; dmr.error.err_code = E_DB_OK; break; /* no more attributes for this index */ } else { switch (dmt.error.err_code) { case E_DM0042_DEADLOCK: gw_rcb->gwr_error.err_code = E_GW0327_DMF_DEADLOCK; break; default: (VOID) gwf_error(dmr.error.err_code, GWF_INTERR, 0); (VOID) gwf_error(E_GW0321_DMR_GET_ERROR, GWF_INTERR, 2, (i4)4, (PTR)&gw_rcb->gwr_tab_id.db_tab_base, (i4)4, (PTR)&gw_rcb->gwr_tab_id.db_tab_index); gw_rcb->gwr_error.err_code = E_GW021E_GWU_MAP_IDX_ATT_ERROR; break; } break; } } continue; /* get next attribute for the base */ } /* ** Okay, now construct the row for tidp. Reuse stage_buf for this. */ MEcopy(Gwf_facility->gwf_gw_info[gw_id].gwf_xatt_tidp, xatt_sz, (PTR)&stage_buf[0]); tab_id = (DB_TAB_ID *)&stage_buf[0]; STRUCT_ASSIGN_MACRO(gw_rcb->gwr_tab_id, *tab_id); attid_ptr = (i2 *)(&stage_buf[0] + sizeof(DB_TAB_ID)); *attid_ptr = i + 1; xatt_rows[i] = &stage_buf[0]; /* ** Finally, put the iigwX_attribute tuples for the gateway secondary ** index. */ dmr.dmr_data.data_in_size = xatt_sz; for (j=0; j<=i; j++) { dmr.dmr_data.data_address = (PTR)xatt_rows[j]; if ((status = (*Dmf_cptr)(DMR_PUT, &dmr)) != E_DB_OK) { switch (dmt.error.err_code) { case E_DM0042_DEADLOCK: gw_rcb->gwr_error.err_code = E_GW0327_DMF_DEADLOCK; break; default: /***note need args here to specify which catalog***/ gwf_error(dmr.error.err_code, GWF_INTERR, 0); gwf_error(E_GW0320_DMR_PUT_ERROR, GWF_INTERR, 2, sizeof(gw_rcb->gwr_tab_id.db_tab_base), &gw_rcb->gwr_tab_id.db_tab_base, sizeof(gw_rcb->gwr_tab_id.db_tab_index), &gw_rcb->gwr_tab_id.db_tab_index); gwf_error(E_GW0623_XCAT_PUT_FAILED, GWF_INTERR, 0); gw_rcb->gwr_error.err_code = E_GW021E_GWU_MAP_IDX_ATT_ERROR; break; } break; } } if ((status = (*Dmf_cptr)(DMT_CLOSE, &dmt)) != E_DB_OK) { switch (dmt.error.err_code) { case E_DM0042_DEADLOCK: gw_rcb->gwr_error.err_code = E_GW0327_DMF_DEADLOCK; break; default: (VOID) gwf_error(dmt.error.err_code, GWF_INTERR, 0); (VOID) gwf_error(E_GW0325_DMT_CLOSE_ERROR, GWF_INTERR, 2, sizeof(dmt.dmt_id.db_tab_base), &dmt.dmt_id.db_tab_base, sizeof(dmt.dmt_id.db_tab_index), &dmt.dmt_id.db_tab_index); gw_rcb->gwr_error.err_code = E_GW021E_GWU_MAP_IDX_ATT_ERROR; break; } break; } /* if we get here everything's OK... */ break; } return(status); }