common.c
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:11k
源码类别:

数据库系统

开发平台:

Unix_Linux

  1. /*-------------------------------------------------------------------------
  2.  *
  3.  * common.c
  4.  *   common routines between pg_dump and pg4_dump
  5.  *
  6.  * Copyright (c) 1994, Regents of the University of California
  7.  *
  8.  *
  9.  * IDENTIFICATION
  10.  *   $Header: /usr/local/cvsroot/pgsql/src/bin/pg_dump/common.c,v 1.32 1999/05/27 16:29:03 momjian Exp $
  11.  *
  12.  * Modifications - 6/12/96 - dave@bensoft.com - version 1.13.dhb.2
  13.  *
  14.  *  - Fixed dumpTable output to output lengths for char and varchar types!
  15.  *  - Added single. quote to twin single quote expansion for 'insert' string
  16.  *    mode.
  17.  *
  18.  *-------------------------------------------------------------------------
  19.  */
  20. #include <stdlib.h>
  21. #include <stdio.h>
  22. #include <string.h>
  23. #include <ctype.h>
  24. #include <sys/param.h> /* for MAXHOSTNAMELEN on most */
  25. #ifdef solaris_sparc
  26. #include <netdb.h> /* for MAXHOSTNAMELEN on some */
  27. #endif
  28. #include "postgres.h"
  29. #include "libpq-fe.h"
  30. #ifndef HAVE_STRDUP
  31. #include "strdup.h"
  32. #endif
  33. #include "pg_dump.h"
  34. static char **findParentsByOid(TableInfo *tbinfo, int numTables,
  35.  InhInfo *inhinfo, int numInherits,
  36.  const char *oid,
  37.  int *numParents);
  38. static int findTableByOid(TableInfo *tbinfo, int numTables, const char *oid);
  39. static void flagInhAttrs(TableInfo *tbinfo, int numTables,
  40.  InhInfo *inhinfo, int numInherits);
  41. static int strInArray(const char *pattern, char **arr, int arr_size);
  42. /*
  43.  * findTypeByOid
  44.  *   given an oid of a type, return its typename
  45.  *
  46.  * if oid is "0", return "opaque" -- this is a special case
  47.  *
  48.  * NOTE:  should hash this, but just do linear search for now
  49.  */
  50. char *
  51. findTypeByOid(TypeInfo *tinfo, int numTypes, const char *oid)
  52. {
  53. int i;
  54. if (strcmp(oid, "0") == 0)
  55. return g_opaque_type;
  56. for (i = 0; i < numTypes; i++)
  57. {
  58. if (strcmp(tinfo[i].oid, oid) == 0)
  59. return tinfo[i].typname;
  60. }
  61. /* should never get here */
  62. fprintf(stderr, "failed sanity check,  type with oid %s was not foundn",
  63. oid);
  64. exit(2);
  65. }
  66. /*
  67.  * findOprByOid
  68.  *   given the oid of an operator, return the name of the operator
  69.  *
  70.  *
  71.  * NOTE:  should hash this, but just do linear search for now
  72.  *
  73.  */
  74. char *
  75. findOprByOid(OprInfo *oprinfo, int numOprs, const char *oid)
  76. {
  77. int i;
  78. for (i = 0; i < numOprs; i++)
  79. {
  80. if (strcmp(oprinfo[i].oid, oid) == 0)
  81. return oprinfo[i].oprname;
  82. }
  83. /* should never get here */
  84. fprintf(stderr, "failed sanity check,  opr with oid %s was not foundn",
  85. oid);
  86. exit(2);
  87. }
  88. /*
  89.  * findParentsByOid
  90.  *   given the oid of a class, return the names of its parent classes
  91.  * and assign the number of parents to the last argument.
  92.  *
  93.  *
  94.  * returns NULL if none
  95.  */
  96. static char **
  97. findParentsByOid(TableInfo *tblinfo, int numTables,
  98.  InhInfo *inhinfo, int numInherits, const char *oid,
  99.  int *numParentsPtr)
  100. {
  101. int i,
  102. j;
  103. int parentInd,
  104. selfInd;
  105. char   **result;
  106. int numParents;
  107. numParents = 0;
  108. for (i = 0; i < numInherits; i++)
  109. {
  110. if (strcmp(inhinfo[i].inhrel, oid) == 0)
  111. numParents++;
  112. }
  113. *numParentsPtr = numParents;
  114. if (numParents > 0)
  115. {
  116. result = (char **) malloc(sizeof(char *) * numParents);
  117. j = 0;
  118. for (i = 0; i < numInherits; i++)
  119. {
  120. if (strcmp(inhinfo[i].inhrel, oid) == 0)
  121. {
  122. parentInd = findTableByOid(tblinfo, numTables,
  123.    inhinfo[i].inhparent);
  124. if (parentInd < 0)
  125. {
  126. selfInd = findTableByOid(tblinfo, numTables, oid);
  127. fprintf(stderr,
  128. "failed sanity check, parent oid %s of table %s (oid %s) was not foundn",
  129. inhinfo[i].inhparent,
  130.   (selfInd >= 0) ? tblinfo[selfInd].relname : "",
  131. oid);
  132. exit(2);
  133. }
  134. result[j++] = tblinfo[parentInd].relname;
  135. }
  136. }
  137. return result;
  138. }
  139. else
  140. return NULL;
  141. }
  142. /*
  143.  * parseArgTypes
  144.  *   parse a string of eight numbers delimited by spaces
  145.  * into a character array
  146.  */
  147. void
  148. parseArgTypes(char **argtypes, const char *str)
  149. {
  150. int j,
  151. argNum;
  152. char temp[100];
  153. char s;
  154. argNum = 0;
  155. j = 0;
  156. while ((s = *str) != '')
  157. {
  158. if (s == ' ')
  159. {
  160. temp[j] = '';
  161. argtypes[argNum] = strdup(temp);
  162. argNum++;
  163. j = 0;
  164. }
  165. else
  166. {
  167. temp[j] = s;
  168. j++;
  169. }
  170. str++;
  171. }
  172. if (j != 0)
  173. {
  174. temp[j] = '';
  175. argtypes[argNum] = strdup(temp);
  176. }
  177. }
  178. /*
  179.  * strInArray:
  180.  *   takes in a string and a string array and the number of elements in the
  181.  * string array.
  182.  *   returns the index if the string is somewhere in the array, -1 otherwise
  183.  *
  184.  */
  185. static int
  186. strInArray(const char *pattern, char **arr, int arr_size)
  187. {
  188. int i;
  189. for (i = 0; i < arr_size; i++)
  190. {
  191. if (strcmp(pattern, arr[i]) == 0)
  192. return i;
  193. }
  194. return -1;
  195. }
  196. /*
  197.  * dumpSchema:
  198.  *   we have a valid connection, we are now going to dump the schema
  199.  * into the file
  200.  *
  201.  */
  202. TableInfo  *
  203. dumpSchema(FILE *fout,
  204.    int *numTablesPtr,
  205.    const char *tablename,
  206.    const bool aclsSkip)
  207. {
  208. int numTypes;
  209. int numFuncs;
  210. int numTables;
  211. int numInherits;
  212. int numAggregates;
  213. int numOperators;
  214. TypeInfo   *tinfo = NULL;
  215. FuncInfo   *finfo = NULL;
  216. AggInfo    *agginfo = NULL;
  217. TableInfo  *tblinfo = NULL;
  218. InhInfo    *inhinfo = NULL;
  219. OprInfo    *oprinfo = NULL;
  220. if (g_verbose)
  221. fprintf(stderr, "%s reading user-defined types %sn",
  222. g_comment_start, g_comment_end);
  223. tinfo = getTypes(&numTypes);
  224. if (g_verbose)
  225. fprintf(stderr, "%s reading user-defined functions %sn",
  226. g_comment_start, g_comment_end);
  227. finfo = getFuncs(&numFuncs);
  228. if (g_verbose)
  229. fprintf(stderr, "%s reading user-defined aggregates %sn",
  230. g_comment_start, g_comment_end);
  231. agginfo = getAggregates(&numAggregates);
  232. if (g_verbose)
  233. fprintf(stderr, "%s reading user-defined operators %sn",
  234. g_comment_start, g_comment_end);
  235. oprinfo = getOperators(&numOperators);
  236. if (g_verbose)
  237. fprintf(stderr, "%s reading user-defined tables %sn",
  238. g_comment_start, g_comment_end);
  239. tblinfo = getTables(&numTables, finfo, numFuncs);
  240. if (g_verbose)
  241. fprintf(stderr, "%s reading table inheritance information %sn",
  242. g_comment_start, g_comment_end);
  243. inhinfo = getInherits(&numInherits);
  244. if (g_verbose)
  245. fprintf(stderr, "%s finding the attribute names and types for each table %sn",
  246. g_comment_start, g_comment_end);
  247. getTableAttrs(tblinfo, numTables);
  248. if (g_verbose)
  249. fprintf(stderr, "%s flagging inherited attributes in subtables %sn",
  250. g_comment_start, g_comment_end);
  251. flagInhAttrs(tblinfo, numTables, inhinfo, numInherits);
  252. if (!tablename && fout)
  253. {
  254. if (g_verbose)
  255. fprintf(stderr, "%s dumping out user-defined types %sn",
  256. g_comment_start, g_comment_end);
  257. dumpTypes(fout, finfo, numFuncs, tinfo, numTypes);
  258. }
  259. if (fout)
  260. {
  261. if (g_verbose)
  262. fprintf(stderr, "%s dumping out tables %sn",
  263. g_comment_start, g_comment_end);
  264. dumpTables(fout, tblinfo, numTables, inhinfo, numInherits,
  265.    tinfo, numTypes, tablename, aclsSkip);
  266. }
  267. if (!tablename && fout)
  268. {
  269. if (g_verbose)
  270. fprintf(stderr, "%s dumping out user-defined procedural languages %sn",
  271. g_comment_start, g_comment_end);
  272. dumpProcLangs(fout, finfo, numFuncs, tinfo, numTypes);
  273. }
  274. if (!tablename && fout)
  275. {
  276. if (g_verbose)
  277. fprintf(stderr, "%s dumping out user-defined functions %sn",
  278. g_comment_start, g_comment_end);
  279. dumpFuncs(fout, finfo, numFuncs, tinfo, numTypes);
  280. }
  281. if (!tablename && fout)
  282. {
  283. if (g_verbose)
  284. fprintf(stderr, "%s dumping out user-defined aggregates %sn",
  285. g_comment_start, g_comment_end);
  286. dumpAggs(fout, agginfo, numAggregates, tinfo, numTypes);
  287. }
  288. if (!tablename && fout)
  289. {
  290. if (g_verbose)
  291. fprintf(stderr, "%s dumping out user-defined operators %sn",
  292. g_comment_start, g_comment_end);
  293. dumpOprs(fout, oprinfo, numOperators, tinfo, numTypes);
  294. }
  295. *numTablesPtr = numTables;
  296. clearAggInfo(agginfo, numAggregates);
  297. clearOprInfo(oprinfo, numOperators);
  298. clearTypeInfo(tinfo, numTypes);
  299. clearFuncInfo(finfo, numFuncs);
  300. clearInhInfo(inhinfo, numInherits);
  301. return tblinfo;
  302. }
  303. /*
  304.  * dumpSchemaIdx:
  305.  *   dump indexes at the end for performance
  306.  *
  307.  */
  308. extern void
  309. dumpSchemaIdx(FILE *fout, const char *tablename,
  310.   TableInfo *tblinfo, int numTables)
  311. {
  312. int numIndices;
  313. IndInfo    *indinfo;
  314. if (g_verbose)
  315. fprintf(stderr, "%s reading indices information %sn",
  316. g_comment_start, g_comment_end);
  317. indinfo = getIndices(&numIndices);
  318. if (fout)
  319. {
  320. if (g_verbose)
  321. fprintf(stderr, "%s dumping out indices %sn",
  322. g_comment_start, g_comment_end);
  323. dumpIndices(fout, indinfo, numIndices, tblinfo, numTables, tablename);
  324. }
  325. clearIndInfo(indinfo, numIndices);
  326. }
  327. /* flagInhAttrs -
  328.  *  for each table in tblinfo, flag its inherited attributes
  329.  * so when we dump the table out, we don't dump out the inherited attributes
  330.  *
  331.  * initializes the parentRels field of each table
  332.  *
  333.  * modifies tblinfo
  334.  *
  335.  */
  336. static void
  337. flagInhAttrs(TableInfo *tblinfo, int numTables,
  338.  InhInfo *inhinfo, int numInherits)
  339. {
  340. int i,
  341. j,
  342. k;
  343. int parentInd;
  344. /*
  345.  * we go backwards because the tables in tblinfo are in OID order,
  346.  * meaning the subtables are after the parent tables we flag inherited
  347.  * attributes from child tables first
  348.  */
  349. for (i = numTables - 1; i >= 0; i--)
  350. {
  351. tblinfo[i].parentRels = findParentsByOid(tblinfo, numTables,
  352.  inhinfo, numInherits,
  353.  tblinfo[i].oid,
  354.  &tblinfo[i].numParents);
  355. for (k = 0; k < tblinfo[i].numParents; k++)
  356. {
  357. parentInd = findTableByName(tblinfo, numTables,
  358. tblinfo[i].parentRels[k]);
  359. if (parentInd < 0)
  360. {
  361. /* shouldn't happen unless findParentsByOid is broken */
  362. fprintf(stderr, "failed sanity check, table %s not found by flagInhAttrsn",
  363. tblinfo[i].parentRels[k]);
  364. exit(2);
  365. }
  366. for (j = 0; j < tblinfo[i].numatts; j++)
  367. {
  368. if (strInArray(tblinfo[i].attnames[j],
  369.    tblinfo[parentInd].attnames,
  370.    tblinfo[parentInd].numatts) != -1)
  371. tblinfo[i].inhAttrs[j] = 1;
  372. }
  373. }
  374. }
  375. }
  376. /*
  377.  * findTableByName
  378.  *   finds the index (in tblinfo) of the table with the given relname
  379.  * returns -1 if not found
  380.  *
  381.  * NOTE:  should hash this, but just do linear search for now
  382.  */
  383. int
  384. findTableByName(TableInfo *tblinfo, int numTables, const char *relname)
  385. {
  386. int i;
  387. for (i = 0; i < numTables; i++)
  388. {
  389. if (strcmp(tblinfo[i].relname, relname) == 0)
  390. return i;
  391. }
  392. return -1;
  393. }
  394. /*
  395.  * findTableByOid
  396.  *   finds the index (in tblinfo) of the table with the given oid
  397.  * returns -1 if not found
  398.  *
  399.  * NOTE:  should hash this, but just do linear search for now
  400.  */
  401. static int
  402. findTableByOid(TableInfo *tblinfo, int numTables, const char *oid)
  403. {
  404. int i;
  405. for (i = 0; i < numTables; i++)
  406. {
  407. if (strcmp(tblinfo[i].oid, oid) == 0)
  408. return i;
  409. }
  410. return -1;
  411. }
  412. /*
  413.  * findFuncByName
  414.  *   finds the index (in finfo) of the function with the given name
  415.  * returns -1 if not found
  416.  *
  417.  * NOTE:  should hash this, but just do linear search for now
  418.  */
  419. int
  420. findFuncByName(FuncInfo *finfo, int numFuncs, const char *name)
  421. {
  422. int i;
  423. for (i = 0; i < numFuncs; i++)
  424. {
  425. if (strcmp(finfo[i].proname, name) == 0)
  426. return i;
  427. }
  428. return -1;
  429. }
  430. /*
  431.  * fmtId
  432.  *
  433.  * checks input string for non-lowercase characters
  434.  * returns pointer to input string or string surrounded by double quotes
  435.  *
  436.  * Note that the returned string should be used immediately since it
  437.  * uses a static buffer to hold the string. Non-reentrant but faster?
  438.  */
  439. const char *
  440. fmtId(const char *rawid, bool force_quotes)
  441. {
  442. const char *cp;
  443. static char id[MAX_QUERY_SIZE];
  444. if (!force_quotes)
  445. for (cp = rawid; *cp != ''; cp++)
  446. if (!(islower(*cp) || isdigit(*cp) || (*cp == '_')))
  447. break;
  448. if (force_quotes || (*cp != ''))
  449. {
  450. strcpy(id, """);
  451. strcat(id, rawid);
  452. strcat(id, """);
  453. cp = id;
  454. }
  455. else
  456. cp = rawid;
  457. return cp;
  458. } /* fmtId() */