⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 arrayfuncs.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
📖 第 1 页 / 共 3 页
字号:
		nbytes = strlen(ARR_DATA_PTR(v)) + VARHDRSZ + *(int *) p;		save_p = (char *) palloc(nbytes);		strcpy(save_p, p + sizeof(int));		strcat(save_p, ASSGN);		strcat(save_p, ARR_DATA_PTR(v));		pfree(p);		return save_p;	}	system_cache_lookup(element_type, false, &typlen, &typbyval,						&typdelim, &typelem, &typoutput, &typalign);	fmgr_info(typoutput, &outputproc);	sprintf(delim, "%c", typdelim);	ndim = ARR_NDIM(v);	dim = ARR_DIMS(v);	nitems = getNitems(ndim, dim);	if (nitems == 0)	{		char	   *emptyArray = palloc(3);		emptyArray[0] = '{';		emptyArray[1] = '}';		emptyArray[2] = '\0';		return emptyArray;	}	p = ARR_DATA_PTR(v);	overall_length = 1;			/* [TRH] don't forget to count \0 at end. */	values = (char **) palloc(nitems * sizeof(char *));	for (i = 0; i < nitems; i++)	{		if (typbyval)		{			switch (typlen)			{				case 1:					values[i] = (*fmgr_faddr(&outputproc)) (*p, typelem);					break;				case 2:					values[i] = (*fmgr_faddr(&outputproc)) (*(int16 *) p, typelem);					break;				case 3:				case 4:					values[i] = (*fmgr_faddr(&outputproc)) (*(int32 *) p, typelem);					break;			}			p += typlen;		}		else		{			values[i] = (*fmgr_faddr(&outputproc)) (p, typelem);			if (typlen > 0)				p += typlen;			else				p += INTALIGN(*(int32 *) p);			/*			 * For the pair of double quotes			 */			overall_length += 2;		}		for (tmp = values[i]; *tmp; tmp++)		{			overall_length += 1;#ifndef TCL_ARRAYS			if (*tmp == '"')				overall_length += 1;#endif		}		overall_length += 1;	}	/*	 * count total number of curly braces in output string	 */	for (i = j = 0, k = 1; i < ndim; k *= dim[i++], j += k);	p = (char *) palloc(overall_length + 2 * j);	retval = p;	strcpy(p, "{");	for (i = 0; i < ndim; indx[i++] = 0);	j = 0;	k = 0;	do	{		for (i = j; i < ndim - 1; i++)			strcat(p, "{");		/*		 * Surround anything that is not passed by value in double quotes.		 * See above for more details.		 */		if (!typbyval)		{			strcat(p, "\"");#ifndef TCL_ARRAYS			l = strlen(p);			for (tmp = values[k]; *tmp; tmp++)			{				if (*tmp == '"')					p[l++] = '\\';				p[l++] = *tmp;			}			p[l] = '\0';#else			strcat(p, values[k]);#endif			strcat(p, "\"");		}		else			strcat(p, values[k]);		pfree(values[k++]);		for (i = ndim - 1; i >= 0; i--)		{			indx[i] = (indx[i] + 1) % dim[i];			if (indx[i])			{				strcat(p, delim);				break;			}			else				strcat(p, "}");		}		j = i;	} while (j != -1);	pfree(values);	return retval;}/*----------------------------------------------------------------------------- * array_dims : *		  returns the dimension of the array pointed to by "v" *---------------------------------------------------------------------------- */char *array_dims(ArrayType *v, bool *isNull){	char	   *p,			   *save_p;	int			nbytes,				i;	int		   *dimv,			   *lb;	if (v == (ArrayType *) NULL)		RETURN_NULL;	nbytes = ARR_NDIM(v) * 33;	/*	 * 33 since we assume 15 digits per number + ':' +'[]'	 */	save_p = p = (char *) palloc(nbytes + VARHDRSZ);	MemSet(save_p, 0, nbytes + VARHDRSZ);	dimv = ARR_DIMS(v);	lb = ARR_LBOUND(v);	p += VARHDRSZ;	for (i = 0; i < ARR_NDIM(v); i++)	{		sprintf(p, "[%d:%d]", lb[i], dimv[i] + lb[i] - 1);		p += strlen(p);	}	nbytes = strlen(save_p + VARHDRSZ) + VARHDRSZ;	memmove(save_p, &nbytes, VARHDRSZ);	return save_p;}/*--------------------------------------------------------------------------- * array_ref : *	  This routing takes an array pointer and an index array and returns *	  a pointer to the referred element if element is passed by *	  reference otherwise returns the value of the referred element. *--------------------------------------------------------------------------- */Datumarray_ref(ArrayType *array,		  int n,		  int *indx,		  int reftype,		  int elmlen,		  int arraylen,		  bool *isNull){	int			i,				ndim,			   *dim,			   *lb,				offset,				nbytes;	struct varlena *v = NULL;	char	   *retval = NULL;	if (array == (ArrayType *) NULL)		RETURN_NULL;	if (arraylen > 0)	{		/*		 * fixed length arrays -- these are assumed to be 1-d		 */		if (indx[0] * elmlen > arraylen)			elog(ERROR, "array_ref: array bound exceeded");		retval = (char *) array + indx[0] * elmlen;		return _ArrayCast(retval, reftype, elmlen);	}	dim = ARR_DIMS(array);	lb = ARR_LBOUND(array);	ndim = ARR_NDIM(array);	nbytes = (*(int32 *) array) - ARR_OVERHEAD(ndim);	if (!SanityCheckInput(ndim, n, dim, lb, indx))		RETURN_NULL;	offset = GetOffset(n, dim, lb, indx);	if (ARR_IS_LO(array))	{		char	   *lo_name;		int			fd = 0;		/* We are assuming fixed element lengths here */		offset *= elmlen;		lo_name = (char *) ARR_DATA_PTR(array);#ifdef LOARRAY		if ((fd = LOopen(lo_name, ARR_IS_INV(array) ? INV_READ : O_RDONLY)) < 0)			RETURN_NULL;#endif		if (ARR_IS_CHUNKED(array))			v = _ReadChunkArray1El(indx, elmlen, fd, array, isNull);		else		{			if (lo_lseek(fd, offset, SEEK_SET) < 0)				RETURN_NULL;#ifdef LOARRAY			v = (struct varlena *) LOread(fd, elmlen);#endif		}		if (*isNull)			RETURN_NULL;		if (VARSIZE(v) - VARHDRSZ < elmlen)			RETURN_NULL;		lo_close(fd);		retval = (char *) _ArrayCast((char *) VARDATA(v), reftype, elmlen);		if (reftype == 0)		{						/* not by value */			char	   *tempdata = palloc(elmlen);			memmove(tempdata, retval, elmlen);			retval = tempdata;		}		pfree(v);		return (Datum) retval;	}	if (elmlen > 0)	{		offset = offset * elmlen;		/* off the end of the array */		if (nbytes - offset < 1)			RETURN_NULL;		retval = ARR_DATA_PTR(array) + offset;		return _ArrayCast(retval, reftype, elmlen);	}	else	{		bool		done = false;		char	   *temp;		int			bytes = nbytes;		temp = ARR_DATA_PTR(array);		i = 0;		while (bytes > 0 && !done)		{			if (i == offset)			{				retval = temp;				done = true;			}			bytes -= INTALIGN(*(int32 *) temp);			temp += INTALIGN(*(int32 *) temp);			i++;		}		if (!done)			RETURN_NULL;		return (Datum) retval;	}}/*----------------------------------------------------------------------------- * array_clip : *		  This routine takes an array and a range of indices (upperIndex and *		   lowerIndx), creates a new array structure for the referred elements *		   and returns a pointer to it. *----------------------------------------------------------------------------- */Datumarray_clip(ArrayType *array,		   int n,		   int *upperIndx,		   int *lowerIndx,		   int reftype,		   int len,		   bool *isNull){	int			i,				ndim,			   *dim,			   *lb,				nbytes;	ArrayType  *newArr;	int			bytes,				span[MAXDIM];	/* timer_start(); */	if (array == (ArrayType *) NULL)		RETURN_NULL;	dim = ARR_DIMS(array);	lb = ARR_LBOUND(array);	ndim = ARR_NDIM(array);	nbytes = (*(int32 *) array) - ARR_OVERHEAD(ndim);	if (!SanityCheckInput(ndim, n, dim, lb, upperIndx))		RETURN_NULL;	if (!SanityCheckInput(ndim, n, dim, lb, lowerIndx))		RETURN_NULL;	for (i = 0; i < n; i++)		if (lowerIndx[i] > upperIndx[i])			elog(ERROR, "lowerIndex cannot be larger than upperIndx");	mda_get_range(n, span, lowerIndx, upperIndx);	if (ARR_IS_LO(array))	{#ifdef LOARRAY		char	   *lo_name;#endif		char	   *newname = NULL;		int			fd = 0,					newfd = 0,					isDestLO = true,					rsize;		if (len < 0)			elog(ERROR, "array_clip: array of variable length objects not supported");#ifdef LOARRAY		lo_name = (char *) ARR_DATA_PTR(array);		if ((fd = LOopen(lo_name, ARR_IS_INV(array) ? INV_READ : O_RDONLY)) < 0)			RETURN_NULL;		newname = _array_newLO(&newfd, Unix);#endif		bytes = strlen(newname) + 1 + ARR_OVERHEAD(n);		newArr = (ArrayType *) palloc(bytes);		memmove(newArr, array, sizeof(ArrayType));		memmove(newArr, &bytes, sizeof(int));		memmove(ARR_DIMS(newArr), span, n * sizeof(int));		memmove(ARR_LBOUND(newArr), lowerIndx, n * sizeof(int));		strcpy(ARR_DATA_PTR(newArr), newname);		rsize = compute_size(lowerIndx, upperIndx, n, len);		if (rsize < MAX_BUFF_SIZE)		{			char	   *buff;			rsize += VARHDRSZ;			buff = palloc(rsize);			if (buff)				isDestLO = false;			if (ARR_IS_CHUNKED(array))			{				_ReadChunkArray(lowerIndx, upperIndx, len, fd, &(buff[VARHDRSZ]),								array, 0, isNull);			}			else			{				_ReadArray(lowerIndx, upperIndx, len, fd, (int) &(buff[VARHDRSZ]),						   array,						   0, isNull);			}			memmove(buff, &rsize, VARHDRSZ);#ifdef LOARRAY			if (!*isNull)				bytes = LOwrite(newfd, (struct varlena *) buff);#endif			pfree(buff);		}		if (isDestLO)		{			if (ARR_IS_CHUNKED(array))			{				_ReadChunkArray(lowerIndx, upperIndx, len, fd, (char *) newfd, array,								1, isNull);			}			else				_ReadArray(lowerIndx, upperIndx, len, fd, newfd, array, 1, isNull);		}#ifdef LOARRAY		LOclose(fd);		LOclose(newfd);#endif		if (*isNull)		{			pfree(newArr);			newArr = NULL;		}		/* timer_end(); */		return (Datum) newArr;	}	if (len > 0)	{		bytes = getNitems(n, span);		bytes = bytes * len + ARR_OVERHEAD(n);	}	else	{		bytes = _ArrayClipCount(lowerIndx, upperIndx, array);		bytes += ARR_OVERHEAD(n);	}	newArr = (ArrayType *) palloc(bytes);	memmove(newArr, array, sizeof(ArrayType));	memmove(newArr, &bytes, sizeof(int));	memmove(ARR_DIMS(newArr), span, n * sizeof(int));	memmove(ARR_LBOUND(newArr), lowerIndx, n * sizeof(int));	_ArrayRange(lowerIndx, upperIndx, len, ARR_DATA_PTR(newArr), array, 1);	return (Datum) newArr;}/*----------------------------------------------------------------------------- * array_set  : *		  This routine sets the value of an array location (specified by an index array) *		  to a new value specified by "dataPtr". * result : *		  returns a pointer to the modified array. *----------------------------------------------------------------------------- */char *array_set(ArrayType *array,		  int n,		  int *indx,		  char *dataPtr,		  int reftype,		  int elmlen,		  int arraylen,		  bool *isNull){	int			ndim,			   *dim,			   *lb,				offset,				nbytes;	char	   *pos;	if (array == (ArrayType *) NULL)		RETURN_NULL;	if (arraylen > 0)	{		/*		 * fixed length arrays -- these are assumed to be 1-d		 */		if (indx[0] * elmlen > arraylen)			elog(ERROR, "array_ref: array bound exceeded");		pos = (char *) array + indx[0] * elmlen;		ArrayCastAndSet(dataPtr, (bool) reftype, elmlen, pos);		return (char *) array;	}	dim = ARR_DIMS(array);	lb = ARR_LBOUND(array);	ndim = ARR_NDIM(array);	nbytes = (*(int32 *) array) - ARR_OVERHEAD(ndim);	if (!SanityCheckInput(ndim, n, dim, lb, indx))	{		elog(ERROR, "array_set: array bound exceeded");		return (char *) array;	}	offset = GetOffset(n, dim, lb, indx);	if (ARR_IS_LO(array))	{		int			fd = 0;		struct varlena *v;		/* We are assuming fixed element lengths here */		offset *= elmlen;#ifdef LOARRAY		char	   *lo_name;		lo_name = ARR_DATA_PTR(array);		if ((fd = LOopen(lo_name, ARR_IS_INV(array) ? INV_WRITE : O_WRONLY)) < 0)			return (char *) array;#endif		if (lo_lseek(fd, offset, SEEK_SET) < 0)			return (char *) array;		v = (struct varlena *) palloc(elmlen + VARHDRSZ);		VARSIZE(v) = elmlen + VARHDRSZ;		ArrayCastAndSet(dataPtr, (bool) reftype, elmlen, VARDATA(v));#ifdef LOARRAY		n = LOwrite(fd, v);#endif		/*		 * if (n < VARSIZE(v) - VARHDRSZ) RETURN_NULL;		 */		pfree(v);		lo_close(fd);		return (char *) array;	}	if (elmlen > 0)	{		offset = offset * elmlen;		/* off the end of the array */		if (nbytes - offset < 1)			return (char *) array;		pos = ARR_DATA_PTR(array) + offset;	}	else	{		ArrayType  *newarray;		char	   *elt_ptr;		int			oldsize,					newsize,					oldlen,					newlen,					lth0,					lth1,					lth2;		elt_ptr = array_seek(ARR_DATA_PTR(array), -1, offset);		oldlen = INTALIGN(*(int32 *) elt_ptr);		newlen = INTALIGN(*(int32 *) dataPtr);		if (oldlen == newlen)		{			/* new element with same size, overwrite old data */			ArrayCastAndSet(dataPtr, (bool) reftype, elmlen, elt_ptr);			return (char *) array;		}		/* new element with different size, reallocate the array */		oldsize = array->size;		lth0 = ARR_OVERHEAD(n);		lth1 = (int) (elt_ptr - ARR_DATA_PTR(array));		lth2 = (int) (oldsize - lth0 - lth1 - oldlen);		newsize = lth0 + lth1 + newlen + lth2;		newarray = (ArrayType *) palloc(newsize);		memmove((char *) newarray, (char *) array, lth0 + lth1);		newarray->size = newsize;		newlen = ArrayCastAndSet(dataPtr, (bool) reftype, elmlen,								 (char *) newarray + lth0 + lth1);		memmove((char *) newarray + lth0 + lth1 + newlen,				(char *) array + lth0 + lth1 + oldlen, lth2);		/* ??? who should free this storage ??? */		return (char *) newarray;	}	ArrayCastAndSet(dataPtr, (bool) reftype, elmlen, pos);	return (char *) array;}/*---------------------------------------------------------------------------- * array_assgn : *		  This routine sets the value of a range of array locations (specified *		  by upper and lower index values ) to new values passed as *		  another array * result : *		  returns a pointer to the modified array. *---------------------------------------------------------------------------- */char *array_assgn(ArrayType *array,			int n,			int *upperIndx,			int *lowerIndx,			ArrayType *newArr,			int reftype,			int len,			bool *isNull){	int			i,				ndim,			   *dim,			   *lb;	if (array == (ArrayType *) NULL)		RETURN_NULL;	if (len < 0)		elog(ERROR, "array_assgn:updates on arrays of variable length elements not allowed");	dim = ARR_DIMS(array);	lb = ARR_LBOUND(array);	ndim = ARR_NDIM(array);	if (!SanityCheckInput(ndim, n, dim, lb, upperIndx) ||		!SanityCheckInput(ndim, n, dim, lb, lowerIndx))		return (char *) array;	for (i = 0; i < n; i++)		if (lowerIndx[i] > upperIndx[i])			elog(ERROR, "lowerIndex larger than upperIndx");	if (ARR_IS_LO(array))	{		int			fd = 0,					newfd = 0;#ifdef LOARRAY		char	   *lo_name;		lo_name = (char *) ARR_DATA_PTR(array);		if ((fd = LOopen(lo_name, ARR_IS_INV(array) ? INV_WRITE : O_WRONLY)) < 0)			return (char *) array;#endif		if (ARR_IS_LO(newArr))		{#ifdef LOARRAY			lo_name = (char *) ARR_DATA_PTR(newArr);			if ((newfd = LOopen(lo_name, ARR_IS_INV(newArr) ? INV_READ : O_RDONLY)) < 0)				return (char *) array;#endif			_LOArrayRange(lowerIndx, upperIndx, len, fd, newfd, array, 1, isNull);			lo_close(newfd);		}		else

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -