Esempio n. 1
0
/*{
** Name:	init_list - initialize list
**
** Description:
**	Initializes the linklist, sets the global pointers to null.
**
** Inputs:
**	none
**
** Outputs:
**	none
**
** Returns:
**	none
*/
void
init_list()
{
	if (top)
	{
		if (atop)
		{
			atop->blink = bottom;
			bottom->link = atop;
			atop = top;
		}
		else
		{
			atop = top;
			abottom = bottom;
		}
	}
	else
	{
		atop = (RLIST *)NULL;
		abottom = (RLIST *)NULL;
	}
	top = (RLIST *)NULL;
	bottom = (RLIST *)NULL;

	/* top %d, atop %d */
	messageit(5, 1262, top, atop);
}
Esempio n. 2
0
/*{
** Name:	list_top - return the head of the list
**
** Description:
**	Returns the top (start) of the list.
**
** Inputs:
**	none
**
** Outputs:
**	none
**
** Returns:
**	A pointer to the head of the list.
**
** Side effects:
**	The static pointer current is also pointed to the head of the list.
*/
RLIST *
list_top()
{
	current = top;
	/* top %d, atop %d */
	messageit(5, 1263, top, atop);
	return (top);
}
Esempio n. 3
0
/*{
** Name:	new_node - new node
**
** Description:
**	Create a new structure and append it to the bottom of the linklist.
**
** Inputs:
**	none
**
** Outputs:
**	none
**
** Returns:
**	A pointer to the new node.
**
** Side effects:
**	Some of the static pointers above are changed.
*/
RLIST *
new_node()
{
	RLIST	*mark;

	/* top %d, atop %d */
	messageit(5, 1264, top, atop);

	if (atop)
	{
		mark = atop;
		atop = atop->link;
	}
	else
	{
		mark = (RLIST *)MEreqmem(0, sizeof(RLIST), TRUE,
			(STATUS *)NULL);
		if (mark == NULL)
		{
			/* Error Allocating Memory for Record List: Aborting */
			messageit(1, 1266);
			RSshutdown(FAIL);
		}
	}

	mark->link = (RLIST *)NULL;
	mark->blink = (RLIST *)NULL;

	if (bottom)	/* there is already a linklist */
	{
		bottom->link = mark;
		mark->blink = bottom;
		bottom = mark;
	}
	else		/* first structure in the linklist */
	{
		top = mark;
		bottom = mark;
	}

	/* top %d, atop %d, mark %d */
	messageit(5, 1265, top, atop, mark);
	return (mark);
}
Esempio n. 4
0
/*{
** Name:	unquiet_db - unquiet a database
**
** Description:
**	Updates the database to mark the specified database number
**	as unquiet.
**
** Inputs:
**	db_no		- database number to be unquieted
**	quiet_type	- used to specify a USER_QUIET or SERVER_QUIET state
**
** Outputs:
**	none
**
** Returns:
**	none
*/
void
unquiet_db(
i2	db_no,
i4	quiet_type)
{
	char	stmt[512];

	/* Unquieting target database %d */
	messageit(2, 1722, db_no);

	STprintf(stmt,
		ERx("UPDATE dd_db_cdds SET is_quiet = %d WHERE server_no = %d \
AND database_no = %d AND is_quiet != %d AND is_quiet <= %d"),
		NOT_QUIET, (i4)RSserver_no, (i4)db_no, NOT_QUIET, quiet_type);
	if (quiet_update(stmt) != IIAPI_ST_SUCCESS)
		RSshutdown(FAIL);
}
Esempio n. 5
0
/*{
** Name:	quiet_db - quiet a database
**
** Description:
**	Updates the database to mark the specified database number
**	as quiet.
**
** Inputs:
**	db_no		- database number to be quieted
**	quiet_type	- used to specify a USER_QUIET or SERVER_QUIET state
**
** Outputs:
**	none
**
** Returns:
**	none
*/
void
quiet_db(
i2	db_no,
i4	quiet_type)
{
	char	stmt[512];

	/* Setting target database %d to quiet */
	messageit(2, 1718, db_no);
	STprintf(stmt,
		ERx("UPDATE dd_db_cdds SET is_quiet = %d WHERE server_no = %d \
AND database_no = %d AND is_quiet < %d"),
		quiet_type, (i4)RSserver_no, (i4)db_no, quiet_type);

	if (quiet_update(stmt) != IIAPI_ST_SUCCESS)
		RSshutdown(FAIL);
}
Esempio n. 6
0
/*{
** Name:        RSmem_allocate  - Rep server large memory allocation. 
**
** Description:
**      Computes and allocates memory size needed for buffers to hold 
**	replicator server internal queries.
**
** Inputs:
**      row_width               - Total row width of registered cols.
**      num_cols                - Number of registered cols. 
**      colname_space           - Maximum name space of registered cols. 
**	overhead		- Additional query overhead
**
** Outputs:
**      NONE		
**
** Returns:
**      buf      		- NULL or Buffer successfully allocated.
*/
char *
RSmem_allocate(
i4 row_width,
i4 num_cols,
i4 colname_space,
i4 overhead)
{
	char *buf = (char *)MEreqmem(0, (num_cols * colname_space + row_width + overhead), TRUE, NULL);

	if (buf == NULL)
	{
	    /* Error allocating buf */
	    messageit(1, 1900);
	    return(buf) ;
	}
	
	return(buf);
}
Esempio n. 7
0
/*{
** Name:	quiet_cdds - quiet a cdds
**
** Description:
**	Updates the database to mark the specified cdds number
**	as quiet.
**
** Inputs:
**	dbno_ptr	- database be quieted, NULL for all
**	cdds_no		- cdds number to be quieted
**	quiet_type	- used to specify a USER_QUIET or SERVER_QUIET state
**
** Outputs:
**	none
**
** Returns:
**	none
*/
void
quiet_cdds(
i2	*dbno_ptr,
i2	cdds_no,
i4	quiet_type)
{
	char	stmt[512];

	if (dbno_ptr == NULL)
	{
		/* Setting CDDS %d to quiet */
		messageit(2, 1726, cdds_no);

		STprintf(stmt,
			ERx("UPDATE dd_db_cdds SET is_quiet = %d WHERE \
server_no = %d AND cdds_no = %d AND is_quiet < %d"),
			quiet_type, (i4)RSserver_no, (i4)cdds_no, quiet_type);
	}
Esempio n. 8
0
/*{
** Name:	RScommit - two-phase commit processing
**
** Description:
**	Prepares to commit locally, commits remotely, commits locally.
**	Logs each step of the commit so that a reasonable attempt can
**	be made to recover if it does not complete.
**
** Inputs:
**	target	- target database, CDDS and connection number
**	row	- distribution queue row
**
** Outputs:
**	none
**
** Returns:
**	OK or Ingres error
**
** Side effects:
**	A distributed transaction is committed using incomplete two-phase
**	commit (a prepare is only done on the local database, so the target
**	database is not aware it is part of a distributed transaction).
*/
STATUS
RScommit(
RS_TARGET	*target,
RS_TRANS_ROW	*row)
{
	i4			high = (i4)RSlocal_conn.db_no;
	SYSTIME			now;
	char			timestamp[21];
	char			timestr[27];
	i4			start_entry_no;
	i4			prepare_entry_no;
	i4			remote_entry_no;
	i4			complete_entry_no;
	RS_TBLDESC		*tbl = row->tbl_desc;
	RS_CONN			*local_conn = &RSlocal_conn;
	RS_CONN			*target_conn = &RSconns[target->conn_no];
	IIAPI_GETEINFOPARM	errParm;
	IIAPI_STATUS		status;

	if (RStwo_phase)	/* two-phase commit is on */
	{
		start_entry_no = RS_2PC_BEGIN;
		prepare_entry_no = RS_PREP_COMMIT;
		remote_entry_no = RS_REMOTE_COMMIT;
		complete_entry_no = RS_2PC_END;
	}
	else			/* two-phase commit is off */
	{
		start_entry_no = RS_NPC_BEGIN;
		remote_entry_no = RS_NPC_REM_COMMIT;
		complete_entry_no = RS_NPC_END;
	}

	TMnow(&now);
	TMstr(&now, timestr);
	mktimestamp(timestr, timestamp);

	SIfprintf(RScommit_fp, log_format, start_entry_no, high, low,
		(i4)target->db_no, tbl->table_owner, tbl->table_name,
		tbl->table_no, row->rep_key.trans_id, row->rep_key.seq_no,
		timestamp, "Start of commit");
	SIflush(RScommit_fp);

	if (RStwo_phase)	/* only prepare to commit if two-phase is on */
	{
		/*
		** Prepare to commit. The high value is %d, The low value is %d
		*/
		messageit(5, 1277, high, low);

		status = IIsw_prepareCommit(&local_conn->tranHandle, &errParm);
		if (status != IIAPI_ST_SUCCESS)
		{
			messageit(1, 1214);
			IIsw_rollback(&target_conn->tranHandle, &errParm);
			IIsw_rollback(&local_conn->tranHandle, &errParm);
			IIsw_releaseXID(&dtrans_id_handle);
			return (status);
		}

		SIfprintf(RScommit_fp, log_format, prepare_entry_no, high, low,
			(i4)target->db_no, tbl->table_owner, tbl->table_name,
			tbl->table_no, row->rep_key.trans_id,
			row->rep_key.seq_no, timestamp, "Prepare to commit");
		SIflush(RScommit_fp);
	}

	status = IIsw_commit(&target_conn->tranHandle, &errParm);
	if (status != IIAPI_ST_SUCCESS)
	{
		IIsw_rollback(&target_conn->tranHandle, &errParm);
		if (IIsw_rollback(&local_conn->tranHandle, &errParm) !=
			IIAPI_ST_SUCCESS)
		{
			RSdo_recover = TRUE;
			messageit(1, 1215);
			messageit(1, 1216);
		}
		else
		{
			messageit(1, 1215);
		}
		IIsw_releaseXID(&dtrans_id_handle);

		SIfprintf(RScommit_fp, log_format, remote_entry_no, high,
			low, (i4)target->db_no, tbl->table_owner,
			tbl->table_name, tbl->table_no, row->rep_key.trans_id,
			row->rep_key.seq_no, timestamp, "Local rollback");
		SIfprintf(RScommit_fp, log_format, complete_entry_no, high,
			low, (i4)target->db_no, tbl->table_owner,
			tbl->table_name, tbl->table_no, row->rep_key.trans_id,
			row->rep_key.seq_no, timestamp, "Commit complete");
		SIflush(RScommit_fp);
		return (status);
	}

	SIfprintf(RScommit_fp, log_format, remote_entry_no, high, low,
		(i4)target->db_no, tbl->table_owner, tbl->table_name,
		tbl->table_no, row->rep_key.trans_id, row->rep_key.seq_no,
		timestamp, "Remote commit");
	SIflush(RScommit_fp);

	status = IIsw_commit(&local_conn->tranHandle, &errParm);
	if (status != IIAPI_ST_SUCCESS)
	{
		RSdo_recover = TRUE;
		IIsw_releaseXID(&dtrans_id_handle);
		return (status);
	}
	IIsw_releaseXID(&dtrans_id_handle);

	SIfprintf(RScommit_fp, log_format, complete_entry_no, high, low,
		(i4)target->db_no, tbl->table_owner, tbl->table_name,
		tbl->table_no, row->rep_key.trans_id, row->rep_key.seq_no,
		timestamp, "Commit complete");
	SIflush(RScommit_fp);

	return (OK);
}
Esempio n. 9
0
/*{
** Name:	RSdelete	- propagate a DELETE row
**
** Description:
**	Propagates a DELETE transaction row, either by calling a remote
**	database procedure or by executing a remote DELETE.
**
** Inputs:
**	row		- row of data
**
** Outputs:
**	none
**
** Returns:
**	OK
**	else	- error
*/
STATUS
RSdelete(
RS_TARGET	*target,
RS_TRANS_ROW	*row)
{
	char 			*stmt=NULL;
	char			*proc_name;
	STATUS			err;
	bool			collision_processed = FALSE;
	RS_TBLDESC		*tbl = row->tbl_desc;
	II_INT2			nparams;
	IIAPI_DESCRIPTOR	pdesc[DB_MAX_COLS+1];
	IIAPI_DATAVALUE		pdata[DB_MAX_COLS+1];
	DB_DELIM_STR		*pnames = NULL;
	RS_CONN			*conn = &RSconns[target->conn_no];
	II_LONG			procRet;
	II_PTR			stmtHandle;
	IIAPI_GETEINFOPARM	errParm;
	IIAPI_GETQINFOPARM	getQinfoParm;
	IIAPI_STATUS		status;
	IIAPI_DESCRIPTOR 	*col;
	IIAPI_DESCRIPTOR 	*pds;
	i4			num_cols=tbl->num_regist_cols;
	i4			row_width=tbl->row_width;

	stmt = RSmem_allocate(row_width,num_cols,DB_MAXNAME+8,128); 
	if (stmt == NULL)
	   return (FAIL);

	messageit(5, 1268, row->rep_key.src_db, row->rep_key.trans_id,
		row->rep_key.seq_no, target->db_no);

	err = RScollision(target, row, tbl, &collision_processed);
	if (err || collision_processed)
	{
		MEfree((PTR)stmt);
		return (err);
	}

	/* For URO targets, delete the base row. */
	if (target->type == TARG_UNPROT_READ)
	{
		char	*where_list=NULL;
		char	objname[DB_MAXNAME*2+3];

		where_list = RSmem_allocate(row_width,tbl->num_key_cols,DB_MAXNAME+8,0); 
		if (where_list == NULL)
		{
			MEfree((PTR)stmt);
			return (FAIL);
		}
		/*
		** Iterate through key_desc and create the WHERE list and
		** prepare the column descriptors. The data will come directly
		** from key_data.
		*/
		*where_list = EOS;
		for (col = row->key_desc, pds = pdesc;
			col < row->key_desc + tbl->num_key_cols; ++col, ++pds)
		{
			if (col != row->key_desc)
				STcat(where_list, ERx(" AND "));
			/*
			** The following is special case code to allow existing
			** customers in non-SQL92 installations to propagate to
			** Gateway databases that use uppercase table and
			** column names.
			*/
			if (conn->name_case == UI_UPPERCASE)
			{
				STcopy(col->ds_columnName, objname);
				CVupper(objname);
				STcat(where_list, objname);
			}
			else
			{
				STcat(where_list, col->ds_columnName);
			}
			STcat(where_list, ERx(" = ~V"));
			*pds = *col;	/* struct */
			pds->ds_columnType = IIAPI_COL_QPARM;
		}
		STcopy(tbl->dlm_table_name, objname);
		if (target->type == TARG_UNPROT_READ &&
				conn->name_case == UI_UPPERCASE)
			CVupper(objname);
		STprintf(stmt, ERx("DELETE FROM %s.%s WHERE %s"),
			tbl->rem_table_owner, objname, where_list);
		status = IIsw_query(conn->connHandle, &conn->tranHandle, stmt,
			tbl->num_key_cols, pdesc, row->key_data, NULL, NULL,
			&stmtHandle, &getQinfoParm, &errParm);
		status = RSerror_check(1556, ROWS_SINGLE_ROW, stmtHandle,
			&getQinfoParm, &errParm, NULL, tbl->table_name);
		MEfree((PTR)where_list);
		if (status != OK)
		{
			MEfree((PTR)stmt);
			return (status);
		}
	}
	/* For FP and PRO targets, call the remote database procedure. */
	else
	{
	      pnames = (DB_DELIM_STR *)RSmem_allocate(0, DB_MAX_COLS+1,
			sizeof(*pnames),0); 
	      if (pnames == NULL)
	      {
		 MEfree((PTR)stmt);
		 return (FAIL);
	      }

		proc_name = pnames[0];
		if (RPtblobj_name(tbl->table_name, row->table_no,
			TBLOBJ_REM_DEL_PROC, proc_name) != OK)
		{
			messageit(1, 1816, ERx("RSdelete"), tbl->table_name);
			RSmem_free(stmt, (char *)pnames, NULL, NULL, NULL);
			return (RS_INTERNAL_ERR);
		}

		if (RSpdp_PrepDbprocParams(proc_name, target, tbl, row, pnames,
				&nparams, pdesc, pdata) != OK)
		{
			RSmem_free(stmt, (char *)pnames, NULL, NULL, NULL);
			return (RS_INTERNAL_ERR);
		}
		status = IIsw_execProcedure(conn->connHandle,
			&conn->tranHandle, nparams, pdesc, pdata, &procRet,
			&stmtHandle, &getQinfoParm, &errParm);
		status = RSerror_check(1573, ROWS_DONT_CARE, stmtHandle,
			&getQinfoParm, &errParm, NULL, proc_name);
		if (status != OK)
		{
			RSmem_free(stmt, (char *)pnames, NULL, NULL, NULL);
			return (status);
		}
		if (procRet)
		{
			messageit(1, procRet, row->rep_key.src_db,
				row->rep_key.trans_id, row->rep_key.seq_no,
				target->db_no, tbl->table_name);
			RSmem_free(stmt, (char *)pnames, NULL, NULL, NULL);
			return (procRet);
		}
	}

	RSstats_update(target->db_no, tbl->table_no, RS_DELETE);
	if (target->type != TARG_UNPROT_READ)
		RSmonitor_notify(&RSconns[target->conn_no], RS_INC_DELETE,
			RSlocal_conn.db_no, tbl->table_name, tbl->table_owner);
	RSmonitor_notify(&RSlocal_conn, RS_OUT_DELETE, target->db_no,
		tbl->table_name, tbl->table_owner);

	RSmem_free(stmt, (char *)pnames, NULL, NULL, NULL);
	return (OK);
}