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

📄 arrayfuncs.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
📖 第 1 页 / 共 3 页
字号:
		{			_LOArrayRange(lowerIndx, upperIndx, len, fd, (int) ARR_DATA_PTR(newArr),						  array, 0, isNull);		}		lo_close(fd);		return (char *) array;	}	_ArrayRange(lowerIndx, upperIndx, len, ARR_DATA_PTR(newArr), array, 0);	return (char *) array;}/* * array_map() * * Map an arbitrary function to an array and return a new array with * same dimensions and the source elements transformed by fn(). */ArrayType  *array_map(ArrayType *v,		  Oid type,		  char *(*fn) (),		  Oid retType,		  int nargs,		  ...){	ArrayType  *result;	void	   *args[4];	char	  **values;	char	   *elt;	int		   *dim;	int			ndim;	int			nitems;	int			i;	int			nbytes = 0;	int			inp_typlen;	bool		inp_typbyval;	int			typlen;	bool		typbyval;	char		typdelim;	Oid			typelem;	Oid			proc;	char		typalign;	char	   *s;	char	   *p;	va_list		ap;	/* Large objects not yet supported */	if (ARR_IS_LO(v) == true)		elog(ERROR, "array_map: large objects not supported");	/* Check nargs */	if ((nargs < 0) || (nargs > 4))		elog(ERROR, "array_map: invalid nargs: %d", nargs);	/* Copy extra args to local variable */	va_start(ap, nargs);	for (i = 0; i < nargs; i++)		args[i] = (void *) va_arg(ap, char *);	va_end(ap);	/* Lookup source and result types. Unneeded variables are reused. */	system_cache_lookup(type, false, &inp_typlen, &inp_typbyval,						&typdelim, &typelem, &proc, &typalign);	system_cache_lookup(retType, false, &typlen, &typbyval,						&typdelim, &typelem, &proc, &typalign);	ndim = ARR_NDIM(v);	dim = ARR_DIMS(v);	nitems = getNitems(ndim, dim);	/* Check for empty array */	if (nitems <= 0)		return v;	/* Allocate temporary array for new values */	values = (char **) palloc(nitems * sizeof(char *));	MemSet(values, 0, nitems * sizeof(char *));	/* Loop over source data */	s = (char *) ARR_DATA_PTR(v);	for (i = 0; i < nitems; i++)	{		/* Get source element */		if (inp_typbyval)		{			switch (inp_typlen)			{				case 1:					elt = (char *) ((int) (*(char *) s));					break;				case 2:					elt = (char *) ((int) (*(int16 *) s));					break;				case 3:				case 4:				default:					elt = (char *) (*(int32 *) s);					break;			}			s += inp_typlen;		}		else		{			elt = s;			if (inp_typlen > 0)				s += inp_typlen;			else				s += INTALIGN(*(int32 *) s);		}		/*		 * Apply the given function to source elt and extra args. nargs is		 * the number of extra args taken by fn().		 */		switch (nargs)		{			case 0:				p = (char *) (*fn) (elt);				break;			case 1:				p = (char *) (*fn) (elt, args[0]);				break;			case 2:				p = (char *) (*fn) (elt, args[0], args[1]);				break;			case 3:				p = (char *) (*fn) (elt, args[0], args[1], args[2]);				break;			case 4:			default:				p = (char *) (*fn) (elt, args[0], args[1], args[2], args[3]);				break;		}		/* Update values and total result size */		if (typbyval)		{			values[i] = (char *) p;			nbytes += typlen;		}		else		{			int			len;			len = ((typlen > 0) ? typlen : INTALIGN(*(int32 *) p));			/* Needed because _CopyArrayEls tries to pfree items */			if (p == elt)			{				p = (char *) palloc(len);				memcpy(p, elt, len);			}			values[i] = (char *) p;			nbytes += len;		}	}	/* Allocate and initialize the result array */	nbytes += ARR_OVERHEAD(ndim);	result = (ArrayType *) palloc(nbytes);	MemSet(result, 0, nbytes);	memcpy((char *) result, (char *) &nbytes, sizeof(int));	memcpy((char *) ARR_NDIM_PTR(result), (char *) &ndim, sizeof(int));	memcpy((char *) ARR_DIMS(result), ARR_DIMS(v), 2 * ndim * sizeof(int));	/* Copy new values into the result array. values is pfreed. */	_CopyArrayEls((char **) values,				  ARR_DATA_PTR(result), nitems,				  typlen, typalign, typbyval);	return result;}/*----------------------------------------------------------------------------- * array_eq : *		  compares two arrays for equality * result : *		  returns 1 if the arrays are equal, 0 otherwise. *----------------------------------------------------------------------------- */intarray_eq(ArrayType *array1, ArrayType *array2){	if ((array1 == NULL) || (array2 == NULL))		return 0;	if (*(int *) array1 != *(int *) array2)		return 0;	if (memcmp(array1, array2, *(int *) array1))		return 0;	return 1;}/***************************************************************************//******************|		  Support  Routines			  |*****************//***************************************************************************/static voidsystem_cache_lookup(Oid element_type,					bool input,					int *typlen,					bool *typbyval,					char *typdelim,					Oid *typelem,					Oid *proc,					char *typalign){	HeapTuple	typeTuple;	Form_pg_type typeStruct;	typeTuple = SearchSysCacheTuple(TYPOID,									ObjectIdGetDatum(element_type),									0, 0, 0);	if (!HeapTupleIsValid(typeTuple))	{		elog(ERROR, "array_out: Cache lookup failed for type %u\n",			 element_type);		return;	}	typeStruct = (Form_pg_type) GETSTRUCT(typeTuple);	*typlen = typeStruct->typlen;	*typbyval = typeStruct->typbyval;	*typdelim = typeStruct->typdelim;	*typelem = typeStruct->typelem;	*typalign = typeStruct->typalign;	if (input)		*proc = typeStruct->typinput;	else		*proc = typeStruct->typoutput;}static Datum_ArrayCast(char *value, bool byval, int len){	if (byval)	{		switch (len)		{				case 1:				return (Datum) *value;			case 2:				return (Datum) *(int16 *) value;			case 3:			case 4:				return (Datum) *(int32 *) value;			default:				elog(ERROR, "array_ref: byval and elt len > 4!");				break;		}	}	else		return (Datum) value;	return 0;}static intArrayCastAndSet(char *src,				bool typbyval,				int typlen,				char *dest){	int			inc;	if (typlen > 0)	{		if (typbyval)		{			switch (typlen)			{				case 1:					*dest = DatumGetChar(src);					break;				case 2:					*(int16 *) dest = DatumGetInt16(src);					break;				case 4:					*(int32 *) dest = (int32) src;					break;			}		}		else			memmove(dest, src, typlen);		inc = typlen;	}	else	{		memmove(dest, src, *(int32 *) src);		inc = (INTALIGN(*(int32 *) src));	}	return inc;}#ifdef LOARRAYstatic char *_AdvanceBy1word(char *str, char **word){	char	   *retstr,			   *space;	*word = NULL;	if (str == NULL)		return str;	while (isspace(*str))		str++;	*word = str;	if ((space = (char *) strchr(str, ' ')) != (char *) NULL)	{		retstr = space + 1;		*space = '\0';	}	else		retstr = NULL;	return retstr;}#endifstatic intSanityCheckInput(int ndim, int n, int *dim, int *lb, int *indx){	int			i;	/* Do Sanity check on input */	if (n != ndim)		return 0;	for (i = 0; i < ndim; i++)		if ((lb[i] > indx[i]) || (indx[i] >= (dim[i] + lb[i])))			return 0;	return 1;}static void_ArrayRange(int *st,			int *endp,			int bsize,			char *destPtr,			ArrayType *array,			int from){	int			n,			   *dim,			   *lb,				st_pos,				prod[MAXDIM];	int			span[MAXDIM],				dist[MAXDIM],				indx[MAXDIM];	int			i,				j,				inc;	char	   *srcPtr;	n = ARR_NDIM(array);	dim = ARR_DIMS(array);	lb = ARR_LBOUND(array);	srcPtr = ARR_DATA_PTR(array);	for (i = 0; i < n; st[i] -= lb[i], endp[i] -= lb[i], i++);	mda_get_prod(n, dim, prod);	st_pos = tuple2linear(n, st, prod);	srcPtr = array_seek(srcPtr, bsize, st_pos);	mda_get_range(n, span, st, endp);	mda_get_offset_values(n, dist, prod, span);	for (i = 0; i < n; indx[i++] = 0);	i = j = n - 1;	inc = bsize;	do	{		srcPtr = array_seek(srcPtr, bsize, dist[j]);		if (from)			inc = array_read(destPtr, bsize, 1, srcPtr);		else			inc = array_read(srcPtr, bsize, 1, destPtr);		destPtr += inc;		srcPtr += inc;	} while ((j = next_tuple(i + 1, indx, span)) != -1);}static int_ArrayClipCount(int *stI, int *endpI, ArrayType *array){	int			n,			   *dim,			   *lb,				st_pos,				prod[MAXDIM];	int			span[MAXDIM],				dist[MAXDIM],				indx[MAXDIM];	int			i,				j,				inc,				st[MAXDIM],				endp[MAXDIM];	int			count = 0;	char	   *ptr;	n = ARR_NDIM(array);	dim = ARR_DIMS(array);	lb = ARR_LBOUND(array);	ptr = ARR_DATA_PTR(array);	for (i = 0; i < n; st[i] = stI[i] - lb[i], endp[i] = endpI[i] - lb[i], i++);	mda_get_prod(n, dim, prod);	st_pos = tuple2linear(n, st, prod);	ptr = array_seek(ptr, -1, st_pos);	mda_get_range(n, span, st, endp);	mda_get_offset_values(n, dist, prod, span);	for (i = 0; i < n; indx[i++] = 0);	i = j = n - 1;	do	{		ptr = array_seek(ptr, -1, dist[j]);		inc = INTALIGN(*(int32 *) ptr);		ptr += inc;		count += inc;	} while ((j = next_tuple(i + 1, indx, span)) != -1);	return count;}static char *array_seek(char *ptr, int eltsize, int nitems){	int			i;	if (eltsize > 0)		return ptr + eltsize * nitems;	for (i = 0; i < nitems; i++)		ptr += INTALIGN(*(int32 *) ptr);	return ptr;}static intarray_read(char *destptr, int eltsize, int nitems, char *srcptr){	int			i,				inc,				tmp;	if (eltsize > 0)	{		memmove(destptr, srcptr, eltsize * nitems);		return eltsize * nitems;	}	for (i = inc = 0; i < nitems; i++)	{		tmp = (INTALIGN(*(int32 *) srcptr));		memmove(destptr, srcptr, tmp);		srcptr += tmp;		destptr += tmp;		inc += tmp;	}	return inc;}static void_LOArrayRange(int *st,			  int *endp,			  int bsize,			  int srcfd,			  int destfd,			  ArrayType *array,			  int isSrcLO,			  bool *isNull){	int			n,			   *dim,				st_pos,				prod[MAXDIM];	int			span[MAXDIM],				dist[MAXDIM],				indx[MAXDIM];	int			i,				j,				inc,				tmp,			   *lb,				offset;	n = ARR_NDIM(array);	dim = ARR_DIMS(array);	lb = ARR_LBOUND(array);	for (i = 0; i < n; st[i] -= lb[i], endp[i] -= lb[i], i++);	mda_get_prod(n, dim, prod);	st_pos = tuple2linear(n, st, prod);	offset = st_pos * bsize;	if (lo_lseek(srcfd, offset, SEEK_SET) < 0)		return;	mda_get_range(n, span, st, endp);	mda_get_offset_values(n, dist, prod, span);	for (i = 0; i < n; indx[i++] = 0);	for (i = n - 1, inc = bsize; i >= 0; inc *= span[i--])		if (dist[i])			break;	j = n - 1;	do	{		offset += (dist[j] * bsize);		if (lo_lseek(srcfd, offset, SEEK_SET) < 0)			return;		tmp = _LOtransfer((char **) &srcfd, inc, 1, (char **) &destfd, isSrcLO, 1);		if (tmp < inc)			return;		offset += inc;	} while ((j = next_tuple(i + 1, indx, span)) != -1);}static void_ReadArray(int *st,		   int *endp,		   int bsize,		   int srcfd,		   int destfd,		   ArrayType *array,		   int isDestLO,		   bool *isNull){	int			n,			   *dim,				st_pos,				prod[MAXDIM];	int			span[MAXDIM],				dist[MAXDIM],				indx[MAXDIM];	int			i,				j,				inc,				tmp,			   *lb,				offset;	n = ARR_NDIM(array);	dim = ARR_DIMS(array);	lb = ARR_LBOUND(array);	for (i = 0; i < n; st[i] -= lb[i], endp[i] -= lb[i], i++);	mda_get_prod(n, dim, prod);	st_pos = tuple2linear(n, st, prod);	offset = st_pos * bsize;	if (lo_lseek(srcfd, offset, SEEK_SET) < 0)		return;	mda_get_range(n, span, st, endp);	mda_get_offset_values(n, dist, prod, span);	for (i = 0; i < n; indx[i++] = 0);	for (i = n - 1, inc = bsize; i >= 0; inc *= span[i--])		if (dist[i])			break;	j = n - 1;	do	{		offset += (dist[j] * bsize);		if (lo_lseek(srcfd, offset, SEEK_SET) < 0)			return;		tmp = _LOtransfer((char **) &destfd, inc, 1, (char **) &srcfd, 1, isDestLO);		if (tmp < inc)			return;		offset += inc;	} while ((j = next_tuple(i + 1, indx, span)) != -1);}int_LOtransfer(char **destfd,			int size,			int nitems,			char **srcfd,			int isSrcLO,			int isDestLO){#define MAX_READ (512 * 1024)#define min(a, b) (a < b ? a : b)	struct varlena *v = NULL;	int			tmp,				inc,				resid;	inc = nitems * size;	if (isSrcLO && isDestLO && inc > 0)		for (tmp = 0, resid = inc;			 resid > 0 && (inc = min(resid, MAX_READ)) > 0; resid -= inc)		{#ifdef LOARRAY			v = (struct varlena *) LOread((int) *srcfd, inc);			if (VARSIZE(v) - VARHDRSZ < inc)			{				pfree(v);				return -1;			}			tmp += LOwrite((int) *destfd, v);#endif			pfree(v);		}	else if (!isSrcLO && isDestLO)	{		tmp = lo_write((int) *destfd, *srcfd, inc);		*srcfd = *srcfd + tmp;	}	else if (isSrcLO && !isDestLO)	{		tmp = lo_read((int) *srcfd, *destfd, inc);		*destfd = *destfd + tmp;	}	else	{		memmove(*destfd, *srcfd, inc);		tmp = inc;		*srcfd += inc;		*destfd += inc;	}	return tmp;#undef MAX_READ}char *_array_newLO(int *fd, int flag){	char	   *p;	char		saveName[NAME_LEN];	p = (char *) palloc(NAME_LEN);	sprintf(p, "/Arry.%u", newoid());	strcpy(saveName, p);#ifdef LOARRAY	if ((*fd = LOcreat(saveName, 0600, flag)) < 0)		elog(ERROR, "Large object create failed");#endif	return p;}

⌨️ 快捷键说明

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