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

📄 copy.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
📖 第 1 页 / 共 3 页
字号:
		{			int32		null_ct = 0,						length;			for (i = 0; i < attr_count; i++)			{				if (nulls[i] == 'n')					null_ct++;			}			length = tuple->t_len - tuple->t_data->t_hoff;			CopySendData(&length, sizeof(int32), fp);			if (oids)				CopySendData((char *) &tuple->t_data->t_oid, sizeof(int32), fp);			CopySendData(&null_ct, sizeof(int32), fp);			if (null_ct > 0)			{				for (i = 0; i < attr_count; i++)				{					if (nulls[i] == 'n')					{						CopySendData(&i, sizeof(int32), fp);						nulls[i] = ' ';					}				}			}			CopySendData((char *) tuple->t_data + tuple->t_data->t_hoff,						 length, fp);		}	}	heap_endscan(scandesc);	if (binary)		pfree(nulls);	else	{		pfree(out_functions);		pfree(elements);		pfree(typmod);	}	heap_close(rel);}static voidCopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim){	HeapTuple	tuple;	AttrNumber	attr_count;	Form_pg_attribute *attr;	FmgrInfo   *in_functions;	int			i;	Oid			in_func_oid;	Datum	   *values;	char	   *nulls,			   *index_nulls;	bool	   *byval;	bool		isnull;	bool		has_index;	int			done = 0;	char	   *string = NULL,			   *ptr;	Relation   *index_rels;	int32		len,				null_ct,				null_id;	int32		ntuples,				tuples_read = 0;	bool		reading_to_eof = true;	Oid		   *elements;	int32	   *typmod;	FuncIndexInfo *finfo,			  **finfoP = NULL;	TupleDesc  *itupdescArr;	HeapTuple	pgIndexTup;	Form_pg_index *pgIndexP = NULL;	int		   *indexNatts = NULL;	char	   *predString;	Node	  **indexPred = NULL;	TupleDesc	rtupdesc;	ExprContext *econtext = NULL;	EState	   *estate = makeNode(EState);		/* for ExecConstraints() */#ifndef OMIT_PARTIAL_INDEX	TupleTable	tupleTable;	TupleTableSlot *slot = NULL;#endif	int			natts;	AttrNumber *attnumP;	Datum	   *idatum;	int			n_indices;	InsertIndexResult indexRes;	TupleDesc	tupDesc;	Oid			loaded_oid;	bool		skip_tuple = false;	tupDesc = RelationGetDescr(rel);	attr = tupDesc->attrs;	attr_count = tupDesc->natts;	has_index = false;	/*	 * This may be a scalar or a functional index.	We initialize all	 * kinds of arrays here to avoid doing extra work at every tuple copy.	 */	if (rel->rd_rel->relhasindex)	{		GetIndexRelations(RelationGetRelid(rel), &n_indices, &index_rels);		if (n_indices > 0)		{			has_index = true;			itupdescArr = (TupleDesc *) palloc(n_indices * sizeof(TupleDesc));			pgIndexP = (Form_pg_index *) palloc(n_indices * sizeof(Form_pg_index));			indexNatts = (int *) palloc(n_indices * sizeof(int));			finfo = (FuncIndexInfo *) palloc(n_indices * sizeof(FuncIndexInfo));			finfoP = (FuncIndexInfo **) palloc(n_indices * sizeof(FuncIndexInfo *));			indexPred = (Node **) palloc(n_indices * sizeof(Node *));			econtext = NULL;			for (i = 0; i < n_indices; i++)			{				itupdescArr[i] = RelationGetDescr(index_rels[i]);				pgIndexTup = SearchSysCacheTuple(INDEXRELID,					   ObjectIdGetDatum(RelationGetRelid(index_rels[i])),												 0, 0, 0);				Assert(pgIndexTup);				pgIndexP[i] = (Form_pg_index) GETSTRUCT(pgIndexTup);				for (attnumP = &(pgIndexP[i]->indkey[0]), natts = 0;				 natts < INDEX_MAX_KEYS && *attnumP != InvalidAttrNumber;					 attnumP++, natts++);				if (pgIndexP[i]->indproc != InvalidOid)				{					FIgetnArgs(&finfo[i]) = natts;					natts = 1;					FIgetProcOid(&finfo[i]) = pgIndexP[i]->indproc;					*(FIgetname(&finfo[i])) = '\0';					finfoP[i] = &finfo[i];				}				else					finfoP[i] = (FuncIndexInfo *) NULL;				indexNatts[i] = natts;				if (VARSIZE(&pgIndexP[i]->indpred) != 0)				{					predString = fmgr(F_TEXTOUT, &pgIndexP[i]->indpred);					indexPred[i] = stringToNode(predString);					pfree(predString);					/* make dummy ExprContext for use by ExecQual */					if (econtext == NULL)					{#ifndef OMIT_PARTIAL_INDEX						tupleTable = ExecCreateTupleTable(1);						slot = ExecAllocTableSlot(tupleTable);						econtext = makeNode(ExprContext);						econtext->ecxt_scantuple = slot;						rtupdesc = RelationGetDescr(rel);						slot->ttc_tupleDescriptor = rtupdesc;						/*						 * There's no buffer associated with heap tuples						 * here, so I set the slot's buffer to NULL.						 * Currently, it appears that the only way a						 * buffer could be needed would be if the partial						 * index predicate referred to the "lock" system						 * attribute.  If it did, then heap_getattr would						 * call HeapTupleGetRuleLock, which uses the						 * buffer's descriptor to get the relation id.						 * Rather than try to fix this, I'll just disallow						 * partial indexes on "lock", which wouldn't be						 * useful anyway. --Nels, Nov '92						 */						/* SetSlotBuffer(slot, (Buffer) NULL); */						/* SetSlotShouldFree(slot, false); */						slot->ttc_buffer = (Buffer) NULL;						slot->ttc_shouldFree = false;#endif	 /* OMIT_PARTIAL_INDEX */					}				}				else					indexPred[i] = NULL;			}		}	}	if (!binary)	{		in_functions = (FmgrInfo *) palloc(attr_count * sizeof(FmgrInfo));		elements = (Oid *) palloc(attr_count * sizeof(Oid));		typmod = (int32 *) palloc(attr_count * sizeof(int32));		for (i = 0; i < attr_count; i++)		{			in_func_oid = (Oid) GetInputFunction(attr[i]->atttypid);			fmgr_info(in_func_oid, &in_functions[i]);			elements[i] = GetTypeElement(attr[i]->atttypid);			typmod[i] = attr[i]->atttypmod;		}	}	else	{		in_functions = NULL;		elements = NULL;		typmod = NULL;		CopyGetData(&ntuples, sizeof(int32), fp);		if (ntuples != 0)			reading_to_eof = false;	}	values = (Datum *) palloc(sizeof(Datum) * attr_count);	nulls = (char *) palloc(attr_count);	index_nulls = (char *) palloc(attr_count);	idatum = (Datum *) palloc(sizeof(Datum) * attr_count);	byval = (bool *) palloc(attr_count * sizeof(bool));	for (i = 0; i < attr_count; i++)	{		nulls[i] = ' ';		index_nulls[i] = ' ';		byval[i] = (bool) IsTypeByVal(attr[i]->atttypid);	}	lineno = 0;	while (!done)	{		if (!binary)		{#ifdef COPY_PATCH			int			newline = 0;#endif			lineno++;			if (oids)			{#ifdef COPY_PATCH				string = CopyReadAttribute(fp, &isnull, delim, &newline);#else				string = CopyReadAttribute(fp, &isnull, delim);#endif				if (string == NULL)					done = 1;				else				{					loaded_oid = oidin(string);					if (loaded_oid < BootstrapObjectIdData)						elog(ERROR, "COPY TEXT: Invalid Oid. line: %d", lineno);				}			}			for (i = 0; i < attr_count && !done; i++)			{#ifdef COPY_PATCH				string = CopyReadAttribute(fp, &isnull, delim, &newline);#else				string = CopyReadAttribute(fp, &isnull, delim);#endif				if (isnull)				{					values[i] = PointerGetDatum(NULL);					nulls[i] = 'n';				}				else if (string == NULL)					done = 1;				else				{					values[i] = (Datum) (*fmgr_faddr(&in_functions[i])) (string,															 elements[i],															  typmod[i]);					/*					 * Sanity check - by reference attributes cannot					 * return NULL					 */					if (!PointerIsValid(values[i]) &&						!(rel->rd_att->attrs[i]->attbyval))						elog(ERROR, "copy from line %d: Bad file format", lineno);				}			}#ifdef COPY_PATCH			if (!done)				CopyReadNewline(fp, &newline);#endif		}		else		{						/* binary */			CopyGetData(&len, sizeof(int32), fp);			if (CopyGetEof(fp))				done = 1;			else			{				if (oids)				{					CopyGetData(&loaded_oid, sizeof(int32), fp);					if (loaded_oid < BootstrapObjectIdData)						elog(ERROR, "COPY BINARY: Invalid Oid line: %d", lineno);				}				CopyGetData(&null_ct, sizeof(int32), fp);				if (null_ct > 0)				{					for (i = 0; i < null_ct; i++)					{						CopyGetData(&null_id, sizeof(int32), fp);						nulls[null_id] = 'n';					}				}				string = (char *) palloc(len);				CopyGetData(string, len, fp);				ptr = string;				for (i = 0; i < attr_count; i++)				{					if (byval[i] && nulls[i] != 'n')					{						switch (attr[i]->attlen)						{							case sizeof(char):								values[i] = (Datum) *(unsigned char *) ptr;								ptr += sizeof(char);								break;							case sizeof(short):								ptr = (char *) SHORTALIGN(ptr);								values[i] = (Datum) *(unsigned short *) ptr;								ptr += sizeof(short);								break;							case sizeof(int32):								ptr = (char *) INTALIGN(ptr);								values[i] = (Datum) *(uint32 *) ptr;								ptr += sizeof(int32);								break;							default:								elog(ERROR, "COPY BINARY: impossible size! line: %d", lineno);								break;						}					}					else if (nulls[i] != 'n')					{						ptr = (char *) att_align(ptr, attr[i]->attlen, attr[i]->attalign);						values[i] = (Datum) ptr;						ptr = att_addlength(ptr, attr[i]->attlen, ptr);					}				}			}		}		if (done)			continue;		/*		 * Does it have any sence ? - vadim 12/14/96		 *		 * tupDesc = CreateTupleDesc(attr_count, attr);		 */		tuple = heap_formtuple(tupDesc, values, nulls);		if (oids)			tuple->t_data->t_oid = loaded_oid;		skip_tuple = false;		/* BEFORE ROW INSERT Triggers */		if (rel->trigdesc &&			rel->trigdesc->n_before_row[TRIGGER_EVENT_INSERT] > 0)		{			HeapTuple	newtuple;			newtuple = ExecBRInsertTriggers(rel, tuple);			if (newtuple == NULL)		/* "do nothing" */				skip_tuple = true;			else if (newtuple != tuple) /* modified by Trigger(s) */			{				pfree(tuple);				tuple = newtuple;			}		}		if (!skip_tuple)		{			/* ----------------			 * Check the constraints of a tuple			 * ----------------			 */			if (rel->rd_att->constr)				ExecConstraints("CopyFrom", rel, tuple, estate);			heap_insert(rel, tuple);			if (has_index)			{				for (i = 0; i < n_indices; i++)				{					if (indexPred[i] != NULL)					{#ifndef OMIT_PARTIAL_INDEX						/*						 * if tuple doesn't satisfy predicate, don't						 * update index						 */						slot->val = tuple;						/* SetSlotContents(slot, tuple); */						if (ExecQual((List *) indexPred[i], econtext) == false)							continue;#endif	 /* OMIT_PARTIAL_INDEX */					}					FormIndexDatum(indexNatts[i],								(AttrNumber *) &(pgIndexP[i]->indkey[0]),								   tuple,								   tupDesc,								   idatum,								   index_nulls,								   finfoP[i]);					indexRes = index_insert(index_rels[i], idatum, index_nulls,											&(tuple->t_self), rel);					if (indexRes)						pfree(indexRes);				}			}			/* AFTER ROW INSERT Triggers */			if (rel->trigdesc &&				rel->trigdesc->n_after_row[TRIGGER_EVENT_INSERT] > 0)				ExecARInsertTriggers(rel, tuple);		}		if (binary)			pfree(string);		for (i = 0; i < attr_count; i++)		{			if (!byval[i] && nulls[i] != 'n')			{				if (!binary)					pfree((void *) values[i]);			}			else if (nulls[i] == 'n')				nulls[i] = ' ';		}		pfree(tuple);		tuples_read++;		if (!reading_to_eof && ntuples == tuples_read)			done = true;	}	pfree(values);	pfree(nulls);	pfree(index_nulls);	pfree(idatum);	pfree(byval);	if (!binary)	{		pfree(in_functions);

⌨️ 快捷键说明

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