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

📄 tupdesc.c

📁 postgresql8.3.4源码,开源数据库
💻 C
📖 第 1 页 / 共 2 页
字号:
		 *		 * attcacheoff must NOT be checked since it's possibly not set in both		 * copies.		 */		if (strcmp(NameStr(attr1->attname), NameStr(attr2->attname)) != 0)			return false;		if (attr1->atttypid != attr2->atttypid)			return false;		if (attr1->attstattarget != attr2->attstattarget)			return false;		if (attr1->attlen != attr2->attlen)			return false;		if (attr1->attndims != attr2->attndims)			return false;		if (attr1->atttypmod != attr2->atttypmod)			return false;		if (attr1->attbyval != attr2->attbyval)			return false;		if (attr1->attstorage != attr2->attstorage)			return false;		if (attr1->attalign != attr2->attalign)			return false;		if (attr1->attnotnull != attr2->attnotnull)			return false;		if (attr1->atthasdef != attr2->atthasdef)			return false;		if (attr1->attisdropped != attr2->attisdropped)			return false;		if (attr1->attislocal != attr2->attislocal)			return false;		if (attr1->attinhcount != attr2->attinhcount)			return false;	}	if (tupdesc1->constr != NULL)	{		TupleConstr *constr1 = tupdesc1->constr;		TupleConstr *constr2 = tupdesc2->constr;		if (constr2 == NULL)			return false;		if (constr1->has_not_null != constr2->has_not_null)			return false;		n = constr1->num_defval;		if (n != (int) constr2->num_defval)			return false;		for (i = 0; i < n; i++)		{			AttrDefault *defval1 = constr1->defval + i;			AttrDefault *defval2 = constr2->defval;			/*			 * We can't assume that the items are always read from the system			 * catalogs in the same order; so use the adnum field to identify			 * the matching item to compare.			 */			for (j = 0; j < n; defval2++, j++)			{				if (defval1->adnum == defval2->adnum)					break;			}			if (j >= n)				return false;			if (strcmp(defval1->adbin, defval2->adbin) != 0)				return false;		}		n = constr1->num_check;		if (n != (int) constr2->num_check)			return false;		for (i = 0; i < n; i++)		{			ConstrCheck *check1 = constr1->check + i;			ConstrCheck *check2 = constr2->check;			/*			 * Similarly, don't assume that the checks are always read in the			 * same order; match them up by name and contents. (The name			 * *should* be unique, but...)			 */			for (j = 0; j < n; check2++, j++)			{				if (strcmp(check1->ccname, check2->ccname) == 0 &&					strcmp(check1->ccbin, check2->ccbin) == 0)					break;			}			if (j >= n)				return false;		}	}	else if (tupdesc2->constr != NULL)		return false;	return true;}/* * TupleDescInitEntry *		This function initializes a single attribute structure in *		a previously allocated tuple descriptor. */voidTupleDescInitEntry(TupleDesc desc,				   AttrNumber attributeNumber,				   const char *attributeName,				   Oid oidtypeid,				   int32 typmod,				   int attdim){	HeapTuple	tuple;	Form_pg_type typeForm;	Form_pg_attribute att;	/*	 * sanity checks	 */	AssertArg(PointerIsValid(desc));	AssertArg(attributeNumber >= 1);	AssertArg(attributeNumber <= desc->natts);	/*	 * initialize the attribute fields	 */	att = desc->attrs[attributeNumber - 1];	att->attrelid = 0;			/* dummy value */	/*	 * Note: attributeName can be NULL, because the planner doesn't always	 * fill in valid resname values in targetlists, particularly for resjunk	 * attributes.	 */	if (attributeName != NULL)		namestrcpy(&(att->attname), attributeName);	else		MemSet(NameStr(att->attname), 0, NAMEDATALEN);	att->attstattarget = -1;	att->attcacheoff = -1;	att->atttypmod = typmod;	att->attnum = attributeNumber;	att->attndims = attdim;	att->attnotnull = false;	att->atthasdef = false;	att->attisdropped = false;	att->attislocal = true;	att->attinhcount = 0;	tuple = SearchSysCache(TYPEOID,						   ObjectIdGetDatum(oidtypeid),						   0, 0, 0);	if (!HeapTupleIsValid(tuple))		elog(ERROR, "cache lookup failed for type %u", oidtypeid);	typeForm = (Form_pg_type) GETSTRUCT(tuple);	att->atttypid = oidtypeid;	att->attlen = typeForm->typlen;	att->attbyval = typeForm->typbyval;	att->attalign = typeForm->typalign;	att->attstorage = typeForm->typstorage;	ReleaseSysCache(tuple);}/* * BuildDescForRelation * * Given a relation schema (list of ColumnDef nodes), build a TupleDesc. * * Note: the default assumption is no OIDs; caller may modify the returned * TupleDesc if it wants OIDs.	Also, tdtypeid will need to be filled in * later on. */TupleDescBuildDescForRelation(List *schema){	int			natts;	AttrNumber	attnum;	ListCell   *l;	TupleDesc	desc;	AttrDefault *attrdef = NULL;	TupleConstr *constr = (TupleConstr *) palloc0(sizeof(TupleConstr));	char	   *attname;	Oid			atttypid;	int32		atttypmod;	int			attdim;	int			ndef = 0;	/*	 * allocate a new tuple descriptor	 */	natts = list_length(schema);	desc = CreateTemplateTupleDesc(natts, false);	constr->has_not_null = false;	attnum = 0;	foreach(l, schema)	{		ColumnDef  *entry = lfirst(l);		/*		 * for each entry in the list, get the name and type information from		 * the list and have TupleDescInitEntry fill in the attribute		 * information we need.		 */		attnum++;		attname = entry->colname;		atttypid = typenameTypeId(NULL, entry->typename, &atttypmod);		attdim = list_length(entry->typename->arrayBounds);		if (entry->typename->setof)			ereport(ERROR,					(errcode(ERRCODE_INVALID_TABLE_DEFINITION),					 errmsg("column \"%s\" cannot be declared SETOF",							attname)));		TupleDescInitEntry(desc, attnum, attname,						   atttypid, atttypmod, attdim);		/* Fill in additional stuff not handled by TupleDescInitEntry */		if (entry->is_not_null)			constr->has_not_null = true;		desc->attrs[attnum - 1]->attnotnull = entry->is_not_null;		/*		 * Note we copy only pre-cooked default expressions. Digestion of raw		 * ones is someone else's problem.		 */		if (entry->cooked_default != NULL)		{			if (attrdef == NULL)				attrdef = (AttrDefault *) palloc(natts * sizeof(AttrDefault));			attrdef[ndef].adnum = attnum;			attrdef[ndef].adbin = pstrdup(entry->cooked_default);			ndef++;			desc->attrs[attnum - 1]->atthasdef = true;		}		desc->attrs[attnum - 1]->attislocal = entry->is_local;		desc->attrs[attnum - 1]->attinhcount = entry->inhcount;	}	if (constr->has_not_null || ndef > 0)	{		desc->constr = constr;		if (ndef > 0)			/* DEFAULTs */		{			if (ndef < natts)				constr->defval = (AttrDefault *)					repalloc(attrdef, ndef * sizeof(AttrDefault));			else				constr->defval = attrdef;			constr->num_defval = ndef;		}		else		{			constr->defval = NULL;			constr->num_defval = 0;		}		constr->check = NULL;		constr->num_check = 0;	}	else	{		pfree(constr);		desc->constr = NULL;	}	return desc;}/* * BuildDescFromLists * * Build a TupleDesc given lists of column names (as String nodes), * column type OIDs, and column typmods.  No constraints are generated. * * This is essentially a cut-down version of BuildDescForRelation for use * with functions returning RECORD. */TupleDescBuildDescFromLists(List *names, List *types, List *typmods){	int			natts;	AttrNumber	attnum;	ListCell   *l1;	ListCell   *l2;	ListCell   *l3;	TupleDesc	desc;	natts = list_length(names);	Assert(natts == list_length(types));	Assert(natts == list_length(typmods));	/*	 * allocate a new tuple descriptor	 */	desc = CreateTemplateTupleDesc(natts, false);	attnum = 0;	l2 = list_head(types);	l3 = list_head(typmods);	foreach(l1, names)	{		char	   *attname = strVal(lfirst(l1));		Oid			atttypid;		int32		atttypmod;		atttypid = lfirst_oid(l2);		l2 = lnext(l2);		atttypmod = lfirst_int(l3);		l3 = lnext(l3);		attnum++;		TupleDescInitEntry(desc, attnum, attname, atttypid, atttypmod, 0);	}	return desc;}

⌨️ 快捷键说明

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