1996-07-09 08:22:35 +02:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
*
|
1999-02-14 00:22:53 +01:00
|
|
|
* common.c
|
1997-09-07 07:04:48 +02:00
|
|
|
* common routines between pg_dump and pg4_dump
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
2002-05-11 00:36:27 +02:00
|
|
|
* Since pg4_dump is long-dead code, there is no longer any useful distinction
|
|
|
|
* between this file and pg_dump.c.
|
|
|
|
*
|
2003-08-04 04:40:20 +02:00
|
|
|
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
2000-01-26 06:58:53 +01:00
|
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
*
|
|
|
|
* IDENTIFICATION
|
2003-11-21 23:32:49 +01:00
|
|
|
* $Header: /cvsroot/pgsql/src/bin/pg_dump/common.c,v 1.76 2003/11/21 22:32:49 tgl Exp $
|
2000-09-15 06:35:16 +02:00
|
|
|
*
|
1996-07-09 08:22:35 +02:00
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
|
2001-06-27 23:21:37 +02:00
|
|
|
#include "postgres_fe.h"
|
2001-02-10 03:31:31 +01:00
|
|
|
#include "pg_dump.h"
|
2001-06-27 23:21:37 +02:00
|
|
|
#include "pg_backup_archiver.h"
|
2002-04-24 04:44:19 +02:00
|
|
|
#include "postgres.h"
|
|
|
|
#include "catalog/pg_class.h"
|
1996-07-09 08:22:35 +02:00
|
|
|
|
1997-10-30 17:48:03 +01:00
|
|
|
#include <ctype.h>
|
1996-07-09 08:22:35 +02:00
|
|
|
|
|
|
|
#include "libpq-fe.h"
|
1997-02-13 09:32:20 +01:00
|
|
|
#ifndef HAVE_STRDUP
|
1996-11-26 08:39:11 +01:00
|
|
|
#include "strdup.h"
|
|
|
|
#endif
|
1996-07-09 08:22:35 +02:00
|
|
|
|
2002-05-11 00:36:27 +02:00
|
|
|
static void findParentsByOid(TableInfo *tblinfo, int numTables,
|
2002-09-04 22:31:48 +02:00
|
|
|
InhInfo *inhinfo, int numInherits,
|
|
|
|
const char *oid,
|
|
|
|
int *numParentsPtr, int **parentIndexes);
|
2002-05-11 00:36:27 +02:00
|
|
|
static void flagInhTables(TableInfo *tbinfo, int numTables,
|
2002-09-04 22:31:48 +02:00
|
|
|
InhInfo *inhinfo, int numInherits);
|
1998-09-01 06:40:42 +02:00
|
|
|
static void flagInhAttrs(TableInfo *tbinfo, int numTables,
|
1997-09-08 23:56:23 +02:00
|
|
|
InhInfo *inhinfo, int numInherits);
|
1997-09-08 04:41:22 +02:00
|
|
|
static int strInArray(const char *pattern, char **arr, int arr_size);
|
1997-08-19 23:40:56 +02:00
|
|
|
|
1996-07-09 08:22:35 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* dumpSchema:
|
1997-09-07 07:04:48 +02:00
|
|
|
* we have a valid connection, we are now going to dump the schema
|
1996-07-09 08:22:35 +02:00
|
|
|
* into the file
|
|
|
|
*/
|
|
|
|
|
2001-10-25 07:50:21 +02:00
|
|
|
TableInfo *
|
2001-03-22 05:01:46 +01:00
|
|
|
dumpSchema(Archive *fout,
|
|
|
|
int *numTablesPtr,
|
|
|
|
const bool aclsSkip,
|
|
|
|
const bool schemaOnly,
|
|
|
|
const bool dataOnly)
|
1996-07-09 08:22:35 +02:00
|
|
|
{
|
2002-05-11 00:36:27 +02:00
|
|
|
int numNamespaces;
|
1997-09-08 04:41:22 +02:00
|
|
|
int numTypes;
|
|
|
|
int numFuncs;
|
|
|
|
int numTables;
|
|
|
|
int numInherits;
|
|
|
|
int numAggregates;
|
|
|
|
int numOperators;
|
2002-07-30 23:56:04 +02:00
|
|
|
int numOpclasses;
|
2003-11-21 23:32:49 +01:00
|
|
|
int numConversions;
|
2002-05-11 00:36:27 +02:00
|
|
|
NamespaceInfo *nsinfo;
|
|
|
|
TypeInfo *tinfo;
|
|
|
|
FuncInfo *finfo;
|
|
|
|
AggInfo *agginfo;
|
|
|
|
TableInfo *tblinfo;
|
|
|
|
InhInfo *inhinfo;
|
|
|
|
OprInfo *oprinfo;
|
2002-07-30 23:56:04 +02:00
|
|
|
OpclassInfo *opcinfo;
|
2003-11-21 23:32:49 +01:00
|
|
|
ConvInfo *convinfo;
|
2002-05-11 00:36:27 +02:00
|
|
|
|
|
|
|
if (g_verbose)
|
2003-07-23 10:47:41 +02:00
|
|
|
write_msg(NULL, "reading schemas\n");
|
2002-05-11 00:36:27 +02:00
|
|
|
nsinfo = getNamespaces(&numNamespaces);
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
if (g_verbose)
|
2001-07-03 22:21:50 +02:00
|
|
|
write_msg(NULL, "reading user-defined types\n");
|
1997-09-07 07:04:48 +02:00
|
|
|
tinfo = getTypes(&numTypes);
|
|
|
|
|
|
|
|
if (g_verbose)
|
2001-07-03 22:21:50 +02:00
|
|
|
write_msg(NULL, "reading user-defined functions\n");
|
1997-09-07 07:04:48 +02:00
|
|
|
finfo = getFuncs(&numFuncs);
|
|
|
|
|
|
|
|
if (g_verbose)
|
2001-07-03 22:21:50 +02:00
|
|
|
write_msg(NULL, "reading user-defined aggregate functions\n");
|
1997-09-07 07:04:48 +02:00
|
|
|
agginfo = getAggregates(&numAggregates);
|
|
|
|
|
|
|
|
if (g_verbose)
|
2001-07-03 22:21:50 +02:00
|
|
|
write_msg(NULL, "reading user-defined operators\n");
|
1997-09-07 07:04:48 +02:00
|
|
|
oprinfo = getOperators(&numOperators);
|
|
|
|
|
2002-07-30 23:56:04 +02:00
|
|
|
if (g_verbose)
|
|
|
|
write_msg(NULL, "reading user-defined operator classes\n");
|
|
|
|
opcinfo = getOpclasses(&numOpclasses);
|
|
|
|
|
2003-11-21 23:32:49 +01:00
|
|
|
if (g_verbose)
|
|
|
|
write_msg(NULL, "reading user-defined conversions\n");
|
|
|
|
convinfo = getConversions(&numConversions);
|
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
if (g_verbose)
|
2001-07-03 22:21:50 +02:00
|
|
|
write_msg(NULL, "reading user-defined tables\n");
|
2002-05-11 00:36:27 +02:00
|
|
|
tblinfo = getTables(&numTables);
|
2001-01-12 16:41:29 +01:00
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
if (g_verbose)
|
2001-07-03 22:21:50 +02:00
|
|
|
write_msg(NULL, "reading table inheritance information\n");
|
1997-09-07 07:04:48 +02:00
|
|
|
inhinfo = getInherits(&numInherits);
|
|
|
|
|
2002-05-11 00:36:27 +02:00
|
|
|
/* Link tables to parents, mark parents of target tables interesting */
|
1997-09-07 07:04:48 +02:00
|
|
|
if (g_verbose)
|
2002-05-11 00:36:27 +02:00
|
|
|
write_msg(NULL, "finding inheritance relationships\n");
|
|
|
|
flagInhTables(tblinfo, numTables, inhinfo, numInherits);
|
|
|
|
|
|
|
|
if (g_verbose)
|
|
|
|
write_msg(NULL, "reading column info for interesting tables\n");
|
1997-09-07 07:04:48 +02:00
|
|
|
getTableAttrs(tblinfo, numTables);
|
|
|
|
|
|
|
|
if (g_verbose)
|
2001-07-03 22:21:50 +02:00
|
|
|
write_msg(NULL, "flagging inherited columns in subtables\n");
|
1997-09-07 07:04:48 +02:00
|
|
|
flagInhAttrs(tblinfo, numTables, inhinfo, numInherits);
|
|
|
|
|
2002-05-11 00:36:27 +02:00
|
|
|
if (!dataOnly)
|
2000-01-18 19:09:02 +01:00
|
|
|
{
|
|
|
|
if (g_verbose)
|
2001-07-03 22:21:50 +02:00
|
|
|
write_msg(NULL, "dumping out database comment\n");
|
2000-01-18 19:09:02 +01:00
|
|
|
dumpDBComment(fout);
|
|
|
|
}
|
|
|
|
|
2002-05-11 00:36:27 +02:00
|
|
|
if (!dataOnly)
|
|
|
|
{
|
|
|
|
if (g_verbose)
|
2003-07-23 10:47:41 +02:00
|
|
|
write_msg(NULL, "dumping out user-defined schemas\n");
|
2002-05-11 00:36:27 +02:00
|
|
|
dumpNamespaces(fout, nsinfo, numNamespaces);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!dataOnly)
|
1997-09-07 07:04:48 +02:00
|
|
|
{
|
|
|
|
if (g_verbose)
|
2001-07-03 22:21:50 +02:00
|
|
|
write_msg(NULL, "dumping out user-defined types\n");
|
1997-09-07 07:04:48 +02:00
|
|
|
dumpTypes(fout, finfo, numFuncs, tinfo, numTypes);
|
|
|
|
}
|
1996-07-09 08:22:35 +02:00
|
|
|
|
2000-07-04 16:25:28 +02:00
|
|
|
if (g_verbose)
|
2001-07-03 22:21:50 +02:00
|
|
|
write_msg(NULL, "dumping out tables\n");
|
2002-05-11 00:36:27 +02:00
|
|
|
dumpTables(fout, tblinfo, numTables,
|
2002-04-24 04:44:19 +02:00
|
|
|
aclsSkip, schemaOnly, dataOnly);
|
1996-07-09 08:22:35 +02:00
|
|
|
|
2002-05-11 00:36:27 +02:00
|
|
|
if (!dataOnly)
|
2001-01-12 16:41:29 +01:00
|
|
|
{
|
|
|
|
if (g_verbose)
|
2001-07-03 22:21:50 +02:00
|
|
|
write_msg(NULL, "dumping out indexes\n");
|
2002-05-11 00:36:27 +02:00
|
|
|
dumpIndexes(fout, tblinfo, numTables);
|
2001-01-12 16:41:29 +01:00
|
|
|
}
|
|
|
|
|
2002-05-11 00:36:27 +02:00
|
|
|
if (!dataOnly)
|
1998-10-07 00:14:21 +02:00
|
|
|
{
|
|
|
|
if (g_verbose)
|
2001-07-03 22:21:50 +02:00
|
|
|
write_msg(NULL, "dumping out user-defined procedural languages\n");
|
2002-05-11 00:36:27 +02:00
|
|
|
dumpProcLangs(fout, finfo, numFuncs);
|
1998-10-07 00:14:21 +02:00
|
|
|
}
|
|
|
|
|
2002-05-11 00:36:27 +02:00
|
|
|
if (!dataOnly)
|
1997-09-07 07:04:48 +02:00
|
|
|
{
|
|
|
|
if (g_verbose)
|
2001-07-03 22:21:50 +02:00
|
|
|
write_msg(NULL, "dumping out user-defined functions\n");
|
2002-05-11 00:36:27 +02:00
|
|
|
dumpFuncs(fout, finfo, numFuncs);
|
1997-09-07 07:04:48 +02:00
|
|
|
}
|
|
|
|
|
2002-05-11 00:36:27 +02:00
|
|
|
if (!dataOnly)
|
1997-09-07 07:04:48 +02:00
|
|
|
{
|
|
|
|
if (g_verbose)
|
2001-07-03 22:21:50 +02:00
|
|
|
write_msg(NULL, "dumping out user-defined aggregate functions\n");
|
2002-05-11 00:36:27 +02:00
|
|
|
dumpAggs(fout, agginfo, numAggregates);
|
1997-09-07 07:04:48 +02:00
|
|
|
}
|
|
|
|
|
2002-05-11 00:36:27 +02:00
|
|
|
if (!dataOnly)
|
1997-09-07 07:04:48 +02:00
|
|
|
{
|
|
|
|
if (g_verbose)
|
2001-07-03 22:21:50 +02:00
|
|
|
write_msg(NULL, "dumping out user-defined operators\n");
|
2002-05-11 00:36:27 +02:00
|
|
|
dumpOprs(fout, oprinfo, numOperators);
|
1997-09-07 07:04:48 +02:00
|
|
|
}
|
1996-07-09 08:22:35 +02:00
|
|
|
|
2002-07-30 23:56:04 +02:00
|
|
|
if (!dataOnly)
|
|
|
|
{
|
|
|
|
if (g_verbose)
|
|
|
|
write_msg(NULL, "dumping out user-defined operator classes\n");
|
|
|
|
dumpOpclasses(fout, opcinfo, numOpclasses);
|
|
|
|
}
|
|
|
|
|
2002-07-19 01:11:32 +02:00
|
|
|
if (!dataOnly)
|
|
|
|
{
|
|
|
|
if (g_verbose)
|
|
|
|
write_msg(NULL, "dumping out user-defined casts\n");
|
|
|
|
dumpCasts(fout, finfo, numFuncs, tinfo, numTypes);
|
|
|
|
}
|
|
|
|
|
2003-11-21 23:32:49 +01:00
|
|
|
if (!dataOnly)
|
|
|
|
{
|
|
|
|
if (g_verbose)
|
|
|
|
write_msg(NULL, "dumping out user-defined conversions\n");
|
|
|
|
dumpConversions(fout, convinfo, numConversions);
|
|
|
|
}
|
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
*numTablesPtr = numTables;
|
2001-01-12 16:41:29 +01:00
|
|
|
return tblinfo;
|
1996-08-24 22:49:41 +02:00
|
|
|
}
|
|
|
|
|
2002-05-11 00:36:27 +02:00
|
|
|
/* flagInhTables -
|
|
|
|
* Fill in parentIndexes fields of every target table, and mark
|
|
|
|
* parents of target tables as interesting
|
1997-09-07 07:04:48 +02:00
|
|
|
*
|
2002-05-11 00:36:27 +02:00
|
|
|
* Note that only direct ancestors of targets are marked interesting.
|
|
|
|
* This is sufficient; we don't much care whether they inherited their
|
|
|
|
* attributes or not.
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
* modifies tblinfo
|
2002-05-11 00:36:27 +02:00
|
|
|
*/
|
|
|
|
static void
|
|
|
|
flagInhTables(TableInfo *tblinfo, int numTables,
|
|
|
|
InhInfo *inhinfo, int numInherits)
|
|
|
|
{
|
|
|
|
int i,
|
|
|
|
j;
|
|
|
|
int numParents;
|
|
|
|
int *parentIndexes;
|
|
|
|
|
|
|
|
for (i = 0; i < numTables; i++)
|
|
|
|
{
|
2002-08-29 02:17:06 +02:00
|
|
|
/* Sequences and views never have parents */
|
2002-05-11 00:36:27 +02:00
|
|
|
if (tblinfo[i].relkind == RELKIND_SEQUENCE ||
|
2002-08-29 02:17:06 +02:00
|
|
|
tblinfo[i].relkind == RELKIND_VIEW)
|
2002-05-11 00:36:27 +02:00
|
|
|
continue;
|
|
|
|
|
|
|
|
/* Don't bother computing anything for non-target tables, either */
|
|
|
|
if (!tblinfo[i].dump)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/* Find all the immediate parent tables */
|
|
|
|
findParentsByOid(tblinfo, numTables,
|
|
|
|
inhinfo, numInherits,
|
|
|
|
tblinfo[i].oid,
|
|
|
|
&tblinfo[i].numParents,
|
|
|
|
&tblinfo[i].parentIndexes);
|
|
|
|
numParents = tblinfo[i].numParents;
|
|
|
|
parentIndexes = tblinfo[i].parentIndexes;
|
|
|
|
|
|
|
|
/* Mark the parents as interesting for getTableAttrs */
|
|
|
|
for (j = 0; j < numParents; j++)
|
|
|
|
{
|
|
|
|
int parentInd = parentIndexes[j];
|
|
|
|
|
|
|
|
tblinfo[parentInd].interesting = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* flagInhAttrs -
|
|
|
|
* for each dumpable table in tblinfo, flag its inherited attributes
|
|
|
|
* so when we dump the table out, we don't dump out the inherited attributes
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
2002-05-11 00:36:27 +02:00
|
|
|
* modifies tblinfo
|
1996-07-09 08:22:35 +02:00
|
|
|
*/
|
1997-08-19 23:40:56 +02:00
|
|
|
static void
|
1997-09-08 23:56:23 +02:00
|
|
|
flagInhAttrs(TableInfo *tblinfo, int numTables,
|
|
|
|
InhInfo *inhinfo, int numInherits)
|
1996-07-09 08:22:35 +02:00
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
int i,
|
|
|
|
j,
|
|
|
|
k;
|
|
|
|
int parentInd;
|
2001-04-03 10:52:59 +02:00
|
|
|
int inhAttrInd;
|
2002-05-11 00:36:27 +02:00
|
|
|
int numParents;
|
|
|
|
int *parentIndexes;
|
2001-10-25 07:50:21 +02:00
|
|
|
bool foundAttr; /* Attr was found in a parent */
|
2001-04-03 10:52:59 +02:00
|
|
|
bool foundNotNull; /* Attr was NOT NULL in a parent */
|
|
|
|
bool defaultsMatch; /* All non-empty defaults match */
|
|
|
|
bool defaultsFound; /* Found a default in a parent */
|
2001-10-25 07:50:21 +02:00
|
|
|
char *attrDef;
|
|
|
|
char *inhDef;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
2002-05-11 00:36:27 +02:00
|
|
|
for (i = 0; i < numTables; i++)
|
1997-09-07 07:04:48 +02:00
|
|
|
{
|
2002-08-29 02:17:06 +02:00
|
|
|
/* Sequences and views never have parents */
|
2002-05-11 00:36:27 +02:00
|
|
|
if (tblinfo[i].relkind == RELKIND_SEQUENCE ||
|
2002-08-29 02:17:06 +02:00
|
|
|
tblinfo[i].relkind == RELKIND_VIEW)
|
2002-05-11 00:36:27 +02:00
|
|
|
continue;
|
|
|
|
|
|
|
|
/* Don't bother computing anything for non-target tables, either */
|
|
|
|
if (!tblinfo[i].dump)
|
2001-04-03 10:52:59 +02:00
|
|
|
continue;
|
|
|
|
|
2002-05-11 00:36:27 +02:00
|
|
|
numParents = tblinfo[i].numParents;
|
|
|
|
parentIndexes = tblinfo[i].parentIndexes;
|
|
|
|
|
|
|
|
if (numParents == 0)
|
|
|
|
continue; /* nothing to see here, move along */
|
2001-04-03 10:52:59 +02:00
|
|
|
|
2002-10-09 18:20:25 +02:00
|
|
|
/*----------------------------------------------------------------
|
2001-10-25 07:50:21 +02:00
|
|
|
* For each attr, check the parent info: if no parent has an attr
|
|
|
|
* with the same name, then it's not inherited. If there *is* an
|
|
|
|
* attr with the same name, then only dump it if:
|
2001-04-03 10:52:59 +02:00
|
|
|
*
|
2002-10-09 18:20:25 +02:00
|
|
|
* - it is NOT NULL and zero parents are NOT NULL
|
2003-08-04 02:43:34 +02:00
|
|
|
* OR
|
2002-10-09 18:20:25 +02:00
|
|
|
* - it has a default value AND the default value does not match
|
2003-08-04 02:43:34 +02:00
|
|
|
* all parent default values, or no parents specify a default.
|
2001-04-03 10:52:59 +02:00
|
|
|
*
|
|
|
|
* See discussion on -hackers around 2-Apr-2001.
|
2002-10-09 18:20:25 +02:00
|
|
|
*----------------------------------------------------------------
|
2001-04-03 10:52:59 +02:00
|
|
|
*/
|
|
|
|
for (j = 0; j < tblinfo[i].numatts; j++)
|
1997-09-07 07:04:48 +02:00
|
|
|
{
|
2001-04-03 10:52:59 +02:00
|
|
|
foundAttr = false;
|
|
|
|
foundNotNull = false;
|
|
|
|
defaultsMatch = true;
|
|
|
|
defaultsFound = false;
|
|
|
|
|
|
|
|
attrDef = tblinfo[i].adef_expr[j];
|
|
|
|
|
2002-05-11 00:36:27 +02:00
|
|
|
for (k = 0; k < numParents; k++)
|
1998-09-20 05:18:43 +02:00
|
|
|
{
|
2002-05-11 00:36:27 +02:00
|
|
|
parentInd = parentIndexes[k];
|
2001-04-03 10:52:59 +02:00
|
|
|
inhAttrInd = strInArray(tblinfo[i].attnames[j],
|
|
|
|
tblinfo[parentInd].attnames,
|
|
|
|
tblinfo[parentInd].numatts);
|
|
|
|
|
|
|
|
if (inhAttrInd != -1)
|
|
|
|
{
|
|
|
|
foundAttr = true;
|
|
|
|
foundNotNull |= tblinfo[parentInd].notnull[inhAttrInd];
|
2002-05-11 00:36:27 +02:00
|
|
|
if (attrDef != NULL) /* If we have a default,
|
2001-10-25 07:50:21 +02:00
|
|
|
* check parent */
|
2001-04-03 10:52:59 +02:00
|
|
|
{
|
|
|
|
inhDef = tblinfo[parentInd].adef_expr[inhAttrInd];
|
|
|
|
|
|
|
|
if (inhDef != NULL)
|
|
|
|
{
|
|
|
|
defaultsFound = true;
|
|
|
|
defaultsMatch &= (strcmp(attrDef, inhDef) == 0);
|
2002-05-11 00:36:27 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2001-04-03 10:52:59 +02:00
|
|
|
|
2001-10-25 07:50:21 +02:00
|
|
|
/*
|
|
|
|
* Based on the scan of the parents, decide if we can rely on
|
|
|
|
* the inherited attr
|
2001-04-03 10:52:59 +02:00
|
|
|
*/
|
2001-10-25 07:50:21 +02:00
|
|
|
if (foundAttr) /* Attr was inherited */
|
1997-09-07 07:04:48 +02:00
|
|
|
{
|
2001-04-03 10:52:59 +02:00
|
|
|
/* Set inherited flag by default */
|
2002-05-11 00:36:27 +02:00
|
|
|
tblinfo[i].inhAttrs[j] = true;
|
|
|
|
tblinfo[i].inhAttrDef[j] = true;
|
|
|
|
tblinfo[i].inhNotNull[j] = true;
|
2001-04-03 10:52:59 +02:00
|
|
|
|
2001-10-25 07:50:21 +02:00
|
|
|
/*
|
|
|
|
* Clear it if attr had a default, but parents did not, or
|
|
|
|
* mismatch
|
|
|
|
*/
|
|
|
|
if ((attrDef != NULL) && (!defaultsFound || !defaultsMatch))
|
2001-04-03 10:52:59 +02:00
|
|
|
{
|
2002-05-11 00:36:27 +02:00
|
|
|
tblinfo[i].inhAttrs[j] = false;
|
|
|
|
tblinfo[i].inhAttrDef[j] = false;
|
2001-04-03 10:52:59 +02:00
|
|
|
}
|
|
|
|
|
2001-10-25 07:50:21 +02:00
|
|
|
/*
|
|
|
|
* Clear it if NOT NULL and none of the parents were NOT
|
|
|
|
* NULL
|
|
|
|
*/
|
2001-04-03 10:52:59 +02:00
|
|
|
if (tblinfo[i].notnull[j] && !foundNotNull)
|
|
|
|
{
|
2002-05-11 00:36:27 +02:00
|
|
|
tblinfo[i].inhAttrs[j] = false;
|
|
|
|
tblinfo[i].inhNotNull[j] = false;
|
2001-04-03 10:52:59 +02:00
|
|
|
}
|
2002-10-09 18:20:25 +02:00
|
|
|
|
|
|
|
/* Clear it if attr has local definition */
|
|
|
|
if (g_fout->remoteVersion >= 70300 && tblinfo[i].attislocal[j])
|
|
|
|
tblinfo[i].inhAttrs[j] = false;
|
1997-09-07 07:04:48 +02:00
|
|
|
}
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
2002-05-11 00:36:27 +02:00
|
|
|
* findTableByOid
|
|
|
|
* finds the index (in tblinfo) of the table with the given oid
|
1997-09-07 07:04:48 +02:00
|
|
|
* returns -1 if not found
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
* NOTE: should hash this, but just do linear search for now
|
|
|
|
*/
|
|
|
|
int
|
2002-05-11 00:36:27 +02:00
|
|
|
findTableByOid(TableInfo *tblinfo, int numTables, const char *oid)
|
1996-07-09 08:22:35 +02:00
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
int i;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
for (i = 0; i < numTables; i++)
|
|
|
|
{
|
2002-05-11 00:36:27 +02:00
|
|
|
if (strcmp(tblinfo[i].oid, oid) == 0)
|
1997-09-07 07:04:48 +02:00
|
|
|
return i;
|
|
|
|
}
|
|
|
|
return -1;
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
2002-05-11 00:36:27 +02:00
|
|
|
|
1996-07-09 08:22:35 +02:00
|
|
|
/*
|
2002-05-11 00:36:27 +02:00
|
|
|
* findFuncByOid
|
|
|
|
* finds the index (in finfo) of the function with the given OID
|
1997-09-07 07:04:48 +02:00
|
|
|
* returns -1 if not found
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
* NOTE: should hash this, but just do linear search for now
|
|
|
|
*/
|
2002-05-11 00:36:27 +02:00
|
|
|
int
|
|
|
|
findFuncByOid(FuncInfo *finfo, int numFuncs, const char *oid)
|
1996-07-09 08:22:35 +02:00
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
int i;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
2002-05-11 00:36:27 +02:00
|
|
|
for (i = 0; i < numFuncs; i++)
|
1997-09-07 07:04:48 +02:00
|
|
|
{
|
2002-05-11 00:36:27 +02:00
|
|
|
if (strcmp(finfo[i].oid, oid) == 0)
|
1997-09-07 07:04:48 +02:00
|
|
|
return i;
|
|
|
|
}
|
|
|
|
return -1;
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
2002-07-19 01:11:32 +02:00
|
|
|
/*
|
|
|
|
* Finds the index (in tinfo) of the type with the given OID. Returns
|
|
|
|
* -1 if not found.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
findTypeByOid(TypeInfo *tinfo, int numTypes, const char *oid)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < numTypes; i++)
|
|
|
|
{
|
|
|
|
if (strcmp(tinfo[i].oid, oid) == 0)
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
1996-07-09 08:22:35 +02:00
|
|
|
/*
|
2002-05-11 00:36:27 +02:00
|
|
|
* findOprByOid
|
|
|
|
* given the oid of an operator, return the name of the operator
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
* NOTE: should hash this, but just do linear search for now
|
|
|
|
*/
|
2002-05-11 00:36:27 +02:00
|
|
|
char *
|
|
|
|
findOprByOid(OprInfo *oprinfo, int numOprs, const char *oid)
|
|
|
|
{
|
|
|
|
int i;
|
1996-07-09 08:22:35 +02:00
|
|
|
|
2002-05-11 00:36:27 +02:00
|
|
|
for (i = 0; i < numOprs; i++)
|
|
|
|
{
|
|
|
|
if (strcmp(oprinfo[i].oid, oid) == 0)
|
|
|
|
return oprinfo[i].oprname;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* should never get here */
|
2003-07-23 10:47:41 +02:00
|
|
|
write_msg(NULL, "failed sanity check, operator with OID %s not found\n", oid);
|
2002-05-11 00:36:27 +02:00
|
|
|
|
|
|
|
/* no suitable operator name was found */
|
|
|
|
return (NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* findParentsByOid
|
|
|
|
* given the oid of a class, find its parent classes in tblinfo[]
|
|
|
|
*
|
|
|
|
* Returns the number of parents and their array indexes into the
|
|
|
|
* last two arguments.
|
|
|
|
*/
|
|
|
|
|
|
|
|
static void
|
|
|
|
findParentsByOid(TableInfo *tblinfo, int numTables,
|
|
|
|
InhInfo *inhinfo, int numInherits,
|
|
|
|
const char *oid,
|
|
|
|
int *numParentsPtr, int **parentIndexes)
|
|
|
|
{
|
|
|
|
int i,
|
|
|
|
j;
|
|
|
|
int parentInd,
|
|
|
|
selfInd;
|
|
|
|
int numParents;
|
|
|
|
|
|
|
|
numParents = 0;
|
|
|
|
for (i = 0; i < numInherits; i++)
|
|
|
|
{
|
|
|
|
if (strcmp(inhinfo[i].inhrelid, oid) == 0)
|
|
|
|
numParents++;
|
|
|
|
}
|
|
|
|
|
|
|
|
*numParentsPtr = numParents;
|
|
|
|
|
|
|
|
if (numParents > 0)
|
|
|
|
{
|
|
|
|
*parentIndexes = (int *) malloc(sizeof(int) * numParents);
|
|
|
|
j = 0;
|
|
|
|
for (i = 0; i < numInherits; i++)
|
|
|
|
{
|
|
|
|
if (strcmp(inhinfo[i].inhrelid, oid) == 0)
|
|
|
|
{
|
|
|
|
parentInd = findTableByOid(tblinfo, numTables,
|
|
|
|
inhinfo[i].inhparent);
|
|
|
|
if (parentInd < 0)
|
|
|
|
{
|
|
|
|
selfInd = findTableByOid(tblinfo, numTables, oid);
|
|
|
|
if (selfInd >= 0)
|
2003-07-23 10:47:41 +02:00
|
|
|
write_msg(NULL, "failed sanity check, parent OID %s of table \"%s\" (OID %s) not found\n",
|
2002-05-11 00:36:27 +02:00
|
|
|
inhinfo[i].inhparent,
|
|
|
|
tblinfo[selfInd].relname,
|
|
|
|
oid);
|
|
|
|
else
|
2003-07-23 10:47:41 +02:00
|
|
|
write_msg(NULL, "failed sanity check, parent OID %s of table (OID %s) not found\n",
|
2002-05-11 00:36:27 +02:00
|
|
|
inhinfo[i].inhparent,
|
|
|
|
oid);
|
|
|
|
|
|
|
|
exit_nicely();
|
|
|
|
}
|
|
|
|
(*parentIndexes)[j++] = parentInd;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
*parentIndexes = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* parseNumericArray
|
|
|
|
* parse a string of numbers delimited by spaces into a character array
|
|
|
|
*/
|
|
|
|
|
|
|
|
void
|
|
|
|
parseNumericArray(const char *str, char **array, int arraysize)
|
|
|
|
{
|
|
|
|
int j,
|
|
|
|
argNum;
|
|
|
|
char temp[100];
|
|
|
|
char s;
|
|
|
|
|
|
|
|
argNum = 0;
|
|
|
|
j = 0;
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
s = *str++;
|
|
|
|
if (s == ' ' || s == '\0')
|
|
|
|
{
|
|
|
|
if (j > 0)
|
|
|
|
{
|
|
|
|
if (argNum >= arraysize)
|
|
|
|
{
|
2003-07-23 10:47:41 +02:00
|
|
|
write_msg(NULL, "could not parse numeric array: too many numbers\n");
|
2002-05-11 00:36:27 +02:00
|
|
|
exit_nicely();
|
|
|
|
}
|
|
|
|
temp[j] = '\0';
|
|
|
|
array[argNum++] = strdup(temp);
|
|
|
|
j = 0;
|
|
|
|
}
|
|
|
|
if (s == '\0')
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!(isdigit((unsigned char) s) || s == '-') ||
|
|
|
|
j >= sizeof(temp) - 1)
|
|
|
|
{
|
2003-07-23 10:47:41 +02:00
|
|
|
write_msg(NULL, "could not parse numeric array: invalid character in number\n");
|
2002-05-11 00:36:27 +02:00
|
|
|
exit_nicely();
|
|
|
|
}
|
|
|
|
temp[j++] = s;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
while (argNum < arraysize)
|
|
|
|
array[argNum++] = strdup("0");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* strInArray:
|
|
|
|
* takes in a string and a string array and the number of elements in the
|
|
|
|
* string array.
|
|
|
|
* returns the index if the string is somewhere in the array, -1 otherwise
|
|
|
|
*/
|
|
|
|
|
|
|
|
static int
|
|
|
|
strInArray(const char *pattern, char **arr, int arr_size)
|
1996-07-09 08:22:35 +02:00
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
int i;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
2002-05-11 00:36:27 +02:00
|
|
|
for (i = 0; i < arr_size; i++)
|
1997-09-07 07:04:48 +02:00
|
|
|
{
|
2002-05-11 00:36:27 +02:00
|
|
|
if (strcmp(pattern, arr[i]) == 0)
|
1997-09-07 07:04:48 +02:00
|
|
|
return i;
|
|
|
|
}
|
|
|
|
return -1;
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|