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

📄 pg_dump.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
📖 第 1 页 / 共 5 页
字号:
						i_tgnargs,						i_tgargs;			int			ntups2;			int			i2;			if (g_verbose)				fprintf(stderr, "%s finding Triggers for relation: '%s' %s\n",						g_comment_start,						tblinfo[i].relname,						g_comment_end);			sprintf(query, "SELECT tgname, tgfoid, tgtype, tgnargs, tgargs "					"from pg_trigger "					"where tgrelid = '%s'::oid ",					tblinfo[i].oid);			res2 = PQexec(g_conn, query);			if (!res2 ||				PQresultStatus(res2) != PGRES_TUPLES_OK)			{				fprintf(stderr, "getTables(): SELECT (for TRIGGER) failed.  Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));				exit_nicely(g_conn);			}			ntups2 = PQntuples(res2);			if (ntups2 != tblinfo[i].ntrig)			{				fprintf(stderr, "getTables(): relation '%s': %d Triggers were expected, but got %d\n",						tblinfo[i].relname, tblinfo[i].ntrig, ntups2);				exit_nicely(g_conn);			}			i_tgname = PQfnumber(res2, "tgname");			i_tgfoid = PQfnumber(res2, "tgfoid");			i_tgtype = PQfnumber(res2, "tgtype");			i_tgnargs = PQfnumber(res2, "tgnargs");			i_tgargs = PQfnumber(res2, "tgargs");			tblinfo[i].triggers = (char **) malloc(ntups2 * sizeof(char *));			for (i2 = 0, query[0] = 0; i2 < ntups2; i2++)			{				char	   *tgfunc = PQgetvalue(res2, i2, i_tgfoid);				int2		tgtype = atoi(PQgetvalue(res2, i2, i_tgtype));				int			tgnargs = atoi(PQgetvalue(res2, i2, i_tgnargs));				char	   *tgargs = PQgetvalue(res2, i2, i_tgargs);				char	   *p;				char		farg[MAX_QUERY_SIZE];				int			findx;				for (findx = 0; findx < numFuncs; findx++)				{					if (strcmp(finfo[findx].oid, tgfunc) == 0 &&						finfo[findx].nargs == 0 &&						strcmp(finfo[findx].prorettype, "0") == 0)						break;				}				if (findx == numFuncs)				{					fprintf(stderr, "getTables(): relation '%s': cannot find function with oid %s for trigger %s\n",							tblinfo[i].relname, tgfunc, PQgetvalue(res2, i2, i_tgname));					exit_nicely(g_conn);				}				tgfunc = finfo[findx].proname;#if 0				/* XXX - how to emit this DROP TRIGGER? */				if (dropSchema)				{					sprintf(query, "DROP TRIGGER %s ON %s;\n",					 fmtId(PQgetvalue(res2, i2, i_tgname), force_quotes),							fmtId(tblinfo[i].relname, force_quotes));					fputs(query, fout);				}#endif				sprintf(query, "CREATE TRIGGER %s ", fmtId(PQgetvalue(res2, i2, i_tgname), force_quotes));				/* Trigger type */				findx = 0;				if (TRIGGER_FOR_BEFORE(tgtype))					strcat(query, "BEFORE");				else					strcat(query, "AFTER");				if (TRIGGER_FOR_INSERT(tgtype))				{					strcat(query, " INSERT");					findx++;				}				if (TRIGGER_FOR_DELETE(tgtype))				{					if (findx > 0)						strcat(query, " OR DELETE");					else						strcat(query, " DELETE");					findx++;				}				if (TRIGGER_FOR_UPDATE(tgtype))				{					if (findx > 0)						strcat(query, " OR UPDATE");					else						strcat(query, " UPDATE");				}				sprintf(query, "%s ON %s FOR EACH ROW EXECUTE PROCEDURE %s (",				 query, fmtId(tblinfo[i].relname, force_quotes), tgfunc);				for (findx = 0; findx < tgnargs; findx++)				{					char	   *s,							   *d;					for (p = tgargs;;)					{						p = strchr(p, '\\');						if (p == NULL)						{							fprintf(stderr, "getTables(): relation '%s': bad argument string (%s) for trigger '%s'\n",									tblinfo[i].relname,									PQgetvalue(res2, i2, i_tgargs),									PQgetvalue(res2, i2, i_tgname));							exit_nicely(g_conn);						}						p++;						if (*p == '\\')						{							p++;							continue;						}						if (p[0] == '0' && p[1] == '0' && p[2] == '0')							break;					}					p--;					for (s = tgargs, d = &(farg[0]); s < p;)					{						if (*s == '\'')							*d++ = '\\';						*d++ = *s++;					}					*d = 0;					sprintf(query, "%s'%s'%s", query, farg,							(findx < tgnargs - 1) ? ", " : "");					tgargs = p + 4;				}				strcat(query, ");\n");				tblinfo[i].triggers[i2] = strdup(query);			}			PQclear(res2);		}		else			tblinfo[i].triggers = NULL;	}	PQclear(res);	return tblinfo;}/* * getInherits *	  read all the inheritance information * from the system catalogs return them in the InhInfo* structure * * numInherits is set to the number of tables read in * * */InhInfo    *getInherits(int *numInherits){	PGresult   *res;	int			ntups;	int			i;	char		query[MAX_QUERY_SIZE];	InhInfo    *inhinfo;	int			i_inhrel;	int			i_inhparent;	/* find all the inheritance information */	sprintf(query, "SELECT inhrel, inhparent from pg_inherits");	res = PQexec(g_conn, query);	if (!res ||		PQresultStatus(res) != PGRES_TUPLES_OK)	{		fprintf(stderr, "getInherits(): SELECT failed.  Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));		exit_nicely(g_conn);	}	ntups = PQntuples(res);	*numInherits = ntups;	inhinfo = (InhInfo *) malloc(ntups * sizeof(InhInfo));	i_inhrel = PQfnumber(res, "inhrel");	i_inhparent = PQfnumber(res, "inhparent");	for (i = 0; i < ntups; i++)	{		inhinfo[i].inhrel = strdup(PQgetvalue(res, i, i_inhrel));		inhinfo[i].inhparent = strdup(PQgetvalue(res, i, i_inhparent));	}	PQclear(res);	return inhinfo;}/* * getTableAttrs - *	  for each table in tblinfo, read its attributes types and names * * this is implemented in a very inefficient way right now, looping * through the tblinfo and doing a join per table to find the attrs and their * types * *	modifies tblinfo */voidgetTableAttrs(TableInfo *tblinfo, int numTables){	int			i,				j;	char		q[MAX_QUERY_SIZE];	int			i_attname;	int			i_typname;	int			i_atttypmod;	int			i_attnotnull;	int			i_atthasdef;	PGresult   *res;	int			ntups;	for (i = 0; i < numTables; i++)	{		if (tblinfo[i].sequence)			continue;		/* find all the user attributes and their types */		/* we must read the attribute names in attribute number order! */		/*		 * because we will use the attnum to index into the attnames array		 * later		 */		if (g_verbose)			fprintf(stderr, "%s finding the attrs and types for table: '%s' %s\n",					g_comment_start,					tblinfo[i].relname,					g_comment_end);		sprintf(q, "SELECT a.attnum, a.attname, t.typname, a.atttypmod, "				"a.attnotnull, a.atthasdef "				"from pg_attribute a, pg_type t "				"where a.attrelid = '%s'::oid and a.atttypid = t.oid "				"and a.attnum > 0 order by attnum",				tblinfo[i].oid);		res = PQexec(g_conn, q);		if (!res ||			PQresultStatus(res) != PGRES_TUPLES_OK)		{			fprintf(stderr, "getTableAttrs(): SELECT failed.  Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));			exit_nicely(g_conn);		}		ntups = PQntuples(res);		i_attname = PQfnumber(res, "attname");		i_typname = PQfnumber(res, "typname");		i_atttypmod = PQfnumber(res, "atttypmod");		i_attnotnull = PQfnumber(res, "attnotnull");		i_atthasdef = PQfnumber(res, "atthasdef");		tblinfo[i].numatts = ntups;		tblinfo[i].attnames = (char **) malloc(ntups * sizeof(char *));		tblinfo[i].typnames = (char **) malloc(ntups * sizeof(char *));		tblinfo[i].atttypmod = (int *) malloc(ntups * sizeof(int));		tblinfo[i].inhAttrs = (int *) malloc(ntups * sizeof(int));		tblinfo[i].notnull = (bool *) malloc(ntups * sizeof(bool));		tblinfo[i].adef_expr = (char **) malloc(ntups * sizeof(char *));		tblinfo[i].parentRels = NULL;		tblinfo[i].numParents = 0;		for (j = 0; j < ntups; j++)		{			tblinfo[i].attnames[j] = strdup(PQgetvalue(res, j, i_attname));			tblinfo[i].typnames[j] = strdup(PQgetvalue(res, j, i_typname));			tblinfo[i].atttypmod[j] = atoi(PQgetvalue(res, j, i_atttypmod));			tblinfo[i].inhAttrs[j] = 0; /* this flag is set in										 * flagInhAttrs() */			tblinfo[i].notnull[j] = (PQgetvalue(res, j, i_attnotnull)[0] == 't') ? true : false;			if (PQgetvalue(res, j, i_atthasdef)[0] == 't')			{				PGresult   *res2;				if (g_verbose)					fprintf(stderr, "%s finding DEFAULT expression for attr: '%s' %s\n",							g_comment_start,							tblinfo[i].attnames[j],							g_comment_end);				sprintf(q, "SELECT adsrc from pg_attrdef "						"where adrelid = '%s'::oid and adnum = %d ",						tblinfo[i].oid, j + 1);				res2 = PQexec(g_conn, q);				if (!res2 ||					PQresultStatus(res2) != PGRES_TUPLES_OK)				{					fprintf(stderr, "getTableAttrs(): SELECT (for DEFAULT) failed.  Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));					exit_nicely(g_conn);				}				tblinfo[i].adef_expr[j] = strdup(PQgetvalue(res2, 0, PQfnumber(res2, "adsrc")));				PQclear(res2);			}			else				tblinfo[i].adef_expr[j] = NULL;		}		PQclear(res);	}}/* * getIndices *	  read all the user-defined indices information * from the system catalogs return them in the InhInfo* structure * * numIndices is set to the number of indices read in * * */IndInfo    *getIndices(int *numIndices){	int			i;	char		query[MAX_QUERY_SIZE];	PGresult   *res;	int			ntups;	IndInfo    *indinfo;	int			i_indexrelname;	int			i_indrelname;	int			i_indamname;	int			i_indproc;	int			i_indkey;	int			i_indclass;	int			i_indisunique;	/*	 * find all the user-defined indices. We do not handle partial	 * indices.	 *	 * Notice we skip indices on inversion objects (relkind 'l')	 *	 * this is a 4-way join !!	 */	sprintf(query,		  "SELECT t1.relname as indexrelname, t2.relname as indrelname, "			"i.indproc, i.indkey, i.indclass, "			"a.amname as indamname, i.indisunique "			"from pg_index i, pg_class t1, pg_class t2, pg_am a "			"where t1.oid = i.indexrelid and t2.oid = i.indrelid "			"and t1.relam = a.oid and i.indexrelid > '%u'::oid "			"and t2.relname !~ '^pg_' and t2.relkind != 'l'",			g_last_builtin_oid);	res = PQexec(g_conn, query);	if (!res ||		PQresultStatus(res) != PGRES_TUPLES_OK)	{		fprintf(stderr, "getIndices(): SELECT failed.  Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));		exit_nicely(g_conn);	}	ntups = PQntuples(res);	*numIndices = ntups;	indinfo = (IndInfo *) malloc(ntups * sizeof(IndInfo));	i_indexrelname = PQfnumber(res, "indexrelname");	i_indrelname = PQfnumber(res, "indrelname");	i_indamname = PQfnumber(res, "indamname");	i_indproc = PQfnumber(res, "indproc");	i_indkey = PQfnumber(res, "indkey");	i_indclass = PQfnumber(res, "indclass");	i_indisunique = PQfnumber(res, "indisunique");	for (i = 0; i < ntups; i++)	{		indinfo[i].indexrelname = strdup(PQgetvalue(res, i, i_indexrelname));		indinfo[i].indrelname = strdup(PQgetvalue(res, i, i_indrelname));		indinfo[i].indamname = strdup(PQgetvalue(res, i, i_indamname));		indinfo[i].indproc = strdup(PQgetvalue(res, i, i_indproc));		parseArgTypes((char **) indinfo[i].indkey,					  (const char *) PQgetvalue(res, i, i_indkey));		parseArgTypes((char **) indinfo[i].indclass,					  (const char *) PQgetvalue(res, i, i_indclass));		indinfo[i].indisunique = strdup(PQgetvalue(res, i, i_indisunique));	}	PQclear(res);	return indinfo;}/* * dumpTypes *	  writes out to fout the queries to recreate all the user-defined types * */voiddumpTypes(FILE *fout, FuncInfo *finfo, int numFuncs,		  TypeInfo *tinfo, int numTypes){	int			i;	char		q[MAX_QUERY_SIZE];	int			funcInd;	for (i = 0; i < numTypes; i++)	{		/* skip all the builtin types */		if (atoi(tinfo[i].oid) < g_last_builtin_oid)			continue;		/* skip relation types */		if (atoi(tinfo[i].typrelid) != 0)			continue;		/* skip all array types that start w/ underscore */		if ((tinfo[i].typname[0] == '_') &&			(strcmp(tinfo[i].typinput, "array_in") == 0))			continue;		/*		 * before we create a type, we need to create the input and output		 * functions for it, if they haven't been created already		 */		funcInd = findFuncByName(finfo, numFuncs, tinfo[i].typinput);		if (funcInd != -1)			dumpOneFunc(fout, finfo, funcInd, tinfo, numTypes);		funcInd = findFuncByName(finfo, numFuncs, tinfo[i].typoutput);		if (funcInd != -1)			dumpOneFunc(fout, finfo, funcInd, tinfo, numTypes);		becomeUser(fout, tinfo[i].usename);		if (dropSchema)		{			sprintf(q, "DROP TYPE %s;\n", fmtId(tinfo[i].typname, force_quotes));			fputs(q, fout);		}		sprintf(q,				"CREATE TYPE %s "				"( internallength = %s, externallength = %s, input = %s, "				"output = %s, send = %s, receive = %s, default = '%s'",				fmtId(tinfo[i].typname, force_quotes),				tinfo[i].typlen,				tinfo[i].typprtlen,				tinfo[i].typinput,				tinfo[i].typoutput,				tinfo[i].typsend,				tinfo[i].typreceive,				tinfo[i].typdefault);		if (tinfo[i].isArray)		{			char	   *elemType;			elemType = findTypeByOid(tinfo, numTypes, tinfo[i].typelem);			sprintf(q, "%s, element = %s, delimiter = '%s'",					q, elemType, tinfo[i].typdelim);		}		if (tinfo[i].passedbyvalue)			strcat(q, ",passedbyvalue);\n");		else			strcat(q, ");\n");		fputs(q, fout);	}}/* * dumpProcLangs *		  writes out to fout the queries to recreate user-defined procedural languages * */voiddumpProcLangs(FILE *fout, FuncInfo *finfo, int numFuncs,			  TypeInfo *tinfo, int numTypes){	PGresult   *res;	char		query[MAX_QUERY_SIZE];	int			ntups;	int			i_lanname;	int			i_lanpltrusted;	int			i_lanplcallfoid;	int			i_lancompiler;	char	   *lanname;	char	   *lancompiler;	char	   *lanplcallfoid;	int			i,				fidx;	sprintf(query, "SELECT * FROM pg_language "			"WHERE lanispl "			"ORDER BY oid");	res = PQexec(g_conn, query);	if (!res ||		PQresultStatus(res) != PGRES_TUPLES_OK)	{		fprintf(stderr, "dumpProcLangs(): SELECT failed.  Explanation from backend: '%s'.\n", PQerrorMessage(g_conn));		exit_nicely(g_conn);	}	ntups = PQntuples(res);	i_lanname = PQfnumber(res, "lanname");	i_lanpltrusted = PQfnumber(res, "lanpltrusted");	i_lanplcallfoid = PQfnumber(res, "lanplcallfoid");	i_lancompiler = PQfnumber(res, "lancompiler");	for (i = 0; i < ntups; i++)	{		lanplcallfoid = PQgetvalue(res, i, i_lanplcallfoid);		for (fidx = 0; fidx < numFuncs; fidx++)		{			if (!strcmp(finfo[fidx].oid, lanplcallfoid))

⌨️ 快捷键说明

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