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

📄 portalbuf.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
字号:
/*------------------------------------------------------------------------- * * portalbuf.c *	  portal buffer support routines for src/libpq/portal.c * * Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION *	  $Header: /usr/local/cvsroot/pgsql/src/backend/libpq/portalbuf.c,v 1.16 1999/06/19 05:00:27 momjian Exp $ * *------------------------------------------------------------------------- *//* * INTERFACE ROUTINES *		pbuf_alloc		  - allocate memory for libpq routines *		pbuf_free		  - free memory for libpq routines *		pbuf_addPortal	  - Allocate a new portal buffer *		pbuf_addGroup	  - Add a new tuple group to the portal *		pbuf_addTypes	  - Allocate n type blocks *		pbuf_addTuples	  - Allocate a tuple block *		pbuf_addTuple	  - Allocate a tuple of n fields (attributes) *		pbuf_addValues	  - Allocate n bytes for a value *		pbuf_addEntry	  - Allocate a portal entry *		pbuf_freeEntry	  - Free a portal entry in the portal table *		pbuf_freeTypes	  - Free up the space used by a portal *		pbuf_freeTuples   - free space used by tuple block *		pbuf_freeGroup	  - free space used by group, types and tuples *		pbuf_freePortal   - free space used by portal and portal's group *		pbuf_getIndex	  - Return the index of the portal entry *		pbuf_setup		  - Set up a portal for dumping data *		pbuf_close		  - Close a portal, remove it from the portal table *		pbuf_findGroup	  - Return group given the group_index *		pbuf_findFnumber  - Return field index of a given field within a group *		pbuf_findFname	  - Find the field name given the field index *		pbuf_checkFnumber - signal an error if field number is out of bounds * * NOTES *		These functions may be used by both frontend routines which *		communicate with a backend or by user-defined functions which *		are compiled or dynamically loaded into a backend. * *		the portals[] array should be organized as a hash table for *		quick portal-by-name lookup. * *		Do not confuse "PortalEntry" (or "PortalBuffer") with "Portal" *		see utils/mmgr/portalmem.c for why. -cim 2/22/91 * */#include <string.h>#include <sys/types.h>#include <postgres.h>#include <libpq/libpq.h>		/* where the declarations go */#include <utils/exc.h>PortalEntry **portals = (PortalEntry **) NULL;size_t		portals_array_size = 0;/* portals array memory is palloc'd instead of using MemoryContexts *//* since it will be used by both front and backend programs*//*	GlobalMemory portals_mmcxt = (GlobalMemory) NULL;  *//* ------------------------------- * portals_realloc *	  grow the size of the portals array by size * *	  also ensures that elements are initially NULL */static voidportals_realloc(size_t size){	size_t		oldsize;	int			i;	PortalEntry **newp;	oldsize = portals_array_size;	portals_array_size += size;	if (portals)		newp = (PortalEntry **) realloc(portals,							 portals_array_size * sizeof(PortalEntry *));	else		newp = (PortalEntry **) palloc(portals_array_size * sizeof(PortalEntry *));	if (newp)		portals = newp;	else		libpq_raise(&PortalError,					vararg_format("Cannot alloc more memory in portals_realloc"));	for (i = oldsize; i < portals_array_size; i++)		portals[i] = (PortalEntry *) NULL;}/* -------------------------------- *		pbuf_alloc - allocate memory for portal buffers * *		remember: palloc() in the backend uses the postgres MemoryContext *		library and palloc() in the frontend (fe-pqstubs.c) calls malloc(). * -------------------------------- */caddr_tpbuf_alloc(size_t size){	caddr_t		addr;	if (size <= 0)		libpq_raise(&MemoryError, vararg_format("Invalid argument to pbuf_alloc()."));	addr = (caddr_t) palloc(size);	if (addr == (caddr_t) NULL)		libpq_raise(&MemoryError, vararg_format("Cannot Allocate space."));	return addr;}/* -------------------------------- *		pbuf_free - free memory for portal buffers * *		remember: pfree() in the backend uses the postgres MemoryContext *		library and pfree() in the frontend (fe-pqstubs.c) calls free(). * -------------------------------- */voidpbuf_free(caddr_t pointer){	if (pointer)		pfree(pointer);	else		libpq_raise(&MemoryError, vararg_format("Tried to free NULL memory pointer"));}/* -------------------------------- *		pbuf_addPortal - Allocate a new portal buffer * -------------------------------- */PortalBuffer *pbuf_addPortal(){	PortalBuffer *portal;	portal = (PortalBuffer *)		pbuf_alloc(sizeof(PortalBuffer));	portal->rule_p = 0;	portal->no_tuples = 0;	portal->no_groups = 0;	portal->groups = NULL;	return portal;}/* -------------------------------- *		pbuf_addGroup - Add a new tuple group to the portal * -------------------------------- */GroupBuffer *pbuf_addGroup(PortalBuffer *portal){	GroupBuffer *group,			   *group1;	group = (GroupBuffer *)		pbuf_alloc(sizeof(GroupBuffer));	/* Initialize the new group buffer. */	group->no_tuples = 0;	group->no_fields = 0;	group->types = NULL;	group->tuples = NULL;	group->next = NULL;	if ((group1 = portal->groups) == NULL)		portal->groups = group;	else	{		while (group1->next != NULL)			group1 = group1->next;		group1->next = group;	}	return group;}/* -------------------------------- *		pbuf_addTypes - Allocate n type blocks * -------------------------------- */TypeBlock  *pbuf_addTypes(int n){	TypeBlock  *types;	types = (TypeBlock *)		pbuf_alloc(n * sizeof(TypeBlock));	return types;}/* -------------------------------- *		pbuf_addTuples - Allocate a tuple block * -------------------------------- */TupleBlock *pbuf_addTuples(){	TupleBlock *tuples;	tuples = (TupleBlock *)		pbuf_alloc(sizeof(TupleBlock));	tuples->next = NULL;	tuples->tuple_index = 0;	return tuples;}/* -------------------------------- *		pbuf_addTuple - Allocate a tuple of n fields (attributes) * -------------------------------- */char	  **pbuf_addTuple(int n){	return (char **)	pbuf_alloc(n * sizeof(char *));}/* -------------------------------- *		pbuf_addTupleValueLengths - Allocate a tuple of n lengths (attributes) * -------------------------------- */int *pbuf_addTupleValueLengths(int n){	return (int *)	pbuf_alloc(n * sizeof(int));}/* -------------------------------- *		pbuf_addValues - Allocate n bytes for a value * -------------------------------- */char *pbuf_addValues(int n){	return pbuf_alloc(n);}/* -------------------------------- *		pbuf_addEntry - Allocate a portal entry * -------------------------------- */PortalEntry *pbuf_addEntry(){	return (PortalEntry *)	pbuf_alloc(sizeof(PortalEntry));}/* -------------------------------- *		pbuf_freeEntry - Free a portal entry in the portal table *		the portal is freed separately. * -------------------------------- */voidpbuf_freeEntry(int i){	if (portals)	{		pbuf_free((caddr_t) portals[i]);		portals[i] = NULL;	}}/* -------------------------------- *		pbuf_freeTypes - Free up the space used by a portal * -------------------------------- */voidpbuf_freeTypes(TypeBlock *types){	pbuf_free((caddr_t) types);}/* -------------------------------- *		pbuf_freeTuples - free space used by tuple block * -------------------------------- */voidpbuf_freeTuples(TupleBlock *tuples,				int no_tuples,				int no_fields){	int			i,				j;	if (no_tuples > TupleBlockSize)	{		pbuf_freeTuples(tuples->next, no_tuples - TupleBlockSize, no_fields);		no_tuples = TupleBlockSize;	}	/* For each tuple, free all its attribute values. */	for (i = 0; i < no_tuples; i++)	{		for (j = 0; j < no_fields; j++)			if (tuples->values[i][j] != NULL)				pbuf_free((caddr_t) tuples->values[i][j]);		if (tuples->lengths[i])			pbuf_free((caddr_t) tuples->lengths[i]);		if (tuples->values[i])			pbuf_free((caddr_t) tuples->values[i]);	}	pbuf_free((caddr_t) tuples);}/* -------------------------------- *		pbuf_freeGroup - free space used by group, types and tuples * -------------------------------- */voidpbuf_freeGroup(GroupBuffer *group){	if (group->next != NULL)		pbuf_freeGroup(group->next);	if (group->types != NULL)		pbuf_freeTypes(group->types);	if (group->tuples != NULL)		pbuf_freeTuples(group->tuples, group->no_tuples, group->no_fields);	pbuf_free((caddr_t) group);}/* -------------------------------- *		pbuf_freePortal - free space used by portal and portal's group * -------------------------------- */voidpbuf_freePortal(PortalBuffer *portal){	if (portal->groups != NULL)		pbuf_freeGroup(portal->groups);	pbuf_free((caddr_t) portal);}/* -------------------------------- *		pbuf_getIndex - Return the index of the portal entry *		note: portals[] maps portal names to portal buffers. * -------------------------------- */intpbuf_getIndex(char *pname){	int			i;	if (portals)	{		for (i = 0; i < portals_array_size; i++)			if (portals[i] != NULL &&				strncmp(portals[i]->name, pname, PortalNameLength) == 0)				return i;	}	return -1;}/* -------------------------------- *		pbuf_setportalname - assign a user given name to a portal * -------------------------------- */voidpbuf_setportalinfo(PortalEntry *entry, char *pname){	if (entry)		StrNCpy(entry->name, pname, PortalNameLength);}/* -------------------------------- *		pbuf_setup - Set up a portal for dumping data * -------------------------------- */PortalEntry *pbuf_setup(char *pname){	int			i;	if (!portals)				/* the portals array has not been								 * allocated yet */	{		/* allocate portals[] array here */		portals_realloc(PORTALS_INITIAL_SIZE);	}	/* If a portal with the same name already exists, close it. */	/* else look for an empty entry in the portal table. */	if ((i = pbuf_getIndex(pname)) != -1)		pbuf_freePortal(portals[i]->portal);	else	{		for (i = 0; i < portals_array_size; i++)			if (portals[i] == NULL)				break;		/* If the portal table is full, enlarge it */		if (i >= portals_array_size)			portals_realloc(PORTALS_GROW_BY);		portals[i] = pbuf_addEntry();		strncpy(portals[i]->name, pname, PortalNameLength);	}	portals[i]->portal = pbuf_addPortal();	portals[i]->portalcxt = NULL;	portals[i]->result = NULL;	return portals[i];}/* -------------------------------- *		pbuf_close - Close a portal, remove it from the portal table *						and free up the space * -------------------------------- */voidpbuf_close(char *pname){	int			i;	if ((i = pbuf_getIndex(pname)) == -1)		libpq_raise(&PortalError, vararg_format("Portal %s does not exist.", pname));	pbuf_freePortal(portals[i]->portal);	pbuf_freeEntry(i);}/* -------------------------------- *		pbuf_findGroup - Return the group given the group_index * -------------------------------- */GroupBuffer *pbuf_findGroup(PortalBuffer *portal,			   int group_index){	GroupBuffer *group;	group = portal->groups;	while (group_index > 0 && group != NULL)	{		group = group->next;		group_index--;	}	if (group == NULL)		libpq_raise(&PortalError,					vararg_format("Group index %d out of bound.", group_index));	return group;}/* -------------------------------- * pbuf_findFnumber - Return the field index of a given field within a group * -------------------------------- */intpbuf_findFnumber(GroupBuffer *group,				 char *field_name){	TypeBlock  *types;	int			i;	types = group->types;	for (i = 0; i < group->no_fields; i++)		if (strncmp(types[i].name, field_name, NAMEDATALEN) == 0)			return i;	libpq_raise(&PortalError,				vararg_format("Field-name %s does not exist.", field_name));	/* not reached, here to make compiler happy */	return 0;}/* -------------------------------- *		pbuf_checkFnumber - signal an error if field number is out of bounds * -------------------------------- */voidpbuf_checkFnumber(GroupBuffer *group,				  int field_number){	if (field_number < 0 || field_number >= group->no_fields)		libpq_raise(&PortalError,					vararg_format("Field number %d out of bound.", field_number));}/* -------------------------------- *		pbuf_findFname - Find the field name given the field index * -------------------------------- */char *pbuf_findFname(GroupBuffer *group,			   int field_number){	pbuf_checkFnumber(group, field_number);	return (group->types[field_number]).name;}

⌨️ 快捷键说明

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