/*{ ** Name: ule_initiate - Provide server constant info for the server header ** ** Description: ** This routine takes in the server constant parameters SERVER NAME and ** NODE NAME, placing them in an area which is easily found to place on ** all error messages. ** ** Inputs: ** node_name Pointer to node name, which is ** l_node_name characters long ** server_name Same for server name ** l_server_name ** ** Outputs: ** None. ** Returns: ** VOID ** Exceptions: ** none ** ** Side Effects: ** none ** ** History: ** 06-Aug-1987 (fred) ** Created. ** 21-Mar-2005 (mutma03) ** cleanup of node translation code for clusters. ** 07-jan-2008 (joea) ** Undo 28-jun-2001 and 21-mar-2005 cluster nickname changes. */ VOID ule_initiate( char *node_name, i4 l_node_name, char *server_name, i4 l_server_name ) { PID proc_id; char fmt[20]; if (Ule_started <= 0) { PCpid(&proc_id); MEfill(sizeof(ULE_MHDR), (u_char)' ', (PTR)&Ule_mhdr); MEmove( l_node_name, (PTR) node_name, (char) ' ', sizeof(Ule_mhdr.ule_node), (PTR) &Ule_mhdr.ule_node[0]); MEmove( l_server_name, (PTR) server_name, (char) ' ', sizeof(Ule_mhdr.ule_server), (PTR) &Ule_mhdr.ule_server[0]); MEfill( sizeof(Ule_mhdr.ule_session), (u_char) '*', (PTR) &Ule_mhdr.ule_session[0]); Ule_mhdr.ule_pad1[0] = ':', Ule_mhdr.ule_pad1[1] = ':', Ule_mhdr.ule_pad1[2] = '['; Ule_mhdr.ule_pad2[0] = ',', Ule_mhdr.ule_pad2[1] = ' '; STprintf( fmt, "%s", PIDFMT ); STprintf(Ule_mhdr.ule_pid, fmt, proc_id); Ule_mhdr.ule_pad3[0] = ',', Ule_mhdr.ule_pad3[1] = ' '; Ule_mhdr.ule_pad4[0] = ','; Ule_mhdr.ule_pad4[1] = ' '; MEfill( sizeof(Ule_mhdr.ule_source), (char) ' ', (PTR) &Ule_mhdr.ule_source[0]); Ule_mhdr.ule_pad5[0] = ']', Ule_mhdr.ule_pad5[1] = ':', Ule_mhdr.ule_pad5[2] = ' '; Ule_started = 1; } }
VOID qee_d1_qid( QEE_DSH *v_dsh_p) { QEE_DDB_CB *qee_p = v_dsh_p->dsh_ddb_cb; DB_CURSOR_ID *csr_p; SYSTIME tm_now; char hi_ascii[QEK_015_LEN], lo_ascii[QEK_015_LEN], pid_ascii[QEK_015_LEN], temp[QEK_050_LEN + DB_CURSOR_MAXNAME]; PID pid; /* an i4 */ PCpid(& pid); /* get process (server) id */ CVla(pid, pid_ascii); /* convert to ascii */ TMnow(& tm_now); csr_p = & qee_p->qee_d4_given_qid; csr_p->db_cursor_id[0] = tm_now.TM_secs; csr_p->db_cursor_id[1] = tm_now.TM_msecs; CVla(tm_now.TM_secs, hi_ascii); CVla(tm_now.TM_msecs, lo_ascii); STpolycat((i4) 4, /* 4 constituent pieces */ "dd", lo_ascii, hi_ascii, pid_ascii, temp); MEmove(STlength(temp), temp, ' ', DB_CURSOR_MAXNAME, csr_p->db_cur_name); csr_p = & qee_p->qee_d5_local_qid; csr_p->db_cursor_id[0] = 0; csr_p->db_cursor_id[1] = 0; MEfill(DB_CURSOR_MAXNAME, ' ', (PTR) csr_p->db_cur_name); return; }
DB_STATUS qee_d2_tmp( QEF_RCB *qef_rcb, QEE_DSH *dsh, ULM_RCB *ulm) { DB_STATUS status = E_DB_OK; QEF_QP_CB *qp_p = dsh->dsh_qp_ptr; QEQ_DDQ_CB *ddq_p = & qp_p->qp_ddq_cb; QEE_DDB_CB *qee_p = dsh->dsh_ddb_cb; DB_CURSOR_ID *csr_p; if (ddq_p->qeq_d3_elt_cnt > 0) { SYSTIME tm_now, tm_last; char hi_ascii[QEK_015_LEN], lo_ascii[QEK_015_LEN], /* pid_ascii[QEK_015_LEN], */ temp[QEK_050_LEN+DB_MAXNAME];/* must be > DB_MAXNAME */ DD_TAB_NAME *name_p; i4 *long_p; /* PID pid; ** an i4 ** */ i4 m, n; char *p, *q; u_i2 hi_len, /* lo_len, */ tmp_len; #define QEE_10SQL_NAME_LEN 10 /* allocate space for array of temporary-table names and ** generate their names */ /* 1. allocate array for DD_TAB_NAMEs */ ulm->ulm_psize = ddq_p->qeq_d3_elt_cnt * sizeof(DD_TAB_NAME); if (status = qec_malloc(ulm)) { qef_rcb->error.err_code = ulm->ulm_error.err_code; qed_u10_trap(); return(status); } qee_p->qee_d1_tmp_p = (DD_TAB_NAME *) ulm->ulm_pptr; /* ptr to array of DD_TAB_NAMEs */ /* 2. allocate array for i4 status */ ulm->ulm_psize = ddq_p->qeq_d3_elt_cnt * sizeof(i4); if (status = qec_malloc(ulm)) { qef_rcb->error.err_code = ulm->ulm_error.err_code; qed_u10_trap(); return(status); } qee_p->qee_d2_sts_p = (i4 *) ulm->ulm_pptr; /* ptr to array of i4s */ /* initialize both allocated arrays */ name_p = qee_p->qee_d1_tmp_p; long_p = qee_p->qee_d2_sts_p; tm_last.TM_secs = 0; tm_last.TM_msecs = 0; /* PCpid(& pid); ** get process (server) id ** CVla(pid, pid_ascii); ** convert to ascii ** */ for (n = 0; n < ddq_p->qeq_d3_elt_cnt; n++) { /* 3. generate temporary table name */ TMnow(& tm_now); if (tm_now.TM_secs == tm_last.TM_secs) { if (tm_now.TM_msecs <= tm_last.TM_msecs) tm_now.TM_msecs = tm_last.TM_msecs + 1; } CVla(tm_now.TM_secs, hi_ascii); CVla(tm_now.TM_msecs, lo_ascii); hi_len = STlength(hi_ascii); /* transpose the hi_ascii string to get lower digits */ p = hi_ascii; q = hi_ascii + hi_len - 1; /* backup past EOS */ for (m = 0; m < (i4) hi_len - 1; m++) /* do length - 1 characters */ { *p = *q; p++; q--; } STpolycat((i4) 3, /* 3 constituent pieces */ "z", lo_ascii, hi_ascii, temp); tmp_len = STlength(temp); /* use at most 10 characters */ if (tmp_len > QEE_10SQL_NAME_LEN) tmp_len = QEE_10SQL_NAME_LEN; MEmove(tmp_len, temp, ' ', sizeof(DD_TAB_NAME), (char *)name_p); STRUCT_ASSIGN_MACRO(tm_now, tm_last); /* save for comparison */ name_p++; /* pt to next slot */ /* 4. initialize status word for this table */ *long_p = QEE_00M_NIL; long_p++; /* pt to next status word */ } /* for */ } else { qee_p->qee_d1_tmp_p = (DD_TAB_NAME *) NULL; qee_p->qee_d2_sts_p = (i4 *) NULL; } /* 5. initialize */ qee_p->qee_d3_status = QEE_00Q_NIL; if (! (qp_p->qp_status & QEQP_RPT)) { /* initialize if not repeat query */ csr_p = & qee_p->qee_d4_given_qid; csr_p->db_cursor_id[0] = 0; csr_p->db_cursor_id[1] = 0; MEfill(DB_CURSOR_MAXNAME, ' ', (PTR) csr_p->db_cur_name); } csr_p = & qee_p->qee_d5_local_qid; csr_p->db_cursor_id[0] = 0; csr_p->db_cursor_id[1] = 0; MEfill(DB_CURSOR_MAXNAME, ' ', (PTR) csr_p->db_cur_name); return(status); }
/*{ ** Name: openTempTable - Open a temp table used for set input ** procedure. ** ** Description: ** The current execution environment is saved and an ** environment is created in which to execute the ** named procedure. ** ** This procedure is only called when a nested procedure is invoked. ** This can occur the first time through, or if the procedure is not ** found (LOAD_QP) or the plan was deemed invalid (INVALID_QUERY) then ** the procedure is re-entered in this routine. ** ** If rules are turned off (QEF_T_NORULES) then this procedure returns ** immediately. ** ** Inputs: ** qef_rcb ** tempTableNumber index to dsh temptable array for temporary ** table to be created. ** ** Outputs: ** Returns: ** E_DB_{OK,WARN,ERROR,FATAL} (from table creation) ** Exceptions: ** none ** ** Side Effects: ** none ** ** History: ** 18-jul-96 (inkdo01) ** Created. ** 29-oct-1998 (somsa01) ** If we are opening a Global Temporary Table, turn on the ** DMT_SESSION_TEMP flag in dmt_flags_mask before the open. ** (Bug #94059) ** 12-nov-1998 (somsa01) ** Added another parameter, and refined the check for a Global ** Session Temporary Table. (Bug #94059) ** 15-mar-04 (inkdo01) ** dsh_tempTables is now an array of ptrs. ** 13-Jul-2004 (schka24) ** Pass in dsh so we get the right one for sure. ** 30-Jul-2004 (jenjo02) ** Use dsh_dmt_id rather than qef_dmt_id transaction context. ** 4-Jun-2009 (kschendel) b122118 ** Use open-and-link utility. */ static DB_STATUS openTempTable( QEF_RCB *rcb, QEE_DSH *dsh, i4 tempTableNumber, bool gttparm ) { QEE_TEMP_TABLE *tempTable = dsh->dsh_tempTables[ tempTableNumber ]; DMT_CB *dmt = tempTable->tt_dmtcb; DMR_CB *dmr = tempTable->tt_dmrcb; DM_MDATA dm_mdata; DB_STATUS status = E_DB_OK; for (;;) /* something to break out of */ { /* create the table if it doesn't already exist */ if ( !( tempTable->tt_statusFlags & TT_CREATED ) ) { dmt->dmt_db_id = rcb->qef_db_id; dmt->dmt_tran_id = dsh->dsh_dmt_id; MEmove(8, (PTR) "$default", (char) ' ', sizeof(DB_LOC_NAME), (PTR) dmt->dmt_location.data_address); dmt->dmt_location.data_in_size = sizeof(DB_LOC_NAME); dmt->dmt_flags_mask = DMT_DBMS_REQUEST; if (gttparm) dmt->dmt_flags_mask |= DMT_SESSION_TEMP; dmr->dmr_flags_mask = 0; /* ** We assume that the sort key descriptor was set up ** earlier, probably at QEE time. */ if ( tempTable->tt_statusFlags & TT_PLEASE_SORT ) dmt->dmt_flags_mask |= DMT_LOAD; if ( tempTable->tt_statusFlags & TT_NO_DUPLICATES ) dmr->dmr_flags_mask |= DMR_NODUPLICATES; dmr->dmr_count = 1; dmr->dmr_s_estimated_records = TT_TUPLE_COUNT_GUESS; dmr->dmr_tid = 0; dm_mdata.data_address = dsh->dsh_row[ tempTable->tt_tuple ]; dm_mdata.data_size = dsh->dsh_qp_ptr->qp_row_len[ tempTable->tt_tuple ]; dmr->dmr_mdata = &dm_mdata; status = dmf_call(DMT_CREATE_TEMP, dmt); if (status != E_DB_OK) { if (dmt->error.err_code == E_DM0078_TABLE_EXISTS) { dsh->dsh_error.err_code = E_QE0050_TEMP_TABLE_EXISTS; status = E_DB_ERROR; } else { dsh->dsh_error.err_code = dmt->error.err_code; } break; } /* Open the temp table */ dmt->dmt_flags_mask = 0; if (gttparm) dmt->dmt_flags_mask |= DMT_SESSION_TEMP; dmt->dmt_sequence = dsh->dsh_stmt_no; dmt->dmt_access_mode = DMT_A_WRITE; dmt->dmt_lock_mode = DMT_X; dmt->dmt_update_mode = DMT_U_DIRECT; status = qen_openAndLink(dmt, dsh); if (status != E_DB_OK) { break; } tempTable->tt_statusFlags |= TT_CREATED; dmr->dmr_access_id = dmt->dmt_record_access_id; } /* end of table creation */ break; } /* end of code block */ return( status ); }
/*{ ** Name: psy_dbpriv - GRANT/REVOKE database privileges ** ** INTERNAL PSF call format: status = psy_dbpriv(&psy_cb, sess_cb); ** EXTERNAL call format: status = psy_call (PSY_DBPRIV,&psy_cb, sess_cb); ** ** Description: ** This procedure is sued to grant and revoke database privileges. ** A template iidbpriv tuple is built and shipped to RDF. ** Eventually, the tuple is added/merged into iidbpriv. ** This procedure is called for SQL language only. ** ** Inputs: ** psy_cb ** .psy_usrq list of grantees ** .psy_tblq list of objects ** .psy_gtype grantee type ** .psy_grant statement type (GRANT or REVOKE) ** .psy_fl_dbpriv control flags ** .psy_qdio_limit query I/O limit ** .psy_qrow_limit query row limit ** .psy_qcpu_limit query CPU limit ** .psy_qpage_limit query page limit ** .psy_qcost_limit query cost limit ** .psy_idle_limit idle time limit ** .psy_connect_limit connect time limit ** .psy_priority_limit priority limit ** sess_cb Pointer to session control block ** (Can be NULL) ** ** Outputs: ** psy_cb ** .psy_error Filled in if error happens ** Returns: ** E_DB_OK Function completed normally. ** E_DB_WARN Function completed with warning(s); ** E_DB_ERROR Function failed; non-catastrophic error ** E_DB_SEVERE Function failed; catastrophic error ** Exceptions: ** none ** ** Side Effects: ** None. ** ** History: ** 10-apr-89 (ralph) ** written ** 06-jun-89 (ralph) ** corrected unix portability problems ** 24-jun-89 (ralph) ** corrected internal error message ** 06-sep-89 (ralph) ** added support for GRANT/REVOKE ON ALL DATABASES ** removed DBGR_DEFAULT ** 12-mar-90 (andre) ** set rdr_2types_mask to 0. ** 22-may-90 (teg) ** init rdr_instr to RDF_NO_INSTR ** 19-jul-92 (andre) ** changes were made to enable a user to specify privileges to PUBLIC ** along with one or more user authorization identifiers ** 10-aug-93 (andre) ** fixed cause of a compiler warning */ DB_STATUS psy_dbpriv( PSY_CB *psy_cb, PSS_SESBLK *sess_cb) { DB_STATUS status = E_DB_OK; DB_STATUS stat; i4 err_code; RDF_CB rdf_cb; register RDR_RB *rdf_rb = &rdf_cb.rdf_rb; DB_PRIVILEGES dbprtuple; register DB_PRIVILEGES *dbprtup = &dbprtuple; PSY_USR *psy_usr; PSY_TBL *psy_tbl; bool grant_to_public; bool leave_loop = TRUE; /* This code is called for SQL only */ do { /* Fill in the RDF request block */ pst_rdfcb_init(&rdf_cb, sess_cb); if (psy_cb->psy_grant == PSY_DGRANT) rdf_rb->rdr_update_op = RDR_APPEND; else if (psy_cb->psy_grant == PSY_DREVOKE) rdf_rb->rdr_update_op = RDR_DELETE; else { /* Invalid operation specified in psy_grant */ err_code = E_PS0D45_INVALID_GRANT_OP; (VOID) psf_error(E_PS0D45_INVALID_GRANT_OP, 0L, PSF_INTERR, &err_code, &psy_cb->psy_error, 0); status = E_DB_ERROR; break; } rdf_rb->rdr_status = DB_SQL; rdf_rb->rdr_types_mask = RDR_DBPRIV; rdf_rb->rdr_qrytuple = (PTR) dbprtup; rdf_rb->rdr_qtuple_count = 1; /* Initialize the template iidbpriv tuple */ dbprtup->dbpr_gtype = psy_cb->psy_gtype; dbprtup->dbpr_control = psy_cb->psy_ctl_dbpriv; dbprtup->dbpr_dbflags = 0; dbprtup->dbpr_flags = psy_cb->psy_fl_dbpriv; dbprtup->dbpr_qrow_limit = psy_cb->psy_qrow_limit; dbprtup->dbpr_qdio_limit = psy_cb->psy_qdio_limit; dbprtup->dbpr_qcpu_limit = psy_cb->psy_qcpu_limit; dbprtup->dbpr_qpage_limit = psy_cb->psy_qpage_limit; dbprtup->dbpr_qcost_limit = psy_cb->psy_qcost_limit; dbprtup->dbpr_connect_time_limit = psy_cb->psy_connect_limit; dbprtup->dbpr_idle_time_limit = psy_cb->psy_idle_limit; dbprtup->dbpr_priority_limit = psy_cb->psy_priority_limit; MEfill(sizeof(dbprtup->dbpr_database), (u_char) ' ', (PTR) &dbprtup->dbpr_database); MEfill(sizeof(dbprtup->dbpr_reserve), (u_char) ' ', (PTR) dbprtup->dbpr_reserve); /* Point to first database object, if any */ psy_tbl = (PSY_TBL *)psy_cb->psy_tblq.q_next; /* No database objects means GRANT/REVOKE ON ALL DATABASES */ if (psy_tbl == (PSY_TBL *) &psy_cb->psy_tblq) dbprtup->dbpr_dbflags |= DBPR_ALLDBS; /* ** Pass the template tuples to RDF for each database/grantee. ** RDF/QEF will return E_DB_INFO if a database/grantee is rejected, ** or E_DB_WARN is a database is rejected. Anything worse than ** E_DB_WARN is a fatal error. */ /* Process each database/grantee */ for (;;) { /* ** Copy in database name if one was provided. ** None will be provided if ON ALL DATABASES was specified. */ if (psy_tbl != (PSY_TBL *) &psy_cb->psy_tblq) MEcopy((PTR)&psy_tbl->psy_tabnm, sizeof(dbprtup->dbpr_database), (PTR)&dbprtup->dbpr_database); grant_to_public = (psy_cb->psy_flags & PSY_PUBLIC) != 0; psy_usr = (PSY_USR *) psy_cb->psy_usrq.q_next; do { if (grant_to_public) { /* ** user specified TO/FROM PUBLIC, possibly along with other ** user auth ids; we will process TO/FROM PUBLIC first */ dbprtup->dbpr_gtype = DBGR_PUBLIC; MEmove(sizeof("public") - 1, (PTR) "public", ' ', sizeof(dbprtup->dbpr_gname), (PTR) &dbprtup->dbpr_gname); } else { STRUCT_ASSIGN_MACRO(psy_usr->psy_usrnm, dbprtup->dbpr_gname); } stat = rdf_call(RDF_UPDATE, (PTR) &rdf_cb); status = (stat > status) ? stat : status; if (stat > E_DB_INFO) break; if (grant_to_public) { dbprtup->dbpr_gtype = psy_cb->psy_gtype; /* ** remember that we have processed GRANT TO PUBLIC on this ** database or on the installation */ grant_to_public = FALSE; } else { psy_usr = (PSY_USR *) psy_usr->queue.q_next; } } while (psy_usr != (PSY_USR *) &psy_cb->psy_usrq); /* Break out if failure */ if (DB_FAILURE_MACRO(status)) break; /* Point to next database object */ psy_tbl = (PSY_TBL *) psy_tbl->queue.q_next; /* Break out if no more objects */ if (psy_tbl == (PSY_TBL *) &psy_cb->psy_tblq) break; } /* We are done */ /* leave_loop has already been set to TRUE */ } while (!leave_loop); if (DB_FAILURE_MACRO(status)) (VOID) psf_rdf_error(RDF_UPDATE, &rdf_cb.rdf_error, &psy_cb->psy_error); return (status); }
static DB_STATUS qen_ts_dump( QEN_SHD *shd, QEE_DSH *dsh, QEN_NODE *node, i4 rowno, bool heap_sort, bool no_qef ) { PTR *cbs = dsh->dsh_cbs; DMT_CB *dmt = (DMT_CB *)cbs[node->node_qen.qen_tsort.tsort_create]; DMR_CB *dmr_load = (DMR_CB*)cbs[node->node_qen.qen_tsort.tsort_load]; DMR_CB *dmr_get = (DMR_CB*) cbs[node->node_qen.qen_tsort.tsort_get]; DMT_CHAR_ENTRY char_array[2]; DB_STATUS status; for (;;) /* to break off in case of error */ { /* Initialize the DMT_CB for the sorter table */ dmt->dmt_flags_mask = DMT_LOAD | DMT_DBMS_REQUEST; dmt->dmt_db_id = dsh->dsh_qefcb->qef_rcb->qef_db_id; dmt->dmt_tran_id = dsh->dsh_dmt_id; MEmove(8, (PTR) "$default", (char) ' ', sizeof(DB_LOC_NAME), (PTR) dmt->dmt_location.data_address); dmt->dmt_location.data_in_size = sizeof(DB_LOC_NAME); /* Initialize table attribute descriptors */ dmt->dmt_attr_array.ptr_address = (PTR) node->node_qen.qen_tsort.tsort_atts; dmt->dmt_attr_array.ptr_in_count = node->node_qen.qen_tsort.tsort_acount; dmt->dmt_attr_array.ptr_size = sizeof (DMF_ATTR_ENTRY); /* Initialize the the sort key descriptors */ dmt->dmt_key_array.ptr_address = (PTR) node->node_qen.qen_tsort.tsort_satts; dmt->dmt_key_array.ptr_in_count = node->node_qen.qen_tsort.tsort_scount; dmt->dmt_key_array.ptr_size = sizeof (DMT_KEY_ENTRY); /* Pass the page size */ char_array[0].char_id = DMT_C_PAGE_SIZE; char_array[0].char_value = node->node_qen.qen_tsort.tsort_pagesize; char_array[1].char_id = DMT_C_DUPLICATES; char_array[1].char_value = DMT_C_ON; /* duplicate rows allowed */ dmt->dmt_char_array.data_address = (PTR) &char_array; dmt->dmt_char_array.data_in_size = 2 * sizeof(DMT_CHAR_ENTRY); /* Create the sorter table */ status = dmf_call(DMT_CREATE_TEMP, dmt); if (status != E_DB_OK) { if (dmt->error.err_code == E_DM0078_TABLE_EXISTS) { dsh->dsh_error.err_code = E_QE0050_TEMP_TABLE_EXISTS; status = E_DB_ERROR; } else { dsh->dsh_error.err_code = dmt->error.err_code; } break; } /* Open the sorter table */ dmt->dmt_flags_mask = 0; dmt->dmt_sequence = dsh->dsh_stmt_no; dmt->dmt_access_mode = DMT_A_WRITE; dmt->dmt_lock_mode = DMT_X; dmt->dmt_update_mode = DMT_U_DIRECT; dmt->dmt_char_array.data_address = 0; dmt->dmt_char_array.data_in_size = 0; status = qen_openAndLink(dmt, dsh); if (status != E_DB_OK) { break; } /* Initialize the DMR_CB for loading the sorter */ dmr_load->dmr_access_id = dmt->dmt_record_access_id; dmr_load->dmr_count = 1; dmr_load->dmr_flags_mask = (node->node_qen.qen_tsort.tsort_dups | DMR_SORT_NOCOPY); dmr_load->dmr_s_estimated_records = node->qen_est_tuples; dmr_load->dmr_tid = 0; /* Initialize the DMR_CB for reading the sorter */ dmr_get->dmr_access_id = dmt->dmt_record_access_id; dmr_get->dmr_data.data_address = dsh->dsh_row[rowno]; dmr_get->dmr_data.data_in_size = dsh->dsh_qp_ptr->qp_row_len[rowno]; dmr_get->dmr_tid = 0; if (no_qef) break; /* leave, if nothing there */ /* If we have tuples in the in-memory sort buffer, load them into ** DMF sorter table now and write current tuple. */ if (heap_sort) status = qes_dump(dsh, shd, dmr_load); else status = qes_dumploop(dsh, shd, dmr_load); break; } /* end of error-break loop */ return (status); }
DB_STATUS dmc_add_db( DMC_CB *dmc_cb) { DMC_CB *dmc = dmc_cb; DM_SVCB *svcb = dmf_svcb; DMC_LOC_ENTRY *location; i4 loc_count; i4 flags; i4 mode; i4 dm2mode; i4 error,local_error; DMM_LOC_LIST *loc_ptr[4]; DB_STATUS status; DMP_DCB *dcb; CLRDBERR(&dmc->error); for (status = E_DB_ERROR;;) { /* Verify control block parameters. */ if (dmc->dmc_op_type != DMC_DATABASE_OP) { SETDBERR(&dmc->error, 0, E_DM000C_BAD_CB_TYPE); break; } if (dmc->dmc_id != svcb->svcb_id) { SETDBERR(&dmc->error, 0, E_DM002D_BAD_SERVER_ID); break; } flags = 0; if (dmc->dmc_flags_mask & ~(DMC_NOJOURNAL | DMC_JOURNAL | DMC_FSTCOMMIT | DMC_SOLECACHE | DMC_CNF_LOCKED | DMC_CVCFG | DMC_ADMIN_DB | DMC_DMCM)) { SETDBERR(&dmc->error, 0, E_DM001A_BAD_FLAG); break; } if (dmc->dmc_flags_mask & DMC_NOJOURNAL) flags |= DM2D_NOJOURNAL; if (dmc->dmc_flags_mask & DMC_JOURNAL) flags |= DM2D_JOURNAL; if (dmc->dmc_flags_mask & DMC_FSTCOMMIT) flags |= DM2D_FASTCOMMIT; if (dmc->dmc_flags_mask & DMC_SOLECACHE) flags |= DM2D_BMSINGLE; if (dmc->dmc_flags_mask & DMC_CVCFG) flags |= DM2D_CVCFG; /* b97083 - Is the CNF file already locked by caller? */ if (dmc->dmc_flags_mask & DMC_CNF_LOCKED) flags |= DM2D_CNF_LOCKED; if (dmc->dmc_s_type & DMC_S_SINGLE) flags |= DM2D_SINGLE; if (dmc->dmc_s_type & DMC_S_MULTIPLE) flags |= DM2D_MULTIPLE; /* ** (ICL phil.p) */ if (dmc->dmc_flags_mask & DMC_DMCM) flags |= DM2D_DMCM; if (dmc->dmc_flags_mask2 & DMC2_READONLYDB) flags |= DM2D_READONLYDB; /* No MO objects if so requested */ if ( dmc->dmc_flags_mask2 & DMC2_NODBMO || mode == DMC_A_CREATE || mode == DMC_A_DESTROY ) { flags |= DM2D_NODBMO; } /* ** It is an error to specify Fast Commit without specifying to ** use a single buffer manager. ** (ICL phil.p) UNLESS running DMCM, which effectively means ** running FastCommit in a Multi-Cache environment. */ if (!(flags & DM2D_DMCM)) { if ((flags & (DM2D_FASTCOMMIT | DM2D_BMSINGLE)) == DM2D_FASTCOMMIT) { SETDBERR(&dmc->error, 0, E_DM0115_FCMULTIPLE); break; } } mode = dmc->dmc_db_access_mode; if (mode != DMC_A_READ && mode != DMC_A_WRITE && mode != DMC_A_CREATE && mode != DMC_A_DESTROY) { SETDBERR(&dmc->error, 0, E_DM000F_BAD_DB_ACCESS_MODE); break; } dm2mode = (mode == DMC_A_READ) ? DM2D_A_READ : DM2D_A_WRITE; /* Check that at least one location was passed in. */ location = (DMC_LOC_ENTRY *)dmc->dmc_db_location.data_address; loc_count = dmc->dmc_db_location.data_in_size / sizeof(DMC_LOC_ENTRY); if (loc_count == 0) { SETDBERR(&dmc->error, 0, E_DM002A_BAD_PARAMETER); break; } /* Check if database should be created. */ if (mode == DMC_A_CREATE) { SCF_CB scf_cb; SCF_SCI sci_list[2]; DB_NAME collation; DB_NAME ucollation; char *p; char ucolname[] = "udefault"; i4 dbservice; scf_cb.scf_length = sizeof(SCF_CB); scf_cb.scf_type = SCF_CB_TYPE; scf_cb.scf_facility = DB_DMF_ID; scf_cb.scf_session = (SCF_SESSION)dmc->dmc_session_id; scf_cb.scf_ptr_union.scf_sci = (SCI_LIST *)sci_list; sci_list[0].sci_length = sizeof(dbservice); sci_list[0].sci_code = SCI_DBSERVICE; sci_list[0].sci_aresult = (char *)&dbservice; sci_list[0].sci_rlength = 0; scf_cb.scf_len_union.scf_ilength = 1; status = scf_call(SCU_INFORMATION, &scf_cb); if (status != E_DB_OK) { uleFormat(&scf_cb.scf_error, 0, (CL_ERR_DESC *)NULL, ULE_LOG, NULL, (char *)0, (i4)0, (i4 *)0, &error, 0); SETDBERR(&dmc->error, 0, E_DM002F_BAD_SESSION_ID); break; } /* Collation for iidbdb can only be the default. */ MEfill(sizeof(collation.db_name), ' ', collation.db_name); NMgtAt("II_COLLATION", &p); if (p && *p) MEmove(STlength(p), p, ' ', sizeof(collation.db_name), collation.db_name); MEmove(STlength(ucolname), ucolname, ' ', sizeof(ucollation.db_name), ucollation.db_name); loc_ptr[0] = (DMM_LOC_LIST *) &loc_list[0]; loc_ptr[1] = (DMM_LOC_LIST *) &loc_list[1]; loc_ptr[2] = (DMM_LOC_LIST *) &loc_list[2]; loc_ptr[3] = (DMM_LOC_LIST *) &loc_list[3]; /* Even though the iidbdb is not "operative" at this stage, we ** will mark it as operative in the config file now (it will not ** be marked operative in the iidatabase catalog until after it ** is fully created). Although we would like to mark the iidbdb ** "inoperative" in the config file now and update it to operative ** status when creation is successfully completed (as is done for ** all other DBs) the internal procedure "iiqef_alter_db" which ** updates this bit will not work on the iidbdb; see comments in ** createdb regarding this problem. */ status = dmm_add_create(0, &dmc->dmc_db_name, &dmc->dmc_db_owner, 1, dbservice, DU_OPERATIVE, (DB_LOC_NAME *) &dbdb_location, 11, "II_DATABASE", 4, loc_ptr, collation.db_name, ucollation.db_name, &dmc->error); if (status != E_DB_OK) { if (dmc->error.err_code > E_DM_INTERNAL) { uleFormat( &dmc->error, 0, NULL, ULE_LOG , NULL, (char * )0, 0L, (i4 *)0, &local_error, 0); SETDBERR(&dmc->error, 0, E_DM0084_ERROR_ADDING_DB); } break; } } else if (mode == DMC_A_DESTROY) { return (E_DB_OK); } /* Call the physical layer to construct a DCB for this database. */ status = dm2d_add_db(flags, &dm2mode, &dmc->dmc_db_name, &dmc->dmc_db_owner, loc_count, (DM2D_LOC_ENTRY *)location, &dcb, (i4 *)dmc->dmc_lock_list, &dmc->error); if (status != E_DB_OK) { if (dmc->error.err_code > E_DM_INTERNAL) { uleFormat( &dmc->error, 0, NULL, ULE_LOG , NULL, (char * )0, 0L, (i4 *)0, &local_error, 0); SETDBERR(&dmc->error, 0, E_DM0084_ERROR_ADDING_DB); } break; } /* Use the access mode passed back */ dmc->dmc_db_access_mode = (dm2mode == DM2D_A_READ) ? DMC_A_READ : DMC_A_WRITE; dmc->dmc_db_id = (char *)dcb; dmc->dmc_dbservice = dcb->dcb_dbservice; dmc->dmc_dbcmptlvl = dcb->dcb_dbcmptlvl; dmc->dmc_1dbcmptminor = dcb->dcb_1dbcmptminor; return (E_DB_OK); } return (status); }
/*{ ** Name: psy_gproc - Get a database procedure definition from ** the system catalogs. ** ** Description: ** ** Inputs: ** psq_cb ** psq_cursid ** db_cur_name dbproc name ** sess_cb ** pss_user current user name ** pss_dba dba name ** qsf_rb ** rdf_cb ** dbp_owner name of the owner whose dbproc will be ** looked up iff gproc_mask & PSS_DBP_BY_OWNER. ** gproc_mask mask used to specify the possible owners of ** the dbproc to look for ** PSS_USRDBP look for dbproc owned by the current user ** PSS_DBADBP look for dbproc owned by the DBA ** PSS_INGDBP look for dbproc owned by $INGRES ** PSS_DBP_BY_OWNER look for dbproc owned by the specific user ** ** NOTE: if PSS_DBP_BY_OWNER is set, ** PSS_USRDBP, PSS_DBADBP, and PSS_INGDBP ** will be disregarded ** otherwise, we expect that PSS_USRDBP ** will be always set, while PSS_DBADBP ** and PSS_INGDBP may or may not be set ** ** Outputs: ** alt_user set to point the name of dbproc owner if ** different from cb->pss_user ** psq_cb ** psq_error filled in if an error occurred ** ** ret_flags bits may be set to pass info to the caller ** PSS_MISSING_DBPROC dbproc not found ** ** Exceptions: ** none ** ** Returns ** E_DB_OK, E_DB_ERROR ** ** Side Effects: ** Allocates memory. ** ** History: ** 27-apr-88 (stec) ** Created. ** 04-aug-88 (stec) ** Improve recovery of resources. ** 17-aug-88 (stec) ** Change bad STRUCT_ASSIGN statements. ** 28-sep-88 (stec) ** Do not lock object on cleanup. ** 28-sep-88 (stec) ** Must not unfix RDF entry. ** 16-mar-89 (andre) ** Added a new parameter - alt_user. ** psy_gproc will no longer reset pss_user or set pss_ruset. Instead ** it may set the ptr passed to it to the name of the dbproc owner. ** 16-mar-89 (neil) ** Modified psy_gproc to access the procedure through the specified ** owner (psq_als_owner) if psq_alias_set is on. ** 27-apr-89 (andre) ** Further modify to search for dbprocs owned by $ingres if the search ** by user and DBA failed. The search part of the function has been, ** essentially, rewritten. ** 12-mar-90 (andre) ** set rdr_2types_mask to 0. ** 22-may-90 (teg) ** init rdr_instr to RDF_NO_INSTR ** 01-jun-90 (andre) ** Changed interface to allow caller to explicitly specify the possible ** owners of the dbproc to look for. ** 01-oct-91 (andre) ** Added ret_flags to the interface - this field will be used to pass ** additional info to the caller. in particular, it will allow us to ** signal certain classes of errors (e.g. dbproc not found) without ** setting return status to E_DB_ERROR, thus enabling the caller to ** distinguish such errors from unexpected errors ** 15-oct-1993 (rog) ** We need to use ulm_copy() instead of MEcopy() when copying query ** text that might be more than 64k. ** 12-jan-94 (andre) ** As a part of fix for bug 58048, we must remove the assumption that ** either PSS_USRDBP or PSS_DBP_BY_OWNER bit will always be set in ** gproc_mask. Now we will be prepared to handle PSS_DBP_BY_OWNER or ** one or more of PSS_USRDBP, PSS_DBADBP, and PSS_INGDBP. ** 13-jan-94 (andre) ** if we fail to find a dbproc, we will set PSS_MISSING_DBPROC in ** *ret_flags, but leave it up to the caller to issue an error ** message - this way the caller can decide whether this warrants an ** error message and if so can choose his favourite error message */ DB_STATUS psy_gproc( PSQ_CB *psq_cb, PSS_SESBLK *sess_cb, QSF_RCB *qsf_rb, RDF_CB *rdf_cb, DB_OWN_NAME **alt_user, DB_OWN_NAME *dbp_owner, i4 gproc_mask, i4 *ret_flags) { DB_STATUS status, stat; i4 err_code; RDD_QRYMOD *pinfo; PSQ_QDESC *qdesc; bool leave_loop = TRUE; DB_PROCEDURE *dbp; SXF_ACCESS access; i4 msgid; i4 local_status; *ret_flags = 0; /* First call RDF to retrieve the definition ** of the procedure. */ /* Initialize the RDF control block */ pst_rdfcb_init(rdf_cb, sess_cb); (VOID) MEcopy((PTR) psq_cb->psq_cursid.db_cur_name, sizeof (DB_DBP_NAME), (PTR) &rdf_cb->rdf_rb.rdr_name.rdr_prcname); rdf_cb->rdf_rb.rdr_types_mask = RDR_PROCEDURE | RDR_BY_NAME; /* assume that the dbproc is owned by the current user */ *alt_user = (DB_OWN_NAME *) NULL; do { if (gproc_mask & (PSS_USRDBP | PSS_DBP_BY_OWNER)) { if (gproc_mask & PSS_USRDBP) { STRUCT_ASSIGN_MACRO(sess_cb->pss_user, rdf_cb->rdf_rb.rdr_owner); } else { STRUCT_ASSIGN_MACRO((*dbp_owner), rdf_cb->rdf_rb.rdr_owner); if (MEcmp((PTR)&sess_cb->pss_user, (PTR) dbp_owner, sizeof(DB_OWN_NAME))) { *alt_user = dbp_owner; /* Try someone else */ } } /* Get the text */ status = rdf_call(RDF_GETINFO, (PTR) rdf_cb); /* ** We do not want to continue search if: ** 1) dbproc was found OR ** 2) we got an error other that PROC_NOT_FOUND OR ** 3) caller requested a dbproc owned by a specific user ** (gproc_mask & PSS_DBP_BY_OWNER) OR */ if ( DB_SUCCESS_MACRO(status) || rdf_cb->rdf_error.err_code != E_RD0201_PROC_NOT_FOUND || gproc_mask & PSS_DBP_BY_OWNER) { break; } } /* ** if we were told to check whether a dbproc is owned by the DBA, do so ** unless the DBA is the current user and we have already established ** that the current user does not own a dbproc with this name */ if ( gproc_mask & PSS_DBADBP && ( ~gproc_mask & PSS_USRDBP || MEcmp((PTR) &sess_cb->pss_user, (PTR) &sess_cb->pss_dba.db_tab_own, sizeof(DB_OWN_NAME)) ) ) { STRUCT_ASSIGN_MACRO(sess_cb->pss_dba.db_tab_own, rdf_cb->rdf_rb.rdr_owner); /* ** If we succeed and the DBA is different from the current user, ** the procedure text will have to be parsed in the context of ** dbproc's owner, i.e. DBA. Note that if we were also asked to ** check whether the dbproc is owned by the current user and still ** found ourselves here, DBA must be different from the current user */ if ( gproc_mask & PSS_USRDBP || MEcmp((PTR) &sess_cb->pss_user, (PTR) &sess_cb->pss_dba.db_tab_own, sizeof(DB_OWN_NAME))) { *alt_user = &sess_cb->pss_dba.db_tab_own; } /* Get the text */ status = rdf_call(RDF_GETINFO, (PTR) rdf_cb); /* ** We do not want to continue search if: ** 1) dbproc was found OR ** 2) we got an error other that PROC_NOT_FOUND */ if (DB_SUCCESS_MACRO(status) || rdf_cb->rdf_error.err_code != E_RD0201_PROC_NOT_FOUND) { break; } } if (gproc_mask & PSS_INGDBP) { MEmove(sizeof(*sess_cb->pss_cat_owner), (PTR)sess_cb->pss_cat_owner, ' ', DB_OWN_MAXNAME, (PTR) &rdf_cb->rdf_rb.rdr_owner); } else { /* ** if user has not requested that a dbproc owned by $INGRES be ** looked up, might as well get out of the loop */ break; } /* ** if we were told to check whether a dbproc is owned by $ingres, do so ** unless the $ingres is the current user and we have already ** established that the current user does not own a dbproc with this ** name or $ingres is the DBA and we have already established that the ** DBA does not own a dbproc with this name */ if ( ( ~gproc_mask & PSS_USRDBP || MEcmp((PTR)&sess_cb->pss_user, (PTR) &rdf_cb->rdf_rb.rdr_owner, sizeof(DB_OWN_NAME)) ) && ( ~gproc_mask & PSS_DBADBP || MEcmp((PTR) &sess_cb->pss_dba.db_tab_own, (PTR) &rdf_cb->rdf_rb.rdr_owner, sizeof(DB_OWN_NAME)) ) ) { /* ** If we succeed, the procedure text will have to be parsed in ** the context of the original owner, i.e. $ingres. */ *alt_user = &rdf_cb->rdf_rb.rdr_owner; /* ** If we succeed and $ingres is not the current user, the procedure ** text will have to be parsed in the context of dbproc's owner, ** i.e. $ingres. Note that if we were also asked to check whether ** the dbproc is owned by the current user and still found ourselves ** here, the current user must NOT be $ingres */ if ( gproc_mask & PSS_USRDBP || MEcmp((PTR) &sess_cb->pss_user, (PTR) &rdf_cb->rdf_rb.rdr_owner, sizeof(DB_OWN_NAME))) { *alt_user = &sess_cb->pss_dba.db_tab_own; } /* Get the text */ status = rdf_call(RDF_GETINFO, (PTR) rdf_cb); } /* leave_loop has already been set to TRUE */ } while (!leave_loop); if (DB_FAILURE_MACRO(status)) { if (rdf_cb->rdf_error.err_code == E_RD0201_PROC_NOT_FOUND) { /* ** dbproc was not found - set a bit in ret_flags and reset status to ** E_DB_OK to enable callers to distinguish between this and other ** errors */ status = E_DB_OK; *ret_flags |= PSS_MISSING_DBPROC; } else { (VOID) psf_rdf_error(RDF_GETINFO, &rdf_cb->rdf_error, &psq_cb->psq_error); } return(status); } /* we get here only if the dbproc was found */ /* ** If the procedure has a security label, validate it */ dbp=rdf_cb->rdf_info_blk->rdr_dbp; /* Initialize the QSF control block */ qsf_rb->qsf_type = QSFRB_CB; qsf_rb->qsf_ascii_id = QSFRB_ASCII_ID; qsf_rb->qsf_length = sizeof(QSF_RCB); qsf_rb->qsf_owner = (PTR)DB_PSF_ID; qsf_rb->qsf_sid = sess_cb->pss_sessid; qsf_rb->qsf_obj_id.qso_type = QSO_QTEXT_OBJ; qsf_rb->qsf_obj_id.qso_lname = 0; /* Having retrieved the text place it in QSF ** because the parser expects it to be there. */ status = qsf_call(QSO_CREATE, qsf_rb); if (DB_FAILURE_MACRO(status)) { i4 qerr = qsf_rb->qsf_error.err_code; if (qerr == E_QS0001_NOMEM) { (VOID) psf_error(qerr, qerr, PSF_CALLERR, &err_code, &psq_cb->psq_error, 0); } else { (VOID) psf_error(E_PS0A05_BADMEMREQ, qerr, PSF_INTERR, &err_code, &psq_cb->psq_error, 0); } goto cleanup2; } /* Object is locked exclusively now. */ pinfo = rdf_cb->rdf_rb.rdr_procedure; /* Allocate enough memory for the query descriptor ** plus the length of text. */ qsf_rb->qsf_sz_piece = sizeof(PSQ_QDESC) + pinfo->rdf_l_querytext + 3; /* one space, one null, ** one for safety. */ status = qsf_call(QSO_PALLOC, qsf_rb); if (DB_FAILURE_MACRO(status)) { i4 qerr = qsf_rb->qsf_error.err_code; if (qerr == E_QS0001_NOMEM) { (VOID) psf_error(qerr, qerr, PSF_CALLERR, &err_code, &psq_cb->psq_error, 0); } else { (VOID) psf_error(E_PS0A05_BADMEMREQ, qerr, PSF_INTERR, &err_code, &psq_cb->psq_error, 0); } goto cleanup1; } qdesc = (PSQ_QDESC *) qsf_rb->qsf_piece; /* Initialize query descriptor. */ qdesc->psq_qrysize = pinfo->rdf_l_querytext + 1; /* 1 trailing space */ qdesc->psq_datasize = 0; qdesc->psq_dnum = 0; qdesc->psq_qrytext = (char *)(qdesc + 1); /* Ptr arithmetic, should point ** right after the PSQ_QDESC. */ qdesc->psq_qrydata = (DB_DATA_VALUE **) NULL; /* QSF memory has been allocated now, copy ** the text from RDF. */ ulm_copy((PTR) pinfo->rdf_querytext, (i4) pinfo->rdf_l_querytext, (PTR) qdesc->psq_qrytext); /* Add a space after the text and null terminate. */ { char *p; p = qdesc->psq_qrytext; /* beginning of text */ p += pinfo->rdf_l_querytext; /* 1st char past end */ *p++ = ' '; *p = '\0'; /* 2nd char past end */ } /* Set root for the QSF object */ qsf_rb->qsf_root = qsf_rb->qsf_piece; status = qsf_call(QSO_SETROOT, qsf_rb); if (DB_FAILURE_MACRO(status)) { (VOID) psf_error(E_PS0A05_BADMEMREQ, qsf_rb->qsf_error.err_code, PSF_INTERR, &err_code, &psq_cb->psq_error, 0); goto cleanup1; } status = qsf_call(QSO_UNLOCK, qsf_rb); if (DB_FAILURE_MACRO(status)) { (VOID) psf_error(E_PS0B05_CANT_UNLOCK, qsf_rb->qsf_error.err_code, PSF_INTERR, &err_code, &psq_cb->psq_error, 0); goto cleanup1; } psq_cb->psq_qid = qsf_rb->qsf_obj_id.qso_handle; return (status); cleanup1: /* Destroy the object, it's already locked. */ stat = qsf_call(QSO_DESTROY, qsf_rb); if (DB_FAILURE_MACRO(stat)) { (VOID) psf_error(E_PS0A09_CANTDESTROY, qsf_rb->qsf_error.err_code, PSF_INTERR, &err_code, &psq_cb->psq_error, 0); if (stat > status) status = stat; } cleanup2: /* RDF object can be released now. */ stat = rdf_call(RDF_UNFIX, (PTR) rdf_cb); if (DB_FAILURE_MACRO(stat)) { (VOID) psf_rdf_error(RDF_UNFIX, &rdf_cb->rdf_error, &psq_cb->psq_error); if (stat > status) status = stat; } return (status); }
/*{ ** Name: psy_gsequence - Get description of a sequence from RDF. ** ** Description: ** This routine calls RDF to return the iisequence tuple for a sequence, ** then moves certain columns into the PSS_SEQINFO structure for its caller. ** It is used by psl to verify the existence of a sequence referenced in ** a sequence operation (next/current value) and return definition information. ** ** Inputs: ** sess_cb Pointer to session control block. ** .pss_user User/owner of the event. ** seq_own Sequence owner (from syntax). ** seq_name Sequence name (from syntax). ** seq_mask flag field ** PSS_USRSEQ search for sequence owned by the current user ** PSS_DBASEQ search for sequence owned by the DBA ** (must not be set unless ** (seq_mask & PSS_USRSEQ)) ** PSS_INGSEQ search for sequence owned by $ingres ** (must not be set unless ** (seq_mask & PSS_USRSEQ)) ** PSS_SEQ_BY_OWNER search for sequence owned by the specified ** owner ** PSS_SEQ_BY_ID search for sequence by id ** NOTE: PSS_USRSEQ <==> !PSS_SEQ_BY_OWNER ** PSS_SEQ_BY_ID ==> !PSS_SEQ_BY_OWNER ** PSS_SEQ_BY_ID ==> !PSS_USRSEQ ** privs Pointer to privilege bit map (if we're to ** check privileges on this sequence) or NULL. ** qmode Query mode (for errors). ** grant_all Flag indicating GRANT ALL accompanied request. ** ** Outputs: ** seq_info Pointer to sequence information block ** .pss_seqname Sequence name. ** .pss_owner Sequence owner. ** .pss_seqid Internal sequence ID. ** .pss_dt Sequence value datatype. ** .pss_length Sequence value length. ** .pss_secid Sequence security ID. ** err_blk ** .err_code Filled in if an error happens: ** E_US1914_SEQ_NOT_FOUND Cannot find sequence definition. ** Generally, the error codes returned by RDF and QEU ** qrymod processing routines are passed back to the caller ** except where they are user errors (eg, sequence doesn't exist). ** ** Returns: ** E_DB_OK, E_DB_WARN, E_DB_ERROR, E_DB_FATAL ** Exceptions: ** none ** ** Side Effects: ** none ** ** History: ** 18-mar-02 (inkdo01) ** Cloned from psy_gevent for sequence support. ** 21-feb-03 (inkdo01) ** Add seq_mask to control iisequence retrieval. ** 24-apr-03 (inkdo01) ** Reset IISEQUENCE ptr for secondary calls to RDF. ** 24-apr-03 (inkdo01) ** Fix "not found" message for "drop sequence". ** 09-Mar-2010 (coomi01) b123351 ** Block users from dropping dba sequences. ** 29-Apr-2010 (coomi01) b123638 ** Backout the above change, then put in a test ** to prevent delete dba's sequence by non dba. ** This allows non-dba to find sequence for ** updating. ** 15-Oct-2010 (kschendel) SIR 124544 ** Update psl-command-string call. */ DB_STATUS psy_gsequence( PSS_SESBLK *sess_cb, DB_OWN_NAME *seq_own, DB_NAME *seq_name, i4 seq_mask, PSS_SEQINFO *seq_info, DB_IISEQUENCE *seqp, i4 *ret_flags, i4 *privs, i4 qmode, i4 grant_all, DB_ERROR *err_blk) { DB_STATUS status; RDF_CB rdf_seq; /* RDF for sequence */ DB_IISEQUENCE seqtuple; /* sequence tuple to retrieve into */ i4 err_code; bool leave_loop = TRUE; *ret_flags = 0; /* First retrieve sequence tuple from RDF */ if (seqp == NULL) seqp = &seqtuple; /* zero out RDF_CB and init common elements */ pst_rdfcb_init(&rdf_seq, sess_cb); /* init relevant elements */ { rdf_seq.rdf_rb.rdr_types_mask = RDR_BY_NAME; rdf_seq.rdf_rb.rdr_2types_mask = RDR2_SEQUENCE; MEmove(sizeof(DB_NAME), (PTR) seq_name, ' ', sizeof(DB_NAME), (PTR) &rdf_seq.rdf_rb.rdr_name.rdr_seqname); STRUCT_ASSIGN_MACRO((*seq_own), rdf_seq.rdf_rb.rdr_owner); } rdf_seq.rdf_rb.rdr_update_op = RDR_OPEN; rdf_seq.rdf_rb.rdr_qtuple_count = 1; rdf_seq.rdf_rb.rdr_qrytuple = (PTR) seqp; do /* something to break out of */ { status = rdf_call(RDF_GETINFO, (PTR) &rdf_seq); /* ** if caller specified sequence owner name, or ** the sequence was found, or ** an error other than "sequence not found" was encountered, ** bail out */ if ( seq_mask & PSS_SEQ_BY_OWNER || status == E_DB_OK || rdf_seq.rdf_error.err_code != E_RD0013_NO_TUPLE_FOUND ) break; /* ** if sequence was not found, and ** - caller requested that DBA's sequences be considered, and ** - user is not the DBA, ** - check we are not attempting to destroy the sequence. ** check if the sequence is owned by the DBA */ if ((qmode != PSQ_DSEQUENCE) && seq_mask & PSS_DBASEQ && MEcmp((PTR) &sess_cb->pss_dba.db_tab_own, (PTR) &sess_cb->pss_user, sizeof(DB_OWN_NAME)) ) { STRUCT_ASSIGN_MACRO(sess_cb->pss_dba.db_tab_own, rdf_seq.rdf_rb.rdr_owner); rdf_seq.rdf_rb.rdr_qtuple_count = 1; rdf_seq.rdf_rb.rdr_qrytuple = (PTR) &seqtuple; status = rdf_call(RDF_GETINFO, (PTR) &rdf_seq); if (status == E_DB_OK) STRUCT_ASSIGN_MACRO(seqtuple, *seqp); } /* ** if still not found, and ** - caller requested that sequences owned by $ingres be considered, and ** - user is not $ingres and ** - DBA is not $ingres, ** check if the sequence is owned by $ingres */ if ( status != E_DB_OK && rdf_seq.rdf_error.err_code == E_RD0013_NO_TUPLE_FOUND && seq_mask & PSS_INGSEQ ) { if ( MEcmp((PTR) &sess_cb->pss_user, (PTR) sess_cb->pss_cat_owner, sizeof(DB_OWN_NAME)) && MEcmp((PTR) &sess_cb->pss_dba.db_tab_own, (PTR) sess_cb->pss_cat_owner, sizeof(DB_OWN_NAME)) ) { STRUCT_ASSIGN_MACRO((*sess_cb->pss_cat_owner), rdf_seq.rdf_rb.rdr_owner); rdf_seq.rdf_rb.rdr_qtuple_count = 1; rdf_seq.rdf_rb.rdr_qrytuple = (PTR) &seqtuple; status = rdf_call(RDF_GETINFO, (PTR) &rdf_seq); if (status == E_DB_OK) STRUCT_ASSIGN_MACRO(seqtuple, *seqp); } } /* leave_loop has already been set to TRUE */ } while (!leave_loop); if (status != E_DB_OK) { if (rdf_seq.rdf_error.err_code == E_RD0013_NO_TUPLE_FOUND) { if (qmode == PSQ_ASEQUENCE || qmode == PSQ_DSEQUENCE) { _VOID_ psf_error(6419L, 0L, PSF_USERERR, &err_code, err_blk, 1, psf_trmwhite(sizeof(*seq_name), (PTR)seq_name), (PTR)seq_name); } else /* must be DML currval/nextval request */ { char qry[PSL_MAX_COMM_STRING]; i4 qry_len; psl_command_string(qmode, sess_cb, qry, &qry_len); _VOID_ psf_error(6420L, 0L, PSF_USERERR, &err_code, err_blk, 2, qry_len, qry, psf_trmwhite(sizeof(*seq_name), (char *) seq_name), (PTR) seq_name); } if (sess_cb->pss_dbp_flags & PSS_DBPROC) sess_cb->pss_dbp_flags |= PSS_MISSING_OBJ; *ret_flags |= PSS_MISSING_SEQUENCE; status = E_DB_OK; } else /* some other error */ { _VOID_ psf_rdf_error(RDF_GETINFO, &rdf_seq.rdf_error, err_blk); } return (status); } /* If RDF did not return the sequence tuple */ STRUCT_ASSIGN_MACRO(rdf_seq.rdf_rb.rdr_owner, (*seq_own)); /* copy back successful owner */ if (seq_info != NULL) { /* fill in a sequence descriptor */ STRUCT_ASSIGN_MACRO(seqp->dbs_name, seq_info->pss_seqname); STRUCT_ASSIGN_MACRO(seqp->dbs_owner, seq_info->pss_seqown); STRUCT_ASSIGN_MACRO(seqp->dbs_uniqueid, seq_info->pss_seqid); seq_info->pss_dt = seqp->dbs_type; seq_info->pss_length = seqp->dbs_length; seq_info->pss_prec = seqp->dbs_prec; } /* ** if we are parsing a dbproc and the sequence which we have just looked up ** is owned by the dbproc's owner, we will add the sequence to the dbproc's ** independent object list unless it has already been added. ** Note that only sequences owned by the current user will be included into ** the list of independent objects. ** ** NOTE: we do not build independent object list for system-generated ** dbprocs */ if ( sess_cb->pss_dbp_flags & PSS_DBPROC && ~sess_cb->pss_dbp_flags & PSS_SYSTEM_GENERATED && !MEcmp((PTR) &sess_cb->pss_user, (PTR) &seqp->dbs_owner, sizeof(sess_cb->pss_user)) ) { status = pst_add_1indepobj(sess_cb, &seqp->dbs_uniqueid, PSQ_OBJTYPE_IS_SEQUENCE, (DB_DBP_NAME *) NULL, &sess_cb->pss_indep_objs.psq_objs, sess_cb->pss_dependencies_stream, err_blk); if (DB_FAILURE_MACRO(status)) { return(status); } } if (privs && *privs) { i4 privs_to_find = *privs; status = psy_seqperm(&rdf_seq, &privs_to_find, sess_cb, seq_info, qmode, grant_all, err_blk); if (DB_FAILURE_MACRO(status)) { return (status); } else if (privs_to_find) { if (grant_all && *privs != privs_to_find) { /* ** if we are processing GRANT ALL and psy_seqperm() has ** determined that the user may grant some but not all ** privileges on the sequence, reset the privilege map ** accordingly */ *privs &= ~(privs_to_find & ~((i4) DB_GRANT_OPTION)); } else { *ret_flags |= PSS_INSUF_SEQ_PRIVS; return(E_DB_OK); } } /* If no permission */ } return(E_DB_OK); }
DB_STATUS adi_tyid( ADF_CB *adf_scb, ADI_DT_NAME *adi_dname, DB_DT_ID *adi_did) { i4 s; i4 n; i4 i; i4 cmp; char *c1; char *c2; ADI_DT_NAME dt_name; bool dategiven = FALSE; s = sizeof(adi_dname->adi_dtname); c2 = &adi_dname->adi_dtname[0]; if (c2 && ((*c2 == 'd') || (*c2 == 'D'))) { if (STbcompare (c2, 0, "date", 0, TRUE) == 0) { dategiven = TRUE; if (adf_scb->adf_date_type_alias & AD_DATE_TYPE_ALIAS_INGRES) { /* replace the input string with ingresdate */ MEmove(10, (PTR)"ingresdate", '\0', sizeof(ADI_DT_NAME), (PTR)&dt_name.adi_dtname); dt_name.adi_dtname[10]='\0'; } else if (adf_scb->adf_date_type_alias & AD_DATE_TYPE_ALIAS_ANSI) { /* replace the input string with ansidate */ MEmove(8, (PTR)"ansidate", '\0', sizeof(ADI_DT_NAME), (PTR)&dt_name.adi_dtname); dt_name.adi_dtname[8]='\0'; } else { return (adu_error(adf_scb, E_AD5065_DATE_ALIAS_NOTSET, 0)); } } } for(n=1; n <= ADI_MXDTS; n++) { if (Adf_globs->Adi_datatypes[n].adi_dtid == DB_NODT) break; cmp = 1; c1 = &Adf_globs->Adi_datatypes[n].adi_dtname.adi_dtname[0]; if (dategiven == TRUE) c2 = (PTR)&dt_name.adi_dtname; else c2 = &adi_dname->adi_dtname[0]; i = 0; while ((i++ < s) && (*c1 != 0 || *c2 != 0)) { if (*c1++ != *c2++) { cmp = 0; break; } } if (cmp) { *adi_did = Adf_globs->Adi_datatypes[n].adi_dtid; return(E_DB_OK); } } *adi_did = DB_NODT; return(adu_error(adf_scb, E_AD2003_BAD_DTNAME, 0)); }
/*{ ** Name: psy_drop_synonym - Drop an IISYNONYM tuple. ** ** Description: ** Call RDF_UPDATE to delete a tuple from IISYNONYM. ** Inputs: ** psy_cb PSY control block. ** sess_cb PSF session control block. ** Outputs: ** Exceptions: ** none ** Returns: ** E_DB_OK synonym tuple has been deleted successfully; ** error status from RDF otherwise ** ** Side Effects: ** Modifies system catalogs. ** ** History: ** 19-apr-90 (andre) ** Created. ** 22-may-90 (teg) ** init rdr_instr to RDF_NO_INSTR ** 03-aug-92 (barbara) ** Invalidate base table infoblk from RDF's cache. ** 10-aug-93 (andre) ** fixed causes of compiler warnings ** 13-sep-93 (andre) ** QEF will assume responsibility for altering timestamps of tables ** (or underlying tables of views) synonym(s) on which have been ** dropped. We will supply QEF with the id of the object on which ** the synonym was defined ** 22-oct-93 (andre) ** In the unlikely event that RDF's cache entry for the synonym named ** in the DROP SYNONYM statement is stale and the synonym no longer ** exists, RDF will return E_RD014A_NONEXISTENT_SYNONYM which we will ** translate into 2753L */ DB_STATUS psy_drop_synonym( PSY_CB *psy_cb, PSS_SESBLK *sess_cb) { RDF_CB rdf_cb; RDF_CB rdf_inv_cb; DB_IISYNONYM syn_tuple; register RDR_RB *rdf_rb = &rdf_cb.rdf_rb; DB_STATUS status; register i4 syn_count; i4 err_code; /* Initialize the RDF request block. */ pst_rdfcb_init(&rdf_cb, sess_cb); pst_rdfcb_init(&rdf_inv_cb, sess_cb); STRUCT_ASSIGN_MACRO(sess_cb->pss_user, rdf_rb->rdr_owner); rdf_rb->rdr_2types_mask = (RDF_TYPES) RDR2_SYNONYM; rdf_rb->rdr_update_op = RDR_DELETE; rdf_rb->rdr_qrytuple = (PTR) &syn_tuple; rdf_rb->rdr_tabid.db_tab_base = DM_B_SYNONYM_TAB_ID; rdf_rb->rdr_tabid.db_tab_index = DM_I_SYNONYM_TAB_ID; MEmove(sizeof(DB_OWN_NAME), (char *)&sess_cb->pss_user, ' ', sizeof(DB_SYNOWN), (char *)&syn_tuple.db_synowner); for (syn_count = 0; syn_count < psy_cb->psy_numtabs; syn_count++) { /* store synonym name in the tuple */ MEmove(sizeof(DB_TAB_NAME), (char *)(psy_cb->psy_tabname + syn_count), ' ', sizeof(DB_SYNNAME), (char *)&syn_tuple.db_synname); syn_tuple.db_syntab_id.db_tab_base = psy_cb->psy_tables[syn_count].db_tab_base; syn_tuple.db_syntab_id.db_tab_index = psy_cb->psy_tables[syn_count].db_tab_index; /* Drop a tuple from IISYNONYM */ status = rdf_call(RDF_UPDATE, (PTR) &rdf_cb); if (DB_FAILURE_MACRO(status)) { if (rdf_cb.rdf_error.err_code == E_RD0144_DROP_SYNONYM) { (VOID) psf_error(E_PS0456_DROP_SYN_ERROR, 0L, PSF_USERERR, &err_code, &psy_cb->psy_error, 1, psf_trmwhite(sizeof(DB_SYNNAME), (char *) &syn_tuple.db_synname), &syn_tuple.db_synname); } else if (rdf_cb.rdf_error.err_code == E_RD014A_NONEXISTENT_SYNONYM) { /* ** looks like RDF cache entry was stale - tell user that ** synonym did not exist and proceed on to the next entry */ status = E_DB_OK; (VOID) psf_error(2753L, 0L, PSF_USERERR, &err_code, &psy_cb->psy_error, 2, sizeof("DROP SYNONYM") - 1, "DROP SYNONYM", psf_trmwhite(sizeof(DB_SYNNAME), (char *) &syn_tuple.db_synname), &syn_tuple.db_synname); continue; } else { (VOID) psf_rdf_error(RDF_UPDATE, &rdf_cb.rdf_error, &psy_cb->psy_error); } break; } STRUCT_ASSIGN_MACRO(psy_cb->psy_tables[syn_count], rdf_inv_cb.rdf_rb.rdr_tabid); status = rdf_call(RDF_INVALIDATE, (PTR) &rdf_inv_cb); if (DB_FAILURE_MACRO(status)) { (VOID) psf_rdf_error(RDF_INVALIDATE, &rdf_inv_cb.rdf_error, &psy_cb->psy_error); break; } } return (status); }
/*{ ** Name: scu_xencode - encrypt a character string ** ** Description: ** This function uses CI routines to encrypt a character string. ** Since the character string is used to generate the key schedule, ** the encryption is essentially one-way (you'd need to know the ** password to decode the password....) This routine was designed ** to encrypt application_id passwords. ** ** Inputs: ** SCU_XENCODE the opcode to scf_call() ** scf_cb control block in which is specified ** .scf_ptr_union.scf_xpassword ** pointer to buffer to be encrypted ** .scf_nbr_union.scf_xpasskey ** pointer to seed for key schedule ** .scf_len_union.scf_xpwdlen ** length of password and key seed ** ** Outputs: ** scf_cb the same control block ** .error the error control area ** .err_code E_SC_OK or ... ** E_SC0261_XENCODE_BAD_PARM ** E_SC0262_XENCODE_BAD_RESULT ** Returns: ** E_DB_{OK, WARNING, ERROR, FATAL} ** Exceptions: ** none ** ** Side Effects: ** none ** ** History: ** 24-mar-89 (ralph) ** Written for terminator ** 20-may-89 (ralph) ** Changed encryption to use separate key ** 06-jun-89 (ralph) ** Fixed unix compile problems ** 06-may-1993 (ralph) ** DELIM_IDENT: ** Translate key seed to lower case prior to encryption. ** 2-Jul-1993 (daveb) ** prototyped. ** 14-jul-93 (ed) ** replacing <dbms.h> by <gl.h> <sl.h> <iicommon.h> <dbdbms.h> ** 12-Sep-2007 (drivi01) ** Modified scu_xencode function to fix numerous bugs. ** The buffers for password manipulation shouldn't exceed ** the size of scb_xpassword field in SCF control block, ** otherwise the data will be truncated. */ DB_STATUS scu_xencode(SCF_CB *scf_cb, SCD_SCB *scb ) { STATUS status; CI_KS KS; char inbuffer[DB_PASSWORD_LENGTH+1]; char outbuffer[DB_PASSWORD_LENGTH+1]; char keybuffer[DB_PASSWORD_LENGTH]; u_i2 i2_size; i4 longnat_size; i4 nat_size; char *char_ptr; #define PASSINIT "hjodvwHOJHOJhodh498032&*&*#)$&*jpkshghjlg58925fjkdjkpg" status = E_DB_OK; CLRDBERR(&scf_cb->scf_error); /* Ensure input parameter is okay */ if ((scf_cb->scf_len_union.scf_xpwdlen <= 0) || (scf_cb->scf_len_union.scf_xpwdlen >= sizeof(inbuffer)) || (scf_cb->scf_nbr_union.scf_xpasskey == NULL) || (scf_cb->scf_ptr_union.scf_xpassword == NULL)) { sc0ePut(NULL, E_SC0261_XENCODE_BAD_PARM, NULL, 0); SETDBERR(&scf_cb->scf_error, 0, E_SC0261_XENCODE_BAD_PARM); return(E_DB_ERROR); } /* Copy string to input buffer */ MEmove(scf_cb->scf_len_union.scf_xpwdlen, (PTR)scf_cb->scf_ptr_union.scf_xpassword, (char)'\0', sizeof(inbuffer), (PTR)inbuffer); /* Copy key to key buffer */ MEmove(scf_cb->scf_len_union.scf_xpwdlen, (PTR)scf_cb->scf_nbr_union.scf_xpasskey, (char)'?', sizeof(keybuffer), (PTR)keybuffer); /* Fold the key to lower case */ for (nat_size = sizeof(keybuffer), char_ptr = keybuffer; nat_size > 0; nat_size = CMbytedec(nat_size, char_ptr), char_ptr = CMnext(char_ptr)) { CMtolower(char_ptr, char_ptr); } /* Remove white space from input string */ nat_size = STzapblank(inbuffer, outbuffer); /* Check size */ if ((nat_size <= 0) || (nat_size > sizeof(outbuffer)-1)) { sc0ePut(NULL, E_SC0261_XENCODE_BAD_PARM, NULL, 0); SETDBERR(&scf_cb->scf_error, 0, E_SC0261_XENCODE_BAD_PARM); return(E_DB_ERROR); } /* Initialize input buffer to "garbage" */ MEmove(sizeof(PASSINIT), (PTR)PASSINIT, (char)'?', sizeof(inbuffer), (PTR)inbuffer); /* Normalize the string back into input buffer */ MEcopy((PTR)outbuffer, nat_size, (PTR)inbuffer); /* Reset output buffer to blanks */ MEfill(sizeof(outbuffer), (u_char)' ', (PTR)outbuffer); /* ** First, encrypt the key seed using the string to encode. ** Then, encrypt the string using the encrypted seed. ** This is done to prevent two roles with the same password ** from having the same encrypted value. ** Note that this makes the encryption one-way, since ** the password must be provided to decrypt the password! */ /* Generate the key schedule to encrypt the key seed */ (VOID)CIsetkey((PTR)inbuffer, KS); /* Encrypt the key seed */ longnat_size = DB_PASSWORD_LENGTH; (VOID)CIencode((PTR)keybuffer, longnat_size, KS, (PTR)outbuffer); /* Generate the second key schedule */ (VOID)CIsetkey((PTR)keybuffer, KS); /* Encode the string */ longnat_size = DB_PASSWORD_LENGTH; (VOID)CIencode((PTR)inbuffer, longnat_size, KS, (PTR)outbuffer); /* Make sure it was really encoded */ if ((char *)STskipblank(outbuffer, (i4)sizeof(outbuffer)) != NULL) { /* It was; copy result to caller's area */ i2_size = scf_cb->scf_len_union.scf_xpwdlen; MEmove(sizeof(outbuffer), (PTR)outbuffer, (char)' ', i2_size, (PTR)scf_cb->scf_ptr_union.scf_xpassword); } else { /* The encryption did not work; return an error */ sc0ePut(NULL, E_SC0262_XENCODE_BAD_RESULT, NULL, 0); SETDBERR(&scf_cb->scf_error, 0, E_SC0262_XENCODE_BAD_RESULT); status = E_DB_ERROR; } return(status); }