Beispiel #1
0
/* Set ^#t(<gbl>,"#TRHASH",hash_code,nnn)=<gbl>_$c(0)_trigindx where gv_currkey is ^#t(<gbl>).
 * Note: This routine has code very similar to that in "add_trigger_hash_entry". There is just
 * not enough commonality to justify merging the two.
 */
STATICFNDEF void	gvtr_set_hashtrhash(char *trigvn, int trigvn_len, uint4 hash_code, int trigindx)
{
	uint4		curend;
	mval		mv_indx, *mv_indx_ptr;
	mval		mv_hash;
	int		hash_indx, num_len;
	char		name_and_index[MAX_MIDENT_LEN + 1 + MAX_DIGITS_IN_INT];
	char		*ptr;
	char		indx_str[MAX_DIGITS_IN_INT];
	uint4		len;
	int4		result;
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	curend = gv_currkey->end; /* note down gv_currkey->end before changing it so we can restore it before function returns */
	assert(KEY_DELIMITER == gv_currkey->base[curend]);
	assert(gv_target->gd_csa == cs_addrs);
	/* Set ^#t(<gvn>,"#TRHASH",kill_hash_code,i). To do that, first determine the
	 * highest i such that ^#t(<gvn>,"#TRHASH",kill_hash_code,i) exists. Set
	 * ^#t(<gvn>,"#TRHASH",kill_hash_code,i+1)=kill_hash_code in that case.
	 */
	MV_FORCE_UMVAL(&mv_hash, hash_code);
	BUILD_HASHT_SUB_SUB_MSUB_SUB_CURRKEY(trigvn, trigvn_len, LITERAL_HASHTRHASH, STRLEN(LITERAL_HASHTRHASH), mv_hash, "", 0);
	op_zprevious(&mv_indx);
	mv_indx_ptr = &mv_indx;
	hash_indx = (0 == mv_indx.str.len) ? 1 : (mval2i(mv_indx_ptr) + 1);
	i2mval(mv_indx_ptr, hash_indx);
	MV_FORCE_STR(mv_indx_ptr);
	/* Prepare the value of the SET */
	num_len = 0;
	I2A(indx_str, num_len, trigindx);
	assert(MAX_MIDENT_LEN >= trigvn_len);
	memcpy(name_and_index, trigvn, trigvn_len);
	ptr = name_and_index + trigvn_len;
	*ptr++ = '\0';
	memcpy(ptr, indx_str, num_len);
	len = trigvn_len + 1 + num_len;
	/* Do the SET */
	SET_TRIGGER_GLOBAL_SUB_SUB_MSUB_MSUB_STR(trigvn, trigvn_len,
		LITERAL_HASHTRHASH, STRLEN(LITERAL_HASHTRHASH), mv_hash, mv_indx, name_and_index, len, result);
	assert(PUT_SUCCESS == result);
	gv_currkey->end = curend;	/* reset gv_currkey->end to what it was at function entry */
	gv_currkey->base[curend] = KEY_DELIMITER;    /* restore terminator for entire key so key is well-formed */
	return;
}
Beispiel #2
0
STATICFNDEF int4 update_trigger_hash_value(char *trigvn, int trigvn_len, char **values, uint4 *value_len, stringkey *set_hash,
					   stringkey *kill_hash, int old_trig_index, int new_trig_index)
{
	sgmnt_addrs		*csa;
	int			hash_index;
	mval			key_val;
	uint4			len;
	mval			mv_hash;
	mval			mv_hash_indx;
	int			num_len;
	char			*ptr;
	int4			result;
	char			tmp_str[MAX_MIDENT_LEN + 1 + MAX_DIGITS_IN_INT];
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	assert(!gv_cur_region->read_only);		/* caller should have already checked this */
	assert(cs_addrs->hasht_tree == gv_target);	/* should have been set up by caller */
	assert(gv_target->root);			/* should have been ensured by caller */
	csa = cs_addrs;
	if ((NULL != strchr(values[CMD_SUB], 'S')) && (set_hash->hash_code != kill_hash->hash_code))
	{
		if (!search_trigger_hash(trigvn, trigvn_len, set_hash, old_trig_index, &hash_index))
		{	/* There has to be an entry with the old hash value, we just looked it up */
			TRHASH_DEFINITION_RETRY_OR_ERROR(set_hash, csa);
		}
		MV_FORCE_UMVAL(&mv_hash, set_hash->hash_code);
		MV_FORCE_UMVAL(&mv_hash_indx, hash_index);
		BUILD_HASHT_SUB_SUB_MSUB_MSUB_CURRKEY(trigvn, trigvn_len,
			LITERAL_HASHTRHASH, STRLEN(LITERAL_HASHTRHASH), mv_hash, mv_hash_indx);
		if (!gvcst_get(&key_val))
		{	/* There has to be a #TRHASH entry */
			TRHASH_DEFINITION_RETRY_OR_ERROR(set_hash, csa);
		}
		assert((MAX_MIDENT_LEN + 1 + MAX_DIGITS_IN_INT) >= key_val.str.len);
		ptr = key_val.str.addr;
		len = MIN(key_val.str.len, MAX_MIDENT_LEN);
		STRNLEN(ptr, len, len);
		ptr += len;
		if ((key_val.str.len == len) || ('\0' != *ptr))
		{	/* We expect $c(0) in the middle of ptr. If we dont find it, this is a restartable situation */
			if (CDB_STAGNATE > t_tries)
				t_retry(cdb_sc_triggermod);
			assert(WBTEST_HELPOUT_TRIGDEFBAD == gtm_white_box_test_case_number);
			rts_error_csa(CSA_ARG(REG2CSA(gv_cur_region)) VARLSTCNT(8) ERR_TRIGDEFBAD, 6, trigvn_len, trigvn,
					LEN_AND_LIT("\"#BHASH\""), mv_hash.str.len, mv_hash.str.addr);
		}
		memcpy(tmp_str, key_val.str.addr, len);
		ptr = tmp_str + len;
		*ptr++ = '\0';
		num_len = 0;
		I2A(ptr, num_len, new_trig_index);
		len += num_len + 1;
		SET_TRIGGER_GLOBAL_SUB_SUB_MSUB_MSUB_STR(trigvn, trigvn_len,
			LITERAL_HASHTRHASH, STRLEN(LITERAL_HASHTRHASH), mv_hash, mv_hash_indx, tmp_str, len, result);
		if (PUT_SUCCESS != result)
			return result;
	}
	if (!search_trigger_hash(trigvn, trigvn_len, kill_hash, old_trig_index, &hash_index))
	{	/* There has to be an entry with the old hash value, we just looked it up */
		TRHASH_DEFINITION_RETRY_OR_ERROR(kill_hash, csa);
	}
	MV_FORCE_UMVAL(&mv_hash, kill_hash->hash_code);
	MV_FORCE_UMVAL(&mv_hash_indx, hash_index);
	BUILD_HASHT_SUB_SUB_MSUB_MSUB_CURRKEY(trigvn, trigvn_len,
		LITERAL_HASHTRHASH, STRLEN(LITERAL_HASHTRHASH), mv_hash, mv_hash_indx);
	if (!gvcst_get(&key_val))
	{	/* There has to be a #TRHASH entry */
		TRHASH_DEFINITION_RETRY_OR_ERROR(kill_hash, csa);
	}
	assert((MAX_MIDENT_LEN + 1 + MAX_DIGITS_IN_INT) >= key_val.str.len);
	ptr = key_val.str.addr;
	len = MIN(key_val.str.len, MAX_MIDENT_LEN);
	STRNLEN(ptr, len, len);
	ptr += len;
	if ((key_val.str.len == len) || ('\0' != *ptr))
	{	/* We expect $c(0) in the middle of ptr. If we dont find it, this is a restartable situation */
		if (CDB_STAGNATE > t_tries)
			t_retry(cdb_sc_triggermod);
		assert(WBTEST_HELPOUT_TRIGDEFBAD == gtm_white_box_test_case_number);
		rts_error_csa(CSA_ARG(REG2CSA(gv_cur_region)) VARLSTCNT(8) ERR_TRIGDEFBAD, 6, trigvn_len, trigvn,
				LEN_AND_LIT("\"#LHASH\""), mv_hash.str.len, mv_hash.str.addr);
	}
	memcpy(tmp_str, key_val.str.addr, len);
	ptr = tmp_str + len;
	*ptr++ = '\0';
	num_len = 0;
	I2A(ptr, num_len, new_trig_index);
	len += num_len + 1;
	SET_TRIGGER_GLOBAL_SUB_SUB_MSUB_MSUB_STR(trigvn, trigvn_len,
		LITERAL_HASHTRHASH, STRLEN(LITERAL_HASHTRHASH), mv_hash, mv_hash_indx, tmp_str, len, result);
	return result;
}